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); }
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); }
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 ocddsdasmerge(OCstate* state, OCnode* dasroot, OCnode* ddsroot) { OClist* dasglobals = oclistnew(); OClist* dasnodes = oclistnew(); OClist* varnodes = oclistnew(); OClist* ddsnodes; unsigned int i,j; if(dasroot->tree == NULL || dasroot->tree->dxdclass != OCDAS) return THROW(OC_EINVAL); if(ddsroot->tree == NULL || (ddsroot->tree->dxdclass != OCDDS && ddsroot->tree->dxdclass != OCDATADDS)) return THROW(OC_EINVAL); ddsnodes = ddsroot->tree->nodes; /* 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 separately*/ for(i=0;i<oclistlength(dasroot->tree->nodes);i++) { OCnode* das = (OCnode*)oclistget(dasroot->tree->nodes,i); int hasattributes = 0; if(das->octype == OC_Attribute) continue; /* ignore these for now*/ if(das->name == NULL || das->att.isglobal) { oclistpush(dasglobals,(ocelem)das); continue; } for(j=0;j<oclistlength(das->subnodes);j++) { OCnode* subnode = (OCnode*)oclistget(das->subnodes,j); if(subnode->octype == OC_Attribute) {hasattributes = 1; break;} } if(hasattributes) { /* Look for previously collected nodes with same name*/ for(j=0;j<oclistlength(dasnodes);j++) { OCnode* das2 = (OCnode*)oclistget(dasnodes,j); if(das->name == NULL || das2->name == NULL) continue; if(strcmp(das->name,das2->name)==0) { oc_log(LOGWARN,"oc_mergedas: potentially ambiguous DAS name: %s",das->name); } } oclistpush(dasnodes,(ocelem)das); } } /* 2. collect all the leaf DDS nodes (of type OC_Primitive)*/ for(i=0;i<oclistlength(ddsnodes);i++) { OCnode* dds = (OCnode*)oclistget(ddsnodes,i); if(dds->octype == OC_Primitive) oclistpush(varnodes,(ocelem)dds); } /* 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 */ for(i=0;i<oclistlength(dasnodes);i++) { OCnode* das = (OCnode*)oclistget(dasnodes,i); for(j=0;j<oclistlength(varnodes);j++) { OCnode* dds = (OCnode*)oclistget(varnodes,j); if(strcmp(das->fullname,dds->fullname)==0 || strcmp(das->name,dds->fullname)==0 || strcmp(das->name,dds->name)==0) { mergedas1(dds,das); /* remove from dasnodes list*/ oclistset(dasnodes,i,(ocelem)NULL); } } } /* 4. If there are attributes left, then complain about them being lost.*/ for(i=0;i<oclistlength(dasnodes);i++) { OCnode* das = (OCnode*)oclistget(dasnodes,i); if(das != NULL) marklostattribute(das); } /* 5. Assign globals*/ for(i=0;i<oclistlength(dasglobals);i++) { OCnode* das = (OCnode*)oclistget(dasglobals,i); mergedas1(ddsroot,das); } /* cleanup*/ oclistfree(dasglobals); oclistfree(dasnodes); oclistfree(varnodes); return THROW(OC_NOERR); }
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); }