Exemple #1
0
/*
Given two projection lists, merge
src into dst taking
overlapping projections into acct.
Assume that name qualification has occured.
Dst will be modified.
*/
NCerror
mergeprojections3(NClist* dst, NClist* src)
{
    int i;
    NClist* cat = nclistnew();
    NCerror ncstat = NC_NOERR;

#ifdef DEBUG
fprintf(stderr,"mergeprojection: dst = %s\n",dumpprojections(dst));
fprintf(stderr,"mergeprojection: src = %s\n",dumpprojections(src));
#endif

    ASSERT(dst != NULL);

    /* get dst concat clone(src) */
    nclistsetalloc(cat,nclistlength(dst)+nclistlength(src));
    for(i=0;i<nclistlength(dst);i++) {
	DCEprojection* p = (DCEprojection*)nclistget(dst,i);
	nclistpush(cat,(ncelem)p);
    }    
    if(src != NULL) for(i=0;i<nclistlength(src);i++) {
	DCEprojection* p = (DCEprojection*)nclistget(src,i);
	nclistpush(cat,(ncelem)dceclone((DCEnode*)p));
    }    

    nclistclear(dst);

    /* Repeatedly pull elements from the concat,
       merge with all duplicates, and stick into
       the dst
    */
    while(nclistlength(cat) > 0) {
	DCEprojection* target = (DCEprojection*)nclistremove(cat,0);
	if(target == NULL) continue;
        if(target->discrim != CES_VAR) continue;
        for(i=0;i<nclistlength(cat);i++) {
	    DCEprojection* p2 = (DCEprojection*)nclistget(cat,i);
	    if(p2 == NULL) continue;
	    if(p2->discrim != CES_VAR) continue;
	    if(target->var->cdfleaf != p2->var->cdfleaf) continue;
	    /* This entry matches our current target; merge  */
	    ncstat = mergeprojection31(target,p2);
	    /* null out this merged entry and release it */
	    nclistset(cat,i,(ncelem)NULL);	    
	    dcefree((DCEnode*)p2);	    
	}		    
	/* Capture the clone */
	nclistpush(dst,(ncelem)target);
    }	    
    nclistfree(cat);
    return ncstat;
}
int
dcemergeprojectionlists(NClist* dst, NClist* src)
{
    int i;
    NClist* cat = nclistnew();
    int ncstat = NC_NOERR;

#ifdef DEBUG
fprintf(stderr,"dapmergeprojection: dst = %s\n",dcetostring((DCEnode*)dst));
fprintf(stderr,"dapmergeprojection: src = %s\n",dcetostring((DCEnode*)src));
#endif

    /* get dst concat clone(src) */
    nclistsetalloc(cat,nclistlength(dst)+nclistlength(src));
    for(i=0;i<nclistlength(dst);i++) {
	DCEprojection* p = (DCEprojection*)nclistget(dst,i);
	nclistpush(cat,(void*)p);
    }
    for(i=0;i<nclistlength(src);i++) {
	DCEprojection* p = (DCEprojection*)nclistget(src,i);
	nclistpush(cat,(void*)dceclone((DCEnode*)p));
    }

    nclistclear(dst);

    /* Repeatedly pull elements from the concat,
       merge with all duplicates, and stick into
       the dst
    */
    while(nclistlength(cat) > 0) {
	DCEprojection* target = (DCEprojection*)nclistremove(cat,0);
	if(target == NULL) continue;
        if(target->discrim != CES_VAR) continue;
        for(i=0;i<nclistlength(cat);i++) {
	    DCEprojection* p2 = (DCEprojection*)nclistget(cat,i);
	    if(p2 == NULL) continue;
	    if(p2->discrim != CES_VAR) continue;
	    if(dcesamepath(target->var->segments,
			   p2->var->segments)!=0) continue;
	    /* This entry matches our current target; merge  */
	    ncstat = dcemergeprojections(target,p2);
	    /* null out this merged entry and release it */
	    nclistset(cat,i,(void*)NULL);
	    dcefree((DCEnode*)p2);
	}
	/* Capture the clone */
	nclistpush(dst,(void*)target);
    }
    nclistfree(cat);
    return ncstat;
}
Exemple #3
0
static NCerror
structwrap(NCDAPCOMMON* ncc, CDFnode* node, CDFnode* parent, int parentindex,
                           CDFnode* patterngrid, int gridindex)
{
    CDFnode* newstruct;

    ASSERT((patterngrid->nctype == NC_Grid));
    newstruct = makenewstruct(ncc, node,patterngrid);
    if(newstruct == NULL) {return THROW(NC_ENOMEM);}

    /* replace the node with the new structure
       in the parent's list of children*/
    nclistset(parent->subnodes,parentindex,(void*)newstruct);

    /* Update the list of all nodes in the tree */
    nclistpush(node->root->tree->nodes,(void*)newstruct);
    return NC_NOERR;
}
Exemple #4
0
static NCerror
builddims(NCDAPCOMMON* dapcomm)
{
    int i;
    NCerror ncstat = NC_NOERR;
    int dimid;
    NClist* dimset = NULL;
    NC* drno = dapcomm->controller;
    NC* ncsub;
    char* definename;

    /* collect all dimensions from variables */
    dimset = dapcomm->cdf.dimnodes;

    /* Sort by fullname just for the fun of it */
    for(;;) {
	int last = nclistlength(dimset) - 1;
	int swap = 0;
        for(i=0;i<last;i++) {
	    CDFnode* dim1 = (CDFnode*)nclistget(dimset,i);
	    CDFnode* dim2 = (CDFnode*)nclistget(dimset,i+1);
   	    if(strcmp(dim1->ncfullname,dim2->ncfullname) > 0) {
		nclistset(dimset,i,(ncelem)dim2);
		nclistset(dimset,i+1,(ncelem)dim1);
		swap = 1;
		break;
	    }
	}
	if(!swap) break;
    }

    /* Define unlimited only if needed */ 
    if(dapcomm->cdf.recorddim != NULL) {
	CDFnode* unlimited = dapcomm->cdf.recorddim;
	definename = getdefinename(unlimited);
        ncstat = nc_def_dim(drno->substrate,
			definename,
			NC_UNLIMITED,
			&unlimited->ncid);
	nullfree(definename);
        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}

        /* get the id for the substrate */
        ncstat = NC_check_id(drno->substrate,&ncsub);
        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}

        /* Set the effective size of UNLIMITED;
           note that this cannot be done thru the normal API.*/
        NC_set_numrecs(ncsub,unlimited->dim.declsize);
    }

    for(i=0;i<nclistlength(dimset);i++) {
	CDFnode* dim = (CDFnode*)nclistget(dimset,i);
        if(dim->dim.basedim != NULL) continue; /* handle below */
	if(DIMFLAG(dim,CDFDIMRECORD)) continue; /* defined above */
#ifdef DEBUG1
fprintf(stderr,"define: dim: %s=%ld\n",dim->ncfullname,(long)dim->dim.declsize);
#endif
	definename = getdefinename(dim);
        ncstat = nc_def_dim(drno->substrate,definename,dim->dim.declsize,&dimid);
        if(ncstat != NC_NOERR) {
	    THROWCHK(ncstat); goto done;
	}
	nullfree(definename);
        dim->ncid = dimid;
    }

    /* Make all duplicate dims have same dimid as basedim*/
    /* (see computecdfdimnames)*/
    for(i=0;i<nclistlength(dimset);i++) {
	CDFnode* dim = (CDFnode*)nclistget(dimset,i);
        if(dim->dim.basedim != NULL) {
	    dim->ncid = dim->dim.basedim->ncid;
	}
    }
