static int mergedas1(OCnode* dds, OCnode* das) { int i,j; int stat = OC_NOERR; if(dds->attributes == NULL) dds->attributes = oclistnew(); /* assign the simple attributes in the das set to this dds node*/ for(i=0;i<oclistlength(das->subnodes);i++) { OCnode* attnode = (OCnode*)oclistget(das->subnodes,i); if(attnode->octype == OC_Attribute) { Attribute* att = makeattribute(attnode->name, attnode->etype, attnode->att.values); oclistpush(dds->attributes,(ocelem)att); } } /* Try to merge any enclosed sets with subnodes of dds*/ for(i=0;i<oclistlength(das->subnodes);i++) { OCnode* dasnode = (OCnode*)oclistget(das->subnodes,i); int match = 0; if(dasnode->octype == OC_Attribute) continue; /* already dealt with above*/ for(j=0;j<oclistlength(dds->subnodes) && !match;j++) { OCnode* ddsnode = (OCnode*)oclistget(dds->subnodes,j); if(strcmp(dasnode->name,ddsnode->name) == 0) { match = 1; stat = mergedas1(ddsnode,dasnode); if(stat != OC_NOERR) break; } } if(!match) {marklostattribute(dasnode);} } return THROW(stat); }
static OCerror occorrelater(OCnode* dds, OCnode* dxd) { int i,j; OCerror ocstat = OC_NOERR; if(dds->octype != dxd->octype) { THROWCHK((ocstat = OC_EINVAL)); goto fail; } if(dxd->name != NULL && dxd->name != NULL && strcmp(dxd->name,dds->name) != 0) { THROWCHK((ocstat = OC_EINVAL)); goto fail; } else if(dxd->name != dxd->name) { /* test NULL==NULL */ THROWCHK((ocstat = OC_EINVAL)); goto fail; } if(dxd->array.rank != dds->array.rank) { THROWCHK((ocstat = OC_EINVAL)); goto fail; } dds->datadds = dxd; switch (dds->octype) { case OC_Dataset: case OC_Structure: case OC_Grid: case OC_Sequence: /* Remember: there may be fewer datadds fields than dds fields */ for(i=0;i<oclistlength(dxd->subnodes);i++) { OCnode* dxd1 = (OCnode*)oclistget(dxd->subnodes,i); for(j=0;j<oclistlength(dds->subnodes);j++) { OCnode* dds1 = (OCnode*)oclistget(dds->subnodes,j); if(strcmp(dxd1->name,dds1->name) == 0) { ocstat = occorrelater(dds1,dxd1); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} break; } } } break; case OC_Dimension: case OC_Primitive: break; default: OCPANIC1("unexpected node type: %d",dds->octype); } /* Correlate the dimensions */ if(dds->array.rank > 0) { for(i=0;i<oclistlength(dxd->subnodes);i++) { OCnode* ddsdim = (OCnode*)oclistget(dds->array.dimensions,i); OCnode* dxddim = (OCnode*)oclistget(dxd->array.dimensions,i); ocstat = occorrelater(ddsdim,dxddim); if(!ocstat) goto fail; } } fail: return THROW(ocstat); }
void makedimlist(OClist* path, OClist* dims) { unsigned int i,j; for(i=0;i<oclistlength(path);i++) { OCnode* node = (OCnode*)oclistget(path,i); unsigned int rank = node->array.rank; for(j=0;j<rank;j++) { OCnode* dim = (OCnode*)oclistget(node->array.dimensions,j); oclistpush(dims,(void*)dim); } } }
static char* scopeduplicates(OClist* list) { unsigned int i,j; for(i=0;i<oclistlength(list);i++) { OCnode* io = (OCnode*)oclistget(list,i); for(j=i+1;j<oclistlength(list);j++) { OCnode* jo = (OCnode*)oclistget(list,j); if(strcmp(io->name,jo->name)==0) return io->name; } } return NULL; }
/* Return all the OCobjects associated with a tree with specified root */ OCobject* oc_inq_objects(OCconnection conn, OCobject root0) { unsigned int i; OCstate* state; OCnode* root; OClist* nodes; OCobject* objects = NULL; unsigned int nobjects; OCVERIFYX(OCstate*,state,conn,OCNULL); OCDEREF(OCstate*,state,conn); OCVERIFYX(OCnode*,root,root0,OCNULL); OCDEREF(OCnode*,root,root0); if(root == NULL) return NULL; root = root->root; if(root == NULL) return NULL; nodes = root->tree->nodes; nobjects = oclistlength(nodes); if(nodes != NULL && nobjects > 0) { size_t len = sizeof(OCobject)*(1+nobjects); objects = (OCobject*)ocmalloc(len); for(i=0;i<oclistlength(nodes);i++) { objects[i] = (OCobject)oclistget(nodes,i); } objects[nobjects] = OCNULL; /* null terminate */ } return objects; }
/* This procedure returns the value as the original DAS string */ OCerror oc_inq_attrstrings(OCconnection conn, OCobject node0, unsigned int i, char** namep, OCtype* octypep, unsigned int* nvaluesp, char*** stringsp) { OCstate* state; OCnode* node; OCattribute* attr; unsigned int nattrs; OCVERIFY(OCstate*,state,conn); OCDEREF(OCstate*,state,conn); OCVERIFY(OCnode*,node,node0); OCDEREF(OCnode*,node,node0); nattrs = oclistlength(node->attributes); if(i >= nattrs) return OC_EINVAL; attr = (OCattribute*)oclistget(node->attributes,i); if(namep) *namep = strdup(attr->name); if(octypep) *octypep = attr->etype; if(nvaluesp) *nvaluesp = attr->nvalues; if(stringsp) { size_t space = attr->nvalues * sizeof(char*); char** strings = (space > 0?ocmalloc(space):NULL); for(i=0;i<attr->nvalues;i++) strings[i] = nulldup(attr->values[i]); *stringsp = strings; } return OC_NOERR; }
static int occompilefields(OCstate* state, OCnode* xnode, OCmemdata** memdatap, XDR* xdrs) { OCmemdata* structdata = NULL; OCmemdata** qmem; OCerror ocstat = OC_NOERR; unsigned int i,nfields; nfields = oclistlength(xnode->subnodes); structdata = makememdata(OC_Structure,OC_NAT,nfields); MEMCHECK(structdata,OC_ENOMEM); qmem = (OCmemdata**)&structdata->data; structdata->mode = Fieldmode; for(i=0;i<nfields;i++) { OCnode* field = (OCnode*)oclistget(xnode->subnodes,i); OCmemdata* fielddata; ocstat = occompile1(state,field,&fielddata,xdrs); if(ocstat == OC_ENODATA) { fielddata = NULL; } else if(ocstat != OC_NOERR) { freeocmemdata(structdata); return THROW(ocstat); } qmem[i] = fielddata; } if(memdatap) *memdatap = structdata; return THROW(ocstat); }
void ocfreenodes(OClist* nodes) { unsigned int i,j; for(i=0;i<oclistlength(nodes);i++) { OCnode* node = (OCnode*)oclistget(nodes,i); ocfree(node->name); ocfree(node->fullname); while(oclistlength(node->att.values) > 0) { char* value = (char*)oclistpop(node->att.values); ocfree(value); } while(oclistlength(node->attributes) > 0) { OCattribute* attr = (OCattribute*)oclistpop(node->attributes); ocfree(attr->name); /* If the attribute type is string, then we need to free them*/ if(attr->etype == OC_String || attr->etype == OC_URL) { char** strings = (char**)attr->values; for(j=0;j<attr->nvalues;j++) {ocfree(*strings); strings++;} } ocfree(attr->values); ocfree(attr); } if(node->array.dimensions != NULL) oclistfree(node->array.dimensions); if(node->subnodes != NULL) oclistfree(node->subnodes); if(node->att.values != NULL) oclistfree(node->att.values); if(node->attributes != NULL) oclistfree(node->attributes); ocfree(node); } oclistfree(nodes); }
/* Caller must free returned list */ OCerror oc_inq_subnodes(OCconnection conn, OCobject node0, OCobject** subnodesp) { OCstate* state; OCnode* node; OCobject* subnodes = NULL; unsigned int len; OCVERIFY(OCstate*,state,conn); OCDEREF(OCstate*,state,conn); OCVERIFY(OCnode*,node,node0); OCDEREF(OCnode*,node,node0); len = oclistlength(node->subnodes); if(len > 0) { unsigned int i; subnodes = (OCobject*)occalloc(sizeof(OCobject),len+1); for(i=0;i<len;i++) { OCnode* ocnode = (OCnode*)oclistget(node->subnodes,i); subnodes[i] = (OCobject)ocnode; } subnodes[len] = OCNULL; /* NULL terminate */ } if(subnodesp) *subnodesp = subnodes; return OC_NOERR; }
OCerror oc_inq_attr(OCconnection conn, OCobject node0, unsigned int i, char** namep, OCtype* octypep, unsigned int* nvaluesp, void** valuesp) { OCstate* state; OCnode* node; OCattribute* attr; unsigned int nattrs; OCVERIFY(OCstate*,state,conn); OCDEREF(OCstate*,state,conn); OCVERIFY(OCnode*,node,node0); OCDEREF(OCnode*,node,node0); nattrs = oclistlength(node->attributes); if(i >= nattrs) return OC_EINVAL; attr = (OCattribute*)oclistget(node->attributes,i); if(namep) *namep = strdup(attr->name); if(octypep) *octypep = attr->etype; if(nvaluesp) *nvaluesp = attr->nvalues; if(valuesp && attr->nvalues > 0) { void* memory = NULL; memory = oclinearize(attr->etype,attr->nvalues,attr->values); *valuesp = memory; } return OC_NOERR; }
int oclistcontains(OClist* list, ocelem elem) { unsigned int i; for(i=0;i<oclistlength(list);i++) { if(elem == oclistget(list,i)) return 1; } return 0; }
static void setroot(OCnode* root, OClist* ocnodes) { int i; for(i=0;i<oclistlength(ocnodes);i++) { OCnode* node = (OCnode*)oclistget(ocnodes,i); node->root = root; } }
static void addedges(OCnode* node) { unsigned int i; if(node->subnodes == NULL) return; for(i=0;i<oclistlength(node->subnodes);i++) { OCnode* subnode = (OCnode*)oclistget(node->subnodes,i); subnode->container = node; } }
static void dumpdimensions(OCnode* node) { unsigned int i; for(i=0;i<node->array.rank;i++) { OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i); fprintf(stdout,"[%s=%lu]", (dim->name?dim->name:"?"), (unsigned long)dim->dim.declsize); } }
void ocparamfree(OClist* params) { int i; if(params == NULL) return; for(i=0;i<oclistlength(params);i++) { char* s = (char*)oclistget(params,i); if(s != NULL) free((void*)s); } oclistfree(params); }
/* Compute total # of elements if dimensioned*/ size_t totaldimsize(OCnode* node) { unsigned int i; size_t count = 1; for(i=0;i<node->array.rank;i++) { OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i); count *= (dim->dim.declsize); } return count; }
static void ocuncorrelate(OCnode* root) { OCtree* tree = root->tree; unsigned int i; if(tree == NULL) return; for(i=0;i<oclistlength(tree->nodes);i++) { OCnode* node = (OCnode*)oclistget(tree->nodes,i); node->datadds = NULL; } }
int ocddsdasmerge(OCstate* state, OCnode* ddsroot, OCnode* dasroot) { int i,j; int stat = OC_NOERR; OClist* globals = oclistnew(); if(dasroot == NULL) return THROW(stat); /* Start by looking for global attributes*/ for(i=0;i<oclistlength(dasroot->subnodes);i++) { OCnode* node = (OCnode*)oclistget(dasroot->subnodes,i); if(node->att.isglobal) { for(j=0;j<oclistlength(node->subnodes);j++) { OCnode* attnode = (OCnode*)oclistget(node->subnodes,j); Attribute* att = makeattribute(attnode->name, attnode->etype, attnode->att.values); oclistpush(globals,(ocelem)att); } } } ddsroot->attributes = globals; /* Now try to match subnode names with attribute set names*/ for(i=0;i<oclistlength(dasroot->subnodes);i++) { OCnode* das = (OCnode*)oclistget(dasroot->subnodes,i); int match = 0; if(das->att.isglobal) continue; if(das->octype == OC_Attributeset) { for(j=0;j<oclistlength(ddsroot->subnodes) && !match;j++) { OCnode* dds = (OCnode*)oclistget(ddsroot->subnodes,j); if(strcmp(das->name,dds->name) == 0) { match = 1; stat = mergedas1(dds,das); if(stat != OC_NOERR) break; } } } if(!match) {marklostattribute(das);} } if(stat == OC_NOERR) ddsroot->attributed = 1; return THROW(stat); }
void ocdumpclause(OCprojectionclause* ref) { unsigned int i; OClist* path = oclistnew(); occollectpathtonode(ref->node,path); for(i=0;i<oclistlength(path);i++) { OClist* sliceset; OCnode* node = (OCnode*)oclistget(path,i); if(node->tree != NULL) continue; /* leave off the root node*/ fprintf(stdout,"%s%s",(i>0?PATHSEPARATOR:""),node->name); sliceset = (OClist*)oclistget(ref->indexsets,i); if(sliceset != NULL) { unsigned int j; for(j=0;j<oclistlength(sliceset);j++) { OCslice* slice = (OCslice*)oclistget(sliceset,j); ocdumpslice(slice); } } } }
void computeocfullnames(OCnode* root) { unsigned int i; if(root->name != NULL) computefullname(root); if(root->subnodes != NULL) { /* recurse*/ for(i=0;i<oclistlength(root->subnodes);i++) { OCnode* node = (OCnode*)oclistget(root->subnodes,i); computeocfullnames(node); } } }
/* Process ocnodes to fix various semantic issues*/ void computeocsemantics(OClist* ocnodes) { unsigned int i; OCASSERT((ocnodes != NULL)); for(i=0;i<oclistlength(ocnodes);i++) { OCnode* node = (OCnode*)oclistget(ocnodes,i); /* set the container for dims*/ if(node->octype == OC_Dimension && node->dim.array != NULL) { node->container = node->dim.array->container; } } }
static void ocassignall(OClist* list) { unsigned int i; if(list != NULL) for(i=0;i<oclistlength(list);i++) { void* object = (void*)oclistget(list,i); #ifdef TRACK fprintf(stderr,"assign: %lu\n",(unsigned long)object); fflush(stderr); #endif oclistpush(ocmap,(ocelem)object); } }
/* Insert new client param (name,value); return value = 1 => not already defined 0 => param already defined (no change) */ int ocparaminsert(OClist* params, const char* clientparam, const char* value) { int i; if(params == NULL || clientparam == NULL) return 0; for(i=0;i<oclistlength(params);i+=2) { char* name = (char*)oclistget(params,i); if(strcmp(clientparam,name)==0) return 0; } /* not found, append */ oclistpush(params,(ocelem)nulldup(clientparam)); oclistpush(params,(ocelem)nulldup(value)); return 1; }
/* Delete the entry. return value = 1 => found and deleted; 0 => param not found */ int ocparamdelete(OClist* params, const char* clientparam) { int i,found = 0; if(params == NULL || clientparam == NULL) return 0; for(i=0;i<oclistlength(params);i+=2) { char* name = (char*)oclistget(params,i); if(strcmp(clientparam,name)==0) {found=1; break;} } if(found) { oclistremove(params,i+1); /* remove value */ oclistremove(params,i); /* remove name */ } return found; }
/* Replace new client param (name,value); return value = 1 => replacement performed 0 => insertion performed */ int ocparamreplace(OClist* params, const char* clientparam, const char* value) { int i; if(params == NULL || clientparam == NULL) return 0; for(i=0;i<oclistlength(params);i+=2) { char* name = (char*)oclistget(params,i); if(strcmp(clientparam,name)==0) { oclistinsert(params,i+1,(ocelem)nulldup(value)); return 1; } } ocparaminsert(params,clientparam,value); return 0; }
/* Convert path to a string; leave off the dataset name*/ static char* pathtostring(OClist* path, char* separator, int usecdfname) { int slen,i,len; char* pathname; if(path == NULL || (len = oclistlength(path))==0) return NULL; for(slen=0,i=0;i<len;i++) { OCnode* node = (OCnode*)oclistget(path,i); if(node->container == NULL || node->name == NULL) continue; slen += strlen(node->name); } slen += ((len-1)*strlen(separator)); slen += 1; /* for null terminator*/ pathname = (char*)ocmalloc(slen); MEMCHECK(pathname,NULL); pathname[0] = '\0'; for(i=0;i<len;i++) { OCnode* node = (OCnode*)oclistget(path,i); if(node->container == NULL || node->name == NULL) continue; if(strlen(pathname) > 0) strcat(pathname,separator); strcat(pathname,node->name); } return pathname; }
void freeAttributes(OClist* attset) { unsigned int i,j; for(i=0;i<oclistlength(attset);i++) { OCattribute* att = (OCattribute*)oclistget(attset,i); if(att->name != NULL) free(att->name); if(att->etype == OC_String || att->etype == OC_URL) { for(j=0;j<att->nvalues;j++) { char* s = ((char**)att->values)[j]; if(s != NULL) free(s); } } else { free(att->values); } } }
OCattribute* makeattribute(char* name, OCtype ptype, OClist* values) { OCattribute* att = (OCattribute*)ocmalloc(sizeof(OCattribute)); /* ocmalloc zeros*/ MEMCHECK(att,(OCattribute*)NULL); att->name = nulldup(name); att->etype = ptype; att->nvalues = oclistlength(values); att->values = NULL; if(att->nvalues > 0) { int i; att->values = (char**)ocmalloc(sizeof(char*)*att->nvalues); for(i=0;i<att->nvalues;i++) att->values[i] = nulldup((char*)oclistget(values,i)); } return att; }
OCerror oc_inq_ithdim(OCconnection conn, OCobject node0, unsigned int index, OCobject* dimidp) { OCstate* state; OCnode* node; OCobject dimid = OCNULL; OCVERIFY(OCstate*,state,conn); OCDEREF(OCstate*,state,conn); OCVERIFY(OCnode*,node,node0); OCDEREF(OCnode*,node,node0); if(node->array.rank >= 0 && index < node->array.rank) { dimid = (OCobject)oclistget(node->array.dimensions,index); } else return OC_EINVAL; if(dimidp) *dimidp = dimid; return OC_NOERR; }
void freeOCnode(OCnode* cdf, int deep) { unsigned int i; if(cdf == NULL) return; if(cdf->name != NULL) free(cdf->name); if(cdf->fullname != NULL) free(cdf->fullname); if(cdf->attributes != NULL) freeAttributes(cdf->attributes); if(cdf->subnodes != NULL) { if(deep) { for(i=0;i<oclistlength(cdf->subnodes);i++) { OCnode* node = (OCnode*)oclistget(cdf->subnodes,i); freeOCnode(node,deep); } } oclistfree(cdf->subnodes); } free(cdf); }