Example #1
0
/* Like collectnodepath3, but in ocspace */
void
collectocpath(OClink conn, OCddsnode node, NClist* path)
{
    OCddsnode container;
    OCtype octype;
    if(node == NULL) return;
    oc_dds_class(conn,node,&octype);
    if(octype != OC_Dataset) {
        oc_dds_container(conn,node,&container);
        if(container != NULL)
            collectocpath(conn,container,path);
    }
    nclistpush(path,(void*)node);
}
Example #2
0
/*
Given a das attribute walk it to see if it
has at least 1 actual attribute (no recursion)
*/
static int
hasattribute3(OClink conn, OCdasnode dasnode)
{
    int i;
    OCerror ocstat = OC_NOERR;
    int tf = 0; /* assume false */
    OCtype ocsubtype;
    NClist* subnodes = nclistnew();

    OCCHECK(oc_dds_octype(conn,dasnode,&ocsubtype));
    if(ocsubtype == OC_Attribute) return 1; /* this is an attribute */
    ASSERT((ocsubtype == OC_Attributeset));

    OCCHECK(collect_subnodes(conn,dasnode,subnodes));
    for(i=0;i<nclistlength(subnodes);i++) {
        OCdasnode subnode = (OCdasnode)nclistget(subnodes,i);
        OCCHECK(oc_dds_class(conn,subnode,&ocsubtype));
	if(ocsubtype == OC_Attribute) {tf=1; break;}
    }
done:
    nclistfree(subnodes);
    return tf;
}
Example #3
0
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);
}
Example #4
0
static NCerror
buildcdftreer(NCDAPCOMMON* nccomm, OCddsnode ocnode, CDFnode* container,
                CDFtree* tree, CDFnode** cdfnodep)
{
    size_t i,ocrank,ocnsubnodes;
    OCtype octype;
    OCtype ocatomtype;
    char* ocname = NULL;
    NCerror ncerr = NC_NOERR;
    CDFnode* cdfnode = NULL;

    oc_dds_class(nccomm->oc.conn,ocnode,&octype);
    if(octype == OC_Atomic)
	oc_dds_atomictype(nccomm->oc.conn,ocnode,&ocatomtype);
    else
	ocatomtype = OC_NAT;
    oc_dds_name(nccomm->oc.conn,ocnode,&ocname);
    oc_dds_rank(nccomm->oc.conn,ocnode,&ocrank);
    oc_dds_nsubnodes(nccomm->oc.conn,ocnode,&ocnsubnodes);

#ifdef DEBUG1
    if(ocatomtype == OC_NAT)
	fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(octype),ocname);
    else
	fprintf(stderr,"buildcdftree: connect: %s %s\n",oc_typetostring(ocatomtype),ocname);
#endif

    switch (octype) {
    case OC_Dataset:
	cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container);
	nclistpush(tree->nodes,(void*)cdfnode);
	tree->root = cdfnode;
	cdfnode->tree = tree;
	break;

    case OC_Grid:
    case OC_Structure:
    case OC_Sequence:
	cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container);
	nclistpush(tree->nodes,(void*)cdfnode);
#if 0
	if(tree->root == NULL) {
	    tree->root = cdfnode;
	    cdfnode->tree = tree;
	}
#endif
	break;

    case OC_Atomic:
	cdfnode = makecdfnode(nccomm,ocname,octype,ocnode,container);
	nclistpush(tree->nodes,(void*)cdfnode);
#if 0
	if(tree->root == NULL) {
	    tree->root = cdfnode;
	    cdfnode->tree = tree;
	}
#endif
	break;

    case OC_Dimension:
    default: PANIC1("buildcdftree: unexpect OC node type: %d",(int)octype);

    }
    /* Avoid a rare but perhaps possible null-dereference
       of cdfnode. Not sure what error to throw, so using
       NC_EDAP: generic DAP error. */
    if(!cdfnode) {
      return NC_EDAP;
    }

#if 0
    /* cross link */
    assert(tree->root != NULL);
    cdfnode->root = tree->root;
#endif

    if(ocrank > 0) defdimensions(ocnode,cdfnode,nccomm,tree);
    for(i=0;i<ocnsubnodes;i++) {
	OCddsnode ocsubnode;
	CDFnode* subnode;
	oc_dds_ithfield(nccomm->oc.conn,ocnode,i,&ocsubnode);
	ncerr = buildcdftreer(nccomm,ocsubnode,cdfnode,tree,&subnode);
	if(ncerr) {
	  if(ocname) free(ocname);
	  return ncerr;
	}
	nclistpush(cdfnode->subnodes,(void*)subnode);
    }
    nullfree(ocname);
    if(cdfnodep) *cdfnodep = cdfnode;
    return ncerr;
}