00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef Fennel_RegisterReference_Included
00026 #define Fennel_RegisterReference_Included
00027
00028 #include "fennel/tuple/TupleData.h"
00029 #include "fennel/tuple/StandardTypeDescriptor.h"
00030 #include "fennel/exec/DynamicParam.h"
00031 #include "boost/lexical_cast.hpp"
00032
00033 #include <strstream>
00034
00035 FENNEL_BEGIN_NAMESPACE
00036
00037 using namespace std;
00038 using boost::lexical_cast;
00039
00040 class Calculator;
00041 class RegisterSetBinding;
00042
00043 typedef RegisterSetBinding ** TRegisterSetP;
00044 typedef TupleDescriptor ** TRegisterSetDescP;
00045 typedef uint32_t TRegisterRefProp;
00046
00047
00049 class FENNEL_CALCULATOR_EXPORT RegisterSetBinding
00050 {
00051 const bool ownTheBase;
00052 uint ncols;
00053 TupleData *const base;
00054 PConstBuffer *datumAddr;
00055
00056
00057
00058
00059
00060
00061
00062
00063 public:
00064 ~RegisterSetBinding();
00065
00069 RegisterSetBinding(TupleData* base, bool ownIt = false);
00070
00077 RegisterSetBinding(
00078 TupleData* base,
00079 const TupleData* shadow,
00080 bool ownIt = false);
00081
00083 const TupleData& asTupleData() const {
00084 return *base;
00085 }
00086
00088 TupleDatum& operator[](int n) {
00089 assert((n >= 0) && (n < ncols));
00090 return (*base)[n];
00091 }
00092
00094 PConstBuffer getTargetAddr(int n) {
00095 assert((n >= 0) && (n < ncols));
00096 return datumAddr[n];
00097 }
00098 };
00099
00100
00113 class FENNEL_CALCULATOR_EXPORT RegisterReference
00114 {
00115 public:
00117 enum ERegisterSet {
00118 EFirstSet = 0,
00119 ELiteral = 0,
00120 EInput = 1,
00121 EOutput = 2,
00122 ELocal = 3,
00123 EStatus = 4,
00124 ELastSet,
00125 EUnknown = 1000
00126 };
00127
00129 explicit
00130 RegisterReference()
00131 : mSetIndex(EUnknown),
00132 mIndex(0),
00133 mType(STANDARD_TYPE_END_NO_UNICODE),
00134 mPData(0),
00135 mCbData(0),
00136 mCbStorage(0),
00137 mPDynamicParamManager(0)
00138 {
00139 mProp = EPropNone;
00140 }
00141
00147 explicit
00148 RegisterReference(
00149 ERegisterSet set,
00150 unsigned long index,
00151 StandardTypeDescriptorOrdinal datatype)
00152 : mSetIndex(set),
00153 mIndex(index),
00154 mType(datatype),
00155 mPData(0),
00156 mCbData(0),
00157 mCbStorage(0),
00158 mPDynamicParamManager(0)
00159 {
00160 assert(mSetIndex < ELastSet);
00161 assert(mSetIndex >= EFirstSet);
00162 setDefaultProperties();
00163 }
00164
00165 virtual
00166 ~RegisterReference() {}
00167
00168
00172 enum EProperties {
00173 EPropNone = 0,
00174 EPropReadOnly = 1,
00175
00176 EPropCachePointer = 2,
00177
00178 EPropPtrReset = 4,
00179 EPropByRefOnly = 8
00180
00181
00182 };
00183
00184
00186 static const uint32_t KLiteralSetDefault =
00187 EPropReadOnly | EPropCachePointer;
00188
00190 static const uint32_t KInputSetDefault = EPropReadOnly;
00191
00193 static const uint32_t KOutputSetDefault = EPropNone;
00194
00197 static const uint32_t KLocalSetDefault =
00198 EPropCachePointer | EPropPtrReset;
00199
00201 static const uint32_t KStatusSetDefault = EPropNone;
00202
00208 void setCalc(Calculator* calcP);
00209
00214 void cachePointer();
00215
00217 ERegisterSet setIndex() const
00218 {
00219 return mSetIndex;
00220 }
00222 unsigned long index() const
00223 {
00224 return mIndex;
00225 }
00227 bool isValid() const
00228 {
00229 return ((mSetIndex < ELastSet) ? true : false);
00230 }
00232 StandardTypeDescriptorOrdinal type() const {
00233 return mType;
00234 }
00235
00237 static inline string getSetName(ERegisterSet set)
00238 {
00239 switch (set) {
00240 case ELiteral:
00241 return "C";
00242 case ELocal:
00243 return "L";
00244 case EInput:
00245 return "I";
00246 case EOutput:
00247 return "O";
00248 case EStatus:
00249 return "S";
00250 default:
00251 throw std::invalid_argument(
00252 "fennel/calculator/RegisterReference::getSetName");
00253 }
00254 }
00255
00256
00259 static inline string toString(ERegisterSet set, unsigned long index)
00260 {
00261 ostringstream ostr("");
00262 ostr << getSetName(set) << index;
00263 return ostr.str();
00264 }
00265
00267 string toString() const;
00269 virtual string valueToString() const = 0;
00271 virtual bool isNull() const = 0;
00272
00274 inline DynamicParamManager* getDynamicParamManager() const {
00275 assert(mPDynamicParamManager);
00276 return mPDynamicParamManager;
00277 }
00278
00282 TupleDatum* getBinding(bool resetFromNull = false) const {
00283
00284 assert(mRegisterSetP);
00285 assert(mSetIndex < ELastSet);
00286 assert(mRegisterSetP[mSetIndex]);
00287 RegisterSetBinding* rsb = mRegisterSetP[mSetIndex];
00288 TupleDatum& bind = (*rsb)[mIndex];
00289 if (resetFromNull) {
00290 if (!bind.pData) {
00291 bind.pData = mRegisterSetP[mSetIndex]->getTargetAddr(mIndex);
00292 }
00293 }
00294 return &bind;
00295 }
00296
00297 protected:
00299 const ERegisterSet mSetIndex;
00300
00302 const unsigned long mIndex;
00303
00305 const StandardTypeDescriptorOrdinal mType;
00306
00310 TRegisterSetP mRegisterSetP;
00311
00315 TRegisterSetDescP mRegisterSetDescP;
00316
00320 vector<RegisterReference *>*mResetP;
00321
00323 bool mCachePtrModified;
00324
00328 PBuffer mPData;
00329
00333 TupleStorageByteLength mCbData;
00334
00338 TupleStorageByteLength mCbStorage;
00339
00341 TRegisterRefProp mProp;
00342
00344 DynamicParamManager* mPDynamicParamManager;
00345
00347 void setDefaultProperties();
00348
00349 };
00350
00352 template<typename TMPLT>
00353 class RegisterRef : public RegisterReference
00354 {
00355 public:
00356 explicit
00358 RegisterRef () : RegisterReference()
00359 {}
00360
00366 explicit
00367 RegisterRef(
00368 ERegisterSet set,
00369 unsigned long index,
00370 StandardTypeDescriptorOrdinal datatype)
00371 : RegisterReference(set, index, datatype)
00372 {}
00373
00377 TMPLT value() const {
00378 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00379 assert(mPData);
00380 return *(reinterpret_cast<TMPLT*>(mPData));
00381 } else {
00382 TupleDatum *bind = getBinding();
00383 assert(bind->pData);
00384 return *(reinterpret_cast<TMPLT*>(
00385 const_cast<PBuffer>(bind->pData)));
00386 }
00387 }
00388
00389
00391 void
00392 value(TMPLT newV)
00393 {
00394
00395
00396 if (0) {
00397 assert(!(mProp & EPropReadOnly));
00398 }
00399
00400 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00401 assert(mPData);
00402 *(reinterpret_cast<TMPLT*>(mPData)) = newV;
00403 } else {
00404 TupleDatum *bind = getBinding(true);
00405 assert(bind->pData);
00406 *(reinterpret_cast<TMPLT*>(
00407 const_cast<PBuffer>(bind->pData))) = newV;
00408 }
00409 }
00410
00412 bool isNullable()
00413 {
00414 return !(mProp & EPropReadOnly);
00415 }
00416
00420 void toNull() {
00421 assert(!(mProp & EPropReadOnly));
00422 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00423 if ((mProp & EPropPtrReset) && !mCachePtrModified) {
00424 mCachePtrModified = true;
00425 mResetP->push_back(this);
00426 }
00427 mPData = NULL;
00428 mCbData = 0;
00429 } else {
00430 TupleDatum *bind = getBinding();
00431 bind->pData = NULL;
00432 }
00433 }
00434
00436 bool isNull() const {
00437 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00438 return (mPData ? false : true);
00439 } else {
00440 TupleDatum *bind = getBinding();
00441 return (bind->pData ? false : true);
00442 }
00443 }
00444
00450 TMPLT
00451 pointer() const {
00452 assert(StandardTypeDescriptor::isArray(mType));
00453 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00454 assert(mPData);
00455 return reinterpret_cast<TMPLT>(mPData);
00456 } else {
00457 TupleDatum *bind = getBinding();
00458 assert(bind->pData);
00459 return reinterpret_cast<TMPLT>(const_cast<PBuffer>(bind->pData));
00460 }
00461 }
00468 void
00469 pointer(TMPLT newP, TupleStorageByteLength len)
00470 {
00471 assert(!(mProp & EPropReadOnly));
00472 assert(newP);
00473 assert(StandardTypeDescriptor::isArray(mType));
00474 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00475 if ((mProp & EPropPtrReset) && !mCachePtrModified) {
00476 mCachePtrModified = true;
00477 mResetP->push_back(this);
00478 }
00479 mPData = reinterpret_cast<PBuffer>(newP);
00480 mCbData = len;
00481 } else {
00482 TupleDatum *bind = getBinding();
00483 bind->pData = reinterpret_cast<PConstBuffer>(newP);
00484 bind->cbData = len;
00485 }
00486 }
00488 TMPLT*
00489 refer() const {
00490 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00491 return reinterpret_cast<TMPLT*>(const_cast<PBuffer>(mPData));
00492 } else {
00493 TupleDatum *bind = getBinding();
00494 return reinterpret_cast<TMPLT*>(const_cast<PBuffer>(bind->pData));
00495 }
00496 }
00503 void
00504 refer(RegisterRef<TMPLT>* from)
00505 {
00506 assert(!(mProp & (EPropCachePointer | EPropPtrReset)));
00507 TupleDatum *bind = getBinding();
00508 bind->pData = reinterpret_cast<PConstBuffer>(
00509 const_cast<TMPLT*>(from->refer()));
00510 bind->cbData = from->length();
00511 }
00512
00518 TupleStorageByteLength
00519 length() const
00520 {
00521 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00522 return mCbData;
00523 } else {
00524 TupleDatum *bind = getBinding();
00525 return bind->cbData;
00526 }
00527 }
00534 TupleStorageByteLength
00535 storage() const
00536 {
00537 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00538 return mCbStorage;
00539 } else {
00540 assert(mRegisterSetP);
00541 assert(mSetIndex < ELastSet);
00542 assert(mRegisterSetDescP[mSetIndex]);
00543
00544
00545
00546
00547 return ((*(mRegisterSetDescP[mSetIndex]))[mIndex]).cbStorage;
00548 }
00549 }
00554 TupleStorageByteLength
00555 stringLength() const
00556 {
00557 assert(StandardTypeDescriptor::isArray(mType));
00558 if (StandardTypeDescriptor::isVariableLenArray(mType)) {
00559 return length();
00560 } else {
00561 return storage();
00562 }
00563 }
00569 void
00570 length(TupleStorageByteLength newLen)
00571 {
00572 if (mProp & (EPropCachePointer | EPropPtrReset)) {
00573
00574 assert(newLen == 0 ? true : (mPData == 0 ? false : true));
00575
00576 assert(newLen <= mCbStorage);
00577 mCbData = newLen;
00578 } else {
00579 assert(
00580 newLen
00581 <= ((*(mRegisterSetDescP[mSetIndex]))[mIndex]).cbStorage);
00582 TupleDatum *bind = getBinding();
00583 bind->cbData = newLen;
00584 }
00585 }
00590 void
00591 stringLength(TupleStorageByteLength newLen)
00592 {
00593 assert(StandardTypeDescriptor::isArray(mType));
00594 if (StandardTypeDescriptor::isVariableLenArray(mType)) {
00595 length(newLen);
00596 }
00597 }
00598
00603 string
00604 valueToString() const {
00605 if (this->isNull()) {
00606 return "NULL";
00607 }
00608 if (StandardTypeDescriptor::isArray(mType)) {
00609 #if 0
00610
00611
00612
00613 string ret((char *)(this->pointer()), this->getS());
00614 return ret;
00615 #endif
00616 return "Unimpl";
00617 } else {
00618
00619 return boost::lexical_cast<std::string>(this->value());
00620 }
00621 }
00622 protected:
00623
00624 };
00625
00626 FENNEL_END_NAMESPACE
00627
00628 #endif
00629
00630