char* makepathstring(NClist* path, const char* separator, int flags) { int i,len,first; NCbytes* pathname = NULL; char* result; CDFnode* node; len = nclistlength(path); ASSERT(len > 0); /* dataset at least */ if(len == 1) {/* dataset only */ node = (CDFnode*)nclistget(path,0); return nulldup(node->ncbasename); } pathname = ncbytesnew(); for(first=1,i=0;i<len;i++) { CDFnode* node = (CDFnode*)nclistget(path,i); char* name; if(!node->elided || (flags & PATHELIDE)==0) { if(node->nctype != NC_Dataset) { name = node->ncbasename; assert(name != NULL); if(!first) ncbytescat(pathname,separator); ncbytescat(pathname,name); first = 0; } } } result = ncbytesextract(pathname); ncbytesfree(pathname); return result; }
/* Suppress variables not in usable sequences*/ NCerror suppressunusablevars3(NCDAPCOMMON* dapcomm) { int i,j; int found = 1; NClist* path = nclistnew(); while(found) { found = 0; /* Walk backwards to aid removal semantics */ for(i=nclistlength(dapcomm->cdf.ddsroot->tree->varnodes)-1;i>=0;i--) { CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.ddsroot->tree->varnodes,i); /* See if this var is under an unusable sequence */ nclistclear(path); collectnodepath3(var,path,WITHOUTDATASET); for(j=0;j<nclistlength(path);j++) { CDFnode* node = (CDFnode*)nclistget(path,j); if(node->nctype == NC_Sequence && !node->usesequence) { #ifdef DEBUG fprintf(stderr,"suppressing var in unusable sequence: %s.%s\n",node->ncfullname,var->ncbasename); #endif found = 1; break; } } if(found) break; } if(found) nclistremove(dapcomm->cdf.ddsroot->tree->varnodes,i); } nclistfree(path); return NC_NOERR; }
NCerror showprojection3(NCDAPCOMMON* dapcomm, CDFnode* var) { int i,rank; NCerror ncstat = NC_NOERR; NCbytes* projection = ncbytesnew(); NClist* path = nclistnew(); NC* drno = dapcomm->controller; /* Collect the set of DDS node name forming the xpath */ collectnodepath3(var,path,WITHOUTDATASET); for(i=0;i<nclistlength(path);i++) { CDFnode* node = (CDFnode*)nclistget(path,i); if(i > 0) ncbytescat(projection,"."); ncbytescat(projection,node->ocname); } /* Now, add the dimension info */ rank = nclistlength(var->array.dimset0); for(i=0;i<rank;i++) { CDFnode* dim = (CDFnode*)nclistget(var->array.dimset0,i); char tmp[32]; ncbytescat(projection,"["); snprintf(tmp,sizeof(tmp),"%lu",(unsigned long)dim->dim.declsize); ncbytescat(projection,tmp); ncbytescat(projection,"]"); } /* Define the attribute */ ncstat = nc_put_att_text(getncid(drno),var->ncid, "_projection", ncbyteslength(projection), ncbytescontents(projection)); return ncstat; }
static int printMetaData(D4printer* out, NCD4node* node, int depth) { int ret = NC_NOERR; int i; if(nclistlength(node->dims) > 0) { for(i=0;i<nclistlength(node->dims);i++) { NCD4node* dim = (NCD4node*)nclistget(node->dims,i); printDimref(out,dim,depth); CAT("\n"); } } if(nclistlength(node->maps) > 0) { for(i=0;i<nclistlength(node->maps);i++) { NCD4node* mapref = (NCD4node*)nclistget(node->maps,i); printMap(out,mapref,depth); CAT("\n"); } } if(nclistlength(node->attributes) > 0) { for(i=0;i<nclistlength(node->attributes);i++) { NCD4node* attr = (NCD4node*)nclistget(node->attributes,i); printAttribute(out,attr,depth); CAT("\n"); } } return THROW(ret); }
/** * @internal Get information about an enum member: an identifier and * value. Identifier size will be <= NC_MAX_NAME. * * @param ncid File and group ID. * @param typeid1 Type ID. * @param idx Enum member index. * @param identifier Gets the identifier. * @param value Gets the enum value. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @return ::NC_EBADTYPE Type not found. * @return ::NC_EINVAL Bad idx. * @author Ed Hartnett */ int NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier, void *value) { NC_GRP_INFO_T *grp; NC_TYPE_INFO_T *type; NC_ENUM_MEMBER_INFO_T *enum_member; int retval; LOG((2, "nc_inq_enum_member: ncid 0x%x typeid %d", ncid, typeid1)); /* Find group metadata. */ if ((retval = nc4_find_nc4_grp(ncid, &grp))) return retval; /* Find this type. */ if (!(type = nclistget(grp->nc4_info->alltypes, typeid1))) return NC_EBADTYPE; /* Complain if they are confused about the type. */ if (type->nc_type_class != NC_ENUM) return NC_EBADTYPE; /* Move to the desired enum member in the list. */ if (!(enum_member = nclistget(type->u.e.enum_member, idx))) return NC_EINVAL; /* Give the people what they want. */ if (identifier) strcpy(identifier, enum_member->name); if (value) memcpy(value, enum_member->value, type->size); return NC_NOERR; }
static NCerror fillsegmentpath(DCEprojection* p, NClist* nodes) { int i; NCerror ncstat = NC_NOERR; NClist* path = nclistnew(); ASSERT(p->discrim == CES_VAR); collectsegmentnames3(p->var->segments,path); ncstat = matchpartialname3(nodes,path,&p->var->cdfleaf); if(ncstat) goto done; /* Now complete the segment path */ nclistclear(path); collectnodepath3(p->var->cdfleaf,path,!WITHDATASET); if(nclistlength(path) != nclistlength(p->var->segments)) { ncstat = NC_EINVAL; goto done; } for(i=0;i<nclistlength(p->var->segments);i++) { DCEsegment* seg = (DCEsegment*)nclistget(p->var->segments,i); CDFnode* node = (CDFnode*)nclistget(path,i); seg->cdfnode = node; #ifdef DEBUG fprintf(stderr,"reref: %s -> %s\n",seg->name,node->name); #endif } done: nclistfree(path); return ncstat; }
static int matchsuffix3(NClist* matchpath, NClist* segments) { int i,j; int nsegs = nclistlength(segments); int pathlen = nclistlength(matchpath); ASSERT(pathlen >= nsegs); for(i=0;i<pathlen;i++) { int pathmatch = 1; /* Starting at this point in the path, try to match the segment list */ for(j=0;j<nsegs && (i+j < pathlen);j++) { int segmatch = 1; DCEsegment* seg = (DCEsegment*)nclistget(segments,j); CDFnode* node = (CDFnode*)nclistget(matchpath,i+j); int rank = seg->rank; /* Do the names match (in oc name space) */ if(strcmp(seg->name,node->ocname) != 0) { segmatch = 0;/* no match */ } else /* Do the ranks match (watch out for sequences) */ if(rank == 0) /* rank == 9 matches any set of dimensions */ segmatch = 1; else if(node->nctype == NC_Sequence) segmatch = (rank == 1?1:0); else /*!NC_Sequence*/ segmatch = (rank == nclistlength(node->array.dimset0)?1:0); if(!segmatch) pathmatch = 0; } if(pathmatch) return 1; } return 0; }
/* Free up a single node, but not any nodes it points to. */ static void free1cdfnode(CDFnode* node) { unsigned int j,k; if(node == NULL) return; nullfree(node->ocname); nullfree(node->ncbasename); nullfree(node->ncfullname); if(node->attributes != NULL) { for(j=0;j<nclistlength(node->attributes);j++) { NCattribute* att = (NCattribute*)nclistget(node->attributes,j); nullfree(att->name); for(k=0;k<nclistlength(att->values);k++) nullfree((char*)nclistget(att->values,k)); nclistfree(att->values); nullfree(att); } } nullfree(node->dodsspecial.dimname); nclistfree(node->subnodes); nclistfree(node->attributes); nclistfree(node->array.dimsetplus); nclistfree(node->array.dimsetall); nclistfree(node->array.dimset0); nclistfree(node->array.dimsettrans); /* Clean up the ncdap4 fields also */ nullfree(node->typename); nullfree(node->vlenname); nullfree(node); }
/* Fill in: 1. projection segments 2. projection segment slices declsize 3. selection path */ NCerror qualifyconstraints3(DCEconstraint* constraint) { NCerror ncstat = NC_NOERR; int i; #ifdef DEBUG fprintf(stderr,"qualifyconstraints.before: %s\n", dumpconstraint(constraint)); #endif if(constraint != NULL) { for(i=0;i<nclistlength(constraint->projections);i++) { DCEprojection* p = (DCEprojection*)nclistget(constraint->projections,i); ncstat = qualifyprojectionnames3(p); ncstat = qualifyprojectionsizes3(p); } #ifdef IGNORE for(i=0;i<nclistlength(constraint->selections);i++) { DCEselection* s = (DCEselection*)nclistget(constraint->selections,i); ncstat = qualifyselectionnames3(s); } #endif } #ifdef DEBUG fprintf(stderr,"qualifyconstraints.after: %s\n", dumpconstraint(constraint)); #endif return ncstat; }
static void completesegments3(NClist* fullpath, NClist* segments) { int i,delta; /* add path nodes to segments to create full path */ delta = (nclistlength(fullpath) - nclistlength(segments)); ASSERT((delta >= 0)); for(i=0;i<delta;i++) { DCEsegment* seg = (DCEsegment*)dcecreate(CES_SEGMENT); CDFnode* node = (CDFnode*)nclistget(fullpath,i); seg->name = nulldup(node->ocname); seg->annotation = (void*)node; seg->rank = nclistlength(node->array.dimset0); #ifdef IGNORE for(j=0;j<seg->rank;j++) { CDFnode* dim = (CDFnode*)nclistget(node->array.dimset0,j); dcemakewholeslice(seg->slices+j,dim->dim.declsize); } #endif nclistinsert(segments,i,(ncelem)seg); } /* Now modify the segments to point to the appropriate node and fill in the slices. */ for(i=delta;i<nclistlength(segments);i++) { DCEsegment* seg = (DCEsegment*)nclistget(segments,i); CDFnode* node = (CDFnode*)nclistget(fullpath,i); seg->annotation = (void*)node; #ifdef IGNORE if(!seg->slicesdefined) { makewholesegment3(seg,node); } #endif } }
/* Based on the tactic, determine the set of variables to add */ static void computevarset4(NCDRNO* drno, Getvara* getvar, NClist* varlist) { int i; nclistclear(varlist); for(i=0;i<nclistlength(drno->cdf.varnodes);i++) { CDFnode* var = (CDFnode*)nclistget(drno->cdf.varnodes,i); #ifdef IGNORE int ok = 1; for(j=0;j<nclistlength(var->array.ncdimensions);j++) { CDFnode* dim = (CDFnode*)nclistget(var->array.ncdimensions,j); if(dim->dim.declsize == NC_UNLIMITED) {ok = 0; break;} } if(!ok) continue; #endif switch (getvar->tactic->tactic) { case tactic_all: /* add all visible variables */ nclistpush(varlist,(ncelem)var); break; case tactic_partial: /* add only small variables + target */ if(var->estimatedsize < drno->cdf.smallsizelimit || getvar->target == var) { nclistpush(varlist,(ncelem)var); } break; case tactic_var: /* add only target var */ if(getvar->target == var) nclistpush(varlist,(ncelem)var); break; default: break; } } }
static int slicematch(NClist* seglist1, NClist* seglist2) { int i,j; if((seglist1 == NULL || seglist2 == NULL) && seglist1 != seglist2) return 0; if(nclistlength(seglist1) != nclistlength(seglist2)) return 0; for(i=0;i<nclistlength(seglist1);i++) { DCEsegment* seg1 = (DCEsegment*)nclistget(seglist1,i); DCEsegment* seg2 = (DCEsegment*)nclistget(seglist2,i); if(seg1->rank != seg2->rank) return 0; for(j=0;j<seg1->rank;j++) { DCEslice* slice1 = &seg1->slices[j]; DCEslice* slice2 = &seg2->slices[j]; size_t count1 = slice1->count; size_t count2 = slice2->count; if(slice1->first != slice2->first || count1 != count2 || slice1->stride != slice2->stride) return 0; } } return 1; }
/* Return 1 if we can reuse cached data to address the current get_vara request; return 0 otherwise. Target is in the constrained tree space. Currently, if the target matches a cache that is not a whole variable, then match is false. */ int iscached(NCDAPCOMMON* nccomm, CDFnode* target, NCcachenode** cachenodep) { int i,j,found,index; NCcache* cache; NCcachenode* cachenode; found = 0; if(target == NULL) goto done; /* Match the target variable against the prefetch, if any */ /* Note that prefetches are always whole variable */ cache = nccomm->cdf.cache; cachenode = cache->prefetch; if(cachenode!= NULL) { for(found=0,i=0;i<nclistlength(cachenode->vars);i++) { CDFnode* var = (CDFnode*)nclistget(cachenode->vars,i); if(var == target) { if(cachenodep) *cachenodep = cachenode; found=1; goto done; } } } /*search other cache nodes starting at latest first */ index = 0; for(i=nclistlength(cache->nodes)-1;i>=0;i--) { cachenode = (NCcachenode*)nclistget(cache->nodes,i); /* We currently do not try to match constraints; If the cachenode is constrained, then skip it */ if(!cachenode->wholevariable) continue; for(found=0,j=0;j<nclistlength(cachenode->vars);j++) { CDFnode* var = (CDFnode*)nclistget(cachenode->vars,j); if(var == target) {found=1;index=i;break;} } if(found) break; } if(found) { ASSERT((cachenode != NULL)); if(nclistlength(cache->nodes) > 1) { /* Manage the cache nodes as LRU */ nclistremove(cache->nodes,index); nclistpush(cache->nodes,(ncelem)cachenode); } if(cachenodep) *cachenodep = cachenode; } done: #ifdef DEBUG fprintf(stderr,"iscached: search: %s\n",makesimplepathstring3(target)); if(found) fprintf(stderr,"iscached: found: %s\n",dumpcachenode(cachenode)); else fprintf(stderr,"iscached: notfound\n"); #endif return found; }
static void removepseudodims3(DCEprojection* clone) { int i; int nsegs; DCEsegment* seg; ASSERT((clone != NULL)); nsegs = nclistlength(clone->var->segments); /* 1. scan for sequences and remove any index projections. */ for(i=0;i<nsegs;i++) { seg = (DCEsegment*)nclistget(clone->var->segments,i); if(seg->cdfnode->nctype != NC_Sequence) continue; /* not a sequence */ seg->rank = 0; } /* 2. Check the terminal segment to see if it is a String primitive, and if so, then remove the string dimension */ if(nsegs > 0) { seg = (DCEsegment*)nclistget(clone->var->segments,nsegs-1); /* See if the node has a string dimension */ if(seg->cdfnode->nctype == NC_Primitive && seg->cdfnode->array.stringdim != NULL) { /* Remove the string dimension projection from the segment */ seg->rank--; } } }
/* Convert a CDFnode var to a projection; include pseudodimensions; always whole variable. */ int dapvar2projection(CDFnode* var, DCEprojection** projectionp) { int i,j; int ncstat = NC_NOERR; NClist* path = nclistnew(); NClist* segments; DCEprojection* projection = NULL; int dimindex; /* Collect the nodes needed to construct the projection segment */ collectnodepath3(var,path,!WITHDATASET); segments = nclistnew(); dimindex = 0; /* point to next subset of slices */ nclistsetalloc(segments,nclistlength(path)); for(i=0;i<nclistlength(path);i++) { DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT); CDFnode* n = (CDFnode*)nclistget(path,i); int localrank; NClist* dimset; segment->annotation = (void*)n; segment->name = nulldup(n->ocname); /* We need to assign whole slices to each segment */ localrank = nclistlength(n->array.dimsetplus); segment->rank = localrank; dimset = n->array.dimsetplus; for(j=0;j<localrank;j++) { DCEslice* slice; CDFnode* dim; slice = &segment->slices[j]; dim = (CDFnode*)nclistget(dimset,j); ASSERT(dim->dim.declsize0 > 0); dcemakewholeslice(slice,dim->dim.declsize0); } segment->slicesdefined = 1; segment->slicesdeclized = 1; dimindex += localrank; nclistpush(segments,(ncelem)segment); } projection = (DCEprojection*)dcecreate(CES_PROJECT); projection->discrim = CES_VAR; projection->var = (DCEvar*)dcecreate(CES_VAR); projection->var->annotation = (void*)var; projection->var->segments = segments; #ifdef DEBUG1 fprintf(stderr,"dapvar2projection: projection=%s\n", dumpprojection(projection)); #endif nclistfree(path); if(ncstat) dcefree((DCEnode*)projection); else if(projectionp) *projectionp = projection; return ncstat; }
NCerror mapconstraints3(DCEconstraint* constraint, CDFnode* root) { int i; NCerror ncstat = NC_NOERR; NClist* nodes = root->tree->nodes; NClist* dceprojections; NClist* dceselections; dceprojections = constraint->projections; dceselections = constraint->selections; /* Convert the projection paths to leaves in the dds tree */ for(i=0;i<nclistlength(dceprojections);i++) { DCEprojection* proj = (DCEprojection*)nclistget(dceprojections,i); if(proj->discrim != CES_VAR) continue; // ignore functions ncstat = matchpartialname3(nodes,proj->var->segments, (CDFnode**)&proj->var->annotation); if(ncstat) goto done; } #ifdef IGNORE Only care about projections /* Convert the selection paths to leaves in the dds tree */ for(i=0;i<nclistlength(dceselections);i++) { DCEselection* sel = (DCEselection*)nclistget(dceselections,i); if(sel->lhs->discrim != CES_VAR) continue; ncstat = matchpartialname3(nodes,sel->lhs->var->segments, (CDFnode**)&sel->lhs->var->annotation); if(ncstat) goto done; } /* Convert the selection path values to leaves in the dds tree */ for(i=0;i<nclistlength(dceselections);i++) { int j; DCEselection* sel = (DCEselection*)nclistget(dceselections,i); for(j=0;j<nclistlength(sel->rhs);j++) { DCEvalue* value = (DCEvalue*)nclistget(sel->rhs,j); if(value->discrim != CES_VAR) continue; ncstat = matchpartialname3(nodes,value->var->segments, (CDFnode**)&value->var->annotation); if(ncstat) goto done; } } #endif #ifdef DEBUG fprintf(stderr,"mapconstraint.projections: %s\n", dumpprojections(dceprojections)); fprintf(stderr,"mapconstraint.selections: %s\n", dumpselections(dceselections)); #endif done: return THROW(ncstat); }
static NCerror buildattribute3a(NCDAPCOMMON* dapcomm, NCattribute* att, nc_type vartype, int varid) { int i; NCerror ncstat = NC_NOERR; unsigned int nvalues = nclistlength(att->values); NC* drno = dapcomm->controller; /* If the type of the attribute is string, then we need*/ /* to convert to a single character string by concatenation. modified: 10/23/09 to insert newlines. modified: 10/28/09 to interpret escapes */ if(att->etype == NC_STRING || att->etype == NC_URL) { char* newstring; size_t newlen = 0; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(att->values,i); newlen += (1+strlen(s)); } newstring = (char*)malloc(newlen); MEMCHECK(newstring,NC_ENOMEM); newstring[0] = '\0'; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(att->values,i); if(i > 0) strcat(newstring,"\n"); strcat(newstring,s); } dapexpandescapes(newstring); if(newstring[0]=='\0') ncstat = nc_put_att_text(drno->substrate,varid,att->name,1,newstring); else ncstat = nc_put_att_text(drno->substrate,varid,att->name,strlen(newstring),newstring); free(newstring); } else { nc_type atype; unsigned int typesize; void* mem; /* It turns out that some servers upgrade the type of _FillValue in order to correctly preserve the original value. However, since the type of the underlying variable is not changes, we get a type mismatch. So, make sure the type of the fillvalue is the same as that of the controlling variable. */ if(varid != NC_GLOBAL && strcmp(att->name,"_FillValue")==0) atype = nctypeconvert(dapcomm,vartype); else atype = nctypeconvert(dapcomm,att->etype); typesize = nctypesizeof(atype); mem = malloc(typesize * nvalues); ncstat = dapcvtattrval3(atype,mem,att->values); ncstat = nc_put_att(drno->substrate,varid,att->name,atype,nvalues,mem); nullfree(mem); } return THROW(ncstat); }
static void ceallnodesr(DCEnode* node, NClist* allnodes, CEsort which) { int i; if(node == NULL) return; if(nclistcontains(allnodes,(ncelem)node)) return; if(which == CES_NIL || node->sort == which) nclistpush(allnodes,(ncelem)node); switch(node->sort) { case CES_FCN: { DCEfcn* fcn = (DCEfcn*)node; for(i=0;i<nclistlength(fcn->args);i++) { ceallnodesr((DCEnode*)nclistget(fcn->args,i),allnodes,which); } } break; case CES_VAR: { DCEvar* var = (DCEvar*)node; for(i=0;i<nclistlength(var->segments);i++) { ceallnodesr((DCEnode*)nclistget(var->segments,i),allnodes,which); } } break; case CES_VALUE: { DCEvalue* value = (DCEvalue*)node; if(value->discrim == CES_VAR) ceallnodesr((DCEnode*)value->var,allnodes,which); else if(value->discrim == CES_FCN) ceallnodesr((DCEnode*)value->fcn,allnodes,which); else ceallnodesr((DCEnode*)value->constant,allnodes,which); } break; case CES_SELECT: { DCEselection* selection = (DCEselection*)node; ceallnodesr((DCEnode*)selection->lhs,allnodes,which); for(i=0;i<nclistlength(selection->rhs);i++) ceallnodesr((DCEnode*)nclistget(selection->rhs,i),allnodes,which); } break; case CES_PROJECT: { DCEprojection* projection = (DCEprojection*)node; if(projection->discrim == CES_VAR) ceallnodesr((DCEnode*)projection->var,allnodes,which); else ceallnodesr((DCEnode*)projection->fcn,allnodes,which); } break; case CES_CONSTRAINT: { DCEconstraint* constraint = (DCEconstraint*)node; for(i=0;i<nclistlength(constraint->projections);i++) ceallnodesr((DCEnode*)nclistget(constraint->projections,i),allnodes,which); for(i=0;i<nclistlength(constraint->selections);i++) ceallnodesr((DCEnode*)nclistget(constraint->selections,i),allnodes,which); } break; /* All others have no subnodes */ default: break; } }
NCerror mapconstraints3(NCDAPCOMMON* dapcomm) { int i; NCerror ncstat = NC_NOERR; CDFnode* root = dapcomm->cdf.ddsroot; NClist* nodes = root->tree->nodes; NClist* dceprojections; NClist* dceselections; dceprojections = dapcomm->oc.dapconstraint->projections; dceselections = dapcomm->oc.dapconstraint->selections; /* Convert the projection paths to leaves in the dds tree */ for(i=0;i<nclistlength(dceprojections);i++) { DCEprojection* proj = (DCEprojection*)nclistget(dceprojections,i); if(proj->discrim != CES_VAR) continue; ncstat = matchpartialname3(nodes,proj->var->segments, &proj->var->cdfleaf); if(ncstat) goto done; } /* Convert the selection paths to leaves in the dds tree */ for(i=0;i<nclistlength(dceselections);i++) { DCEselection* sel = (DCEselection*)nclistget(dceselections,i); if(sel->lhs->discrim != CES_VAR) continue; ncstat = matchpartialname3(nodes,sel->lhs->var->segments,&sel->lhs->var->cdfleaf); if(ncstat) goto done; } /* Convert the selection path values to leaves in the dds tree */ for(i=0;i<nclistlength(dceselections);i++) { int j; DCEselection* sel = (DCEselection*)nclistget(dceselections,i); for(j=0;j<nclistlength(sel->rhs);j++) { DCEvalue* value = (DCEvalue*)nclistget(sel->rhs,j); if(value->discrim != CES_VAR) continue; ncstat = matchpartialname3(nodes,value->var->segments,&value->var->cdfnode); if(ncstat) goto done; } } /* Fill in segment information */ ncstat = qualifyconstraints3(dapcomm->oc.dapconstraint); if(ncstat != NC_NOERR) goto done; #ifdef DEBUG fprintf(stderr,"mapconstraint.projections: %s\n", dumpprojections(dceprojections)); fprintf(stderr,"mapconstraint.selections: %s\n", dumpselections(dceselections)); #endif done: return THROW(ncstat); }
static NCerror movetofield(NCDAPCOMMON* nccomm, OCdatanode currentcontent, NClist* path, int depth, /* depth is position in segment list*/ Getvara* xgetvar, size_t dimindex, /* dimindex is position in xgetvar->slices*/ struct NCMEMORY* memory, NClist* segments) { OCerror ocstat = OC_NOERR; NCerror ncstat = NC_NOERR; size_t fieldindex,gridindex; OClink conn = nccomm->oc.conn; CDFnode* xnode = (CDFnode*)nclistget(path,depth); OCdatanode reccontent = NULL; OCdatanode dimcontent = NULL; OCdatanode fieldcontent = NULL; CDFnode* xnext; int newdepth; /* currentcontent points to the grid/dataset/structure/record instance */ xnext = (CDFnode*)nclistget(path,depth+1); ASSERT((xnext != NULL)); fieldindex = findfield(xnode,xnext); /* If the next node is a nc_virtual node, then we need to effectively ignore it and use the appropriate subnode. If the next node is a re-struct'd node, then use it as is. */ if(xnext->nc_virtual) { CDFnode* xgrid = xnext; xnext = (CDFnode*)nclistget(path,depth+2); /* real node */ gridindex = fieldindex; fieldindex = findfield(xgrid,xnext); fieldindex += gridindex; newdepth = depth+2; } else { newdepth = depth+1; } /* Move to appropriate field */ ocstat = oc_data_ithfield(conn,currentcontent,fieldindex,&fieldcontent); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} ncstat = movetor(nccomm,fieldcontent, path,newdepth,xgetvar,dimindex,memory, segments); done: oc_data_free(conn,dimcontent); oc_data_free(conn,fieldcontent); oc_data_free(conn,reccontent); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
void ncprintpropinfo(struct NCPROPINFO* info) { int i; fprintf(stderr,"[%p] version=%d\n",info,info->version); for(i=0;i<nclistlength(info->properties);i+=2) { char* name = nclistget(info->properties,i); char* value = nclistget(info->properties,i+1); fprintf(stderr,"\t[%d] name=|%s| value=|%s|\n",i,name,value); } }
/* Given two projection lists, merge src into dst taking overlapping projections into acct. Assume that name qualification has occured. Dst will be modified. */ NCerror mergeprojections3(NClist* dst, NClist* src) { int i; NClist* cat = nclistnew(); NCerror ncstat = NC_NOERR; #ifdef DEBUG fprintf(stderr,"mergeprojection: dst = %s\n",dumpprojections(dst)); fprintf(stderr,"mergeprojection: src = %s\n",dumpprojections(src)); #endif ASSERT(dst != NULL); /* get dst concat clone(src) */ nclistsetalloc(cat,nclistlength(dst)+nclistlength(src)); for(i=0;i<nclistlength(dst);i++) { DCEprojection* p = (DCEprojection*)nclistget(dst,i); nclistpush(cat,(ncelem)p); } if(src != NULL) for(i=0;i<nclistlength(src);i++) { DCEprojection* p = (DCEprojection*)nclistget(src,i); nclistpush(cat,(ncelem)dceclone((DCEnode*)p)); } nclistclear(dst); /* Repeatedly pull elements from the concat, merge with all duplicates, and stick into the dst */ while(nclistlength(cat) > 0) { DCEprojection* target = (DCEprojection*)nclistremove(cat,0); if(target == NULL) continue; if(target->discrim != CES_VAR) continue; for(i=0;i<nclistlength(cat);i++) { DCEprojection* p2 = (DCEprojection*)nclistget(cat,i); if(p2 == NULL) continue; if(p2->discrim != CES_VAR) continue; if(target->var->cdfleaf != p2->var->cdfleaf) continue; /* This entry matches our current target; merge */ ncstat = mergeprojection31(target,p2); /* null out this merged entry and release it */ nclistset(cat,i,(ncelem)NULL); dcefree((DCEnode*)p2); } /* Capture the clone */ nclistpush(dst,(ncelem)target); } nclistfree(cat); return ncstat; }
int dcesamepath(NClist* list1, NClist* list2) { int i; int len = nclistlength(list1); if(len != nclistlength(list2)) return 0; for(i=0;i<len;i++) { DCEsegment* s1 = (DCEsegment*)nclistget(list1,i); DCEsegment* s2 = (DCEsegment*)nclistget(list2,i); if(strcmp(s1->name,s2->name) != 0) return 0; } return 1; }
static NClist* nc_urlparamlookup(NClist* params, const char* pname) { int i; if(params == NULL || pname == NULL) return NULL; for(i=0;i<nclistlength(params);i+=2) { char* name = (char*)nclistget(params,i); if(strcmp(pname,name)==0) { return (NClist*)nclistget(params,i+1); } } return NULL; }
int dcemergeprojectionlists(NClist* dst, NClist* src) { int i; NClist* cat = nclistnew(); int ncstat = NC_NOERR; #ifdef DEBUG fprintf(stderr,"dapmergeprojection: dst = %s\n",dcetostring((DCEnode*)dst)); fprintf(stderr,"dapmergeprojection: src = %s\n",dcetostring((DCEnode*)src)); #endif /* get dst concat clone(src) */ nclistsetalloc(cat,nclistlength(dst)+nclistlength(src)); for(i=0;i<nclistlength(dst);i++) { DCEprojection* p = (DCEprojection*)nclistget(dst,i); nclistpush(cat,(void*)p); } for(i=0;i<nclistlength(src);i++) { DCEprojection* p = (DCEprojection*)nclistget(src,i); nclistpush(cat,(void*)dceclone((DCEnode*)p)); } nclistclear(dst); /* Repeatedly pull elements from the concat, merge with all duplicates, and stick into the dst */ while(nclistlength(cat) > 0) { DCEprojection* target = (DCEprojection*)nclistremove(cat,0); if(target == NULL) continue; if(target->discrim != CES_VAR) continue; for(i=0;i<nclistlength(cat);i++) { DCEprojection* p2 = (DCEprojection*)nclistget(cat,i); if(p2 == NULL) continue; if(p2->discrim != CES_VAR) continue; if(dcesamepath(target->var->segments, p2->var->segments)!=0) continue; /* This entry matches our current target; merge */ ncstat = dcemergeprojections(target,p2); /* null out this merged entry and release it */ nclistset(cat,i,(void*)NULL); dcefree((DCEnode*)p2); } /* Capture the clone */ nclistpush(dst,(void*)target); } nclistfree(cat); return ncstat; }
static NCerror mapnodesr(CDFnode* connode, CDFnode* fullnode, int depth) { unsigned int i,j; NCerror ncstat = NC_NOERR; ASSERT((simplenodematch(connode,fullnode))); #ifdef DEBUG { char* path1 = makecdfpathstring(fullnode,"."); char* path2 = makecdfpathstring(connode,"."); fprintf(stderr,"mapnode: %s->%s\n",path1,path2); nullfree(path1); nullfree(path2); } #endif /* Map node */ mapfcn(connode,fullnode); #if 0 { int i; for(i=0;i<nclistlength(fullnode->subnodes);i++) { CDFnode* n = (CDFnode*)nclistget(fullnode->subnodes,i); fprintf(stderr,"fullnode.subnode[%d]: (%d) %s\n",i,n->nctype,n->ocname); } for(i=0;i<nclistlength(connode->subnodes);i++) { CDFnode* n = (CDFnode*)nclistget(connode->subnodes,i); fprintf(stderr,"connode.subnode[%d]: (%d) %s\n",i,n->nctype,n->ocname); } } #endif /* Try to match connode subnodes against fullnode subnodes */ ASSERT(nclistlength(connode->subnodes) <= nclistlength(fullnode->subnodes)); for(i=0;i<nclistlength(connode->subnodes);i++) { CDFnode* consubnode = (CDFnode*)nclistget(connode->subnodes,i); /* Search full subnodes for a matching subnode from con */ for(j=0;j<nclistlength(fullnode->subnodes);j++) { CDFnode* fullsubnode = (CDFnode*)nclistget(fullnode->subnodes,j); if(simplenodematch(fullsubnode,consubnode)) { ncstat = mapnodesr(consubnode,fullsubnode,depth+1); if(ncstat) goto done; } } } done: return THROW(ncstat); }
char* dumpcache(NCcache* cache) { char* result = NULL; char tmp[8192]; int i; NCbytes* buf; if(cache == NULL) return strdup("cache{null}"); buf = ncbytesnew(); snprintf(tmp,sizeof(tmp),"cache{limit=%lu; size=%lu;\n", (unsigned long)cache->cachelimit, (unsigned long)cache->cachesize); ncbytescat(buf,tmp); if(cache->prefetch) { ncbytescat(buf,"\tprefetch="); ncbytescat(buf,dumpcachenode(cache->prefetch)); ncbytescat(buf,"\n"); } if(nclistlength(cache->nodes) > 0) { for(i=0;i<nclistlength(cache->nodes);i++) { NCcachenode* node = (NCcachenode*)nclistget(cache->nodes,i); ncbytescat(buf,"\t"); ncbytescat(buf,dumpcachenode(node)); ncbytescat(buf,"\n"); } } ncbytescat(buf,"}"); result = ncbytesdup(buf); ncbytesfree(buf); return result; }
char* dumpcachenode(NCcachenode* node) { char* result = NULL; char tmp[8192]; int i; NCbytes* buf; if(node == NULL) return strdup("cachenode{null}"); buf = ncbytesnew(); snprintf(tmp,sizeof(tmp),"cachenode%s(%lx){size=%lu; constraint=%s; vars=", node->prefetch?"*":"", (unsigned long)node, (unsigned long)node->xdrsize, buildconstraintstring3(node->constraint)); ncbytescat(buf,tmp); if(nclistlength(node->vars)==0) ncbytescat(buf,"null"); else for(i=0;i<nclistlength(node->vars);i++) { CDFnode* var = (CDFnode*)nclistget(node->vars,i); if(i > 0) ncbytescat(buf,","); ncbytescat(buf,makesimplepathstring3(var)); } ncbytescat(buf,"}"); result = ncbytesdup(buf); ncbytesfree(buf); return result; }
static void dumptreer1(CDFnode* root, NCbytes* buf, int indent, char* tag, int visible) { int i; dumpindent(indent,buf); ncbytescat(buf,tag); ncbytescat(buf," {\n"); for(i=0;i<nclistlength(root->subnodes);i++) { CDFnode* node = (CDFnode*)nclistget(root->subnodes,i); if(visible && !root->visible) continue; if(root->nctype == NC_Grid) { if(i==0) { dumpindent(indent+1,buf); ncbytescat(buf,"Array:\n"); } else if(i==1) { dumpindent(indent+1,buf); ncbytescat(buf,"Maps:\n"); } dumptreer(node,buf,indent+2,visible); } else { dumptreer(node,buf,indent+1,visible); } } dumpindent(indent,buf); ncbytescat(buf,"} "); ncbytescat(buf,root->name); }
/* If we have a url, see if we can determine DAP */ static int NC_dapinfer(NClist* modeargs, NCmodel* model) { int stat = NC_NOERR; int i; /* 1. search modeargs for indicators */ for(i=0;i<nclistlength(modeargs);i++) { const char* arg = nclistget(modeargs,i); if(strcasecmp(arg,"bytes")==0 || strcasecmp(arg,"zarr")==0) { /* Ok, we know this is not DAP, so give up */ return stat; } if(strcasecmp(arg,"dap2")==0) { model->format = NC_FORMAT_NC3; model->iosp = NC_IOSP_DAP2; model->impl = NC_FORMATX_DAP2; } else if(strcasecmp(arg,"dap4")==0) { model->format = NC_FORMAT_NETCDF4; model->iosp = NC_IOSP_DAP4; model->impl = NC_FORMATX_DAP4; } } /* Ok, we have a URL, but no tags to tell us what it is, so assume DAP2 */ if(model->impl == 0) { model->format = NC_FORMAT_NC3; model->iosp = NC_IOSP_DAP2; model->impl = NC_FORMATX_DAP2; } return stat; }