static void write_alignment(int alignment, Bytebuffer* buf) { int pad = 0; ptrdiff_t offset = bbLength(buf); pad = getpadding(offset,alignment); if(pad > 0) { bbAppendn(buf,(void*)zeros,pad); } }
static void alignto(int alignment, Bytebuffer* buf, ptrdiff_t base) { int pad = 0; ptrdiff_t offset = bbLength(buf); offset -= base; /* Need to actually align wrt to the base */ pad = getpadding(offset,alignment); if(pad > 0) { bbAppendn(buf,(void*)zeros,pad); } }
static int computefieldinfo(struct NCAUX_CMPD* cmpd) { int i; int status = NC_NOERR; size_t offset = 0; size_t totaldimsize; /* Assign the sizes for the fields */ for(i=0;i<cmpd->nfields;i++) { struct NCAUX_FIELD* field = &cmpd->fields[i]; status = nc_inq_type(cmpd->ncid,field->fieldtype,NULL,&field->size); if(status != NC_NOERR) goto done; totaldimsize = dimproduct(field->ndims,field->dimsizes); field->size *= totaldimsize; } for(offset=0,i=0;i<cmpd->nfields;i++) { struct NCAUX_FIELD* field = &cmpd->fields[i]; int alignment = 0; nc_type firsttype = findfirstfield(cmpd->ncid,field->fieldtype); /* only support 'c' alignment for now*/ switch (field->fieldtype) { case NC_OPAQUE: field->alignment = 1; break; case NC_ENUM: field->alignment = ncaux_type_alignment(firsttype,cmpd->ncid); break; case NC_VLEN: /*fall thru*/ case NC_COMPOUND: field->alignment = ncaux_type_alignment(firsttype,cmpd->ncid); break; default: field->alignment = ncaux_type_alignment(field->fieldtype,cmpd->ncid); break; } offset += getpadding(offset,alignment); field->offset = offset; offset += field->size; } cmpd->size = offset; cmpd->alignment = cmpd->fields[0].alignment; done: return status; }
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; int largealign; 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 = ncaux_class_alignment(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 = ncaux_class_alignment(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); if(i==0) tsym->typ.alignment = field->typ.alignment; } /* now compute the size of the compound based on what user specified*/ offset = 0; largealign = 1; 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; int padding = getpadding(offset,alignment); offset += padding; field->typ.offset = offset; offset += field->typ.size; if (alignment > largealign) { largealign = alignment; } } tsym->typ.cmpdalign = largealign; /* total structure size alignment */ offset += (offset % largealign); 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,rankfor(&tsym->typ.dimset)); 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; } }