📄 class.cpp
字号:
} *(bool*)(dst + fd->dbsOffs) = b; break; case dbField::tpInt1: switch (fd->oldDbsType) { case dbField::tpBool: i1 = *(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: i1 = *(int1*)(src + fd->oldDbsOffs); break; case dbField::tpInt2: i1 = (int1)*(int2*)(src + fd->oldDbsOffs); break; case dbField::tpInt4: i1 = (int1)*(int4*)(src + fd->oldDbsOffs); break; case dbField::tpInt8: i1 = (int1)*(db_int8*)(src + fd->oldDbsOffs); break; case dbField::tpReal4: i1 = (int1)*(real4*)(src + fd->oldDbsOffs); break; case dbField::tpReal8: i1 = (int1)*(real8*)(src + fd->oldDbsOffs); break; default: i1 = 0; } *(int1*)(dst + fd->dbsOffs) = i1; break; case dbField::tpInt2: switch (fd->oldDbsType) { case dbField::tpBool: i2 = *(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: i2 = *(int1*)(src + fd->oldDbsOffs); break; case dbField::tpInt2: i2 = *(int2*)(src + fd->oldDbsOffs); break; case dbField::tpInt4: i2 = (int2)*(int4*)(src + fd->oldDbsOffs); break; case dbField::tpInt8: i2 = (int2)*(db_int8*)(src + fd->oldDbsOffs); break; case dbField::tpReal4: i2 = (int2)*(real4*)(src + fd->oldDbsOffs); break; case dbField::tpReal8: i2 = (int2)*(real8*)(src + fd->oldDbsOffs); break; default: i2 = 0; } *(int2*)(dst + fd->dbsOffs) = i2; break; case dbField::tpInt4: switch (fd->oldDbsType) { case dbField::tpBool: i4 = *(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: i4 = *(int1*)(src + fd->oldDbsOffs); break; case dbField::tpInt2: i4 = *(int2*)(src + fd->oldDbsOffs); break; case dbField::tpInt4: i4 = *(int4*)(src + fd->oldDbsOffs); break; case dbField::tpInt8: i4 = (int4)*(db_int8*)(src + fd->oldDbsOffs); break; case dbField::tpReal4: i4 = (int4)*(real4*)(src + fd->oldDbsOffs); break; case dbField::tpReal8: i4 = (int4)*(real8*)(src + fd->oldDbsOffs); break; default: i4 = 0; } *(int4*)(dst + fd->dbsOffs) = i4; break; case dbField::tpInt8: switch (fd->oldDbsType) { case dbField::tpBool: i8 = *(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: i8 = *(int1*)(src + fd->oldDbsOffs); break; case dbField::tpInt2: i8 = *(int2*)(src + fd->oldDbsOffs); break; case dbField::tpInt4: i8 = *(int4*)(src + fd->oldDbsOffs); break; case dbField::tpInt8: i8 = *(db_int8*)(src + fd->oldDbsOffs); break; case dbField::tpReal4: i8 = (db_int8)*(real4*)(src + fd->oldDbsOffs); break; case dbField::tpReal8: i8 = (db_int8)*(real8*)(src + fd->oldDbsOffs); break; default: i8 = 0; } *(db_int8*)(dst + fd->dbsOffs) = i8; break; case dbField::tpReal4: switch (fd->oldDbsType) { case dbField::tpBool: f4 = (real4)*(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: f4 = (real4)*(int1*)(src + fd->oldDbsOffs); break; case dbField::tpInt2: f4 = (real4)*(int2*)(src + fd->oldDbsOffs); break; case dbField::tpInt4: f4 = (real4)*(int4*)(src + fd->oldDbsOffs); break; case dbField::tpInt8: f4 = (real4)*(db_int8*)(src + fd->oldDbsOffs); break; case dbField::tpReal4: f4 = *(real4*)(src + fd->oldDbsOffs); break; case dbField::tpReal8: f4 = (real4)*(real8*)(src + fd->oldDbsOffs); break; default: f4 = 0; } *(real4*)(dst + fd->dbsOffs) = f4; break; case dbField::tpReal8: switch (fd->oldDbsType) { case dbField::tpBool: f8 = (real8)*(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: f8 = (real8)*(int1*)(src + fd->oldDbsOffs); break; case dbField::tpInt2: f8 = (real8)*(int2*)(src + fd->oldDbsOffs); break; case dbField::tpInt4: f8 = (real8)*(int4*)(src + fd->oldDbsOffs); break; case dbField::tpInt8: f8 = (real8)*(db_int8*)(src + fd->oldDbsOffs); break; case dbField::tpReal4: f8 = *(real4*)(src + fd->oldDbsOffs); break; case dbField::tpReal8: f8 = *(real8*)(src + fd->oldDbsOffs); break; default: f8 = 0; } *(real8*)(dst + fd->dbsOffs) = f8; break; case dbField::tpRawBinary: if (fd->oldDbsType == dbField::tpRawBinary) { memcpy(dst + fd->dbsOffs, src + fd->oldDbsOffs, size_t(fd->oldDbsSize) < fd->dbsSize ? size_t(fd->oldDbsSize) : fd->dbsSize); } break; case dbField::tpString: if (fd->oldDbsType == dbField::tpUnknown) { ((dbVarying*)(dst + fd->dbsOffs))->size = 1; ((dbVarying*)(dst + fd->dbsOffs))->offs = offs; *(char*)(dst + offs++) = '\0'; } else { size_t len = ((dbVarying*)(src + fd->oldDbsOffs))->size; ((dbVarying*)(dst + fd->dbsOffs))->size = len; ((dbVarying*)(dst + fd->dbsOffs))->offs = offs; memcpy(dst + offs, src + ((dbVarying*)(src+fd->oldDbsOffs))->offs, len); offs += len; } break; case dbField::tpArray: if (fd->oldDbsType == dbField::tpUnknown) { ((dbVarying*)(dst + fd->dbsOffs))->size = 0; ((dbVarying*)(dst + fd->dbsOffs))->offs = 0; } else { int len = ((dbVarying*)(src+fd->oldDbsOffs))->size; byte* srcElem = src + ((dbVarying*)(src+fd->oldDbsOffs))->offs; ((dbVarying*)(dst + fd->dbsOffs))->size = len; byte* dstElem = (byte*)DOALIGN(long(dst)+offs, fd->components->alignment); offs = dstElem - dst; ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; size_t offsElem = len*fd->components->dbsSize; offs += offsElem; while (--len >= 0) { offsElem = fd->components->convertRecord(dstElem, srcElem, offsElem); offsElem -= fd->components->dbsSize; dstElem += fd->components->dbsSize; srcElem += fd->components->oldDbsSize; } offs += offsElem; } break; case dbField::tpStructure: offs = fd->components->convertRecord(dst, src, offs); break; case dbField::tpReference: if (fd->oldDbsType == dbField::tpUnknown) { *(oid_t*)(dst + fd->dbsOffs) = 0; } else { *(oid_t*)(dst + fd->dbsOffs) = *(oid_t*)(src + fd->oldDbsOffs); } break; default: return offs; } } while ((fd = fd->next) != this); return offs;}int dbTableDescriptor::initialAutoincrementCount;dbTableDescriptor::dbTableDescriptor(char* tableName, dbDatabase* database, size_t objSize, describeFunc func, dbTableDescriptor* original){ cloneOf = original; isStatic = true; if (original == NULL) { next = chain; chain = this; } name = tableName; dbSymbolTable::add(name, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER); describeComponentsFunc = func; columns = (*func)(); nextFieldLink = &firstField; hashedFields = NULL; indexedFields = NULL; inverseFields = NULL; tableId = 0; nFields = 0; nColumns = 0; db = database; fixedDatabase = database != NULL; fixedSize = sizeof(dbRecord); int attr = dbFieldDescriptor::OneToOneMapping; appSize = 0; autoincrementCount = initialAutoincrementCount; size_t maxAlignment = calculateFieldsAttributes(columns, "", sizeof(dbRecord), HASHED|INDEXED, attr);#if CHECK_RECORD_SIZE appSize = DOALIGN(appSize, maxAlignment); if (appSize < objSize) { fprintf(stderr, "Warning: may be not all fields of the class '%s' " "were described\n", name); }#endif *nextFieldLink = NULL;}int dbTableDescriptor::calculateFieldsAttributes(dbFieldDescriptor* first, char const* prefix, int offs, int indexMask, int& attr){ dbFieldDescriptor *field = first; size_t alignment = 1; do { if (field->method) { assert(((void)"Not empty record", field != first)); do { assert(((void)"Methods should be specified after variables", field->method != NULL)); field->dbsOffs = first->dbsOffs; field->components = first; if (attr & dbFieldDescriptor::OneToOneMapping) { field->method = field->method->optimize(); } } while ((field = field->next) != first); break; } if (*prefix != '\0') { char* p = new char[strlen(prefix)+strlen(field->name)+1]; sprintf(p, "%s%s", prefix, field->name); field->longName = p; } else { nColumns += 1; field->longName = new char[strlen(field->name)+1]; strcpy(field->longName, field->name); } field->defTable = this; field->indexType &= indexMask|DB_FIELD_INHERITED_MASK; field->attr = (attr & dbFieldDescriptor::ComponentOfArray) | dbFieldDescriptor::OneToOneMapping; if (field->inverseRefName) { assert(!(attr & dbFieldDescriptor::ComponentOfArray) && (field->type == dbField::tpReference || (field->type == dbField::tpArray && field->components->type==dbField::tpReference))); field->nextInverseField = inverseFields; inverseFields = field; } *nextFieldLink = field; nextFieldLink = &field->nextField; field->fieldNo = nFields++; switch (field->type) { case dbField::tpArray: { size_t saveOffs = fixedSize; size_t saveAppSize = appSize; fixedSize = 0; attr = (attr | dbFieldDescriptor::HasArrayComponents) & ~dbFieldDescriptor::OneToOneMapping; field->attr |= dbFieldDescriptor::ComponentOfArray; calculateFieldsAttributes(field->components, field->longName, 0, 0, field->attr); if (field->components->dbsSize != field->components->appSize) { field->attr &= ~dbFieldDescriptor::OneToOneMapping; } fixedSize = saveOffs; appSize = DOALIGN(saveAppSize, sizeof(void*)) + sizeof(void*)*3; break; } case dbField::tpStructure: { char* aggregateName = new char[strlen(field->longName) + 2]; sprintf(aggregateName, "%s.", field->longName); size_t saveOffs = fixedSize; size_t saveAppSize = appSize; appSize = 0; size_t struct_alignment = calculateFieldsAttributes(field->components, aggregateName, offs + field->appOffs, field->indexType, field->attr); field->alignment = struct_alignment; field->dbsOffs = field->components->dbsOffs; attr |= field->attr & dbFieldDescriptor::HasArrayComponents; attr &= field->attr | ~dbFieldDescriptor::OneToOneMapping; field->dbsSize = DOALIGN(fixedSize-saveOffs, struct_alignment); if ((field->attr & dbFieldDescriptor::HasArrayComponents) && struct_alignment < sizeof(void*)) { struct_alignment = sizeof(void*); } appSize = DOALIGN(appSize, struct_alignment) + DOALIGN(saveAppSize, struct_alignment); delete[] aggregateName; break; } case dbField::tpString: attr = (attr | dbFieldDescriptor::HasArrayComponents) & ~dbFieldDescriptor::OneToOneMapping; // no break default: appSize = DOALIGN(appSize, field->appSize) + field->appSize; } if (alignment < field->alignment) { alignment = field->alignment; } if (field->type != dbField::tpStructure) { field->dbsOffs = fixedSize = DOALIGN(fixedSize, field->alignment); fixedSize += field->dbsSize; if (field->dbsOffs != offs + field->appOffs) { attr &= ~dbFieldDescriptor::OneToOneMapping; } if (field->indexType & (HASHED|INDEXED)) { assert(!(field->attr & dbFieldDescriptor::ComponentOfArray)); if (field->indexType & HASHED) { field->nextHashedField = hashedFields; hashedFields = field; } if (field->indexType & INDEXED) { field->nextIndexedField = indexedFields; indexedFields = field; } } } } while ((field = field->next) != first); return alignment;}int dbFieldDescriptor::sizeWithoutOneField(dbFieldDescriptor* field, byte* base, size_t& size){ dbFieldDescriptor* fd = this; int offs, last = 0; do { if (fd != field) { if (fd->type == dbField::tpArray || fd->type == dbField::tpString){ dbVarying* arr = (dbVarying*)(base + fd->dbsOffs); if (arr->offs > last) { last = arr->offs; } int n = arr->size; size = DOALIGN(size, fd->components->alignment) + fd->components->dbsSize * n; if (fd->attr & HasArrayComponents) { byte* elem = base + arr->offs; while (--n >= 0) { offs = fd->components->sizeWithoutOneField(field, elem, size); if (arr->offs + offs > last) { last = arr->offs + offs; } elem += fd->components->dbsSize; } } } else if (fd->attr & HasArrayComponents) { offs = fd->components->sizeWithoutOneField(field, base, size); if (offs > last) { last = offs; } } } } while ((fd = fd->next) != this); return last;}size_t dbFieldDescriptor::copyRecordExceptOneField(dbFieldDescriptor* field, byte* dst, byte* src, size_t offs){ dbFieldDescriptor* fd = this; do { if (fd != field) { if (fd->type == dbField::tpArray || fd->type == dbField::tpString){ dbVarying* srcArr = (dbVarying*)(src + fd->dbsOffs); dbVarying* dstArr = (dbVarying*)(dst + fd->dbsOffs); int n = srcArr->size; byte* srcElem = src + srcArr->offs; byte* dstElem = (byte*)DOALIGN(long(dst) + offs, fd->components->alignment); dstArr->offs = offs = dstElem - dst; dstArr->size = n; size_t sizeElem = fd->components->dbsSize; size_t offsElem = sizeElem * n; offs += offsElem; if (fd->attr & HasArrayComponents) { while (--n >= 0) { offsElem = fd->components-> copyRecordExceptOneField(field, dstElem, srcElem, offsElem); offsElem -= sizeElem; dstElem += sizeElem; srcElem += sizeElem; } offs += offsElem; } else { memcpy(dstElem, srcElem, offsElem); } } else if (fd->attr & HasArrayComponents) { offs = fd->components->copyRecordExceptOneField(field, dst, src, offs); } else if (fd->method == NULL) { memcpy(dst+fd->dbsOffs, src+fd->dbsOffs, fd->dbsSize); } } } while ((fd = fd->next) != this);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -