size_t dbFieldDescriptor::calculateNewRecordSize(byte* base, size_t offs) { dbFieldDescriptor* fd = this; do { if (fd->type == dbField::tpArray) { if (fd->oldDbsType == dbField::tpUnknown) { continue; } int nElems = ((dbVarying*)(base + fd->oldDbsOffs))->size; offs = DOALIGN(offs, fd->components->alignment) + nElems*fd->components->dbsSize; if (fd->attr & HasArrayComponents) { byte* elem = base + ((dbVarying*)(base+fd->oldDbsOffs))->offs; while (--nElems >= 0) { offs = fd->components->calculateNewRecordSize(elem, offs); elem += fd->components->oldDbsSize; } } } else if (fd->type == dbField::tpString) { if (fd->oldDbsType == dbField::tpUnknown) { offs += 1; } else { offs += ((dbVarying*)(base + fd->oldDbsOffs))->size; } } else if (fd->attr & HasArrayComponents) { offs = fd->components->calculateNewRecordSize(base, offs); } } while ((fd = fd->next) != this); return offs; }
bool dbSharedMemory::open(char const* name, size_t size) { char* fileName = (char*)name; #ifndef VXWORKS //Why this portion is commented is we don't have file system now //It is used to generate keys. Once our file system is up then we can use this if (strchr(name, '/') == NULL) { fileName = new char[strlen(name)+strlen(keyFileDir)+1]; sprintf(fileName, "%s%s", keyFileDir, name); } int fd = ::open(fileName, O_RDWR|O_CREAT, ACCESS_PERMISSION_MASK); if (fd < 0) { if (fileName != name) { delete[] fileName; } return false; } ::close(fd); #endif // ndef VXWORKS int key = getKeyFromFile(fileName); if (fileName != name) { delete[] fileName; } if (key < 0) { return false; } shm = shmget(key, DOALIGN(size, 4096), IPC_CREAT|ACCESS_PERMISSION_MASK); if (shm < 0) { return false; } ptr = (char*)shmat(shm, NULL, 0); return (ptr != (char*)-1); }
size_t dbFieldDescriptor::calculateRecordSize(byte* base, size_t offs) { dbFieldDescriptor* fd = this; do { if (fd->type == dbField::tpArray) { int nElems = ((dbAnyArray*)(base + fd->appOffs))->length(); offs = DOALIGN(offs, fd->components->alignment) + nElems*fd->components->dbsSize; if (fd->attr & HasArrayComponents) { byte* elem = (byte*)((dbAnyArray*)(base+fd->appOffs))->base(); dbFieldDescriptor* component = fd->components; size_t elemSize = component->appSize; while (--nElems >= 0) { offs = component->calculateRecordSize(elem, offs); elem += elemSize; } } } else if (fd->type == dbField::tpString) { char* str = *(char**)(base + fd->appOffs); assert(str != NULL); offs += strlen(str) + 1; } else if (fd->attr & HasArrayComponents) { offs = fd->components->calculateRecordSize(base+fd->appOffs, offs); } } while ((fd = fd->next) != this); return offs; }
bool dbSharedMemory::open(char const* name, size_t size) { char* fileName = (char*)name; if (strchr(name, '/') == NULL) { fileName = new char[strlen(name)+strlen(keyFileDir)+1]; sprintf(fileName, "%s%s", keyFileDir, name); } int fd = ::open(fileName, O_RDWR|O_CREAT, 0777); if (fd < 0) { if (fileName != name) { delete[] fileName; } return false; } ::close(fd); int key = getKeyFromFile(fileName); if (fileName != name) { delete[] fileName; } if (key < 0) { return false; } shm = shmget(key, DOALIGN(size, 4096), IPC_CREAT|0777); if (shm < 0) { return false; } ptr = (char*)shmat(shm, NULL, 0); return (ptr != (char*)-1); }
int cli_get_field_offset_fdb(cli_field_descriptor* fields, int field_no) { int offs = 0; int size = 0; for (int i = 0; i <= field_no; i++) { size = sizeof_type[fields[i].type]; offs = DOALIGN(offs, alignof_type[fields[i].type]); offs += size; } return offs - size; }
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 { memcpy(dst+fd->dbsOffs, src+fd->dbsOffs, fd->dbsSize); } } } while ((fd = fd->next) != this); return offs; }
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; }
dbTableDescriptor::dbTableDescriptor(char* tableName, dbDatabase* database, size_t objSize, dbFieldDescriptor* columnsList) { next = chain; chain = this; name = tableName; dbSymbolTable::add(name, tkn_ident, false); columns = columnsList; nextFieldLink = &firstField; hashedFields = NULL; indexedFields = NULL; inverseFields = NULL; tableId = 0; nFields = 0; nColumns = 0; firstRow = 0; lastRow = 0; nRows = 0; db = database; fixedDatabase = database != NULL; fixedSize = sizeof(dbRecord); int attr = dbFieldDescriptor::OneToOneMapping; appSize = 0; size_t maxAlignment = calculateFieldsAttributes(columnsList, "", sizeof(dbRecord), HASHED|INDEXED, attr); #ifdef 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; }
static int xcrypt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { unsigned char *save_iv_store[EVP_MAX_IV_LENGTH + 15]; unsigned char *save_iv = DOALIGN(save_iv_store); unsigned char *ivs_store[EVP_MAX_IV_LENGTH + 15]; unsigned char *ivs = DOALIGN(ivs_store); void *iiv, *iv = NULL, *ivp = NULL; const void *usein = in; void *useout = out, *spare; int cws[4 + 3], *cw = DOALIGN(cws); if (!inl) return (1); if ((inl % ctx->cipher->block_size) != 0) return (0); if (ISUNALIGNED(in) || ISUNALIGNED(out)) { spare = malloc(inl); if (spare == NULL) return (0); if (ISUNALIGNED(in)) { bcopy(in, spare, inl); usein = spare; } if (ISUNALIGNED(out)) useout = spare; } cw[0] = C3_CRYPT_CWLO_ALG_AES | C3_CRYPT_CWLO_KEYGEN_SW | C3_CRYPT_CWLO_NORMAL; cw[0] |= ctx->encrypt ? C3_CRYPT_CWLO_ENCRYPT : C3_CRYPT_CWLO_DECRYPT; cw[1] = cw[2] = cw[3] = 0; switch (ctx->key_len * 8) { case 128: cw[0] |= C3_CRYPT_CWLO_KEY128; break; case 192: cw[0] |= C3_CRYPT_CWLO_KEY192; break; case 256: cw[0] |= C3_CRYPT_CWLO_KEY256; break; } if (ctx->cipher->iv_len) { iv = (caddr_t) ctx->iv; if (!ctx->encrypt) { iiv = (void *) in + inl - ctx->cipher->iv_len; memcpy(save_iv, iiv, ctx->cipher->iv_len); } } ivp = iv; if (ISUNALIGNED(iv)) { bcopy(iv, ivs, ctx->cipher->iv_len); ivp = ivs; } viac3_xcrypt_cbc(cw, usein, useout, ctx->cipher_data, inl / 16, ivp); if (ISUNALIGNED(in) || ISUNALIGNED(out)) { if (ISUNALIGNED(out)) bcopy(spare, out, inl); free(spare); } if (ivp == ivs) bcopy(ivp, iv, ctx->cipher->iv_len); if (ctx->cipher->iv_len) { if (ctx->encrypt) iiv = (void *) out + inl - ctx->cipher->iv_len; else iiv = save_iv; memcpy(ctx->iv, iiv, ctx->cipher->iv_len); } return (1); }
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->alignment) + 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) && field->type != dbField::tpReference); #if 1 // hash table is currently not implemted for this veriosn // use Btree instead of hash table if (field->indexType & HASHED) { field->indexType |= INDEXED; field->indexType &= ~HASHED; } #else if (field->indexType & HASHED) { field->nextHashedField = hashedFields; hashedFields = field; } #endif if (field->indexType & INDEXED) { field->nextIndexedField = indexedFields; indexedFields = field; } } } } while ((field = field->next) != first); return alignment; }
size_t dbFieldDescriptor::convertRecord(byte* dst, byte* src, size_t offs) { dbFieldDescriptor* fd = this; int1 i1; int2 i2; int4 i4; int8 i8; real4 f4; real8 f8; bool b; do { switch (fd->type) { case dbField::tpBool: switch (fd->oldDbsType) { case dbField::tpBool: b = *(bool*)(src + fd->oldDbsOffs); break; case dbField::tpInt1: b = *(int1*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpInt2: b = *(int2*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpInt4: b = *(int4*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpInt8: b = *(int8*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpReal4: b = *(real4*)(src + fd->oldDbsOffs) != 0; break; case dbField::tpReal8: b = *(real8*)(src + fd->oldDbsOffs) != 0; 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; }
size_t dbFieldDescriptor::storeRecordFields(byte* dst, byte* src, size_t offs) { dbFieldDescriptor* fd = this; do { switch (fd->type) { case dbField::tpBool: *(bool*)(dst+fd->dbsOffs) = *(bool*)(src+fd->appOffs); break; case dbField::tpInt1: *(int1*)(dst+fd->dbsOffs) = *(int1*)(src+fd->appOffs); break; case dbField::tpInt2: *(int2*)(dst+fd->dbsOffs) = *(int2*)(src+fd->appOffs); break; case dbField::tpInt4: *(int4*)(dst+fd->dbsOffs) = *(int4*)(src+fd->appOffs); break; case dbField::tpInt8: *(int8*)(dst+fd->dbsOffs) = *(int8*)(src+fd->appOffs); break; case dbField::tpReal4: *(real4*)(dst+fd->dbsOffs) = *(real4*)(src+fd->appOffs); break; case dbField::tpReal8: *(real8*)(dst+fd->dbsOffs) = *(real8*)(src+fd->appOffs); break; case dbField::tpRawBinary: memcpy(dst+fd->dbsOffs, src+fd->appOffs, fd->dbsSize); break; case dbField::tpString: ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; strcpy((char*)dst + offs, *(char**)(src + fd->appOffs)); offs += ((dbVarying*)(dst+fd->dbsOffs))->size = strlen(*(char**)(src + fd->appOffs)) + 1; break; case dbField::tpArray: { int nElems = ((dbAnyArray*)(src + fd->appOffs))->length(); byte* srcElem=(byte*)((dbAnyArray*)(src+fd->appOffs))->base(); byte* dstElem = (byte*)DOALIGN(long(dst)+offs, fd->components->alignment); offs = dstElem - dst; ((dbVarying*)(dst+fd->dbsOffs))->size = nElems; ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; size_t sizeElem = fd->components->dbsSize; size_t offsElem = nElems*sizeElem; offs += offsElem; if (fd->attr & dbFieldDescriptor::OneToOneMapping) { memcpy(dstElem, srcElem, offsElem); } else { dbFieldDescriptor* component = fd->components; while (--nElems >= 0) { offsElem = component->storeRecordFields(dstElem, srcElem, offsElem); offsElem -= sizeElem; dstElem += sizeElem; srcElem += component->appSize; } offs += offsElem; } } break; case dbField::tpReference: *(oid_t*)(dst+fd->dbsOffs) = ((dbAnyReference*)(src+fd->appOffs))->oid; break; case dbField::tpStructure: offs = fd->components->storeRecordFields(dst,src+fd->appOffs,offs); break; default: return offs; } } while ((fd = fd->next) != this); return offs; }