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
00026
00027 #include "Common/metaclass.h"
00028
00029
00030 #include <cstdio>
00031
00032 namespace IXE {
00033 using namespace std;
00034
00035 #if defined(_WIN32) || defined(__DECCXX) || defined(__GNUC__)
00036
00037 #pragma pack(push, 4)
00038 #endif
00039
00040
00046
00047
00048 #ifndef _MSC_VER
00049
00050 template <>
00051 Size FixedField<std::string>::length(byte* base) {
00052 return ((std::string*)base)->size();
00053 }
00054
00055 template <>
00056 byte* FixedField<std::string>::fetch(byte* dst, byte*& row)
00057 {
00058 Size length;
00059 Size maxlen = maxLength();
00060 if (maxlen < 256) {
00061 length = *row;
00062 row += 1;
00063 } else if (maxlen < 65536) {
00064 length = uint2get(row);
00065 row += 2;
00066 } else {
00067 length = uint4get(row);
00068 row += 4;
00069 }
00070 *(std::string*)(dst) = std::string((char*)row, length);
00071 row += sizeof(char) * length;
00072 return row;
00073 }
00074
00075 template <>
00076 byte* FixedField<std::string>::store(byte*& row, byte* src)
00077 {
00078 Size len = length(src);
00079 Size maxlen = maxLength();
00080 if (len > maxlen) len = maxlen;
00081 if (maxlen < 256) {
00082 row[0] = len;
00083 row += 1;
00084 } else if (maxlen < 65536) {
00085 int2store(row, len);
00086 row += 2;
00087 } else {
00088 int4store(row, len);
00089 row += 4;
00090 }
00091 len *= sizeof(char);
00092 ::memcpy((void*)row, ((std::string*)src)->c_str(), len);
00093 row += len;
00094 return row;
00095 }
00096
00097 template <>
00098 Size FixedField<std::string>::packSize(byte* base) {
00099 Size maxlen = maxLength();
00100 Size len = base ? length(base + offset) : maxlen;
00101 if (len > maxlen) len = maxlen;
00102
00103 return ((maxlen < 256) ? 1 :
00104 (maxlen < 65536) ? 2 : 4) + len * sizeof(value_type::value_type);
00105 }
00106 #endif
00107
00108
00114
00115
00116 template <>
00117 bool VarField<char>::isType(Type t) { return (t == Field::String); }
00118
00119 template <>
00120 bool VarField<char const>::isType(Type t) { return (t == Field::String); }
00121
00122 template <>
00123 Size VarField<char>::length(byte* base)
00124 {
00125
00126 return base ?
00127 (*(char**)base ?
00128 ::strlen(*(char**)(base)) + 1
00129 : 0)
00130 : maxLength();
00131 }
00132
00133 template <>
00134 Size VarField<char const>::length(byte* base)
00135 {
00136
00137 return base ?
00138 (*(char**)base ?
00139 ::strlen(*(char**)(base)) + 1
00140 : 0)
00141 : maxLength();
00142 }
00143
00144
00150
00151
00152 byte* CompositeField::store(byte*& row, byte* src)
00153 {
00154 return metaClass->store(row, src);
00155 }
00156
00157 byte* CompositeField::fetch(byte* dst, byte*& row)
00158 {
00159 return metaClass->fetch(dst, row);
00160 }
00161
00162 Size CompositeField::packSize(byte* base)
00163 {
00164 return metaClass->recordSize(base ? base + offset : 0);
00165 }
00166
00167 void CompositeField::clear(void** fieldPtr) {
00168 for (Field* fd = metaClass->fields(); fd; fd = fd->next)
00169 fd->clear((void**)FieldOf(fieldPtr, fd));
00170 }
00171
00172 ostream& CompositeField::print(ostream &out)
00173 {
00174 char buf[128];
00175 sprintf(buf, "%-16s%-14s %2d %4d %4d\n",
00176 name, type->name(), indexType, offset, size());
00177 out << buf;
00178 for (Field* fd = metaClass->fields(); fd != NULL; fd = fd->next) {
00179 out << '\t';
00180 fd->print(out);
00181 }
00182 return out;
00183 }
00184
00185
00191
00192
00193 Field* makeField(char const* name, char const* typeName, Size& offs,
00194 Size maxLength)
00195 {
00196 Field* field = 0;
00197 if (!strcmp(typeName, "double")) {
00198 offs = ALIGN(offs, sizeof(double));
00199 field = &createField(name, 0, offs, (double*)0, Field::none);
00200 } else if (!strcmp(typeName, "float")) {
00201 offs = ALIGN(offs, sizeof(float));
00202 field = &createField(name, 0, offs, (float*)0, Field::none);
00203 } else if (!strcmp(typeName, "int")) {
00204 offs = ALIGN(offs, sizeof(int));
00205 field = &createField(name, 0, offs, (int*)0, Field::none);
00206 } else if (!strcmp(typeName, "int1")) {
00207 offs = ALIGN(offs, sizeof(int1));
00208 field = &createField(name, 0, offs, (int1*)0, Field::none);
00209 } else if (!strcmp(typeName, "int2")) {
00210 offs = ALIGN(offs, sizeof(int2));
00211 field = &createField(name, 0, offs, (int2*)0, Field::none);
00212 } else if (!strcmp(typeName, "int4")) {
00213 offs = ALIGN(offs, sizeof(int4));
00214 field = &createField(name, 0, offs, (int4*)0, Field::none);
00215 } else if (!strcmp(typeName, "int8")) {
00216 offs = ALIGN(offs, sizeof(int8));
00217 field = &createField(name, 0, offs, (int8*)0, Field::none);
00218 } else if (!strcmp(typeName, "nat1")) {
00219 offs = ALIGN(offs, sizeof(nat1));
00220 field = &createField(name, 0, offs, (nat1*)0, Field::none);
00221 } else if (!strcmp(typeName, "nat2")) {
00222 offs = ALIGN(offs, sizeof(nat2));
00223 field = &createField(name, 0, offs, (nat2*)0, Field::none);
00224 } else if (!strcmp(typeName, "nat4")) {
00225 offs = ALIGN(offs, sizeof(nat4));
00226 field = &createField(name, 0, offs, (nat4*)0, Field::none);
00227 } else if (!strcmp(typeName, "nat8")) {
00228 offs = ALIGN(offs, sizeof(nat8));
00229 field = &createField(name, 0, offs, (nat8*)0, Field::none);
00230 } else if (!strcmp(typeName, "real")) {
00231 offs = ALIGN(offs, sizeof(real));
00232 field = &createField(name, 0, offs, (real*)0, Field::none);
00233 } else if (!strcmp(typeName, "real4")) {
00234 offs = ALIGN(offs, sizeof(real4));
00235 field = &createField(name, 0, offs, (real4*)0, Field::none);
00236 } else if (!strcmp(typeName, "real8")) {
00237 offs = ALIGN(offs, sizeof(real8));
00238 field = &createField(name, 0, offs, (real8*)0, Field::none);
00239 } else if (!strcmp(typeName, "text")) {
00240 offs = ALIGN(offs, sizeof(char*));
00241 field = &createField(name, maxLength, offs, (char**)0, Field::none);
00242 } else if (!strcmp(typeName, "varchar")) {
00243 offs = ALIGN(offs, sizeof(char*));
00244 field = &createField(name, maxLength, offs, (char**)0, Field::none);
00245 }
00246 return field;
00247 }
00248
00249
00255
00256
00257 MetaClass::MetaClass(char const* name, Field* columns, Size instanceSize,
00258 void (*factory)(void* dst)) :
00259 name_(name), columns(columns), instanceSize(instanceSize),
00260 factory(factory)
00261 {
00262 nColumns = 0;
00263 for (Field* fd = columns; fd; fd = fd->next)
00264 nColumns++;
00265 }
00266
00267
00276
00277
00278 Size MetaClass::recordSize(byte* base)
00279 {
00280 Size size = 0;
00281 for (Field* fd = columns; fd; fd = fd->next)
00282 size += fd->packSize(base);
00283 return size;
00284 }
00285
00286 Size MetaClass::recordSize(AnyObject const * obj)
00287 {
00288 Size size = 0;
00289
00290 for (vector<Item*>::const_iterator lv = (obj->values).begin();
00291 lv != (obj->values).end(); ++lv)
00292 size += (*lv)->packSize();
00293 return size;
00294 }
00295
00296
00302
00303
00304 Field* MetaClass::find(char const* name)
00305 {
00306 for (Field* field = columns; field; field = field->next)
00307 if (!::strcmp(field->name, name))
00308 return field;
00309 return 0;
00310 }
00311
00312
00313
00314
00315
00316 REGISTER(MetaClass);
00317
00318 #if defined(_WIN32) || defined(__DECCXX) || defined(__GNUC__)
00319
00320 #pragma pack(pop)
00321 #endif
00322
00323 }