/* Given a das attribute walk it to see if it has at least 1 actual attribute (no recursion) */ static int hasattribute3(OCconnection conn, OCobject dasnode) { int i; OCerror ocstat = OC_NOERR; int tf = 0; /* assume false */ unsigned int nsubnodes; OCtype ocsubtype; OCobject* subnodes = NULL; OCHECK(oc_inq_class(conn,dasnode,&ocsubtype)); if(ocsubtype == OC_Attribute) return 1; /* this is an attribute */ ASSERT((ocsubtype == OC_Attributeset)); OCHECK(oc_inq_nsubnodes(conn,dasnode,&nsubnodes)); OCHECK(oc_inq_subnodes(conn,dasnode,&subnodes)); for(i=0;i<nsubnodes;i++) { OCobject subnode = subnodes[i]; OCHECK(oc_inq_class(conn,subnode,&ocsubtype)); if(ocsubtype == OC_Attribute) {tf=1; break;} } done: nullfree(subnodes); return tf; }
static NCerror dodsextra3(NCDRNO* drno, CDFnode* root, NClist* dodsextra) { int i,j; OCtype octype; NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; OCconnection conn = drno->dap.conn; for(i=0;i<nclistlength(dodsextra);i++) { OCobject das = (OCobject)nclistget(dodsextra,i); unsigned int ndodsnodes; OCobject* dodsnodes = NULL; OCHECK(oc_inq_class(conn,das,&octype)); if(octype != OC_Attributeset) continue; /* Get the attributes within the DODS_EXTRA */ OCHECK(oc_inq_nsubnodes(conn,das,&ndodsnodes)); OCHECK(oc_inq_subnodes(conn,das,&dodsnodes)); for(j=0;j<ndodsnodes;j++) { OCobject extranode = dodsnodes[j]; char* dodsname = NULL; char* stringval; unsigned int ocnvalues; OCHECK(oc_inq_class(conn,extranode,&octype)); if(octype != OC_Attribute) continue; OCHECK(oc_inq_name(conn,extranode,&dodsname)); OCHECK(oc_inq_dasattr_nvalues(conn,extranode,&ocnvalues)); if(strcmp(dodsname,"Unlimited_Dimension")==0 && ocnvalues > 0) { OCHECK(oc_inq_dasattr(conn,extranode,0,NULL,&stringval)); drno->cdf.recorddim = stringval; } efree(dodsname); } efree(dodsnodes); } done: return ncstat; }
static int mergedas1(OCconnection conn, CDFnode* dds, OCobject das) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; unsigned int i,j; unsigned int nsubnodes; OCobject* subnodes = NULL; OCobject* dodsnodes = NULL; unsigned int ndodsnodes; if(dds == NULL || das == OCNULL) return NC_NOERR; /* nothing to do */ if(dds->attributes == NULL) dds->attributes = nclistnew(); /* assign the simple attributes in the das set to this dds node*/ OCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes)); OCHECK(oc_inq_subnodes(conn,das,&subnodes)); for(i=0;i<nsubnodes;i++) { OCobject attnode = subnodes[i]; OCtype octype, ocetype; char* ocname = NULL; unsigned int ocnvalues; OCHECK(oc_inq_name(conn,attnode,&ocname)); OCHECK(oc_inq_class(conn,attnode,&octype)); if(octype == OC_Attribute) { NCattribute* att = NULL; NClist* stringvalues; OCHECK(oc_inq_primtype(conn,attnode,&ocetype)); OCHECK(oc_inq_dasattr_nvalues(conn,attnode,&ocnvalues)); stringvalues = nclistnew(); for(j=0;j<ocnvalues;j++) { char* stringval; OCHECK(oc_inq_dasattr(conn,attnode,j,&ocetype,&stringval)); nclistpush(stringvalues,(ncelem)stringval); } ncstat = buildattribute(ocname, octypetonc(ocetype), stringvalues, &att); if(ncstat) goto done; nclistpush(dds->attributes,(ncelem)att); } else if(octype == OC_Attributeset && strcmp(ocname,"DODS")==0) { /* This is a DODS special attribute set */ OCHECK(oc_inq_nsubnodes(conn,attnode,&ndodsnodes)); OCHECK(oc_inq_subnodes(conn,attnode,&dodsnodes)); for(j=0;j<ndodsnodes;j++) { char* dodsname = NULL; char* stringval; OCobject dodsnode = dodsnodes[j]; OCHECK(oc_inq_class(conn,dodsnode,&octype)); if(octype != OC_Attribute) continue; OCHECK(oc_inq_name(conn,dodsnode,&dodsname)); OCHECK(oc_inq_dasattr_nvalues(conn,dodsnode,&ocnvalues)); if(strcmp(dodsname,"strlen")==0) { unsigned int maxstrlen = 0; if(ocnvalues > 0) { OCHECK(oc_inq_dasattr(conn,dodsnode,0,NULL,&stringval)); if(0==sscanf(stringval,"%u",&maxstrlen)) maxstrlen = 0; efree(stringval); } dds->dodsspecial.maxstrlen = maxstrlen; #ifdef DEBUG fprintf(stderr,"%s.maxstrlen=%d\n",dds->name,(int)dds->dodsspecial.maxstrlen); #endif } else if(strcmp(dodsname,"dimName")==0) { if(ocnvalues > 0) { OCHECK(oc_inq_dasattr(conn,dodsnode,0,NULL, &dds->dodsspecial.dimname)); #ifdef DEBUG fprintf(stderr,"%s.dimname=%s\n",dds->name,dds->dodsspecial.dimname); #endif } else dds->dodsspecial.dimname = NULL; } /* else ignore */ efree(dodsname); } efree(dodsnodes); } /* else ignore */ efree(ocname); } done: efree(subnodes); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
int dapmerge3(NCDRNO* drno, CDFnode* ddsroot, OCobject dasroot) { unsigned int i,j; NCerror ncerr = NC_NOERR; OCerror ocstat = OC_NOERR; OCconnection conn = drno->dap.conn; unsigned int nsubnodes, nobjects; OCobject* dasobjects = NULL; NClist* dasglobals = nclistnew(); NClist* dodsextra = nclistnew(); NClist* dasnodes = nclistnew(); NClist* varnodes = nclistnew(); NClist* allddsnodes = ddsroot->tree->nodes; nobjects = oc_inq_nobjects(conn,dasroot); dasobjects = oc_inq_objects(conn,dasroot); /* 1. collect all the relevant DAS nodes; namely those that contain at least one attribute value. Simultaneously look for potential ambiguities if found; complain but continue: result are indeterminate. also collect globals and DODS_EXTRAs separately*/ for(i=0;i<nobjects;i++) { OCobject das = dasobjects[i]; OCtype octype; char* ocname = NULL; int isglobal = 0; int hasattributes = 0; OCobject* subnodes; OCHECK(oc_inq_class(conn,das,&octype)); if(octype == OC_Attribute) continue; /* ignore these for now*/ OCHECK(oc_inq_name(conn,das,&ocname)); OCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes)); isglobal = (ocname == NULL ? 0 : isglobalname3(ocname)); if(ocname == NULL || isglobal) { nclistpush(dasglobals,(ncelem)das); efree(ocname); continue; } if(ocname != NULL && strcmp(ocname,"DODS_EXTRA")==0) { nclistpush(dodsextra,(ncelem)das); efree(ocname); continue; } OCHECK(oc_inq_subnodes(conn,das,&subnodes)); for(j=0;j<nsubnodes;j++) { OCobject subnode = subnodes[j]; OCtype ocsubtype; OCHECK(oc_inq_class(conn,subnode,&ocsubtype)); if(ocsubtype == OC_Attribute) {hasattributes = 1; break;} } efree(subnodes); if(hasattributes) { /* Look for previously collected nodes with same name*/ for(j=0;j<nclistlength(dasnodes);j++) { OCobject das2 = (OCobject)nclistget(dasnodes,j); char* ocname2; OCHECK(oc_inq_name(conn,das2,&ocname2)); if(ocname2 == NULL || ocname == NULL) goto loop; if(strcmp(ocname2,"DODS")==0) goto loop; if(strcmp(ocname,ocname2)==0) oc_log(OCLOGWARN,"nc_mergedas: potentially ambiguous DAS name: %s",ocname2); loop: efree(ocname2); } nclistpush(dasnodes,(ncelem)das); } efree(ocname); } /* 2. collect all the leaf DDS nodes (of type NC_Primitive)*/ for(i=0;i<nclistlength(allddsnodes);i++) { CDFnode* dds = (CDFnode*)nclistget(allddsnodes,i); if(dds->nctype == NC_Primitive) nclistpush(varnodes,(ncelem)dds); } /* 3. For each das node, lncate matching DDS node(s) and attach attributes to the DDS node(s). Match means: 1. DAS->fullname :: DDS->fullname 2. DAS->name :: DDS->fullname (support DAS names with embedded '.' 3. DAS->name :: DDS->name */ for(i=0;i<nclistlength(dasnodes);i++) { OCobject das = (OCobject)nclistget(dasnodes,i); char* ocfullname; char* ocbasename; if(das == OCNULL) continue; ocfullname = makeocpathstring3(conn,das,"."); OCHECK(oc_inq_name(conn,das,&ocbasename)); for(j=0;j<nclistlength(varnodes);j++) { CDFnode* dds = (CDFnode*)nclistget(varnodes,j); char* ddsfullname = makesimplepathstring3(dds); if(strcmp(ocfullname,ddsfullname)==0 || strcmp(ocbasename,ddsfullname)==0 || strcmp(ocbasename,dds->name)==0) { mergedas1(conn,dds,das); /* remove from dasnodes list*/ nclistset(dasnodes,i,(ncelem)NULL); } efree(ddsfullname); } efree(ocfullname); efree(ocbasename); } /* 4. Assign globals*/ for(i=0;i<nclistlength(dasglobals);i++) { OCobject das = (OCobject)nclistget(dasglobals,i); mergedas1(conn,ddsroot,das); } /* process DOD_EXTRA */ if(nclistlength(dodsextra) > 0) dodsextra3(drno,ddsroot,dodsextra); done: /* cleanup*/ efree(dasobjects); nclistfree(dasglobals); nclistfree(dasnodes); nclistfree(dodsextra); nclistfree(varnodes); if(ocstat != OC_NOERR) ncerr = ocerrtoncerr(ocstat); return THROW(ncerr); }
static int mergedas1(NCDAPCOMMON* nccomm, OCconnection conn, CDFnode* dds, OCobject das) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; unsigned int i,j,k; unsigned int nsubnodes; OCobject* subnodes = NULL; OCobject* dodsnodes = NULL; unsigned int ndodsnodes; if(dds == NULL || das == OCNULL) return NC_NOERR; /* nothing to do */ if(dds->attributes == NULL) dds->attributes = nclistnew(); /* assign the simple attributes in the das set to this dds node*/ OCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes)); OCHECK(oc_inq_subnodes(conn,das,&subnodes)); for(i=0;i<nsubnodes;i++) { OCobject attnode = subnodes[i]; OCtype octype, ocetype; char* ocname = NULL; unsigned int ocnvalues; OCHECK(oc_inq_name(conn,attnode,&ocname)); OCHECK(oc_inq_class(conn,attnode,&octype)); if(octype == OC_Attribute) { NCattribute* att = NULL; NClist* stringvalues; OCHECK(oc_inq_primtype(conn,attnode,&ocetype)); OCHECK(oc_inq_dasattr_nvalues(conn,attnode,&ocnvalues)); stringvalues = nclistnew(); for(j=0;j<ocnvalues;j++) { char* stringval; OCHECK(oc_inq_dasattr(conn,attnode,j,&ocetype,&stringval)); nclistpush(stringvalues,(ncelem)stringval); } ncstat = buildattribute(ocname, octypetonc(ocetype), stringvalues, &att); if(ncstat) goto done; nclistpush(dds->attributes,(ncelem)att); } else if(octype == OC_Attributeset && (strcmp(ocname,"DODS")==0 || strcmp(ocname,"DODS_EXTRA")==0)) { /* Turn the DODS special attributes into into special attributes for dds node */ OCHECK(oc_inq_nsubnodes(conn,attnode,&ndodsnodes)); OCHECK(oc_inq_subnodes(conn,attnode,&dodsnodes)); for(j=0;j<ndodsnodes;j++) { char* dodsname = NULL; char newname[4096]; OCobject attnode = dodsnodes[j]; NCattribute* att = NULL; NClist* stringvalues; OCHECK(oc_inq_class(conn,attnode,&octype)); if(octype != OC_Attribute) continue; OCHECK(oc_inq_primtype(conn,attnode,&ocetype)); OCHECK(oc_inq_dasattr_nvalues(conn,attnode,&ocnvalues)); stringvalues = nclistnew(); for(k=0;k<ocnvalues;k++) { char* stringval; OCHECK(oc_inq_dasattr(conn,attnode,k,&ocetype,&stringval)); nclistpush(stringvalues,(ncelem)stringval); } OCHECK(oc_inq_name(conn,attnode,&dodsname)); /* Compute new special name */ strcpy(newname,"_DODS_"); strcat(newname,dodsname); ncstat = buildattribute(newname, octypetonc(ocetype), stringvalues, &att); if(ncstat) goto done; att->invisible = 1; nclistpush(dds->attributes,(ncelem)att); /* Define extra semantics associated with DODS and DODS_EXTRA attribute */ if(strcmp(dodsname,"strlen")==0) { unsigned int maxstrlen = 0; if(nclistlength(stringvalues) > 0) { char* stringval = (char*)nclistget(stringvalues,0); if(0==sscanf(stringval,"%u",&maxstrlen)) maxstrlen = 0; } dds->dodsspecial.maxstrlen = maxstrlen; #ifdef DEBUG fprintf(stderr,"%s.maxstrlen=%d\n",dds->ocname,(int)dds->dodsspecial.maxstrlen); #endif } else if(strcmp(dodsname,"dimName")==0) { if(nclistlength(stringvalues) > 0) { char* stringval = (char*)nclistget(stringvalues,0); dds->dodsspecial.dimname = nulldup(stringval); #ifdef DEBUG fprintf(stderr,"%s.dimname=%s\n",dds->ocname,dds->dodsspecial.dimname); #endif } else dds->dodsspecial.dimname = NULL; } else if(strcmp(dodsname,"Unlimited_Dimension")==0) { if(nccomm->cdf.recorddimname != NULL) { nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications"); } else if(nclistlength(stringvalues) > 0) { char* stringval = (char*)nclistget(stringvalues,0); nccomm->cdf.recorddimname = nulldup(stringval); #ifdef DEBUG fprintf(stderr,"%s.Unlimited_Dimension=%s\n",dds->ocname,nccomm->cdf.recorddimname); #endif } } /* else ignore */ nullfree(dodsname); } nullfree(dodsnodes); } nullfree(ocname); } done: nullfree(subnodes); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
/* Alias for oc_inq_class */ OCerror oc_inq_type(OCconnection conn, OCobject node0, OCtype* typep) { return oc_inq_class(conn,node0,typep); }