// the assumption here is that the data was either built by Deserialize() // or was created by application code in a way that observes our rule: each // struct and string was separately allocated with malloc() void FreeStruct(uint8_t *structStart, const StructMetadata *def) { if (!structStart) return; Type type; const FieldMetadata *fieldDef = NULL; for (int i = 0; i < def->nFields; i++) { fieldDef = def->fields + i; uint8_t *data = structStart + fieldDef->offset; type = (Type)(fieldDef->type & TYPE_MASK); if (TYPE_STRUCT_PTR == type) { uint8_t **p = (uint8_t**)data; FreeStruct(*p, GetStructDef(fieldDef)); } else if (TYPE_ARRAY == type) { Vec<uint8_t*> **vecPtr = (Vec<uint8_t*> **)data; Vec<uint8_t*> *vec = *vecPtr; for (size_t j = 0; j < vec->Count(); j++) { FreeStruct(vec->At(j), GetStructDef(fieldDef)); } delete vec; } else if ((TYPE_STR == type) || (TYPE_WSTR == type)) { char **sp = (char**)data; char *s = *sp; free(s); } } free(structStart); }
static uint8_t *DecodeStruct(DecodeState& ds, const FieldMetadata *fieldDef, TxtNode *node, bool isCompact) { uint8_t *d = NULL; if (isCompact && (TextNode == node->type)) { d = DeserializeCompact(ds, node, GetStructDef(fieldDef)); } else { if (StructNode == node->type) d = DeserializeRec(ds, node, GetStructDef(fieldDef)); } return d; }
DBExtend *SystemDict :: ProvideExtendDef (SDB_Reference sdbref, logical disjopt, logical unionopt, logical intersopt, logical contr_opt ) { DBStructDef *strdefptr; DBExtend *oldext; DBExtend *dbextdef; BEGINSEQ TypeKey tkey(sdbref.get_ddetype(),SYS_NSID); if ( !(strdefptr = GetStructDef(tkey)) ) SDBERR(20) if ( !(dbextdef = new DBExtend(this,&sdbref,strdefptr,disjopt,unionopt,intersopt,contr_opt)) ) SDBERR(95) if ( oldext = GetExtendDef(dbextdef->fmcbname,SYS_NSID) ) { extdef_list.Remove(oldext); dbextdef->SetPrevious(oldext); } extdef_list.Insert(dbextdef); RECOVER dbextdef = NULL; ENDSEQ return(dbextdef); }