void gen_chararray(Dimset* dimset, Datalist* data, Bytebuffer* databuf, Datalist* fillsrc) { int ndims,lastunlim; int fillchar = getfillchar(fillsrc); size_t expectedsize,xproduct; size_t unitsize; ASSERT(bbLength(databuf) == 0); ndims = dimset->ndims; /* Find the last unlimited */ lastunlim = findlastunlimited(dimset); if(lastunlim < 0) lastunlim = 0; /* pretend */ /* Compute crossproduct upto the last dimension, starting at the last unlimited */ xproduct = crossproduct(dimset,lastunlim,ndims-1); if(ndims == 0) { unitsize = 1; } else if(lastunlim == ndims-1) {/* last dimension is unlimited */ unitsize = 1; } else { /* last dim is not unlimited */ unitsize = dimset->dimsyms[ndims-1]->dim.declsize; } expectedsize = (xproduct * unitsize); gen_chararrayr(dimset,0,lastunlim,databuf,data,fillchar,unitsize,expectedsize); }
void gen_chararray(Dimset* dimset, int dimindex, Datalist* data, Bytebuffer* charbuf, Datalist* fillsrc) { int fillchar = getfillchar(fillsrc); int rank = rankfor(dimset); int firstunlim = findunlimited(dimset,0); int nunlim = countunlimited(dimset); int nc3unlim = (nunlim <= 1 && (firstunlim == 0 || firstunlim == rank)); /* netcdf-3 case of at most 1 unlim in 0th dimension */ /* Case: netcdf3 case */ if(nc3unlim) { gen_leafchararray(dimset,0,data,charbuf,fillchar); return; } /* else generate should have done all the hard work */ gen_leafchararray(dimset,dimindex,data,charbuf,fillchar); }
void gen_leafchararray(Dimset* dimset, int lastunlim, Datalist* data, Bytebuffer* databuf, Datalist* fillsrc) { int i; size_t expectedsize,xproduct,unitsize; int ndims = dimset->ndims; int fillchar = getfillchar(fillsrc); ASSERT(bbLength(databuf) == 0); /* Assume dimindex is the last unlimited (or 0 if their are no unlimiteds => we should be at a list of simple constants */ /* Compute crossproduct upto the last dimension, starting at the last unlimited */ xproduct = crossproduct(dimset,lastunlim,ndims-1); /* Compute the required size (after padding) of each string constant */ /* expected size is the size of concat of the string constants after padding */ if(ndims == 0) { unitsize = 1; expectedsize = (xproduct * unitsize); } else if(lastunlim == ndims-1) {/* last dimension is unlimited */ unitsize = 1; expectedsize = (xproduct*dimset->dimsyms[lastunlim]->dim.declsize); } else { /* last dim is not unlimited */ unitsize = dimset->dimsyms[ndims-1]->dim.declsize; expectedsize = (xproduct * unitsize); } for(i=0;i<data->length;i++) { NCConstant* c = datalistith(data,i); ASSERT(!islistconst(c)); if(isstringable(c->nctype)) { int j; size_t constsize; constsize = gen_charconstant(c,databuf,fillchar); if(constsize == 0 || constsize % unitsize > 0) { size_t padsize = unitsize - (constsize % unitsize); for(j=0;j<padsize;j++) bbAppend(databuf,fillchar); } } else { semwarn(constline(c),"Encountered non-string and non-char constant in datalist; ignored"); } } /* If |databuf| > expectedsize, complain: exception is zero length */ if(bbLength(databuf) == 0 && expectedsize == 1) { /* this is okay */ } else if(bbLength(databuf) > expectedsize) { semwarn(data->data[0].lineno,"character data list too long"); } else { size_t bufsize = bbLength(databuf); /* Pad to size dimproduct size */ if(bufsize % expectedsize > 0) { size_t padsize = expectedsize - (bufsize % expectedsize); for(i=0;i<padsize;i++) bbAppend(databuf,fillchar); } } }