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); }
int dapmerge3(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCddsnode dasroot) { unsigned int i,j; NCerror ncerr = NC_NOERR; OCerror ocstat = OC_NOERR; OClink conn = nccomm->oc.conn; size_t nsubnodes; NClist* dasglobals = nclistnew(); NClist* dasnodes = nclistnew(); NClist* dodsextra = nclistnew(); NClist* varnodes = nclistnew(); NClist* alldasnodes = nclistnew(); if(ddsroot == NULL || dasroot == NULL) return NC_NOERR; ocstat = collect_alldasnodes(conn,dasroot,alldasnodes); /* 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_EXTRA separately. */ for(i=0;i<nclistlength(alldasnodes);i++) { OCddsnode das = (OCddsnode)nclistget(alldasnodes,i); OCtype octype; char* ocname = NULL; int isglobal = 0; int hasattributes = 0; OCCHECK(oc_dds_class(conn,das,&octype)); if(octype == OC_Attribute) continue; /* ignore these for now*/ OCCHECK(oc_dds_name(conn,das,&ocname)); OCCHECK(oc_dds_nsubnodes(conn,das,&nsubnodes)); isglobal = (ocname == NULL ? 0 : isglobalname3(ocname)); /* catch DODS_EXTRA */ if(isglobal && ocname != NULL && strcmp(ocname,"DODS_EXTRA")==0) { nclistpush(dodsextra,(void*)das); nullfree(ocname); continue; } if(ocname == NULL || isglobal) { nclistpush(dasglobals,(void*)das); nullfree(ocname); continue; } hasattributes = hasattribute3(conn,das); if(hasattributes) { /* Look for previously collected nodes with same name*/ for(j=0;j<nclistlength(dasnodes);j++) { OCddsnode das2 = (OCddsnode)nclistget(dasnodes,j); char* ocname2; OCCHECK(oc_dds_name(conn,das2,&ocname2)); if(ocname2 == NULL || ocname == NULL) goto loop; if(strcmp(ocname2,"DODS")==0) goto loop; if(strcmp(ocname,ocname2)==0) nclog(NCLOGWARN,"nc_mergedas: potentially ambiguous DAS name: %s",ocname2); loop: nullfree(ocname2); } nclistpush(dasnodes,(void*)das); } nullfree(ocname); } /* 2. collect all the leaf DDS nodes (of type NC_Atomic)*/ ocstat = collect_leaves(link,ddsroot,varnodes); /* 3. For each das node, locate 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 4. special case for DODS. Apply 1-3 on DODS parent. */ for(i=0;i<nclistlength(dasnodes);i++) { OCddsnode das = (OCddsnode)nclistget(dasnodes,i); char* ocfullname = NULL; char* ocbasename = NULL; if(das == NULL) continue; OCCHECK(oc_dds_name(conn,das,&ocbasename)); if(strcmp(ocbasename,"DODS")==0) { OCddsnode container; OCCHECK(oc_dds_container(conn,das,&container)); ASSERT(container != NULL); ocfullname = makeocpathstring3(conn,container,"."); } else { ocfullname = makeocpathstring3(conn,das,"."); } for(j=0;j<nclistlength(varnodes);j++) { CDFnode* dds = (CDFnode*)nclistget(varnodes,j); char* ddsfullname = makecdfpathstring3(dds,"."); if(strcmp(ocfullname,ddsfullname)==0 || strcmp(ocbasename,ddsfullname)==0 || strcmp(ocbasename,dds->ocname)==0) { mergedas1(nccomm,conn,dds,das); /* remove from dasnodes list*/ nclistset(dasnodes,i,(void*)NULL); } nullfree(ddsfullname); } nullfree(ocfullname); nullfree(ocbasename); } /* 4. Assign globals */ for(i=0;i<nclistlength(dasglobals);i++) { OCddsnode das = (OCddsnode)nclistget(dasglobals,i); mergedas1(nccomm,conn,ddsroot,das); } /* 5. Assign DOD_EXTRA */ for(i=0;i<nclistlength(dodsextra);i++) { OCddsnode das = (OCddsnode)nclistget(dodsextra,i); mergedas1(nccomm,conn,ddsroot,das); } done: /* cleanup*/ nclistfree(dasglobals); nclistfree(dasnodes); nclistfree(alldasnodes); nclistfree(dodsextra); nclistfree(varnodes); if(ocstat != OC_NOERR) ncerr = ocerrtoncerr(ocstat); return THROW(ncerr); }