📄 class.cpp
字号:
break;
default:
b = false;
}
*(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)*(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)*(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)*(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 = *(int8*)(src + fd->oldDbsOffs);
break;
case dbField::tpReal4:
i8 = (int8)*(real4*)(src + fd->oldDbsOffs);
break;
case dbField::tpReal8:
i8 = (int8)*(real8*)(src + fd->oldDbsOffs);
break;
default:
i8 = 0;
}
*(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)*(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)*(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -