char* dumpselection(NCselection* sel) { NCbytes* buf = ncbytesnew(); NCbytes* segbuf = ncbytesnew(); char* sstring; NClist* segments = NULL; int j; if(sel == NULL) return nulldup(""); segments = sel->lhs->var->segments; ncbytescat(buf,"&"); tostringncsegments(segments,segbuf); ncbytescat(buf,ncbytescontents(segbuf)); ncbytescat(buf,opstrings[sel->operator]); ncbytescat(buf,"{"); for(j=0;j<nclistlength(sel->rhs);j++) { NCvalue* value = (NCvalue*)nclistget(sel->rhs,j); NCconstant* con = value->constant; char tmp[64]; if(j > 0) ncbytescat(buf,","); switch (value->discrim) { case NS_STR: ncbytescat(buf,con->text); break; case NS_CONST: switch (con->discrim) { case NS_INT: snprintf(tmp,sizeof(tmp),"%lld",con->intvalue); ncbytescat(buf,tmp); break; case NS_FLOAT: snprintf(tmp,sizeof(tmp),"%g",con->floatvalue); ncbytescat(buf,tmp); break; default: PANIC1("unexpected discriminator %d",(int)con->discrim); } break; case NS_VAR: segments = value->var->segments; ncbytesclear(segbuf); tostringncsegments(segments,segbuf); ncbytescat(buf,ncbytescontents(segbuf)); break; default: PANIC1("unexpected discriminator %d",(int)value->discrim); } } ncbytescat(buf,"}"); sstring = ncbytesdup(buf); ncbytesfree(buf); ncbytesfree(segbuf); return sstring; }
static void fill(Symbol* tvsym, Datalist* filler) { int i; Constant con; Datalist* sublist; /* NC_TYPE case*/ switch (tvsym->subclass) { case NC_ENUM: case NC_OPAQUE: case NC_PRIM: con.nctype = tvsym->typ.typecode; nc_getfill(&con); break; case NC_COMPOUND: sublist = builddatalist(listlength(tvsym->subnodes)); for(i=0;i<listlength(tvsym->subnodes);i++) { Symbol* field = (Symbol*)listget(tvsym->subnodes,i); if(field->typ.dimset.ndims > 0) { fillarray(field->typ.basetype,&field->typ.dimset,0,filler); } else filllist(field->typ.basetype,sublist); } con = builddatasublist(sublist); break; case NC_VLEN: sublist = builddatalist(0); filllist(tvsym->typ.basetype,sublist); /* generate a single instance*/ con = builddatasublist(sublist); break; default: PANIC1("fill: unexpected subclass %d",tvsym->subclass); } dlappend(filler,&con); }
static void filllist(Symbol* tsym, Datalist* dl) { int i; Datalist* sublist; NCConstant con; con.filled = 0; ASSERT(tsym->objectclass == NC_TYPE); switch (tsym->subclass) { case NC_ENUM: case NC_OPAQUE: case NC_PRIM: con.nctype = tsym->typ.typecode; nc_getfill(&con); dlappend(dl,&con); break; case NC_COMPOUND: sublist = builddatalist(listlength(tsym->subnodes)); for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* field = (Symbol*)listget(tsym->subnodes,i); filllist(field->typ.basetype,sublist); } con = builddatasublist(sublist); dlappend(dl,&con); break; case NC_VLEN: sublist = builddatalist(0); filllist(tsym->typ.basetype,sublist); /* generate a single instance*/ con = builddatasublist(sublist); dlappend(dl,&con); break; default: PANIC1("fill: unexpected subclass %d",tsym->subclass); } }
unsigned int ncctypealignment(int nctype) { NCtypealignment* align = NULL; int index = 0; if(!dapaligninit) compute_nccalignments(); switch (nctype) { case NC_BYTE: index = NCCTYPEUCHAR; break; case NC_CHAR: index = NCCTYPECHAR; break; case NC_SHORT: index = NCCTYPESHORT; break; case NC_INT: index = NCCTYPEINT; break; case NC_FLOAT: index = NCCTYPEFLOAT; break; case NC_DOUBLE: index = NCCTYPEDOUBLE; break; case NC_UBYTE: index = NCCTYPEUCHAR; break; case NC_USHORT: index = NCCTYPEUSHORT; break; case NC_UINT: index = NCCTYPEUINT; break; case NC_INT64: index = NCCTYPELONGLONG; break; case NC_UINT64: index = NCCTYPEULONGLONG; break; case NC_STRING: index = NCCTYPEPTR; break; case NC_VLEN: index = NCCTYPENCVLEN; break; case NC_OPAQUE: index = NCCTYPEUCHAR; break; default: #ifndef OFFSETTEST PANIC1("nctypealignment: bad type code: %d",nctype); #else return 0; #endif } align = &vec[index]; return align->alignment; }
unsigned int nctypealignment(nc_type nctype) { Alignment* align = NULL; int index = 0; switch (nctype) { case NC_BYTE: index = UCHARINDEX; break; case NC_CHAR: index = CHARINDEX; break; case NC_SHORT: index = SHORTINDEX; break; case NC_INT: index = INTINDEX; break; case NC_FLOAT: index = FLOATINDEX; break; case NC_DOUBLE: index = DOUBLEINDEX; break; case NC_UBYTE: index = UCHARINDEX; break; case NC_USHORT: index = USHORTINDEX; break; case NC_UINT: index = UINTINDEX; break; case NC_INT64: index = LONGLONGINDEX; break; case NC_UINT64: index = ULONGLONGINDEX; break; case NC_STRING: index = PTRINDEX; break; case NC_VLEN: index = NCVLENINDEX; break; case NC_OPAQUE: index = UCHARINDEX; break; default: PANIC1("nctypealignment: bad type code: %d",nctype); } align = &vec[index]; return align->alignment; }
static int checkfill(Symbol* tsym, Datasrc* src) { int i,iscmpd,result; Constant* con; Symbol* original = tsym; result = 1; switch (tsym->subclass) { case NC_ENUM: case NC_OPAQUE: case NC_PRIM: con = srcnext(src); if(src == NULL) { semerror(srcline(src),"%s: malformed _FillValue",original->name); result = 0; } else if(con->nctype != tsym->typ.typecode) result = 0; /* wrong type*/ break; case NC_COMPOUND: if(!issublist(src)) {/* fail on no compound*/ semerror(srcline(src),"Compound constants must be enclosed in {..}"); } srcpush(src); for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* field = (Symbol*)listget(tsym->subnodes,i); result = checkfill(field,src,original); if(!result) break; } srcpop(src); break; case NC_VLEN: if(!issublist(src)) { semerror(srcline(src),"%s: vlen instances in _FillValue must be enclosed in {...}",original->name); result = 0; } else { srcpush(src); while(srcmore(src)) { result = checkfill(tsym->typ.basetype,src,original); if(!result) break; } srcpop(src); } break; case NC_FIELD: /* Braces are optional */ if((iscmpd=issublist(src))) srcpush(src); if(tsym->typ.dimset.ndims > 0) { result = checkarray(tsym->typ.basetype,&tsym->typ.dimset,0,src,original,!TOPLEVEL); } else result = checkfill(tsym->typ.basetype,src,original); if(iscmpd) srcpop(src); break; default: PANIC1("checkfillvalue: unexpected subclass %d",tsym->subclass); } return result; }
static void genbin_data(Symbol* tsym, Datasrc* datasrc, Datalist* fillsrc, Bytebuffer* memory) { int usecmpd; Constant* con = srcpeek(datasrc); if(con == NULL || con->nctype == NC_FILLVALUE) { srcnext(datasrc); genbin_fillvalue(tsym,fillsrc,datasrc,memory); return; } switch (tsym->subclass) { case NC_ENUM: case NC_OPAQUE: case NC_PRIM: if(issublist(datasrc)) { semerror(srcline(datasrc),"Expected primitive found {..}"); } genbin_primdata(tsym,datasrc,fillsrc,memory); break; case NC_COMPOUND: genbin_compound(tsym,datasrc,fillsrc,memory); break; case NC_VLEN: { Constant* cp; nc_vlen_t ptr; if(!issublist(datasrc)) { semerror(srcline(datasrc),"Vlen data must be enclosed in {..}"); } cp = srcnext(datasrc); /* generate the nc_vlen_t instance*/ ptr.p = vlendata[cp->value.compoundv->vlen.uid].data; ptr.len = vlendata[cp->value.compoundv->vlen.uid].count; bbAppendn(memory,(char*)&ptr,sizeof(ptr)); } break; case NC_FIELD: /* enclose in braces if and only if field is an array */ usecmpd = (issublist(datasrc) && tsym->typ.dimset.ndims > 0); if(usecmpd) srcpush(datasrc); if(tsym->typ.dimset.ndims > 0) { genbin_fieldarray(tsym->typ.basetype,datasrc,&tsym->typ.dimset,0,memory); } else { genbin_data(tsym->typ.basetype,datasrc,NULL,memory); } if(usecmpd) srcpop(datasrc); break; default: PANIC1("genbin_data: unexpected subclass %d",tsym->subclass); } }
char* dumpselection1(NCselection* sel) { NCbytes* buf = ncbytesnew(); char* sstring; NClist* path = NULL; char* pathstring = NULL; int j; if(sel == NULL) return nulldup(""); path = sel->path; ncbytescat(buf,"&"); if(path == NULL) pathstring = makecdfpathstring3(sel->node,"."); else pathstring = simplepathstring3(path,"."); ncbytescat(buf,pathstring); efree(pathstring); ncbytescat(buf,opstrings[sel->operator]); ncbytescat(buf,"{"); for(j=0;j<nclistlength(sel->values);j++) { NCvalue* value = (NCvalue*)nclistget(sel->values,j); char tmp[64]; if(j > 0) ncbytescat(buf,","); switch (value->kind) { case ST_STR: ncbytescat(buf,value->value.text); break; case ST_INT: snprintf(tmp,sizeof(tmp),"%lld",value->value.intvalue); ncbytescat(buf,tmp); break; case ST_FLOAT: snprintf(tmp,sizeof(tmp),"%g",value->value.floatvalue); ncbytescat(buf,tmp); break; case ST_VAR: path = value->value.var.path; if(path == NULL) pathstring = makecdfpathstring3(value->value.var.node,"."); else pathstring = simplepathstring3(path,"."); ncbytescat(buf,pathstring); efree(pathstring); break; default: PANIC1("unexpected tag: %d",(int)value->kind); } } ncbytescat(buf,"}"); sstring = ncbytesdup(buf); ncbytesfree(buf); return sstring; }
/* Result is a pool string or a constant => do not free*/ char* f77data_const(Constant* ci) { char tmp[64]; char* result = NULL; tmp[0] = '\0'; switch (ci->nctype) { case NC_CHAR: { strcpy(tmp,"'"); escapifychar(ci->value.charv,tmp+1,'\''); strcat(tmp,"'"); } break; case NC_BYTE: sprintf(tmp,"%hhd",ci->value.int8v); break; case NC_SHORT: sprintf(tmp,"%hd",ci->value.int16v); break; case NC_INT: sprintf(tmp,"%d",ci->value.int32v); break; case NC_FLOAT: sprintf(tmp,"%.8g",ci->value.floatv); break; case NC_DOUBLE: { char* p = tmp; /* FORTRAN requires e|E->D */ sprintf(tmp,"%.16g",ci->value.doublev); while(*p) {if(*p == 'e' || *p == 'E') {*p = 'D';}; p++;} } break; case NC_STRING: { Bytebuffer* buf = bbNew(); bbAppendn(buf,ci->value.stringv.stringv,ci->value.stringv.len); f77quotestring(buf); result = bbDup(buf); bbFree(buf); goto done; } break; default: PANIC1("ncstype: bad type code: %d",ci->nctype); } result = pooldup(tmp); done: return result; /*except for NC_STRING and NC_OPAQUE*/ }
static int f77_constant(Generator* generator, NCConstant* ci, Bytebuffer* codebuf,...) { char tmp[64]; char* special = NULL; switch (ci->nctype) { case NC_CHAR: if(ci->value.charv == '\'') sprintf(tmp,"'\\''"); else sprintf(tmp,"'%c'",ci->value.charv); break; case NC_BYTE: sprintf(tmp,"%hhd",ci->value.int8v); break; case NC_SHORT: sprintf(tmp,"%hd",ci->value.int16v); break; case NC_INT: sprintf(tmp,"%d",ci->value.int32v); break; case NC_FLOAT: sprintf(tmp,"%.8g",ci->value.floatv); break; case NC_DOUBLE: { char* p = tmp; /* FORTRAN requires e|E->D */ sprintf(tmp,"%.16g",ci->value.doublev); while(*p) {if(*p == 'e' || *p == 'E') {*p = 'D';}; p++;} } break; case NC_STRING: { Bytebuffer* buf = bbNew(); bbAppendn(buf,ci->value.stringv.stringv,ci->value.stringv.len); f77quotestring(buf); special = bbDup(buf); bbFree(buf); } break; default: PANIC1("f77data: bad type code: %d",ci->nctype); } if(special != NULL) bbCat(codebuf,special); else bbCat(codebuf,tmp); return 1; }
/* Generate an instance of the basetype using datasrc */ void f77data_basetype(Symbol* tsym, Datasrc* datasrc, Bytebuffer* codebuf, Datalist* fillsrc) { switch (tsym->subclass) { case NC_PRIM: if(issublist(datasrc)) { semerror(srcline(datasrc),"Expected primitive found {..}"); } bbAppend(codebuf,' '); f77data_primdata(tsym,datasrc,codebuf,fillsrc); break; default: PANIC1("f77data_basetype: unexpected subclass %d",tsym->subclass); } }
const char* jtypeallcaps(nc_type type) { switch (type) { case NC_CHAR: return "CHAR"; case NC_BYTE: return "BYTE"; case NC_SHORT: return "SHORT"; case NC_INT: return "INT"; case NC_FLOAT: return "FLOAT"; case NC_DOUBLE: return "DOUBLE"; case NC_UBYTE: return "LONG"; case NC_USHORT: return "LONG"; case NC_UINT: return "LONG"; case NC_INT64: return "LONG"; case NC_UINT64: return "LONG"; case NC_STRING: return "STRING"; default: PANIC1("ncctype: bad type code:%d",type); } return 0; }
static void checkconsistency(void) { int i; for(i=0;i<listlength(grpdefs);i++) { Symbol* sym = (Symbol*)listget(grpdefs,i); if(sym == rootgroup) { if(sym->container != NULL) PANIC("rootgroup has a container"); } else if(sym->container == NULL && sym != rootgroup) PANIC1("symbol with no container: %s",sym->name); else if(sym->container->ref.is_ref != 0) PANIC1("group with reference container: %s",sym->name); else if(sym != rootgroup && !sqContains(sym->container->subnodes,sym)) PANIC1("group not in container: %s",sym->name); if(sym->subnodes == NULL) PANIC1("group with null subnodes: %s",sym->name); } for(i=0;i<listlength(typdefs);i++) { Symbol* sym = (Symbol*)listget(typdefs,i); if(!sqContains(sym->container->subnodes,sym)) PANIC1("type not in container: %s",sym->name); } for(i=0;i<listlength(dimdefs);i++) { Symbol* sym = (Symbol*)listget(dimdefs,i); if(!sqContains(sym->container->subnodes,sym)) PANIC1("dimension not in container: %s",sym->name); } for(i=0;i<listlength(vardefs);i++) { Symbol* sym = (Symbol*)listget(vardefs,i); if(!sqContains(sym->container->subnodes,sym)) PANIC1("variable not in container: %s",sym->name); if(!(isprimplus(sym->typ.typecode) || sqContains(typdefs,sym->typ.basetype))) PANIC1("variable with undefined type: %s",sym->name); } }
const char* jtypecap(nc_type type) { switch (type) { case NC_CHAR: return "Char"; case NC_BYTE: return "Byte"; case NC_SHORT: return "Short"; case NC_INT: return "Int"; case NC_FLOAT: return "Float"; case NC_DOUBLE: return "Double"; case NC_UBYTE: return "Long"; case NC_USHORT: return "Long"; case NC_UINT: return "Long"; case NC_INT64: return "Long"; case NC_UINT64: return "Long"; case NC_STRING: return "String"; case NC_ENUM: return "Int"; case NC_OPAQUE: return "String"; default: PANIC1("ncctype: bad type code:%d",type); } return 0; }
/* * Return java type name for netCDF type, given type code. */ static const char* jtype(nc_type type) { switch (type) { case NC_CHAR: return "char"; case NC_BYTE: return "byte"; case NC_SHORT: return "short"; case NC_INT: return "int"; case NC_FLOAT: return "float"; case NC_DOUBLE: return "double"; case NC_UBYTE: return "long"; case NC_USHORT: return "long"; case NC_UINT: return "long"; case NC_INT64: return "long"; case NC_UINT64: return "long"; case NC_STRING: return "String"; case NC_ENUM: return "int"; case NC_OPAQUE: return "String"; default: PANIC1("ncctype: bad type code:%d",type); } return 0; }
/* Generate an instance of the basetype using datasrc */ void cdata_basetype(Symbol* tsym, Datasrc* datasrc, Bytebuffer* codebuf, Datalist* fillsrc) { int usecmpd; switch (tsym->subclass) { case NC_ENUM: case NC_OPAQUE: case NC_PRIM: if(issublist(datasrc)) { semerror(srcline(datasrc),"Expected primitive found {..}"); } bbAppend(codebuf,' '); cdata_primdata(tsym,datasrc,codebuf,fillsrc); break; case NC_COMPOUND: { int i; Constant* con; if(!isfillvalue(datasrc) && !issublist(datasrc)) {/* fail on no compound*/ semerror(srcline(datasrc),"Compound data must be enclosed in {..}"); } con = srcnext(datasrc); if(con->nctype == NC_FILLVALUE) { Datalist* filler = getfiller(tsym,fillsrc); ASSERT(filler->length == 1); con = &filler->data[0]; if(con->nctype != NC_COMPOUND) { semerror(con->lineno,"Compound data fill value is not enclosed in {..}"); } } srcpushlist(datasrc,con->value.compoundv); /* enter the sublist*/ bbAppend(codebuf,'{'); for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* field = (Symbol*)listget(tsym->subnodes,i); bbAppend(codebuf,' '); cdata_basetype(field,datasrc,codebuf,NULL); } bbAppend(codebuf,'}'); srcpop(datasrc); } break; case NC_VLEN: { Constant* con; if(!isfillvalue(datasrc) && !issublist(datasrc)) {/* fail on no compound*/ semerror(con->lineno,"Vlen data must be enclosed in {..}"); } con = srcnext(datasrc); if(con->nctype == NC_FILLVALUE) { Datalist* filler = getfiller(tsym,fillsrc); ASSERT(filler->length == 1); con = &filler->data[0]; if(con->nctype != NC_COMPOUND) { semerror(con->lineno,"Vlen data fill value is not enclosed in {..}"); } } /* generate the nc_vlen_t instance*/ bbprintf0(stmt,"{%u (void*)vlen_%u}", con->value.compoundv->vlen.count, con->value.compoundv->vlen.uid); bbCatbuf(codebuf,stmt); } break; case NC_FIELD: /* enclose in braces if and only if field is an array */ usecmpd = (issublist(datasrc) && tsym->typ.dimset.ndims > 0); if(usecmpd) srcpush(datasrc); if(tsym->typ.dimset.ndims > 0) { Odometer* fullodom = newodometer(&tsym->typ.dimset,NULL,NULL); cdata_fieldarray(tsym->typ.basetype,datasrc,fullodom,0,codebuf); odometerfree(fullodom); } else { cdata_basetype(tsym->typ.basetype,datasrc,codebuf,NULL); } if(usecmpd) srcpop(datasrc); break; default: PANIC1("cdata_basetype: unexpected subclass %d",tsym->subclass); } }
NCerror nc3d_getvarx(int ncid, int varid, const size_t *startp, const size_t *countp, const ptrdiff_t* stridep, void *data, nc_type dsttype0) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; int i; NC* drno; NC* substrate; NCDAPCOMMON* dapcomm; CDFnode* cdfvar = NULL; /* cdf node mapping to var*/ NClist* varnodes; nc_type dsttype; Getvara* varainfo = NULL; CDFnode* xtarget = NULL; /* target in DATADDS */ CDFnode* target = NULL; /* target in constrained DDS */ DCEprojection* varaprojection = NULL; NCcachenode* cachenode = NULL; size_t localcount[NC_MAX_VAR_DIMS]; NClist* ncdimsall; size_t ncrank; NClist* vars = NULL; DCEconstraint* fetchconstraint = NULL; DCEprojection* fetchprojection = NULL; DCEprojection* walkprojection = NULL; int state; #define FETCHWHOLE 1 /* fetch whole data set */ #define FETCHVAR 2 /* fetch whole variable */ #define FETCHPART 4 /* fetch constrained variable */ #define CACHED 8 /* whole variable is already in the cache */ ncstat = NC_check_id(ncid, (NC**)&drno); if(ncstat != NC_NOERR) goto fail; dapcomm = (NCDAPCOMMON*)drno->dispatchdata; ncstat = NC_check_id(drno->substrate, (NC**)&substrate); if(ncstat != NC_NOERR) goto fail; /* Locate var node via varid */ varnodes = dapcomm->cdf.ddsroot->tree->varnodes; for(i=0;i<nclistlength(varnodes);i++) { CDFnode* node = (CDFnode*)nclistget(varnodes,i); if(node->array.basevar == NULL && node->nctype == NC_Atomic && node->ncid == varid) { cdfvar = node; break; } } ASSERT((cdfvar != NULL)); /* If the variable is prefetchable, then now is the time to do a lazy prefetch */ if(FLAGSET(dapcomm->controls,NCF_PREFETCH) && !FLAGSET(dapcomm->controls,NCF_PREFETCH_EAGER)) { if(dapcomm->cdf.cache != NULL && dapcomm->cdf.cache->prefetch == NULL) { ncstat = prefetchdata3(dapcomm); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} } } /* Get the dimension info */ ncdimsall = cdfvar->array.dimsetall; ncrank = nclistlength(ncdimsall); #ifdef DEBUG { int i; fprintf(stderr,"getvarx: %s",cdfvar->ncfullname); for(i=0;i<ncrank;i++) fprintf(stderr,"(%ld:%ld:%ld)", (long)startp[i], (long)countp[i], (long)stridep[i] ); fprintf(stderr,"\n"); } #endif /* Fill in missing arguments */ if(startp == NULL) startp = nc_sizevector0; if(countp == NULL) { /* Accumulate the dimension sizes */ for(i=0;i<ncrank;i++) { CDFnode* dim = (CDFnode*)nclistget(ncdimsall,i); localcount[i] = dim->dim.declsize; } countp = localcount; } if(stridep == NULL) stridep = nc_ptrdiffvector1; /* Validate the dimension sizes */ for(i=0;i<ncrank;i++) { CDFnode* dim = (CDFnode*)nclistget(ncdimsall,i); if(startp[i] > dim->dim.declsize || startp[i]+countp[i] > dim->dim.declsize) { ncstat = NC_EINVALCOORDS; goto fail; } } #ifdef DEBUG { NClist* dims = cdfvar->array.dimsetall; fprintf(stderr,"getvarx: %s",cdfvar->ncfullname); if(nclistlength(dims) > 0) {int i; for(i=0;i<nclistlength(dims);i++) fprintf(stderr,"(%lu:%lu:%lu)",(unsigned long)startp[i],(unsigned long)countp[i],(unsigned long)stridep[i]); fprintf(stderr," -> "); for(i=0;i<nclistlength(dims);i++) if(stridep[i]==1) fprintf(stderr,"[%lu:%lu]",(unsigned long)startp[i],(unsigned long)((startp[i]+countp[i])-1)); else { unsigned long iend = (stridep[i] * countp[i]); iend = (iend + startp[i]); iend = (iend - 1); fprintf(stderr,"[%lu:%lu:%lu]", (unsigned long)startp[i],(unsigned long)stridep[i],iend); } } fprintf(stderr,"\n"); } #endif dsttype = (dsttype0); /* Default to using the inquiry type for this var*/ if(dsttype == NC_NAT) dsttype = cdfvar->externaltype; /* Validate any implied type conversion*/ if(cdfvar->etype != dsttype && dsttype == NC_CHAR) { /* The only disallowed conversion is to/from char and non-byte numeric types*/ switch (cdfvar->etype) { case NC_STRING: case NC_URL: case NC_CHAR: case NC_BYTE: case NC_UBYTE: break; default: return THROW(NC_ECHAR); } } ncstat = makegetvar34(dapcomm,cdfvar,data,dsttype,&varainfo); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} /* Compile the start/stop/stride info into a projection */ ncstat = buildvaraprojection3(varainfo->target, startp,countp,stridep, &varaprojection); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} fetchprojection = NULL; walkprojection = NULL; /* Create walkprojection as the merge of the url projections and the vara projection; may change in FETCHPART case below*/ ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections, varaprojection,&walkprojection); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} #ifdef DEBUG fprintf(stderr,"getvarx: walkprojection: |%s|\n",dumpprojection(walkprojection)); #endif /* define the var list of interest */ vars = nclistnew(); nclistpush(vars,(void*)varainfo->target); state = 0; if(iscached(dapcomm,cdfvar,&cachenode)) { /* ignores non-whole variable cache entries */ state = CACHED; ASSERT((cachenode != NULL)); #ifdef DEBUG fprintf(stderr,"var is in cache\n"); #endif /* If it is cached, then it is a whole variable but may still need to apply constraints during the walk */ ASSERT(cachenode->wholevariable); /* by construction */ } else if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { state = FETCHWHOLE; } else {/* load using constraints */ if(FLAGSET(dapcomm->controls,NCF_WHOLEVAR)) state = FETCHVAR; else state = FETCHPART; } ASSERT(state != 0); switch (state) { case FETCHWHOLE: { /* buildcachenode3 will create a new cachenode and will also fetch the whole corresponding datadds. */ /* Build the complete constraint to use in the fetch */ fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); /* Use no projections or selections */ fetchconstraint->projections = nclistnew(); fetchconstraint->selections = nclistnew(); #ifdef DEBUG fprintf(stderr,"getvarx: FETCHWHOLE: fetchconstraint: %s\n",dumpconstraint(fetchconstraint)); #endif ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0); fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/ if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} } break; case CACHED: { } break; case FETCHVAR: { /* Fetch a complete single variable */ /* Create fetch projection as the merge of the url projections and the vara projection */ ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections, varaprojection,&fetchprojection); /* elide any sequence and string dimensions (dap servers do not allow such). */ ncstat = removepseudodims(fetchprojection); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} /* Convert to a whole variable projection */ dcemakewholeprojection(fetchprojection); #ifdef DEBUG fprintf(stderr,"getvarx: FETCHVAR: fetchprojection: |%s|\n",dumpprojection(fetchprojection)); #endif /* Build the complete constraint to use in the fetch */ fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); /* merged constraint just uses the url constraint selection */ fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections); /* and the created fetch projection */ fetchconstraint->projections = nclistnew(); nclistpush(fetchconstraint->projections,(void*)fetchprojection); #ifdef DEBUG fprintf(stderr,"getvarx: FETCHVAR: fetchconstraint: %s\n",dumpconstraint(fetchconstraint)); #endif /* buildcachenode3 will create a new cachenode and will also fetch the corresponding datadds. */ ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0); fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/ if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} } break; case FETCHPART: { /* Create fetch projection as the merge of the url projections and the vara projection */ ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections, varaprojection,&fetchprojection); /* elide any sequence and string dimensions (dap servers do not allow such). */ ncstat = removepseudodims(fetchprojection); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} /* Shift the varaprojection for simple walk */ dcefree((DCEnode*)walkprojection) ; /* reclaim any existing walkprojection */ walkprojection = (DCEprojection*)dceclone((DCEnode*)varaprojection); dapshiftprojection(walkprojection); #ifdef DEBUG fprintf(stderr,"getvarx: FETCHPART: fetchprojection: |%s|\n",dumpprojection(fetchprojection)); #endif /* Build the complete constraint to use in the fetch */ fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); /* merged constraint just uses the url constraint selection */ fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections); /* and the created fetch projection */ fetchconstraint->projections = nclistnew(); nclistpush(fetchconstraint->projections,(void*)fetchprojection); #ifdef DEBUG fprintf(stderr,"getvarx: FETCHPART: fetchconstraint: %s\n",dumpconstraint(fetchconstraint)); #endif /* buildcachenode3 will create a new cachenode and will also fetch the corresponding datadds. */ ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0); fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/ if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} } break; default: PANIC1("unknown fetch state: %d\n",state); } ASSERT(cachenode != NULL); #ifdef DEBUG fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds)); #endif /* attach DATADDS to (constrained) DDS */ unattach34(dapcomm->cdf.ddsroot); ncstat = attachsubset34(cachenode->datadds,dapcomm->cdf.ddsroot); if(ncstat) goto fail; /* Fix up varainfo to use the cache */ varainfo->cache = cachenode; cachenode = NULL; varainfo->varaprojection = walkprojection; walkprojection = NULL; /* Get the var correlate from the datadds */ target = varainfo->target; xtarget = target->attachment; if(xtarget == NULL) {THROWCHK(ncstat=NC_ENODATA); goto fail;} /* Switch to datadds tree space*/ varainfo->target = xtarget; save = (DCEnode*)varaprojection; ncstat = moveto(dapcomm,varainfo,varainfo->cache->datadds,data); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} nclistfree(vars); dcefree((DCEnode*)varaprojection); dcefree((DCEnode*)fetchconstraint); freegetvara(varainfo); fail: if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
/* Result is a pool string or a constant => do not free*/ char* cdata_const(Constant* ci) { Bytebuffer* codetmp = bbNew(); char* result; switch (ci->nctype) { case NC_CHAR: { char tmp[64]; tmp[0] = '\0'; escapifychar(ci->value.charv,tmp,'\''); bbCat(codetmp,"'"); bbCat(codetmp,tmp); bbCat(codetmp,"'"); } break; case NC_BYTE: bbprintf(codetmp,"%hhd",ci->value.int8v); break; case NC_SHORT: bbprintf(codetmp,"%hd",ci->value.int16v); break; case NC_INT: bbprintf(codetmp,"%d",ci->value.int32v); break; case NC_FLOAT: bbprintf(codetmp,"%f",ci->value.floatv); break; case NC_DOUBLE: bbprintf(codetmp,"%lf",ci->value.doublev); break; case NC_UBYTE: bbprintf(codetmp,"%hhu",ci->value.uint8v); break; case NC_USHORT: bbprintf(codetmp,"%hu",ci->value.uint16v); break; case NC_UINT: bbprintf(codetmp,"%uU",ci->value.uint32v); break; case NC_INT64: bbprintf(codetmp,"%lldLL",ci->value.int64v); break; case NC_UINT64: bbprintf(codetmp,"%lluLLU",ci->value.uint64v); break; case NC_ECONST: bbprintf(codetmp,"%s",cname(ci->value.enumv)); break; case NC_STRING: { /* handle separately */ char* escaped = escapify(ci->value.stringv.stringv, '"',ci->value.stringv.len); result = poolalloc(1+2+strlen(escaped)); strcpy(result,"\""); strcat(result,escaped); strcat(result,"\""); goto done; } break; case NC_OPAQUE: { char* p; int bslen; bslen=(4*ci->value.opaquev.len); result = poolalloc(bslen+2+1); strcpy(result,"\""); p = ci->value.opaquev.stringv; while(*p) { strcat(result,"\\x"); strncat(result,p,2); p += 2; } strcat(result,"\""); goto done; } break; default: PANIC1("ncstype: bad type code: %d",ci->nctype); } result = pooldup(bbContents(codetmp)); /*except for NC_STRING and NC_OPAQUE*/ bbFree(codetmp); done: return result; }
/* Generate an instance of the basetype */ void generate_basetype(Symbol* tsym, NCConstant* con, Bytebuffer* codebuf, Datalist* filler, Generator* generator) { Datalist* data; switch (tsym->subclass) { case NC_ENUM: case NC_OPAQUE: case NC_PRIM: if(islistconst(con)) { semerror(constline(con),"Expected primitive found {..}"); } generate_primdata(tsym,con,codebuf,filler,generator); break; case NC_COMPOUND: { int i,uid, nfields, dllen; if(con == NULL || isfillconst(con)) { Datalist* fill = (filler==NULL?getfiller(tsym):filler); ASSERT(fill->length == 1); con = &fill->data[0]; if(!islistconst(con)) semerror(con->lineno,"Compound data fill value is not enclosed in {..}"); } if(!islistconst(con)) {/* fail on no compound*/ semerror(constline(con),"Compound data must be enclosed in {..}"); } data = con->value.compoundv; nfields = listlength(tsym->subnodes); dllen = datalistlen(data); if(dllen > nfields) { semerror(con->lineno,"Datalist longer than the number of compound fields"); break; } generator->listbegin(generator,LISTCOMPOUND,listlength(tsym->subnodes),codebuf,&uid); for(i=0;i<nfields;i++) { Symbol* field = (Symbol*)listget(tsym->subnodes,i); con = datalistith(data,i); generator->list(generator,LISTCOMPOUND,uid,i,codebuf); generate_basetype(field,con,codebuf,NULL,generator); } generator->listend(generator,LISTCOMPOUND,uid,i,codebuf); } break; case NC_VLEN: { Bytebuffer* vlenbuf; int uid; size_t count; if(con == NULL || isfillconst(con)) { Datalist* fill = (filler==NULL?getfiller(tsym):filler); ASSERT(fill->length == 1); con = &fill->data[0]; if(con->nctype != NC_COMPOUND) { semerror(con->lineno,"Vlen data fill value is not enclosed in {..}"); } } if(!islistconst(con)) { semerror(constline(con),"Vlen data must be enclosed in {..}"); } data = con->value.compoundv; /* generate the nc_vlen_t instance*/ vlenbuf = bbNew(); if(tsym->typ.basetype->typ.typecode == NC_CHAR) { gen_charvlen(data,vlenbuf); generator->vlenstring(generator,vlenbuf,&uid,&count); } else { generator->listbegin(generator,LISTVLEN,data->length,codebuf,&uid); for(count=0;count<data->length;count++) { NCConstant* con; generator->list(generator,LISTVLEN,uid,count,vlenbuf); con = datalistith(data,count); generate_basetype(tsym->typ.basetype,con,vlenbuf,NULL,generator); } generator->listend(generator,LISTVLEN,uid,count,codebuf,(void*)vlenbuf); } generator->vlendecl(generator,codebuf,tsym,uid,count,vlenbuf); bbFree(vlenbuf); } break; case NC_FIELD: if(tsym->typ.dimset.ndims > 0) { /* Verify that we have a sublist (or fill situation) */ if(con != NULL && !isfillconst(con) && !islistconst(con)) semerror(constline(con),"Dimensioned fields must be enclose in {...}"); generate_fieldarray(tsym->typ.basetype,con,&tsym->typ.dimset,codebuf,filler,generator); } else { generate_basetype(tsym->typ.basetype,con,codebuf,NULL,generator); } break; default: PANIC1("generate_basetype: unexpected subclass %d",tsym->subclass); } }
static void genbin_primdata(Symbol* basetype, Datasrc* src, Datalist* fillsrc, Bytebuffer* memory) { Constant* prim; Constant target; prim = srcnext(src); if(prim == NULL || prim->nctype == NC_FILLVALUE) { genbin_fillvalue(basetype,fillsrc,src,memory); return; } target.nctype = basetype->typ.typecode; if(prim == NULL) { #ifdef GENFILL /* generate a fill value*/ nc_getfill(&target); /* fall thru*/ #else return; #endif } ASSERT(prim->nctype != NC_COMPOUND); if(target.nctype != NC_ECONST) { convert1(prim,&target); alignbuffer(&target,memory); } switch (target.nctype) { case NC_ECONST: if(basetype->subclass != NC_ENUM) { semerror(prim->lineno,"Conversion to enum not supported (yet)"); } else { Datalist* econ = builddatalist(1); srcpushlist(src,econ); dlappend(econ,&prim->value.enumv->typ.econst); genbin_primdata(prim->value.enumv->typ.basetype,src, fillsrc,memory); srcpop(src); } break; case NC_OPAQUE: { unsigned char* bytes; size_t len; setprimlength(&target,basetype->typ.size*2); bytes=makebytestring(target.value.opaquev.stringv,&len); bbAppendn(memory,(void*)bytes,len); } break; case NC_CHAR: bbAppendn(memory,&target.value.charv,sizeof(target.value.charv)); break; case NC_BYTE: bbAppendn(memory,(void*)&target.value.int8v,sizeof(target.value.int8v)); break; case NC_SHORT: bbAppendn(memory,(void*)&target.value.int16v,sizeof(target.value.int16v)); break; case NC_INT: bbAppendn(memory,(void*)&target.value.int32v,sizeof(target.value.int32v)); break; case NC_FLOAT: bbAppendn(memory,(void*)&target.value.floatv,sizeof(target.value.floatv)); break; case NC_DOUBLE: bbAppendn(memory,(void*)&target.value.doublev,sizeof(target.value.doublev)); break; case NC_UBYTE: bbAppendn(memory,(void*)&target.value.uint8v,sizeof(target.value.uint8v)); break; case NC_USHORT: bbAppendn(memory,(void*)&target.value.uint16v,sizeof(target.value.uint16v)); break; case NC_UINT: bbAppendn(memory,(void*)&target.value.uint32v,sizeof(target.value.uint32v)); break; case NC_INT64: { union SI64 { char ch[8]; long long i64;} si64; si64.i64 = target.value.int64v; bbAppendn(memory,(void*)si64.ch,sizeof(si64.ch)); } break; case NC_UINT64: { union SU64 { char ch[8]; unsigned long long i64;} su64; su64.i64 = target.value.uint64v; bbAppendn(memory,(void*)su64.ch,sizeof(su64.ch)); } break; case NC_STRING: { if(usingclassic) { bbAppendn(memory,target.value.stringv.stringv,target.value.stringv.len); } else if(target.nctype == NC_CHAR) { bbAppendn(memory,target.value.stringv.stringv,target.value.stringv.len); } else { char* ptr; int len = (size_t)target.value.stringv.len; ptr = poolalloc(len+1); /* CAREFUL: this has short lifetime*/ memcpy(ptr,target.value.stringv.stringv,len); ptr[len] = '\0'; bbAppendn(memory,(void*)&ptr,sizeof(ptr)); } } break; default: PANIC1("genbin_primdata: unexpected type: %d",target.nctype); } }
/* Figure out the names for variables. */ NCerror computecdfvarnames(NCDAPCOMMON* nccomm, CDFnode* root, NClist* varnodes) { unsigned int i,j,d; /* clear all elided marks; except for dataset and grids */ for(i=0; i<nclistlength(root->tree->nodes); i++) { CDFnode* node = (CDFnode*)nclistget(root->tree->nodes,i); node->elided = 0; if(node->nctype == NC_Grid || node->nctype == NC_Dataset) node->elided = 1; } /* ensure all variables have an initial full name defined */ for(i=0; i<nclistlength(varnodes); i++) { CDFnode* var = (CDFnode*)nclistget(varnodes,i); nullfree(var->ncfullname); var->ncfullname = makecdfpathstring(var,nccomm->cdf.separator); #ifdef DEBUG2 fprintf(stderr,"var names: %s %s %s\n", var->ocname,var->ncbasename,var->ncfullname); #endif } /* unify all variables with same fullname and dimensions basevar fields says: "for duplicate grid variables"; when does this happen? */ if(FLAGSET(nccomm->controls,NCF_NC3)) { for(i=0; i<nclistlength(varnodes); i++) { int match; CDFnode* var = (CDFnode*)nclistget(varnodes,i); for(j=0; j<i; j++) { CDFnode* testnode = (CDFnode*)nclistget(varnodes,j); match = 1; if(testnode->array.basevar != NULL) continue; /* already processed */ if(strcmp(var->ncfullname,testnode->ncfullname) != 0) match = 0; else if(nclistlength(testnode->array.dimsetall) != nclistlength(var->array.dimsetall)) match = 0; else for(d=0; d<nclistlength(testnode->array.dimsetall); d++) { CDFnode* vdim = (CDFnode*)nclistget(var->array.dimsetall,d); CDFnode* tdim = (CDFnode*)nclistget(testnode->array.dimsetall,d); if(vdim->dim.declsize != tdim->dim.declsize) { match = 0; break; } } if(match) { testnode->array.basevar = var; fprintf(stderr,"basevar invoked: %s\n",var->ncfullname); } } } } /* Finally, verify unique names */ for(i=0; i<nclistlength(varnodes); i++) { CDFnode* var1 = (CDFnode*)nclistget(varnodes,i); if(var1->array.basevar != NULL) continue; for(j=0; j<i; j++) { CDFnode* var2 = (CDFnode*)nclistget(varnodes,j); if(var2->array.basevar != NULL) continue; if(strcmp(var1->ncfullname,var2->ncfullname)==0) { PANIC1("duplicate var names: %s",var1->ncfullname); } } } return NC_NOERR; }
NCerror dapcvtattrval(nc_type etype, void* dst, NClist* src) { int i,ok; NCerror ncstat = NC_NOERR; unsigned int memsize = nctypesizeof(etype); unsigned int nvalues = nclistlength(src); char* dstmem = (char*)dst; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(src,i); size_t slen = strlen(s); int nread = 0; /* # of chars read by sscanf */ ok = 0; switch (etype) { case NC_BYTE: { char tmp[128]; unsigned char* p = (unsigned char*)dstmem; #ifdef _MSC_VER ok = sscanf(s,"%hC%n",p,&nread); _ASSERTE(_CrtCheckMemory()); #else ok = sscanf(s,"%hhu%n",p,&nread); #endif } break; case NC_CHAR: { signed char* p = (signed char*)dstmem; ok = sscanf(s,"%c%n",p,&nread); } break; case NC_SHORT: { short* p = (short*)dstmem; ok = sscanf(s,"%hd%n",p,&nread); } break; case NC_INT: { int* p = (int*)dstmem; ok = sscanf(s,"%d%n",p,&nread); } break; case NC_FLOAT: { float* p = (float*)dstmem; ok = sscanf(s,"%g%n",p,&nread); } break; case NC_DOUBLE: { double* p = (double*)dstmem; ok = sscanf(s,"%lg%n",p,&nread); } break; case NC_UBYTE: { unsigned char* p = (unsigned char*)dstmem; #ifdef _MSC_VER ok = sscanf(s, "%hc%n", p,&nread); _ASSERTE(_CrtCheckMemory()); #else ok = sscanf(s,"%hhu%n",p,&nread); #endif } break; case NC_USHORT: { unsigned short* p = (unsigned short*)dstmem; ok = sscanf(s,"%hu%n",p,&nread); } break; case NC_UINT: { unsigned int* p = (unsigned int*)dstmem; ok = sscanf(s,"%u%n",p,&nread); } break; case NC_INT64: { long long* p = (long long*)dstmem; #ifdef _MSC_VER ok = sscanf(s, "%I64d%n", p,&nread); #else ok = sscanf(s,"%lld%n",p,&nread); #endif } break; case NC_UINT64: { unsigned long long* p = (unsigned long long*)dstmem; ok = sscanf(s,"%llu%n",p,&nread); } break; case NC_STRING: case NC_URL: { char** p = (char**)dstmem; *p = nulldup(s); ok = 1; } break; default: PANIC1("unexpected nc_type: %d",(int)etype); } if(ok != 1 || nread != slen) {ncstat = NC_EINVAL; goto done;} dstmem += memsize; } done: return THROW(ncstat); }
static int c_constant(Generator* generator, NCConstant* con, Bytebuffer* buf,...) { Bytebuffer* codetmp = bbNew(); char* special = NULL; switch (con->nctype) { case NC_CHAR: if(con->value.charv == '\'') bbprintf(codetmp,"'\\''"); else bbprintf(codetmp,"'%s'",cescapifychar(con->value.charv,'\'')); break; case NC_BYTE: bbprintf(codetmp,"%hhd",con->value.int8v); break; case NC_SHORT: bbprintf(codetmp,"%hd",con->value.int16v); break; case NC_INT: bbprintf(codetmp,"%d",con->value.int32v); break; case NC_FLOAT: /* Special case for nanf */ if(isnan(con->value.floatv)) bbprintf(codetmp,"nanf"); else bbprintf(codetmp,"%f",con->value.floatv); break; case NC_DOUBLE: /* Special case for nan */ if(isnan(con->value.doublev)) bbprintf(codetmp,"nan"); else bbprintf(codetmp,"%lf",con->value.doublev); break; case NC_UBYTE: bbprintf(codetmp,"%hhu",con->value.uint8v); break; case NC_USHORT: bbprintf(codetmp,"%hu",con->value.uint16v); break; case NC_UINT: bbprintf(codetmp,"%uU",con->value.uint32v); break; case NC_INT64: bbprintf(codetmp,"%lldLL",con->value.int64v); break; case NC_UINT64: bbprintf(codetmp,"%lluLLU",con->value.uint64v); break; case NC_ECONST: bbprintf(codetmp,"%s",cname(con->value.enumv)); break; case NC_NIL: case NC_STRING: { /* handle separately */ if(con->value.stringv.len == 0 && con->value.stringv.stringv == NULL) { bbprintf(codetmp,"NULL"); } else { char* escaped = escapify(con->value.stringv.stringv, '"',con->value.stringv.len); special = poolalloc(1+2+strlen(escaped)); strcpy(special,"\""); strcat(special,escaped); strcat(special,"\""); } } break; case NC_OPAQUE: { char* p; int bslen; bslen=(4*con->value.opaquev.len); special = poolalloc(bslen+2+1); strcpy(special,"\""); p = con->value.opaquev.stringv; while(*p) { strcat(special,"\\x"); strncat(special,p,2); p += 2; } strcat(special,"\""); } break; default: PANIC1("ncstype: bad type code: %d",con->nctype); } if(special == NULL) bbCatbuf(buf,codetmp); else bbCat(buf,special); bbFree(codetmp); return 1; }
/* 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; } }
static int j_constant(Generator* generator, Symbol* sym, NCConstant* con, Bytebuffer* buf,...) { Bytebuffer* codetmp = bbNew(); char* special = NULL; switch (con->nctype) { case NC_CHAR: if(con->value.charv == '\'') bbprintf(codetmp,"'\\''"); else bbprintf(codetmp,"'%c'",con->value.charv); break; case NC_BYTE: bbprintf(codetmp,"%hhd",con->value.int8v); break; case NC_SHORT: bbprintf(codetmp,"%hd",con->value.int16v); break; case NC_INT: bbprintf(codetmp,"%d",con->value.int32v); break; case NC_FLOAT: /* Special case for nan */ if(isnan(con->value.floatv)) bbprintf(codetmp,"Float.NaN"); else bbprintf(codetmp,"%f",con->value.floatv); break; case NC_DOUBLE: /* Special case for nan */ if(isnan(con->value.doublev)) bbprintf(codetmp,"Double.NaN"); else bbprintf(codetmp,"%lf",con->value.doublev); break; case NC_UBYTE: bbprintf(codetmp,"%hhu",con->value.uint8v); break; case NC_USHORT: bbprintf(codetmp,"%hu",con->value.uint16v); break; case NC_UINT: bbprintf(codetmp,"%uU",con->value.uint32v); break; case NC_INT64: bbprintf(codetmp,"%lldLL",con->value.int64v); break; case NC_UINT64: bbprintf(codetmp,"%lluLLU",con->value.uint64v); break; case NC_STRING: { /* handle separately */ char* escaped = escapify(con->value.stringv.stringv, '"',con->value.stringv.len); special = poolalloc(1+2+strlen(escaped)); strcpy(special,"\""); strcat(special,escaped); strcat(special,"\""); } break; default: PANIC1("ncstype: bad type code: %d",con->nctype); } if(special == NULL) bbCatbuf(buf,codetmp); else bbCat(buf,special); bbFree(codetmp); return 1; }
Symbol* locate(Symbol* refsym) { Symbol* sym = NULL; switch (refsym->objectclass) { case NC_DIM: if(refsym->is_prefixed) { /* locate exact dimension specified*/ sym = lookup(NC_DIM,refsym); } else { /* Search for matching dimension in all parent groups*/ Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/ while(parent != NULL) { /* search this parent for matching name and type*/ sym = lookupingroup(NC_DIM,refsym->name,parent); if(sym != NULL) break; parent = parent->container; } } break; case NC_TYPE: if(refsym->is_prefixed) { /* locate exact type specified*/ sym = lookup(NC_TYPE,refsym); } else { Symbol* parent; int i; /* Search for matching type in all groups (except...)*/ /* Short circuit test for primitive types*/ for(i=NC_NAT;i<=NC_STRING;i++) { Symbol* prim = basetypefor(i); if(prim == NULL) continue; if(strcmp(refsym->name,prim->name)==0) { sym = prim; break; } } if(sym == NULL) { /* Added 5/26/09: look in parent hierarchy first */ parent = lookupgroup(refsym->prefix);/*get group for refsym*/ while(parent != NULL) { /* search this parent for matching name and type*/ sym = lookupingroup(NC_TYPE,refsym->name,parent); if(sym != NULL) break; parent = parent->container; } } if(sym == NULL) { sym = uniquetreelocate(refsym,rootgroup); /* want unique */ } } break; case NC_VAR: if(refsym->is_prefixed) { /* locate exact variable specified*/ sym = lookup(NC_VAR,refsym); } else { Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/ /* search this parent for matching name and type*/ sym = lookupingroup(NC_VAR,refsym->name,parent); } break; case NC_GRP: if(refsym->is_prefixed) { /* locate exact group specified*/ sym = lookup(NC_GRP,refsym); } else { Symbol* parent = lookupgroup(refsym->prefix);/*get group for refsym*/ /* search this parent for matching name and type*/ sym = lookupingroup(NC_GRP,refsym->name,parent); } break; default: PANIC1("locate: bad refsym type: %d",refsym->objectclass); } if(debug > 1) { char* ncname; if(refsym->objectclass == NC_TYPE) ncname = ncclassname(refsym->subclass); else ncname = ncclassname(refsym->objectclass); fdebug("locate: %s: %s -> %s\n", ncname,fullname(refsym),(sym?fullname(sym):"NULL")); } return sym; }
NCerror dapcvtattrval3(nc_type etype, void* dst, NClist* src) { int i,ok; NCerror ncstat = NC_NOERR; unsigned int memsize = nctypesizeof(etype); unsigned int nvalues = nclistlength(src); char* dstmem = (char*)dst; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(src,i); ok = 0; switch (etype) { case NC_BYTE: { unsigned char* p = (unsigned char*)dstmem; ok = sscanf(s,"%hhu",p); } break; case NC_CHAR: { signed char* p = (signed char*)dstmem; ok = sscanf(s,"%c",p); } break; case NC_SHORT: { short* p = (short*)dstmem; ok = sscanf(s,"%hd",p); } break; case NC_INT: { int* p = (int*)dstmem; ok = sscanf(s,"%d",p); } break; case NC_FLOAT: { float* p = (float*)dstmem; ok = sscanf(s,"%g",p); } break; case NC_DOUBLE: { double* p = (double*)dstmem; ok = sscanf(s,"%lg",p); } break; case NC_UBYTE: { unsigned char* p = (unsigned char*)dstmem; ok = sscanf(s,"%hhu",p); } break; case NC_USHORT: { unsigned short* p = (unsigned short*)dstmem; ok = sscanf(s,"%hu",p); } break; case NC_UINT: { unsigned int* p = (unsigned int*)dstmem; ok = sscanf(s,"%u",p); } break; case NC_INT64: { long long* p = (long long*)dstmem; ok = sscanf(s,"%lld",p); } break; case NC_UINT64: { unsigned long long* p = (unsigned long long*)dstmem; ok = sscanf(s,"%llu",p); } break; case NC_STRING: case NC_URL: { char** p = (char**)dstmem; *p = nulldup(s); ok = 1; } break; default: PANIC1("unexpected nc_type: %d",(int)etype); } if(ok != 1) {ncstat = NC_EINVAL; goto done;} dstmem += memsize; } done: return THROW(ncstat); }
static int bin_constant(Generator* generator, Symbol* sym, NCConstant* con, Bytebuffer* buf,...) { if(con->nctype != NC_ECONST) { alignbuffer(con,buf); } switch (con->nctype) { case NC_OPAQUE: { unsigned char* bytes = NULL; size_t len; /* Assume the opaque string has been normalized */ bytes=makebytestring(con->value.opaquev.stringv,&len); bbAppendn(buf,(void*)bytes,len); efree(bytes); } break; case NC_CHAR: bbAppendn(buf,&con->value.charv,sizeof(con->value.charv)); break; case NC_BYTE: bbAppendn(buf,(void*)&con->value.int8v,sizeof(con->value.int8v)); break; case NC_SHORT: bbAppendn(buf,(void*)&con->value.int16v,sizeof(con->value.int16v)); break; case NC_INT: bbAppendn(buf,(void*)&con->value.int32v,sizeof(con->value.int32v)); break; case NC_FLOAT: bbAppendn(buf,(void*)&con->value.floatv,sizeof(con->value.floatv)); break; case NC_DOUBLE: bbAppendn(buf,(void*)&con->value.doublev,sizeof(con->value.doublev)); break; case NC_UBYTE: bbAppendn(buf,(void*)&con->value.uint8v,sizeof(con->value.uint8v)); break; case NC_USHORT: bbAppendn(buf,(void*)&con->value.uint16v,sizeof(con->value.uint16v)); break; case NC_UINT: bbAppendn(buf,(void*)&con->value.uint32v,sizeof(con->value.uint32v)); break; case NC_INT64: { union SI64 { char ch[8]; long long i64;} si64; si64.i64 = con->value.int64v; bbAppendn(buf,(void*)si64.ch,sizeof(si64.ch)); } break; case NC_UINT64: { union SU64 { char ch[8]; unsigned long long i64;} su64; su64.i64 = con->value.uint64v; bbAppendn(buf,(void*)su64.ch,sizeof(su64.ch)); } break; case NC_NIL: case NC_STRING: { int len = (size_t)con->value.stringv.len; if(len == 0 && con->value.stringv.stringv == NULL) { char* nil = NULL; bbAppendn(buf,(void*)&nil,sizeof(nil)); } else { char* ptr = (char*)ecalloc(len+1); memcpy(ptr,con->value.stringv.stringv,len); ptr[len] = '\0'; bbAppendn(buf,(void*)&ptr,sizeof(ptr)); ptr = NULL; } } break; default: PANIC1("bin_constant: unexpected type: %d",con->nctype); } return 1; }
static NCerror buildcdftreer(NCDAPCOMMON* nccomm, OCddsnode ocnode, CDFnode* container, CDFtree* tree, CDFnode** cdfnodep) { size_t i,ocrank,ocnsubnodes; OCtype octype; OCtype ocatomtype; char* ocname = NULL; NCerror ncerr = NC_NOERR; CDFnode* cdfnode = NULL; oc_dds_class(nccomm->oc.conn,ocnode,&octype); if(octype == OC_Atomic) oc_dds_atomictype(nccomm->oc.conn,ocnode,&ocatomtype); else ocatomtype = OC_NAT; oc_dds_name(nccomm->oc.conn,ocnode,&ocname); oc_dds_rank(nccomm->oc.conn,ocnode,&ocrank); oc_dds_nsubnodes(nccomm->oc.conn,ocnode,&ocnsubnodes); #ifdef DEBUG1 if(ocatomtype == OC_NAT) fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(octype),ocname); else fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(ocatomtype),ocname); #endif switch (octype) { case OC_Dataset: cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container); nclistpush(tree->nodes,(void*)cdfnode); tree->root = cdfnode; cdfnode->tree = tree; break; case OC_Grid: case OC_Structure: case OC_Sequence: cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container); nclistpush(tree->nodes,(void*)cdfnode); #if 0 if(tree->root == NULL) { tree->root = cdfnode; cdfnode->tree = tree; } #endif break; case OC_Atomic: cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container); nclistpush(tree->nodes,(void*)cdfnode); #if 0 if(tree->root == NULL) { tree->root = cdfnode; cdfnode->tree = tree; } #endif break; case OC_Dimension: default: PANIC1("buildcdftree: unexpect OC node type: %d",(int)octype); } /* Avoid a rare but perhaps possible null-dereference of cdfnode. Not sure what error to throw, so using NC_EDAP: generic DAP error. */ if(!cdfnode) { return NC_EDAP; } #if 0 /* cross link */ assert(tree->root != NULL); cdfnode->root = tree->root; #endif if(ocrank > 0) defdimensions(ocnode,cdfnode,nccomm,tree); for(i=0;i<ocnsubnodes;i++) { OCddsnode ocsubnode; CDFnode* subnode; oc_dds_ithfield(nccomm->oc.conn,ocnode,i,&ocsubnode); ncerr = buildcdftreer(nccomm,ocsubnode,cdfnode,tree,&subnode); if(ncerr) { if(ocname) free(ocname); return ncerr; } nclistpush(cdfnode->subnodes,(void*)subnode); } nullfree(ocname); if(cdfnodep) *cdfnodep = cdfnode; return ncerr; }
static void dumpdataprim(NCConstant* ci, Bytebuffer* buf) { char tmp[64]; ASSERT(isprimplus(ci->nctype) || ci->nctype == NC_FILLVALUE); switch (ci->nctype) { case NC_CHAR: { bbCat(buf,"'"); escapifychar(ci->value.charv,tmp,'\''); bbCat(buf,tmp); bbCat(buf,"'"); } break; case NC_BYTE: sprintf(tmp,"%hhd",ci->value.int8v); bbCat(buf,tmp); break; case NC_SHORT: sprintf(tmp,"%hd",ci->value.int16v); bbCat(buf,tmp); break; case NC_INT: sprintf(tmp,"%d",ci->value.int32v); bbCat(buf,tmp); break; case NC_FLOAT: sprintf(tmp,"%g",ci->value.floatv); bbCat(buf,tmp); break; case NC_DOUBLE: sprintf(tmp,"%lg",ci->value.doublev); bbCat(buf,tmp); break; case NC_UBYTE: sprintf(tmp,"%hhu",ci->value.int8v); bbCat(buf,tmp); break; case NC_USHORT: sprintf(tmp,"%hu",ci->value.uint16v); bbCat(buf,tmp); break; case NC_UINT: sprintf(tmp,"%u",ci->value.uint32v); bbCat(buf,tmp); break; case NC_INT64: sprintf(tmp,"%lld",ci->value.int64v); bbCat(buf,tmp); break; case NC_UINT64: sprintf(tmp,"%llu",ci->value.uint64v); bbCat(buf,tmp); break; case NC_ECONST: sprintf(tmp,"%s",ci->value.enumv->fqn); bbCat(buf,tmp); break; case NC_STRING: bbCat(buf,"\""); bbCat(buf,ci->value.stringv.stringv); bbCat(buf,"\""); break; case NC_OPAQUE: bbCat(buf,"0x"); bbCat(buf,ci->value.opaquev.stringv); break; case NC_FILLVALUE: bbCat(buf,"_"); break; default: PANIC1("dumpdataprim: bad type code:%d",ci->nctype); } }