static size_t hdf5typealignment(NCD4node* typ) { if(!nc_alignments_computed) { nc_compute_alignments(); nc_alignments_computed = 1; } if(typ->hdr.id <= NC_MAX_ATOMIC_TYPE) return nctypealignment(typ->hdr.id); else {/* Presumably a user type */ switch(typ->nc_type_class) { case NC_VLEN: return nctypealignment(typ->hdr.id); case NC_OPAQUE: return nctypealignment(typ->hdr.id); case NC_COMPOUND: {/* get alignment of the first field of the compound */ NC_FIELD_INFO_T* field0 = nclistget(typ->u.c.field,0); NCD4node* fieldtype = NULL; if(nc4_find_type(typ->container->nc4_info,field0->nc_typeid,&fieldtype)) return 0; return hdf5typealignment(fieldtype); /* may recurse repeatedly */ } break; default: break; } } return 0; /* fail */ }
void alignbuffer(NCConstant* prim, Bytebuffer* buf) { int alignment,pad,offset; if(prim->nctype == NC_ECONST) alignment = nctypealignment(prim->value.enumv->typ.typecode); else if(usingclassic && prim->nctype == NC_STRING) alignment = nctypealignment(NC_CHAR); else if(prim->nctype == NC_CHAR) alignment = nctypealignment(NC_CHAR); else alignment = nctypealignment(prim->nctype); offset = bbLength(buf); pad = getpadding(offset,alignment); if(pad > 0) { bbAppendn(buf,(void*)zeros,pad); } }
/* Compute type sizes and compound offsets*/ void computesize(Symbol* tsym) { int i; int offset = 0; unsigned long totaldimsize; if(tsym->touched) return; tsym->touched=1; switch (tsym->subclass) { case NC_VLEN: /* actually two sizes for vlen*/ computesize(tsym->typ.basetype); /* first size*/ tsym->typ.size = ncsize(tsym->typ.typecode); tsym->typ.alignment = nctypealignment(tsym->typ.typecode); tsym->typ.nelems = 1; /* always a single compound datalist */ break; case NC_PRIM: tsym->typ.size = ncsize(tsym->typ.typecode); tsym->typ.alignment = nctypealignment(tsym->typ.typecode); tsym->typ.nelems = 1; break; case NC_OPAQUE: /* size and alignment already assigned*/ tsym->typ.nelems = 1; break; case NC_ENUM: computesize(tsym->typ.basetype); /* first size*/ tsym->typ.size = tsym->typ.basetype->typ.size; tsym->typ.alignment = tsym->typ.basetype->typ.alignment; tsym->typ.nelems = 1; break; case NC_COMPOUND: /* keep if all fields are primitive*/ /* First, compute recursively, the size and alignment of fields*/ for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* field = (Symbol*)listget(tsym->subnodes,i); ASSERT(field->subclass == NC_FIELD); computesize(field); /* alignment of struct is same as alignment of first field*/ if(i==0) tsym->typ.alignment = field->typ.alignment; } /* now compute the size of the compound based on*/ /* what user specified*/ offset = 0; for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* field = (Symbol*)listget(tsym->subnodes,i); /* only support 'c' alignment for now*/ int alignment = field->typ.alignment; offset += getpadding(offset,alignment); field->typ.offset = offset; offset += field->typ.size; } tsym->typ.size = offset; break; case NC_FIELD: /* Compute size assume no unlimited dimensions*/ if(tsym->typ.dimset.ndims > 0) { computesize(tsym->typ.basetype); totaldimsize = crossproduct(&tsym->typ.dimset,0,0); tsym->typ.size = tsym->typ.basetype->typ.size * totaldimsize; tsym->typ.alignment = tsym->typ.basetype->typ.alignment; tsym->typ.nelems = 1; } else { tsym->typ.size = tsym->typ.basetype->typ.size; tsym->typ.alignment = tsym->typ.basetype->typ.alignment; tsym->typ.nelems = tsym->typ.basetype->typ.nelems; } break; default: PANIC1("computesize: unexpected type class: %d",tsym->subclass); break; } }