00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __CLASS_H__
00012 #define __CLASS_H__
00013
00014 #include "stdtp.h"
00015 #include "sync.h"
00016 #include "rectangle.h"
00017
00018 BEGIN_GIGABASE_NAMESPACE
00019
00020 #ifndef dbDatabaseOffsetBits
00021 #ifdef LARGE_DATABASE_SUPPORT
00022 #define dbDatabaseOffsetBits 40 // up to 1 terabyte
00023 #else
00024 #define dbDatabaseOffsetBits 32 // 37 - 128Gb, 40 - up to 1 terabyte
00025 #endif
00026 #endif
00027
00028 #ifndef dbDatabaseOidBits
00029 #define dbDatabaseOidBits 32
00030 #endif
00031
00035 #if dbDatabaseOidBits > 32
00036 typedef nat8 oid_t;
00037 #else
00038 typedef nat4 oid_t;
00039 #endif
00040
00044 #if dbDatabaseOffsetBits > 32
00045 typedef nat8 offs_t;
00046 #else
00047 typedef nat4 offs_t;
00048 #endif
00049
00050 #include "selection.h"
00051
00055 enum dbIndexType {
00056 HASHED = 1,
00057 INDEXED = 2,
00058 CASE_INSENSITIVE = 4,
00059
00060 DB_FIELD_CASCADE_DELETE = 8,
00061 UNIQUE = 16,
00062
00063 AUTOINCREMENT = 32,
00064 OPTIMIZE_DUPLICATES = 64,
00065
00066 DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
00067 };
00068
00072 #define KEY(x, index) \
00073 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00074 sizeof(x), index), x)
00075
00079 #define FIELD(x) KEY(x, 0)
00080
00084 typedef int (*dbUDTComparator)(void*, void*, size_t);
00085
00089 #define UDT(x, index, comparator) \
00090 *dbDescribeRawField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00091 sizeof(x), index), (dbUDTComparator)comparator)
00092
00096 #define RAWFIELD(x) UDT(x, 0, &memcmp)
00097
00101 #define RAWKEY(x, index) UDT(x, index, &memcmp)
00102
00103
00109 #define RELATION(x,inverse) \
00110 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00111 sizeof(x), 0, STRLITERAL(#inverse)), x)
00112
00118 #define INDEXED_RELATION(x,inverse) \
00119 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00120 sizeof(x), INDEXED, STRLITERAL(#inverse)), x)
00121
00127 #define OWNER(x,member) \
00128 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00129 sizeof(x), DB_FIELD_CASCADE_DELETE, \
00130 #member), x)
00131
00135 #define METHOD(x) \
00136 *dbDescribeMethod(new dbFieldDescriptor(STRLITERAL(#x)), &self::x)
00137
00141 #define SUPERCLASS(x) \
00142 x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)
00143
00148 #define TYPE_DESCRIPTOR(fields) \
00149 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00150 return &fields; \
00151 } \
00152 static dbTableDescriptor dbDescriptor
00153
00159 #define CLASS_DESCRIPTOR(name, fields) \
00160 typedef name self; \
00161 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00162 return &fields; \
00163 } \
00164 static dbTableDescriptor dbDescriptor
00165
00166 #if (defined(_MSC_VER) && _MSC_VER+0 < 1200) || defined(__MWERKS__)
00167
00170 #if defined(_MSC_VER)
00171 #define TEMPLATE_SPEC
00172 #else
00173 #define TEMPLATE_SPEC template <>
00174 #endif
00175 #define REGISTER_IN(table, database) \
00176 TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00177 { return &table::dbDescriptor; } \
00178 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00179 { return ((table*)0)->dbDescribeComponents(NULL); } \
00180 dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00181 &dbDescribeComponentsOf##table)
00182
00183 #define REGISTER_TEMPLATE_IN(table, database) \
00184 TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00185 { return &table::dbDescriptor; } \
00186 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00187 { return ((table*)0)->dbDescribeComponents(NULL); } \
00188 template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00189 &dbDescribeComponentsOf##table)
00190 #else
00191
00194 #define REGISTER_IN(table, database) \
00195 dbTableDescriptor* dbGetTableDescriptor(table*) \
00196 { return &table::dbDescriptor; } \
00197 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00198 { return ((table*)0)->dbDescribeComponents(NULL); } \
00199 dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00200 &dbDescribeComponentsOf##table)
00201 #define REGISTER_TEMPLATE_IN(table, database) \
00202 dbTableDescriptor* dbGetTableDescriptor(table*) \
00203 { return &table::dbDescriptor; } \
00204 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00205 { return ((table*)0)->dbDescribeComponents(NULL); } \
00206 template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00207 &dbDescribeComponentsOf##table)
00208 #endif
00209
00214 #define REGISTER(table) REGISTER_IN(table, NULL)
00215 #define REGISTER_TEMPLATE(table) REGISTER_TEMPLATE_IN(table, NULL)
00216
00221 #define DETACHED_TABLE ((dbDatabase*)-1)
00222 #define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
00223 #define REGISTER_TEMPLATE_UNASSIGNED(table) REGISTER_TEMPLATE_IN(table, DETACHED_TABLE)
00224
00225
00226 class dbDatabase;
00227 class dbAnyArray;
00228 class dbTableDescriptor;
00229 class dbAnyMethodTrampoline;
00230 class dbTable;
00231
00235 class GIGABASE_DLL_ENTRY dbFieldDescriptor {
00236 public:
00240 dbFieldDescriptor* next;
00241
00245 dbFieldDescriptor* prev;
00246
00250 dbFieldDescriptor* nextField;
00251
00255 dbFieldDescriptor* nextHashedField;
00256
00260 dbFieldDescriptor* nextIndexedField;
00261
00265 dbFieldDescriptor* nextInverseField;
00266
00270 int fieldNo;
00271
00275 char_t* name;
00276
00280 char_t* longName;
00281
00285 char_t* refTableName;
00286
00290 dbTableDescriptor* refTable;
00291
00295 dbTableDescriptor* defTable;
00296
00300 dbFieldDescriptor* inverseRef;
00301
00305 char_t* inverseRefName;
00306
00310 int type;
00311
00315 int appType;
00316
00320 int indexType;
00321
00325 int dbsOffs;
00326
00330 int appOffs;
00331
00335 dbFieldDescriptor* components;
00336
00340 oid_t hashTable;
00341
00345 oid_t bTree;
00346
00350 size_t dbsSize;
00351
00355 size_t appSize;
00356
00361 size_t alignment;
00362
00366 dbUDTComparator comparator;
00367
00371 enum FieldAttributes {
00372 ComponentOfArray = 0x01,
00373 HasArrayComponents = 0x02,
00374 OneToOneMapping = 0x04,
00375 Updated = 0x08
00376 };
00377 int attr;
00378
00382 int oldDbsType;
00386 int oldDbsOffs;
00390 int oldDbsSize;
00391
00392
00396 dbAnyMethodTrampoline* method;
00397
00401 void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
00402
00413 size_t calculateRecordSize(byte* base, size_t offs);
00414
00424 size_t calculateNewRecordSize(byte* base, size_t offs);
00425
00435 size_t convertRecord(byte* dst, byte* src, size_t offs);
00436
00447 int sizeWithoutOneField(dbFieldDescriptor* field,
00448 byte* base, size_t& size);
00449
00459 size_t copyRecordExceptOneField(dbFieldDescriptor* field,
00460 byte* dst, byte* src, size_t offs);
00461
00472 size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);
00473
00481 void markUpdatedFields(byte* dst, byte* src);
00482
00490 void fetchRecordFields(byte* dst, byte* src);
00491
00497 dbFieldDescriptor* find(const char_t* name);
00498
00503 dbFieldDescriptor* getFirstComponent() {
00504 return components;
00505 }
00506
00511 dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) {
00512 if (field != NULL) {
00513 field = field->next;
00514 if (field == components) {
00515 return NULL;
00516 }
00517 }
00518 return field;
00519 }
00520
00524 dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00525 dbFieldDescriptor* tail = field.prev;
00526 tail->next = this;
00527 prev->next = &field;
00528 field.prev = prev;
00529 prev = tail;
00530 return *this;
00531 }
00532
00533 void* operator new(size_t size);
00534 void operator delete(void* p);
00535
00539 dbFieldDescriptor& adjustOffsets(long offs);
00540
00550 dbFieldDescriptor(char_t const* name, size_t offs, size_t size, int indexType,
00551 char_t const* inverse = NULL,
00552 dbFieldDescriptor* components = NULL);
00553
00558 dbFieldDescriptor(char_t const* name);
00559
00563 ~dbFieldDescriptor();
00564 };
00565
00566
00570 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00571 friend class dbCompiler;
00572 friend class dbDatabase;
00573 friend class dbReplicatedDatabase;
00574 friend class dbTable;
00575 friend class dbAnyCursor;
00576 friend class dbSubSql;
00577 friend class dbParallelQueryContext;
00578 friend class dbServer;
00579 friend class dbAnyContainer;
00580 friend class dbColumnBinding;
00581 friend class dbFieldDescriptor;
00582 friend class dbSelection;
00583 friend class dbTableIterator;
00584 friend class dbCLI;
00585 protected:
00589 dbTableDescriptor* next;
00590 static dbTableDescriptor* chain;
00591
00595 dbTableDescriptor* nextDbTable;
00596
00600 char_t* name;
00601
00605 oid_t tableId;
00606
00610 dbFieldDescriptor* columns;
00611
00615 dbFieldDescriptor* hashedFields;
00616
00620 dbFieldDescriptor* indexedFields;
00621
00625 dbFieldDescriptor* inverseFields;
00626
00630 dbFieldDescriptor* firstField;
00631
00635 dbFieldDescriptor** nextFieldLink;
00636
00640 dbDatabase* db;
00641
00645 bool fixedDatabase;
00646
00650 bool isStatic;
00651
00657 dbTableDescriptor* cloneOf;
00658
00662 size_t appSize;
00663
00667 size_t fixedSize;
00668
00672 size_t nFields;
00673
00677 size_t nColumns;
00678
00682 oid_t firstRow;
00683
00687 oid_t lastRow;
00688
00692 size_t nRows;
00693
00697 int4 autoincrementCount;
00698
00702 dbTableDescriptor* nextBatch;
00703
00707 bool isInBatch;
00708
00712 dbSelection batch;
00713
00714
00715
00719 typedef dbFieldDescriptor* (*describeFunc)();
00720 describeFunc describeComponentsFunc;
00721
00725 size_t totalNamesLength();
00726
00738 int calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00739 char_t const* prefix, int offs,
00740 int indexMask, int& attr);
00741
00750 dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00751 int prefixLen, int& attr);
00755 dbTableDescriptor* clone();
00756
00757 public:
00761 static int initialAutoincrementCount;
00762
00763
00767 dbTableDescriptor* getNextTable() {
00768 return nextDbTable;
00769 }
00770
00774 dbFieldDescriptor* findSymbol(char_t const* name);
00775
00779 dbFieldDescriptor* find(char_t const* name);
00780
00785 dbFieldDescriptor* getFirstField() {
00786 return columns;
00787 }
00788
00789
00795 dbFieldDescriptor* getNextField(dbFieldDescriptor* field) {
00796 if (field != NULL) {
00797 field = field->next;
00798 if (field == columns) {
00799 return NULL;
00800 }
00801 }
00802 return field;
00803 }
00804
00808 char_t* getName() {
00809 return name;
00810 }
00811
00815 size_t size() {
00816 return appSize;
00817 }
00818
00825 bool equal(dbTable* table);
00826
00835 bool match(dbTable* table, bool confirmDeleteColumns);
00836
00842 void checkRelationship();
00843
00848 dbDatabase* getDatabase() { return db; }
00849
00854 void storeInDatabase(dbTable* table);
00855
00860 void setFlags();
00861
00862
00866 static void cleanup();
00867
00868
00873 dbTableDescriptor(dbTable* table);
00874
00883 dbTableDescriptor(char_t const* tableName,
00884 dbDatabase* db,
00885 size_t objSize,
00886 describeFunc func,
00887 dbTableDescriptor* original = NULL);
00888
00892 ~dbTableDescriptor();
00893 };
00894
00898 struct dbVarying {
00899 nat4 size;
00900 int4 offs;
00901 };
00902
00906 struct dbField {
00907 enum FieldTypes {
00908 tpBool,
00909 tpInt1,
00910 tpInt2,
00911 tpInt4,
00912 tpInt8,
00913 tpReal4,
00914 tpReal8,
00915 tpString,
00916 tpReference,
00917 tpArray,
00918 tpMethodBool,
00919 tpMethodInt1,
00920 tpMethodInt2,
00921 tpMethodInt4,
00922 tpMethodInt8,
00923 tpMethodReal4,
00924 tpMethodReal8,
00925 tpMethodString,
00926 tpMethodReference,
00927 tpStructure,
00928 tpRawBinary,
00929 tpStdString,
00930 tpMfcString,
00931 tpRectangle,
00932 tpUnknown
00933 };
00934
00938 dbVarying name;
00939
00943 dbVarying tableName;
00944
00948 dbVarying inverse;
00949
00953 int4 type;
00954
00958 int4 offset;
00959
00963 nat4 size;
00964
00968 oid_t hashTable;
00969
00973 oid_t bTree;
00974 };
00975
00976
00980 class dbRecord {
00981 public:
00985 nat4 size;
00986
00990 oid_t next;
00991
00995 oid_t prev;
00996 };
00997
00998
01002 class dbTable : public dbRecord {
01003 public:
01007 dbVarying name;
01008
01012 dbVarying fields;
01013
01017 nat4 fixedSize;
01018
01022 nat4 nRows;
01023
01027 nat4 nColumns;
01028
01032 oid_t firstRow;
01033
01037 oid_t lastRow;
01038 #ifdef AUTOINCREMENT_SUPPORT
01039
01042 nat4 count;
01043 #endif
01044 };
01045
01046 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01047 {
01048 fd->type = fd->appType = dbField::tpRawBinary;
01049 fd->alignment = 1;
01050 fd->comparator = comparator;
01051 return fd;
01052 }
01053
01054 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
01055 {
01056 fd->type = fd->appType = dbField::tpInt1;
01057 return fd;
01058 }
01059 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
01060 {
01061 fd->type = fd->appType = dbField::tpInt2;
01062 return fd;
01063 }
01064 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
01065 {
01066 fd->type = fd->appType = dbField::tpInt4;
01067 return fd;
01068 }
01069 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
01070 {
01071 fd->type = fd->appType = dbField::tpInt8;
01072 return fd;
01073 }
01074 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
01075 {
01076 fd->type = fd->appType = dbField::tpInt1;
01077 return fd;
01078 }
01079 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
01080 {
01081 fd->type = fd->appType = dbField::tpInt2;
01082 return fd;
01083 }
01084 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
01085 {
01086 fd->type = fd->appType = dbField::tpInt4;
01087 return fd;
01088 }
01089 #if SIZEOF_LONG != 8
01090 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01091 {
01092 fd->type = fd->appType = dbField::tpInt4;
01093 return fd;
01094 }
01095 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01096 {
01097 fd->type = fd->appType = dbField::tpInt4;
01098 return fd;
01099 }
01100 #endif
01101 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
01102 {
01103 fd->type = fd->appType = dbField::tpInt8;
01104 return fd;
01105 }
01106 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
01107 {
01108 fd->type = fd->appType = dbField::tpBool;
01109 return fd;
01110 }
01111 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
01112 {
01113 fd->type = fd->appType = dbField::tpReal4;
01114 return fd;
01115 }
01116 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
01117 {
01118 fd->type = fd->appType = dbField::tpReal8;
01119 return fd;
01120 }
01121 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01122 {
01123 fd->type = fd->appType = dbField::tpRectangle;
01124 fd->alignment = sizeof(coord_t);
01125 return fd;
01126 }
01127
01128 #ifdef USE_STD_STRING
01129 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01130 {
01131 fd->type = dbField::tpString;
01132 fd->appType = dbField::tpStdString;
01133 fd->dbsSize = sizeof(dbVarying);
01134 fd->alignment = 4;
01135 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01136 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01137 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01138 return fd;
01139 }
01140 #endif
01141 #ifdef USE_MFC_STRING
01142 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01143 {
01144 fd->type = dbField::tpString;
01145 fd->appType = dbField::tpMfcString;
01146 fd->dbsSize = sizeof(dbVarying);
01147 fd->alignment = 4;
01148 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01149 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01150 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01151 return fd;
01152 }
01153 #endif
01154
01155 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01156 {
01157 fd->type = fd->appType = dbField::tpString;
01158 fd->dbsSize = sizeof(dbVarying);
01159 fd->alignment = 4;
01160 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01161 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01162 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01163 return fd;
01164 }
01165 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01166 {
01167 fd->type = fd->appType = dbField::tpString;
01168 fd->dbsSize = sizeof(dbVarying);
01169 fd->alignment = 4;
01170 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01171 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01172 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01173 return fd;
01174 }
01175
01176
01177 template<class T>
01178 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01179 {
01180 fd->type = fd->appType = dbField::tpStructure;
01181 fd->components = x.dbDescribeComponents(fd);
01182 return fd;
01183 }
01184
01185
01189 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01190 public:
01191 dbFieldDescriptor* cls;
01192
01198 virtual void invoke(byte* data, void* result) = 0;
01199
01206 virtual dbAnyMethodTrampoline* optimize() = 0;
01207
01212 dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01213
01217 virtual~dbAnyMethodTrampoline();
01218
01219 void* operator new(size_t size);
01220 void operator delete(void* p);
01221 };
01222
01223 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x520 && __SUNPRO_CC_COMPAT == 5)
01224
01227 template<class T, class R>
01228 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01229 public:
01230 typedef R (T::*mfunc)();
01231
01232 mfunc method;
01233 dbFieldDescriptor* cls;
01234 bool optimized;
01235
01236 void invoke(byte* data, void* result) {
01237 if (optimized) {
01238 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01239 } else {
01240 T rec;
01241 this->cls->components->fetchRecordFields((byte*)&rec, data);
01242 *(R*)result = (rec.*method)();
01243 }
01244 }
01245 dbAnyMethodTrampoline* optimize() {
01246 optimized = true;
01247 return this;
01248 }
01249
01250 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01251 : dbAnyMethodTrampoline(fd)
01252 {
01253 this->method = f;
01254 this->cls = fd;
01255 this->optimized = false;
01256 }
01257 };
01258
01259 #else
01260
01264 template<class T, class R>
01265 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01266 public:
01267 typedef R (T::*mfunc)();
01268 mfunc method;
01269
01270 void invoke(byte* data, void* result) {
01271 T rec;
01272 this->cls->components->fetchRecordFields((byte*)&rec, data);
01273 *(R*)result = (rec.*method)();
01274 }
01275 dbAnyMethodTrampoline* optimize();
01276
01277 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01278 : dbAnyMethodTrampoline(fd), method(f) {}
01279 };
01280
01281 template<class T, class R>
01282 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01283 typedef R (T::*mfunc)();
01284 mfunc method;
01285 public:
01286 dbAnyMethodTrampoline* optimize() {
01287 return this;
01288 }
01289 void invoke(byte* data, void* result) {
01290 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01291 }
01292 dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt)
01293 : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01294 delete mt;
01295 }
01296 };
01297
01298 template<class T, class R>
01299 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01300 return new dbMethodFastTrampoline<T,R>(this);
01301 }
01302
01303 #endif
01304 template<class T, class R>
01305 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01306 {
01307 R ret;
01308 dbDescribeField(fd, ret);
01309 assert(fd->type <= dbField::tpReference);
01310 fd->appType = fd->type += dbField::tpMethodBool;
01311 fd->method = new dbMethodTrampoline<T,R>(fd, p);
01312 return fd;
01313 }
01314
01315 END_GIGABASE_NAMESPACE
01316
01317 #endif
01318
01319