done:
    nclistfree(dimset);
    return THROW(ncstat);
}
Exemple #5
0
/**
 * @internal
 *
 * Construct the provenance information for a newly opened file
 * Using the specified _NCProperties value. If NULL, then
 * initialize using dfalt.
 *
 * @param file Pointer to file object.
 * @param propstring The contents of _NCProperties
 * @param dfalt
 *
 * @return ::NC_NOERR No error.
 * @return ::NC_ENOMEM
 * @return ::NC_EINVAL
 * @author Dennis Heimbigner
 */
int
NC4_get_provenance(NC_FILE_INFO_T* file, const char* propstring, const struct NCPROPINFO* dfalt)
{
    int ncstat = NC_NOERR;
    struct NCPROVENANCE* provenance;
    char *name = NULL;
    char *value = NULL;
    int v = 0;
    int superblock = -1;

    LOG((3, "%s: ncid 0x%x propstring %s", __func__, file->root_grp->hdr.id, propstring));

    assert(file->provenance == NULL);
    if((file->provenance = calloc(1,sizeof(struct NCPROVENANCE))) == NULL)
    {ncstat = NC_ENOMEM; goto done;}
    provenance = file->provenance;
    if((provenance->propattr.properties = nclistnew()) == NULL)
    {ncstat = NC_ENOMEM; goto done;}

    /* Set the superblock */
    if((ncstat = NC4_hdf5get_superblock(file,&superblock)))
        goto done;
    provenance->superblockversion = superblock;

    if(propstring == NULL) {
        /* Use dfalt */
        if((ncstat=propinfo_default(&provenance->propattr,dfalt)))
            goto done;
    } else {
        NClist* list = provenance->propattr.properties;
        if((ncstat=properties_parse(propstring,list)))
            goto done;
        /* Check the version and remove from properties list*/
        if(nclistlength(list) < 2)
        {ncstat = NC_EINVAL; goto done;} /* bad _NCProperties attribute */
        /* Extract the purported version=... */
        name = nclistremove(list,0);
        value = nclistremove(list,0);
        if(strcmp(name,NCPVERSION) == 0) {
            if(sscanf(value,"%d",&v) != 1)
            {ncstat = NC_EINVAL; goto done;} /* illegal version */
            if(v <= 0 || v > NCPROPS_VERSION)
            {ncstat = NC_EINVAL; goto done;} /* unknown version */
            provenance->propattr.version = v;
        } else
        {ncstat = NC_EINVAL; goto done;} /* bad _NCProperties attribute */
        /* Now, rebuild from version 1 to version 2 if necessary */
        if(provenance->propattr.version == 1) {
            int i;
            for(i=0;i<nclistlength(list);i+=2) {
                char* newname = NULL;
                name = nclistget(list,i);
                if(name == NULL) continue; /* ignore */
                if(strcmp(name,NCPNCLIB1) == 0)
                    newname = NCPNCLIB2; /* change name */
                else if(strcmp(name,NCPHDF5LIB1) == 0)
                    newname = NCPHDF5LIB2;
                else continue; /* ignore */
                /* Do any rename */
                nclistset(list,i,strdup(newname));
                if(name) {free(name); name = NULL;}
            }
        }
    }
done:
    if(name != NULL) free(name);
    if(value != NULL) free(value);
    return ncstat;
}
Exemple #6
0
NCerror
fixprojections(NClist* list)
{
    int i,j,k;
    NCerror ncstat = NC_NOERR;
    NClist* tmp = nclistnew(); /* misc. uses */

#ifdef DEBUG
fprintf(stderr,"fixprojection: list = %s\n",dumpprojections(list));
#endif

    if(nclistlength(list) == 0) goto done;

    /* Step 1: remove duplicates and complain about slice mismatches */
    for(i=0;i<nclistlength(list);i++) {
	DCEprojection* p1 = (DCEprojection*)nclistget(list,i);
	if(p1 == NULL) continue;
        if(p1->discrim != CES_VAR) continue; /* dont try to unify functions */
        for(j=i;j<nclistlength(list);j++) {
	    DCEprojection* p2 = (DCEprojection*)nclistget(list,j);
	    if(p2 == NULL) continue;
	    if(p1 == p2) continue;
	    if(p2->discrim != CES_VAR) continue;
	    if(p1->var->annotation != p2->var->annotation) continue;
	    /* check for slice mismatches */
	    if(!slicematch(p1->var->segments,p2->var->segments)) {
		/* complain */
		nclog(NCLOGWARN,"Malformed projection: same variable with different slicing");
	    }
	    /* remove p32 */
	    nclistset(list,j,(ncelem)NULL);	    
	    dcefree((DCEnode*)p2);	    
	}	
    }

    /* Step 2: remove containers when a field is also present */
    for(i=0;i<nclistlength(list);i++) {
	DCEprojection* p1 = (DCEprojection*)nclistget(list,i);
	if(p1 == NULL) continue;
        if(p1->discrim != CES_VAR) continue; /* dont try to unify functions */
	if(!iscontainer((CDFnode*)p1->var->annotation))
	    continue;
        for(j=i;j<nclistlength(list);j++) {
	    DCEprojection* p2 = (DCEprojection*)nclistget(list,j);
	    if(p2 == NULL) continue;
	    if(p2->discrim != CES_VAR) continue;
	    nclistclear(tmp);
	    collectnodepath3((CDFnode*)p2->var->annotation,tmp,WITHDATASET);
	    for(k=0;k<nclistlength(tmp);k++) {
		void* candidate = (void*)nclistget(tmp,k);
	        if(candidate == p1->var->annotation) {
		    nclistset(list,i,(ncelem)NULL);	    
	            dcefree((DCEnode*)p1);
		    goto next;
		}
	    }
	}
next:   continue;
    }

    /* Step 3: expand all containers recursively down to the leaf nodes */
    for(;;) {
	nclistclear(tmp);
        for(i=0;i<nclistlength(list);i++) {
            DCEprojection* target = (DCEprojection*)nclistget(list,i);
            CDFnode* leaf;
            if(target == NULL) continue;
            if(target->discrim != CES_VAR)
                continue; /* dont try to unify functions */
            leaf = (CDFnode*)target->var->annotation;
            ASSERT(leaf != NULL);
            if(iscontainer(leaf)) {/* capture container */
		if(!nclistcontains(tmp,(ncelem)target))
                    nclistpush(tmp,(ncelem)target);
                nclistset(list,i,(ncelem)NULL);
            }
        }
	if(nclistlength(tmp) == 0) break; /*done*/
        /* Now explode the containers */
        for(i=0;i<nclistlength(tmp);i++) {
            DCEprojection* container = (DCEprojection*)nclistget(tmp,i);
	    CDFnode* leaf = (CDFnode*)container->var->annotation;
            for(j=0;i<nclistlength(leaf->subnodes);j++) {
                CDFnode* field = (CDFnode*)nclistget(leaf->subnodes,j);
		/* Convert field node to a proper constraint */
		DCEprojection* proj = projectify(field,container);
		nclistpush(list,(ncelem)proj);
	    }	    
            /* reclaim the container */
	    dcefree((DCEnode*)container);
	}
    } /*for(;;)*/

    /* remove all NULL elements */
    for(i=nclistlength(list)-1;i>=0;i--) {
        DCEprojection* target = (DCEprojection*)nclistget(list,i);
	if(target == NULL)
	    nclistremove(list,i);	
    }	

done:
#ifdef DEBUG
fprintf(stderr,"fixprojection: exploded = %s\n",dumpprojections(list));
#endif
    nclistfree(tmp);
    return ncstat;
}
Exemple #7
0
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);
}
Exemple #8
0
NCerror
computevarnodes(NCDAPCOMMON* nccomm, NClist* allnodes, NClist* varnodes)
{
    unsigned int i,len;
    NClist* allvarnodes = nclistnew();
    for(i=0; i<nclistlength(allnodes); i++) {
        CDFnode* node = (CDFnode*)nclistget(allnodes,i);
#if 0
        /* If this node has a bad name, repair it */
        if(dap_badname(node->ocname)) {
            char* newname = dap_repairname(node->ocname);
            nullfree(node->ocname);
            node->ocname = newname;
        }
#endif
        if(node->nctype == NC_Atomic)
            nclistpush(allvarnodes,(void*)node);
    }
    /* Further process the variable nodes to get the final set */
    /* Use toplevel vars first */
    len = nclistlength(allvarnodes);
    for(i=0; i<len; i++) {
        CDFnode* node = (CDFnode*)nclistget(allvarnodes,i);
        if(node == NULL) continue;
        if(daptoplevel(node)) {
            nclistpush(varnodes,(void*)node);
            nclistset(allvarnodes,i,(void*)NULL);
        }
    }
    /*... then grid arrays and maps.
      but exclude the coordinate variables if we are trying to
      exactly mimic nc-dap
    */
    for(i=0; i<len; i++) {
        CDFnode* node = (CDFnode*)nclistget(allvarnodes,i);
        if(node == NULL) continue;
        if(dapgridarray(node)) {
            nclistpush(varnodes,(void*)node);
            nclistset(allvarnodes,i,(void*)NULL);
        } else if(dapgridmap(node)) {
            if(!FLAGSET(nccomm->controls,NCF_NCDAP))
                nclistpush(varnodes,(void*)node);
            nclistset(allvarnodes,i,(void*)NULL);
        }
    }
    /*... then all others */
    for(i=0; i<len; i++) {
        CDFnode* node = (CDFnode*)nclistget(allvarnodes,i);
        if(node == NULL) continue;
        nclistpush(varnodes,(void*)node);
    }
    nclistfree(allvarnodes);
#ifdef DEBUG2
    for(i=0; i<nclistlength(varnodes); i++) {
        CDFnode* node = (CDFnode*)nclistget(varnodes,i);
        if(node == NULL) continue;
        fprintf(stderr,"computevarnodes: var: %s\n",makecdfpathstring(node,"."));
    }
#endif
    return NC_NOERR;
}
Exemple #9
0
/* See if we can unify sets of nodes to be projected
   into larger units.
*/
static NClist*
unifyprojectionnodes3(NClist* varlist)
{
    int i;
    NClist* nodeset = nclistnew();
    NClist* containerset = nclistnew();
    NClist* containernodes = nclistnew();

    nclistsetalloc(nodeset,nclistlength(varlist));
    nclistsetalloc(containerset,nclistlength(varlist));
    /* Duplicate the varlist so we can modify it;
       simultaneously collect unique container set.
    */
    for(i=0;i<nclistlength(varlist);i++) {
	CDFnode* var = (CDFnode*)nclistget(varlist,i);
	CDFnode* container = var->container;
	nclistpush(nodeset,(ncelem)var);
	switch (container->nctype) {
	case NC_Sequence: case NC_Structure: case NC_Grid: case NC_Dataset:
	    /* add (uniquely) to container set */
	    if(!nclistcontains(containerset,(ncelem)container)) 
	        nclistpush(containerset,(ncelem)container);
	    break;
	default: break;
	}
    }

    /* Now, try to find containers whose subnodes are all in the
	varlist; repeat until no more changes */
    for(;;) {
	int changed = 0;
        for(i=0;i<nclistlength(containerset);i++) {
            int j, allfound;
            CDFnode* container = (CDFnode*)nclistget(containerset,i);
	    if(container == NULL) continue;
            nclistclear(containernodes);
            for(allfound=1,j=0;j<nclistlength(container->subnodes);j++) {
                CDFnode* subnode = (CDFnode*)nclistget(container->subnodes,j);
                if(!nclistcontains(varlist,(ncelem)subnode)) {allfound=0;break;}
                nclistpush(containernodes,(ncelem)subnode);
            }
            if(allfound) {
                nclistpush(nodeset,(ncelem)container);
                nclistset(containerset,i,(ncelem)NULL); /* remove */
                for(j=nclistlength(nodeset)-1;j>=0;j--) { /* walk backwards */
                    CDFnode* testnode = (CDFnode*)nclistget(nodeset,j);
                    if(nclistcontains(containernodes,(ncelem)testnode))
                        nclistremove(nodeset,j);/* remove */
                }
		changed = 1;
            }
        }
	if(!changed) break; /* apparently we have reached a stable situation */
    }
    /* If there is only the dataset left as a projection, then remove it */
    if(nclistlength(nodeset) == 1) {
	CDFnode* thenode = (CDFnode*)nclistget(nodeset,0);
	if(thenode->nctype == NC_Dataset) nclistclear(nodeset);
    }
    nclistfree(containerset);
    nclistfree(containernodes);
    return nodeset;
}
Exemple #10
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);
}