示例#1
0
static NCerror
moveto(NCDAPCOMMON* nccomm, Getvara* xgetvar, CDFnode* xrootnode, void* memory)
{
    OCerror ocstat = OC_NOERR;
    NCerror ncstat = NC_NOERR;
    OClink conn = nccomm->oc.conn;
    OCdatanode xrootcontent;
    OCddsnode ocroot;
    NClist* path = nclistnew();
    struct NCMEMORY memstate;

    memstate.next = (memstate.memory = memory);

    /* Get the root content*/
    ocroot = xrootnode->tree->ocroot;
    ocstat = oc_data_getroot(conn,ocroot,&xrootcontent);
    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}

    /* Remember: xgetvar->target is in DATADDS tree */
    collectnodepath3(xgetvar->target,path,WITHDATASET);
    ncstat = movetor(nccomm,xrootcontent,
                     path,0,xgetvar,0,&memstate,
                     xgetvar->varaprojection->var->segments);
done:
    nclistfree(path);
    oc_data_free(conn,xrootcontent);
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#2
0
文件: getvara3.c 项目: UV-CDAT/netcdf
/*
Extract data for a netcdf variable that has a string dimension.
*/
static int
extractstring(
	NCDAPCOMMON* nccomm,
	Getvara* xgetvar,
	CDFnode* xnode,
        DCEsegment* segment,
	size_t dimindex, /*notused*/
        OClink conn,
        OCdatanode currentcontent,
	struct NCMEMORY* memory
       )
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    int i;
    size_t rank0;
    NClist* strings = NULL;
    Dapodometer* odom = NULL;

    ASSERT(xnode->etype == NC_STRING || xnode->etype == NC_URL);

    /* Compute rank minus string dimension */ 
    rank0 = nclistlength(xnode->array.dimset0);

    /* keep whole extracted strings stored in an NClist */
    strings = nclistnew();

    if(rank0 == 0) {/*=> scalar*/
	char* value = NULL;
	ocstat = oc_data_readscalar(conn,currentcontent,sizeof(value),&value);
	if(ocstat != OC_NOERR) goto done;
	nclistpush(strings,(void*)value);	
    } else {
        /* Use the odometer to walk to the appropriate fields*/
        odom = dapodom_fromsegment(segment,0,rank0);
        while(dapodom_more(odom)) {
	    char* value = NULL;
	    ocstat = oc_data_readn(conn,currentcontent,odom->index,1,sizeof(value),&value);
	    if(ocstat != OC_NOERR)
		goto done;
	    nclistpush(strings,(void*)value);	
            dapodom_next(odom);
	}
        dapodom_free(odom);
    }
    /* Get each string in turn, slice it by applying the string dimm
       and store in user supplied memory
    */
    for(i=0;i<nclistlength(strings);i++) {
	char* s = (char*)nclistget(strings,i);
	slicestring(conn,s,&segment->slices[rank0],memory);
	free(s);	
    }    
    nclistfree(strings);
done:
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#3
0
文件: ncdap3a.c 项目: UV-CDAT/netcdf
NCerror
fetchtemplatemetadata3(NCDAPCOMMON* dapcomm)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    OCddsnode ocroot = NULL;
    CDFnode* ddsroot = NULL;
    char* ce = NULL;

    /* Temporary hack: we need to get the selection string
       from the url
    */
    /* Get (almost) unconstrained DDS; In order to handle functions
       correctly, those selections must always be included
    */
    if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
	ce = NULL;
    else
        ce = nulldup(dapcomm->oc.url->selection);

    /* Get selection constrained DDS */
    ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
    if(ocstat != OC_NOERR) {
	/* Special Hack. If the protocol is file, then see if
           we can get the dds from the .dods file
        */
	if(strcmp(dapcomm->oc.url->protocol,"file") != 0) {
	    THROWCHK(ocstat); goto done;
	}
	/* Fetch the data dds */
        ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDATADDS,&ocroot);
        if(ocstat != OC_NOERR) {
	    THROWCHK(ocstat); goto done;
	}
	/* Note what we did */
	nclog(NCLOGWARN,"Cannot locate .dds file, using .dods file");
    }

    /* Get selection constrained DAS */
    ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDAS,&dapcomm->oc.ocdasroot);
    if(ocstat != OC_NOERR) {
	/* Ignore but complain */
	nclog(NCLOGWARN,"Could not read DAS; ignored");
        dapcomm->oc.ocdasroot = NULL;	
	ocstat = OC_NOERR;
    }

    /* Construct the netcdf cdf tree corresponding to the dds tree*/
    ncstat = buildcdftree34(dapcomm,ocroot,OCDDS,&ddsroot);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
    dapcomm->cdf.fullddsroot = ddsroot;

done:
    nullfree(ce);
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return ncstat;
}
示例#4
0
static NCerror
movetofield(NCDAPCOMMON* nccomm,
	OCdatanode currentcontent,
	NClist* path,
        int depth, /* depth is position in segment list*/
	Getvara* xgetvar,
        size_t dimindex, /* dimindex is position in xgetvar->slices*/
	struct NCMEMORY* memory,
	NClist* segments)
{
    OCerror ocstat = OC_NOERR;
    NCerror ncstat = NC_NOERR;
    size_t fieldindex,gridindex;
    OClink conn = nccomm->oc.conn;
    CDFnode* xnode = (CDFnode*)nclistget(path,depth);
    OCdatanode reccontent = NULL;
    OCdatanode dimcontent = NULL;
    OCdatanode fieldcontent = NULL;
    CDFnode* xnext;
    int newdepth;

    /* currentcontent points to the grid/dataset/structure/record instance */
    xnext = (CDFnode*)nclistget(path,depth+1);
    ASSERT((xnext != NULL));
    fieldindex = findfield(xnode,xnext);
    /* If the next node is a nc_virtual node, then
       we need to effectively
       ignore it and use the appropriate subnode.
       If the next node is a re-struct'd node, then
       use it as is.
    */
    if(xnext->nc_virtual) {
        CDFnode* xgrid = xnext;
	xnext = (CDFnode*)nclistget(path,depth+2); /* real node */
        gridindex = fieldindex;
	fieldindex = findfield(xgrid,xnext);
	fieldindex += gridindex;
	newdepth = depth+2;
    } else {
        newdepth = depth+1;
    }
    /* Move to appropriate field */
    ocstat = oc_data_ithfield(conn,currentcontent,fieldindex,&fieldcontent);
    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
    ncstat = movetor(nccomm,fieldcontent,
                     path,newdepth,xgetvar,dimindex,memory,
		     segments);

done:
    oc_data_free(conn,dimcontent);
    oc_data_free(conn,fieldcontent);
    oc_data_free(conn,reccontent);
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#5
0
文件: ncdap3a.c 项目: UV-CDAT/netcdf
NCerror
fetchconstrainedmetadata3(NCDAPCOMMON* dapcomm)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    OCddsnode ocroot;
    CDFnode* ddsroot; /* constrained */
    char* ce = NULL;

    if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
	ce = NULL;
    else
        ce = buildconstraintstring3(dapcomm->oc.dapconstraint);
    {
        ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
        if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}

        /* Construct our parallel dds tree; including attributes*/
        ncstat = buildcdftree34(dapcomm,ocroot,OCDDS,&ddsroot);
        if(ncstat) goto fail;
	ocroot = NULL; /* avoid duplicate reclaim */

	dapcomm->cdf.ddsroot = ddsroot;
	ddsroot = NULL; /* to avoid double reclamation */

        if(!FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
            /* fix DAP server problem by adding back any inserting needed structure nodes */
            ncstat = restruct3(dapcomm->cdf.ddsroot,dapcomm->cdf.fullddsroot,dapcomm->oc.dapconstraint->projections);    
            if(ncstat) goto fail;
	}

#ifdef DEBUG
fprintf(stderr,"constrained:\n%s",dumptree(dapcomm->cdf.ddsroot));
#endif

        /* Combine DDS and DAS */
	if(dapcomm->oc.ocdasroot != NULL) {
            ncstat = dapmerge3(dapcomm,dapcomm->cdf.ddsroot->ocnode,
                               dapcomm->oc.ocdasroot);
            if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
	}

        /* map the constrained DDS to the unconstrained DDS */
        ncstat = mapnodes3(dapcomm->cdf.ddsroot,dapcomm->cdf.fullddsroot);
        if(ncstat) goto fail;

    }

fail:
    nullfree(ce);
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return ncstat;
}
示例#6
0
NCerror
dapmerge3(NCDRNO* drno, CDFnode* node)
{
    unsigned int i;
    char* aname;
    unsigned int nvalues,nattrs;
    void* values;
    OCtype atype;
    OCerror ocstat = OC_NOERR;
    NCerror ncstat = NC_NOERR;
    NCattribute* att;

    if(node->dds == OCNULL) goto done;
    OCHECK(oc_inq_nattr(drno->dap.conn,node->dds,&nattrs));
    if(nattrs == 0) goto done;
    if(node->attributes == NULL) node->attributes = nclistnew();
    for(i=0;i<nattrs;i++) {
	ocstat = oc_inq_attr(drno->dap.conn,node->dds,i,
			           &aname,
			           &atype,
                                   &nvalues,
                                   &values);
	if(ocstat != OC_NOERR) continue; /* ignore */
        if(aname == NULL || nvalues == 0 || values == NULL)
	    continue; /* nothing to do */
	ncstat = buildattribute(aname,octypetonc(atype),
				      nvalues,values,&att);
	if(ncstat == NC_NOERR)
            nclistpush(node->attributes,(ncelem)att);
	efree(aname);
	oc_attr_reclaim(atype,nvalues,values);
    }
done:
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#7
0
static NCerror
movetor(NCDAPCOMMON* nccomm,
	OCdatanode currentcontent,
	NClist* path,
        int depth, /* depth is position in segment list*/
	Getvara* xgetvar,
        size_t dimindex, /* dimindex is position in xgetvar->slices*/
	struct NCMEMORY* memory,
	NClist* segments)
{
    OCerror ocstat = OC_NOERR;
    NCerror ncstat = NC_NOERR;
    OClink conn = nccomm->oc.conn;
    CDFnode* xnode = (CDFnode*)nclistget(path,depth);
    OCdatanode reccontent = NULL;
    OCdatanode dimcontent = NULL;
    OCdatanode fieldcontent = NULL;
    Dapodometer* odom = NULL;
    int hasstringdim = 0;
    DCEsegment* segment;
    OCDT mode;

    /* Note that we use depth-1 because the path contains the DATASET
       but the segment list does not */
    segment = (DCEsegment*)nclistget(segments,depth-1); /*may be NULL*/
    if(xnode->etype == NC_STRING || xnode->etype == NC_URL) hasstringdim = 1;

    /* Get the mode */
    mode = oc_data_mode(conn,currentcontent);

#ifdef DEBUG2
fprintf(stderr,"moveto: nctype=%d depth=%d dimindex=%d mode=%s",
        xnode->nctype, depth,dimindex,oc_data_modestring(mode));
fprintf(stderr," segment=%s hasstringdim=%d\n",
		dcetostring((DCEnode*)segment),hasstringdim);
#endif

    switch (xnode->nctype) {

#if 0
#define OCDT_FIELD     ((OCDT)(1)) /* field of a container */
#define OCDT_ELEMENT   ((OCDT)(2)) /* element of a structure array */
#define OCDT_RECORD    ((OCDT)(4)) /* record of a sequence */
#define OCDT_ARRAY     ((OCDT)(8)) /* is structure array */
#define OCDT_SEQUENCE  ((OCDT)(16)) /* is sequence */
#define OCDT_ATOMIC    ((OCDT)(32)) /* is atomic leaf */
#endif

    default:
	goto done;

    case NC_Grid:
    case NC_Dataset:
    case NC_Structure:
	/* Separate out the case where structure is dimensioned */
	if(oc_data_indexable(conn,currentcontent)) {
	    /* => dimensioned structure */
            /* The current segment should reflect the
	       proper parts of the nc_get_vara argument
	    */
	    /* Create odometer for this structure's part of the projection */
            odom = dapodom_fromsegment(segment,0,segment->rank);
            while(dapodom_more(odom)) {
                /* Compute which instance to move to*/
                ocstat = oc_data_ithelement(conn,currentcontent,
                                            odom->index,&dimcontent);
                if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
                ASSERT(oc_data_indexed(conn,dimcontent));
                ncstat = movetor(nccomm,dimcontent,
                                 path,depth,/*keep same depth*/
                                 xgetvar,dimindex+segment->rank,
                                 memory,segments);
                dapodom_next(odom);
            }
            dapodom_free(odom);
	} else {/* scalar instance */
	    ncstat = movetofield(nccomm,currentcontent,path,depth,xgetvar,dimindex,memory,segments);
	    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	} break;

    case NC_Sequence:
	if(fIsSet(mode,OCDT_SEQUENCE)) {
            ASSERT((xnode->attachment != NULL));
            ASSERT((segment != NULL));
	    ASSERT((segment->rank == 1));
	    /* Build an odometer for walking the sequence,
               however, watch out
               for the case when the user set a limit and that limit
               is not actually reached in this request.
            */
            /* By construction, this sequence represents the first 
               (and only) dimension of this segment */
            odom = dapodom_fromsegment(segment,0,1);
	    while(dapodom_more(odom)) {
		size_t recordindex = dapodom_count(odom);
                ocstat = oc_data_ithrecord(conn,currentcontent,
					   recordindex,&reccontent);
                if(ocstat != OC_NOERR) {
		    if(ocstat == OC_EINDEX)
			ocstat = OC_EINVALCOORDS;
		    THROWCHK(ocstat); goto done;
		}
                ncstat = movetor(nccomm,reccontent,
                                     path,depth,
                                     xgetvar,dimindex+1,
                                     memory,segments);
                if(ncstat != OC_NOERR) {THROWCHK(ncstat); goto done;}
		dapodom_next(odom);
            }
	} else if(fIsSet(mode,OCDT_RECORD)) {
	    /* Treat like structure */
	    /* currentcontent points to the record instance */
	    ncstat = movetofield(nccomm,currentcontent,path,depth,xgetvar,dimindex,memory,segments);
	    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	}
	break;

    case NC_Atomic:

        if(hasstringdim)
	    ncstat = extractstring(nccomm, xgetvar, xnode, segment, dimindex, conn, currentcontent, memory);
	else	
	    ncstat = extract(nccomm, xgetvar, xnode, segment, dimindex, conn, currentcontent, memory);
	break;

    }

done:
    oc_data_free(conn,dimcontent);
    oc_data_free(conn,fieldcontent);
    oc_data_free(conn,reccontent);
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#8
0
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);
}
示例#9
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);
}
示例#10
0
/*
Invoke oc_merge_das and then extract special
attributes such as "strlen" and "dimname"
and stuff from DODS_EXTRA.
*/
int
dapmerge3(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCddsnode dasroot)
{
    int i,j;
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    NClist* allnodes;
    OClink conn;
    char* ocname = NULL;
    char** values = NULL;
    conn = nccomm->oc.conn;

    if(ddsroot == NULL || dasroot == NULL) return NC_NOERR;
    /* Merge the das tree onto the dds tree */
    ocstat = oc_merge_das(nccomm->oc.conn,dasroot,ddsroot);
    if(ocstat != OC_NOERR) goto done;

    /* Create attributes on CDFnodes */
    allnodes = nccomm->cdf.ddsroot->tree->nodes;
    for(i=0;i<nclistlength(allnodes);i++) {
	CDFnode* node = (CDFnode*)nclistget(allnodes,i);
	OCddsnode ocnode = node->ocnode;
	size_t attrcount;
	OCtype ocetype;

	OCCHECK(oc_dds_attr_count(conn,ocnode,&attrcount));
	for(j=0;j<attrcount;j++) {
	    size_t nvalues;

	    NCattribute* att = NULL;

	    if(ocname != NULL) {
	      free(ocname); ocname = NULL;
	    } /* from last loop */

	    OCCHECK(oc_dds_attr(conn,ocnode,j,&ocname,&ocetype,&nvalues,NULL));
	    if(nvalues > 0) {
	        values = (char**)malloc(sizeof(char*)*nvalues);
		if(values == NULL) {ncstat = NC_ENOMEM; goto done;}
	        OCCHECK(oc_dds_attr(conn,ocnode,j,NULL,NULL,NULL,values));
	    }
	    ncstat = buildattribute(ocname,octypetonc(ocetype),nvalues,values,&att);
	    if(ncstat != NC_NOERR) goto done;
	    if(node->attributes == NULL)
		node->attributes = nclistnew();
	    nclistpush(node->attributes,(void*)att);
	    if(strncmp(ocname,"DODS",strlen("DODS"))==0) {
		att->invisible = 1;
	        /* Define extra semantics associated with
                   DODS and DODS_EXTRA attributes */
		if(strcmp(ocname,"DODS.strlen")==0
		   || strcmp(ocname,"DODS_EXTRA.strlen")==0) {
		    unsigned int maxstrlen = 0;
		    if(values != NULL) {
			if(0==sscanf(values[0],"%u",&maxstrlen))
			    maxstrlen = 0;
		    }
		    node->dodsspecial.maxstrlen = maxstrlen;
#ifdef DEBUG
fprintf(stderr,"%s.maxstrlen=%d\n",node->ocname,(int)node->dodsspecial.maxstrlen);
#endif
		} else if(strcmp(ocname,"DODS.dimName")==0
		   || strcmp(ocname,"DODS_EXTRA.dimName")==0) {
		    if(values != NULL) {
		        node->dodsspecial.dimname = nulldup(values[0]);
#ifdef DEBUG
fprintf(stderr,"%s.dimname=%s\n",node->ocname,node->dodsspecial.dimname);
#endif
		    } else node->dodsspecial.dimname = NULL;
		} else if(strcmp(ocname,"DODS.Unlimited_Dimension")==0
		   || strcmp(ocname,"DODS_EXTRA.Unlimited_Dimension")==0) {
		    if(values != NULL) {
		        if(nccomm->cdf.recorddimname != NULL)
		            nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications");
			else
		            nccomm->cdf.recorddimname = nulldup(values[0]);
#ifdef DEBUG
fprintf(stderr,"%s.Unlimited_Dimension=%s\n",node->ocname,nccomm->cdf.recorddimname);
#endif
		    }

		}
	    }
	    /* clean up */
	    if(values) {
		oc_reclaim_strings(nvalues,values);
		free(values);
		values = NULL;
	    }
	}
    }

done:
    if(values != NULL) free(values);
    if(ocname != NULL) free(ocname);
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#11
0
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);
}
示例#12
0
文件: daputil.c 项目: dschwen/libmesh
/* Provide a wrapper for oc_fetch so we can log what it does */
NCerror
dap_fetch(NCDAPCOMMON* nccomm, OClink conn, const char* ce,
             OCdxd dxd, OCddsnode* rootp)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    char* ext = NULL;
    OCflags flags = 0;
    int httpcode = 0;

    if(dxd == OCDDS) ext = ".dds";
    else if(dxd == OCDAS) ext = ".das";
    else ext = ".dods";

    if(ce != NULL && strlen(ce) == 0)
	ce = NULL;

    if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) {
	ce = NULL;
    }

    if(FLAGSET(nccomm->controls,NCF_ONDISK)) {
	flags |= OCONDISK;
    }

    if(SHOWFETCH) {
	/* Build uri string minus the constraint and #tag */
	char* baseurl = ncuribuild(nccomm->oc.url,NULL,ext,NCURIBASE);
	if(ce == NULL)
            LOG1(NCLOGNOTE,"fetch: %s",baseurl);
	else
            LOG2(NCLOGNOTE,"fetch: %s?%s",baseurl,ce);
	nullfree(baseurl);
#ifdef HAVE_GETTIMEOFDAY
	gettimeofday(&time0,NULL);
#endif
    }
    ocstat = oc_fetch(conn,ce,dxd,flags,rootp);
    if(FLAGSET(nccomm->controls,NCF_SHOWFETCH)) {
#ifdef HAVE_GETTIMEOFDAY
        double secs;
	gettimeofday(&time1,NULL);
	secs = deltatime();
	nclog(NCLOGNOTE,"fetch complete: %0.3f secs",secs);
#else
	nclog(NCLOGNOTE,"fetch complete.");
#endif
    }
#ifdef DEBUG2
fprintf(stderr,"fetch: dds:\n");
oc_dumpnode(conn,*rootp);
#endif

    /* Look at the HTTP return code */
    httpcode = oc_httpcode(conn);
    if(httpcode < 400) {
        ncstat = ocerrtoncerr(ocstat);
    } else if(httpcode >= 500) {
        ncstat = NC_EDAPSVC;
    } else if(httpcode == 401) {
	ncstat = NC_EAUTH;
    } else if(httpcode == 404) {
	ncstat = NC_ENOTFOUND;
    } else {
	ncstat = NC_EACCESS;
    }
    return ncstat;
}
示例#13
0
文件: ncdap3a.c 项目: UV-CDAT/netcdf
static NCerror
countsequence(NCDAPCOMMON* dapcomm, CDFnode* xseq, size_t* sizep)
{
    unsigned int i;
    NClist* path = nclistnew();
    int index;
    OCerror ocstat = OC_NOERR;
    NCerror ncstat = NC_NOERR;
    OClink conn = dapcomm->oc.conn;
    size_t recordcount;
    CDFnode* xroot;
    OCdatanode data = NULL;

    ASSERT((xseq->nctype == NC_Sequence));

    /* collect the path to the sequence node */
    collectnodepath3(xseq,path,WITHDATASET);

    /* Get tree root */
    ASSERT(xseq->root == (CDFnode*)nclistget(path,0));
    xroot = xseq->root;
    ocstat = oc_data_getroot(conn,xroot->tree->ocroot,&data);
    if(ocstat) goto done;

    /* Basically we use the path to walk the data instances to reach
       the sequence instance
    */
    for(i=0;i<nclistlength(path);i++) {
        CDFnode* current = (CDFnode*)nclistget(path,i);
	OCdatanode nextdata = NULL;
	CDFnode* next = NULL;
	
	/* invariant: current = ith node in path; data = corresponding
           datanode
        */

	/* get next node in next and next instance in nextdata */
	if(current->nctype == NC_Structure
	   || current->nctype == NC_Dataset) {
	    if(nclistlength(current->array.dimset0) > 0) {
		/* Cannot handle this case */
		ncstat = THROW(NC_EDDS);
		goto done;
	    }
	    /* get next node in path; structure/dataset => exists */
	    next = (CDFnode*)nclistget(path,i+1);
	    index = fieldindex(current,next);
            /* Move to appropriate field */
	    ocstat = oc_data_ithfield(conn,data,index,&nextdata);
	    if(ocstat) goto done;
	    oc_data_free(conn,data);
	    data = nextdata; /* set up for next loop iteration */
	} else if(current->nctype ==  NC_Sequence) {
	    /* Check for nested Sequences */
	    if(current != xseq) {
		/* Cannot handle this case */
		ncstat = THROW(NC_EDDS);
		goto done;
	    }
	    /* Get the record count */
	    ocstat = oc_data_recordcount(conn,data,&recordcount);
    	    if(sizep) *sizep = recordcount;
	    oc_data_free(conn,data); /* reclaim */
	    break; /* leave the loop */
	} else {
	    PANIC("unexpected mode");
	    return NC_EINVAL;
        }
    }

done:
    nclistfree(path);
    if(ocstat) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#14
0
文件: ncdap3a.c 项目: UV-CDAT/netcdf
static NCerror
getseqdimsize(NCDAPCOMMON* dapcomm, CDFnode* seq, size_t* sizep)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    OClink conn = dapcomm->oc.conn;
    OCdatanode rootcontent = NULL;
    OCddsnode ocroot;
    CDFnode* dxdroot;
    CDFnode* xseq;
    NCbytes* seqcountconstraints = ncbytesnew();
    size_t seqsize;

    /* Read the minimal amount of data in order to get the count */
    /* If the url is unconstrainable, then get the whole thing */
    computeseqcountconstraints3(dapcomm,seq,seqcountconstraints);
#ifdef DEBUG
fprintf(stderr,"seqcountconstraints: %s\n",ncbytescontents(seqcountconstraints));
#endif

    /* Fetch the minimal data */
    if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
        ocstat = dap_fetch(dapcomm,conn,NULL,OCDATADDS,&ocroot);
    else
        ocstat = dap_fetch(dapcomm,conn,ncbytescontents(seqcountconstraints),OCDATADDS,&ocroot);
    if(ocstat) goto fail;

    ncstat = buildcdftree34(dapcomm,ocroot,OCDATA,&dxdroot);
    if(ncstat) goto fail;	
    /* attach DATADDS to DDS */
    ncstat = attach34(dxdroot,seq);
    if(ncstat) goto fail;	

    /* WARNING: we are now switching to datadds tree */
    xseq = seq->attachment;
    ncstat = countsequence(dapcomm,xseq,&seqsize);
    if(ncstat) goto fail;

#ifdef DEBUG
fprintf(stderr,"sequencesize: %s = %lu\n",seq->ocname,(unsigned long)seqsize);
#endif

    /* throw away the fetch'd trees */
    unattach34(dapcomm->cdf.ddsroot);
    freecdfroot34(dxdroot);
    if(ncstat != NC_NOERR) {
        /* Cannot get DATADDDS*/
	char* code;
	char* msg;
	long httperr;
	oc_svcerrordata(dapcomm->oc.conn,&code,&msg,&httperr);
	if(code != NULL) {
	    nclog(NCLOGERR,"oc_fetch_datadds failed: %s %s %l",
			code,msg,httperr);
	}
	ocstat = OC_NOERR;
    }		
    if(sizep) *sizep = seqsize;

fail:
    ncbytesfree(seqcountconstraints);
    oc_data_free(conn,rootcontent);
    if(ocstat) ncstat = ocerrtoncerr(ocstat);
    return ncstat;
}
示例#15
0
NCerror
nc3d_getvarx(int ncid, int varid,
	    const size_t *startp,
	    const size_t *countp,
	    const ptrdiff_t* stridep,
	    void *data,
	    nc_type dsttype0)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    int i;
    NC* drno;
    NC* substrate;
    NCDAPCOMMON* dapcomm;
    CDFnode* cdfvar = NULL; /* cdf node mapping to var*/
    NClist* varnodes;
    nc_type dsttype;
    Getvara* varainfo = NULL;
    CDFnode* xtarget = NULL; /* target in DATADDS */
    CDFnode* target = NULL; /* target in constrained DDS */
    DCEprojection* varaprojection = NULL;
    NCcachenode* cachenode = NULL;
    size_t localcount[NC_MAX_VAR_DIMS];
    NClist* ncdimsall;
    size_t ncrank;
    NClist* vars = NULL;
    DCEconstraint* fetchconstraint = NULL;
    DCEprojection* fetchprojection = NULL;
    DCEprojection* walkprojection = NULL;
    int state;
#define FETCHWHOLE 1 /* fetch whole data set */
#define FETCHVAR   2 /* fetch whole variable */
#define FETCHPART  4 /* fetch constrained variable */
#define CACHED     8 /* whole variable is already in the cache */

    ncstat = NC_check_id(ncid, (NC**)&drno);
    if(ncstat != NC_NOERR) goto fail;
    dapcomm = (NCDAPCOMMON*)drno->dispatchdata;
    
    ncstat = NC_check_id(drno->substrate, (NC**)&substrate);
    if(ncstat != NC_NOERR) goto fail;

    /* Locate var node via varid */
    varnodes = dapcomm->cdf.ddsroot->tree->varnodes;
    for(i=0;i<nclistlength(varnodes);i++) {
	CDFnode* node = (CDFnode*)nclistget(varnodes,i);
	if(node->array.basevar == NULL
           && node->nctype == NC_Atomic
           && node->ncid == varid) {
	    cdfvar = node;
	    break;
	}
    }

    ASSERT((cdfvar != NULL));

    /* If the variable is prefetchable, then now
       is the time to do a lazy prefetch */
   if(FLAGSET(dapcomm->controls,NCF_PREFETCH)
      && !FLAGSET(dapcomm->controls,NCF_PREFETCH_EAGER)) {
        if(dapcomm->cdf.cache != NULL && dapcomm->cdf.cache->prefetch == NULL) {
            ncstat = prefetchdata3(dapcomm);
            if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
	}
    }
    
    /* Get the dimension info */
    ncdimsall = cdfvar->array.dimsetall;
    ncrank = nclistlength(ncdimsall);

#ifdef DEBUG
 {
int i;
fprintf(stderr,"getvarx: %s",cdfvar->ncfullname);
for(i=0;i<ncrank;i++)
  fprintf(stderr,"(%ld:%ld:%ld)",
	(long)startp[i],
	(long)countp[i],
	(long)stridep[i]
	);
fprintf(stderr,"\n");
 }
#endif

    /* Fill in missing arguments */
    if(startp == NULL)
	startp = nc_sizevector0;

    if(countp == NULL) {
        /* Accumulate the dimension sizes */
        for(i=0;i<ncrank;i++) {
	    CDFnode* dim = (CDFnode*)nclistget(ncdimsall,i);
	    localcount[i] = dim->dim.declsize;
	}
	countp = localcount;
    }

    if(stridep == NULL)
	stridep = nc_ptrdiffvector1;

    /* Validate the dimension sizes */
    for(i=0;i<ncrank;i++) {
        CDFnode* dim = (CDFnode*)nclistget(ncdimsall,i);
	if(startp[i] > dim->dim.declsize
	   || startp[i]+countp[i] > dim->dim.declsize) {
	    ncstat = NC_EINVALCOORDS;
	    goto fail;	    
	}
    }	     

#ifdef DEBUG
 {
NClist* dims = cdfvar->array.dimsetall;
fprintf(stderr,"getvarx: %s",cdfvar->ncfullname);
if(nclistlength(dims) > 0) {int i;
for(i=0;i<nclistlength(dims);i++) 
fprintf(stderr,"(%lu:%lu:%lu)",(unsigned long)startp[i],(unsigned long)countp[i],(unsigned long)stridep[i]);
fprintf(stderr," -> ");
for(i=0;i<nclistlength(dims);i++) 
if(stridep[i]==1)
fprintf(stderr,"[%lu:%lu]",(unsigned long)startp[i],(unsigned long)((startp[i]+countp[i])-1));
else {
unsigned long iend = (stridep[i] * countp[i]);
iend = (iend + startp[i]);
iend = (iend - 1);
fprintf(stderr,"[%lu:%lu:%lu]",
(unsigned long)startp[i],(unsigned long)stridep[i],iend);
 }
 }
fprintf(stderr,"\n");
 }
#endif

    dsttype = (dsttype0);

    /* Default to using the inquiry type for this var*/
    if(dsttype == NC_NAT) dsttype = cdfvar->externaltype;

    /* Validate any implied type conversion*/
    if(cdfvar->etype != dsttype && dsttype == NC_CHAR) {
        /* The only disallowed conversion is to/from char and non-byte
           numeric types*/
	switch (cdfvar->etype) {
	case NC_STRING: case NC_URL:
	case NC_CHAR: case NC_BYTE: case NC_UBYTE:
	    break;
	default:
	    return THROW(NC_ECHAR);
	}
    }

    ncstat = makegetvar34(dapcomm,cdfvar,data,dsttype,&varainfo);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

    /* Compile the start/stop/stride info into a projection */
    ncstat = buildvaraprojection3(varainfo->target,
		                  startp,countp,stridep,
                                  &varaprojection);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

    fetchprojection = NULL;
    walkprojection = NULL;

    /* Create walkprojection as the merge of the url projections
       and the vara projection; may change in FETCHPART case below*/
    ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
				   varaprojection,&walkprojection);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

#ifdef DEBUG
fprintf(stderr,"getvarx: walkprojection: |%s|\n",dumpprojection(walkprojection));
#endif

    /* define the var list of interest */
    vars = nclistnew();
    nclistpush(vars,(void*)varainfo->target);

    state = 0;
    if(iscached(dapcomm,cdfvar,&cachenode)) { /* ignores non-whole variable cache entries */
	state = CACHED;
	ASSERT((cachenode != NULL));
#ifdef DEBUG
fprintf(stderr,"var is in cache\n");
#endif
        /* If it is cached, then it is a whole variable but may still
           need to apply constraints during the walk */
	ASSERT(cachenode->wholevariable); /* by construction */
    } else if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
	state = FETCHWHOLE;
    } else {/* load using constraints */
        if(FLAGSET(dapcomm->controls,NCF_WHOLEVAR))
	    state = FETCHVAR;
	else
	    state = FETCHPART;
    }
    ASSERT(state != 0);    

    switch (state) {

    case FETCHWHOLE: {
        /* buildcachenode3 will create a new cachenode and
           will also fetch the whole corresponding datadds.
	*/
        /* Build the complete constraint to use in the fetch */
        fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
        /* Use no projections or selections */
        fetchconstraint->projections = nclistnew();
        fetchconstraint->selections = nclistnew();
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHWHOLE: fetchconstraint: %s\n",dumpconstraint(fetchconstraint));
#endif
        ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
	fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
	if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
    } break;

    case CACHED: {
    } break;

    case FETCHVAR: { /* Fetch a complete single variable */
        /* Create fetch projection as the merge of the url projections
           and the vara projection */
        ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
				       varaprojection,&fetchprojection);
	/* elide any sequence and string dimensions (dap servers do not allow such). */
	ncstat = removepseudodims(fetchprojection);
        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

	/* Convert to a whole variable projection */
	dcemakewholeprojection(fetchprojection);

#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHVAR: fetchprojection: |%s|\n",dumpprojection(fetchprojection));
#endif

        /* Build the complete constraint to use in the fetch */
        fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
        /* merged constraint just uses the url constraint selection */
        fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections);
	/* and the created fetch projection */
        fetchconstraint->projections = nclistnew();
	nclistpush(fetchconstraint->projections,(void*)fetchprojection);
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHVAR: fetchconstraint: %s\n",dumpconstraint(fetchconstraint));
#endif
        /* buildcachenode3 will create a new cachenode and
           will also fetch the corresponding datadds.
        */
        ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
	fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
	if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
    } break;

    case FETCHPART: {
        /* Create fetch projection as the merge of the url projections
           and the vara projection */
        ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections,
				       varaprojection,&fetchprojection);
	/* elide any sequence and string dimensions (dap servers do not allow such). */
	ncstat = removepseudodims(fetchprojection);
        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

	/* Shift the varaprojection for simple walk */
	dcefree((DCEnode*)walkprojection) ; /* reclaim any existing walkprojection */        
	walkprojection = (DCEprojection*)dceclone((DCEnode*)varaprojection);
        dapshiftprojection(walkprojection);

#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHPART: fetchprojection: |%s|\n",dumpprojection(fetchprojection));
#endif

        /* Build the complete constraint to use in the fetch */
        fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
        /* merged constraint just uses the url constraint selection */
        fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections);
	/* and the created fetch projection */
        fetchconstraint->projections = nclistnew();
	nclistpush(fetchconstraint->projections,(void*)fetchprojection);
#ifdef DEBUG
fprintf(stderr,"getvarx: FETCHPART: fetchconstraint: %s\n",dumpconstraint(fetchconstraint));
#endif
        /* buildcachenode3 will create a new cachenode and
           will also fetch the corresponding datadds.
        */
        ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
	fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
	if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
    } break;

    default: PANIC1("unknown fetch state: %d\n",state);
    }

    ASSERT(cachenode != NULL);

#ifdef DEBUG
fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
#endif

    /* attach DATADDS to (constrained) DDS */
    unattach34(dapcomm->cdf.ddsroot);
    ncstat = attachsubset34(cachenode->datadds,dapcomm->cdf.ddsroot);
    if(ncstat) goto fail;	

    /* Fix up varainfo to use the cache */
    varainfo->cache = cachenode;
    cachenode = NULL;
    varainfo->varaprojection = walkprojection;
    walkprojection = NULL;

    /* Get the var correlate from the datadds */
    target = varainfo->target;
    xtarget = target->attachment;
    if(xtarget == NULL) 
	{THROWCHK(ncstat=NC_ENODATA); goto fail;}

    /* Switch to datadds tree space*/
    varainfo->target = xtarget;
save = (DCEnode*)varaprojection;
    ncstat = moveto(dapcomm,varainfo,varainfo->cache->datadds,data);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}

    nclistfree(vars);
    dcefree((DCEnode*)varaprojection);
    dcefree((DCEnode*)fetchconstraint);
    freegetvara(varainfo);
fail:
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#16
0
NCerror
buildcachenode34(NCDAPCOMMON* nccomm,
	        DCEconstraint* constraint,
		NClist* varlist,
		NCcachenode** cachep,
		NCFLAGS flags)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    OClink conn = nccomm->oc.conn;
    OCddsnode ocroot = NULL;
    CDFnode* dxdroot = NULL;
    NCcachenode* cachenode = NULL;
    char* ce = NULL;
    int isprefetch = 0;

    if((flags & NCF_PREFETCH) != 0)
	isprefetch = 1;	

    if((flags & NCF_PREFETCH_ALL) == 0)
        ce = buildconstraintstring3(constraint);

    ocstat = dap_fetch(nccomm,conn,ce,OCDATADDS,&ocroot);
    nullfree(ce);
    if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;}

    ncstat = buildcdftree34(nccomm,ocroot,OCDATA,&dxdroot);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* re-struct*/
    if(!FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) {
        ncstat = restruct3(dxdroot,nccomm->cdf.ddsroot,constraint->projections);
        if(ncstat) {THROWCHK(ncstat); goto done;}
    }

    /* create the cache node */
    cachenode = createnccachenode();
    cachenode->isprefetch = isprefetch;
    cachenode->vars = nclistclone(varlist);
    cachenode->datadds = dxdroot;
    /* Give the constraint over to the cachenode */
    cachenode->constraint = constraint;
    constraint = NULL;
    cachenode->wholevariable = iscacheableconstraint(cachenode->constraint);

    /* save the root content*/
    cachenode->ocroot = ocroot;
    ocstat = oc_data_getroot(conn,ocroot,&cachenode->content);
    if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;}

    /* capture the packet size */
    ocstat = oc_raw_xdrsize(conn,ocroot,&cachenode->xdrsize);
    if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;}

#ifdef DEBUG
fprintf(stderr,"buildcachenode: new cache node: %s\n",
	dumpcachenode(cachenode));
#endif
    /* Insert into the cache. If not caching, then
       remove any previous cache node
    */
    if(!isprefetch) {
	NCcache* cache = nccomm->cdf.cache;
	if(cache->nodes == NULL) cache->nodes = nclistnew();
	/* remove cache nodes to get below the max cache size */
	while(cache->cachesize + cachenode->xdrsize > cache->cachelimit
	      && nclistlength(cache->nodes) > 0) {
	    NCcachenode* node = (NCcachenode*)nclistremove(cache->nodes,0);
#ifdef DEBUG
fprintf(stderr,"buildcachenode: purge cache node: %s\n",
	dumpcachenode(cachenode));
#endif
	    cache->cachesize -= node->xdrsize;
	    freenccachenode(nccomm,node);
	}
	/* Remove cache nodes to get below the max cache count */
	/* If not caching, then cachecount should be 0 */
	while(nclistlength(cache->nodes) > cache->cachecount) {
	    NCcachenode* node = (NCcachenode*)nclistremove(cache->nodes,0);
#ifdef DEBUG
fprintf(stderr,"buildcachenode: count purge cache node: %s\n",
	dumpcachenode(node));
#endif
	    cache->cachesize -= node->xdrsize;
	    freenccachenode(nccomm,node);
        }
        nclistpush(nccomm->cdf.cache->nodes,(void*)cachenode);
        cache->cachesize += cachenode->xdrsize;
    }

#ifdef DEBUG
fprintf(stderr,"buildcachenode: %s\n",dumpcachenode(cachenode));
#endif

done:
    if(constraint != NULL) dcefree((DCEnode*)constraint);
    if(cachep) *cachep = cachenode;
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    if(ncstat) {
	freecdfroot34(dxdroot);
	freenccachenode(nccomm,cachenode);
    }
    return THROW(ncstat);
}
示例#17
0
/* See ncd3dispatch.c for other version */
int
NCD3_open(const char * path, int mode,
               int basepe, size_t *chunksizehintp,
 	       int useparallel, void* mpidata,
               NC_Dispatch* dispatch, NC** ncpp)
{
    NCerror ncstat = NC_NOERR;
    OCerror ocstat = OC_NOERR;
    NC* drno = NULL;
    NCDAPCOMMON* dapcomm = NULL;
    const char* value;
    char* tmpname = NULL;

    if(!nc3dinitialized) nc3dinitialize();

    if(path == NULL)
	return NC_EDAPURL;
    if(dispatch == NULL) PANIC("NC3D_open: no dispatch table");

    /* Setup our NC and NCDAPCOMMON state*/
    drno = (NC*)calloc(1,sizeof(NC));
    if(drno == NULL) {ncstat = NC_ENOMEM; goto done;}

    /* compute an ncid */
    ncstat = add_to_NCList(drno);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}

    dapcomm = (NCDAPCOMMON*)calloc(1,sizeof(NCDAPCOMMON));
    if(dapcomm == NULL) {ncstat = NC_ENOMEM; goto done;}

    drno->dispatch = dispatch;
    drno->dispatchdata = dapcomm;
    dapcomm->controller = (NC*)drno;

    dapcomm->cdf.separator = ".";
    dapcomm->cdf.smallsizelimit = DFALTSMALLLIMIT;
    dapcomm->cdf.cache = createnccache();

#ifdef HAVE_GETRLIMIT
    { struct rlimit rl;
      if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
	dapcomm->cdf.cache->cachecount = (size_t)(rl.rlim_cur / 2);
      }
    }
#endif

#ifdef OCCOMPILEBYDEFAULT
    /* set the compile flag by default */
    dapcomm->oc.rawurltext = (char*)emalloc(strlen(path)+strlen("[compile]")+1);
    strcpy(dapcomm->oc.rawurltext,"[compile]");
    strcat(dapcomm->oc.rawurltext, path);    
#else
    dapcomm->oc.rawurltext = strdup(path);
#endif

    nc_uriparse(dapcomm->oc.rawurltext,&dapcomm->oc.url);

    /* parse the client parameters */
    nc_uridecodeparams(dapcomm->oc.url);

    if(!constrainable34(dapcomm->oc.url))
	SETFLAG(dapcomm->controls,NCF_UNCONSTRAINABLE);

    /* Use libsrc code for storing metadata */
    tmpname = nulldup(PSEUDOFILE);
    /* Now, use the file to create the netcdf file */
    if(sizeof(size_t) == sizeof(unsigned int))
	ncstat = nc_create(tmpname,NC_CLOBBER,&drno->substrate);
    else
	ncstat = nc_create(tmpname,NC_CLOBBER|NC_64BIT_OFFSET,&drno->substrate);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}

    /* free the filename so it will automatically go away*/
    unlink(tmpname);
    nullfree(tmpname);

    /* Avoid fill */
    nc_set_fill(drno->substrate,NC_NOFILL,NULL);

    dapcomm->oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
    dapcomm->oc.dapconstraint->projections = nclistnew();
    dapcomm->oc.dapconstraint->selections = nclistnew();

    /* Parse constraints to make sure they are syntactically correct */
    ncstat = parsedapconstraints(dapcomm,dapcomm->oc.url->constraint,dapcomm->oc.dapconstraint);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}

    /* Complain if we are unconstrainable but have constraints */
    if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
	if(dapcomm->oc.url->constraint != NULL
	   && strlen(dapcomm->oc.url->constraint) > 0) {
	    nclog(NCLOGWARN,"Attempt to constrain an unconstrainable data source: %s",
		   dapcomm->oc.url->constraint);
	}
    }

    /* Construct a url for oc minus any parameters */
    dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,
				(NC_URIALL ^ NC_URICONSTRAINTS));

    /* Pass to OC */
    ocstat = oc_open(dapcomm->oc.urltext,&dapcomm->oc.conn);
    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}

    nullfree(dapcomm->oc.urltext); /* clean up */
    dapcomm->oc.urltext = NULL;

    /* process control client parameters */
    applyclientparamcontrols3(dapcomm);

    /* Turn on logging; only do this after oc_open*/
    if((value = paramvalue34(dapcomm,"log")) != NULL) {
	ncloginit();
        ncsetlogging(1);
        nclogopen(value);
	oc_loginit();
        oc_setlogging(1);
        oc_logopen(value);
    }

    /* fetch and build the (almost) unconstrained DDS for use as
       template */
    ncstat = fetchtemplatemetadata3(dapcomm);
    if(ncstat != NC_NOERR) goto done;

    /* fetch and build the constrained DDS */
    ncstat = fetchconstrainedmetadata3(dapcomm);
    if(ncstat != NC_NOERR) goto done;

#ifdef DEBUG2
fprintf(stderr,"constrained dds: %s\n",dumptree(dapcomm->cdf.ddsroot));
#endif


    /* The following actions are (mostly) WRT to the constrained tree */

    /* Accumulate useful nodes sets  */
    ncstat = computecdfnodesets3(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* Fix grids */
    ncstat = fixgrids3(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* Locate and mark usable sequences */
    ncstat = sequencecheck3(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* suppress variables not in usable sequences */
    ncstat = suppressunusablevars3(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* apply client parameters */
    ncstat = applyclientparams34(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* Add (as needed) string dimensions*/
    ncstat = addstringdims(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    if(nclistlength(dapcomm->cdf.seqnodes) > 0) {
	/* Build the sequence related dimensions */
        ncstat = defseqdims(dapcomm);
        if(ncstat) {THROWCHK(ncstat); goto done;}
    }

    /* Define the dimsetplus and dimsetall lists */
    ncstat = definedimsets3(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* Re-compute the dimension names*/
    ncstat = computecdfdimnames34(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* Deal with zero size dimensions */
    ncstat = fixzerodims3(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* Attempt to use the DODS_EXTRA info to turn
       one of the dimensions into unlimited.
       Assume computecdfdimnames34 has already been called.
    */
    ncstat = defrecorddim3(dapcomm);
    if(ncstat) {THROWCHK(ncstat); goto done;}
    if(dapcomm->cdf.recorddimname != NULL
       && nclistlength(dapcomm->cdf.seqnodes) > 0) {
	/*nclog(NCLOGWARN,"unlimited dimension specified, but sequences exist in DDS");*/
	PANIC("unlimited dimension specified, but sequences exist in DDS");	
    }

    /* Re-compute the var names*/
    ncstat = computecdfvarnames3(dapcomm,dapcomm->cdf.ddsroot,dapcomm->cdf.varnodes);
    if(ncstat) {THROWCHK(ncstat); goto done;}

    /* Transfer data from the unconstrained DDS data to the unconstrained DDS */
    ncstat = dimimprint3(dapcomm);
    if(ncstat) goto done;

    /* Process the constraints to map to the constrained CDF tree */
    /* (must follow fixgrids3 */
    ncstat = mapconstraints3(dapcomm->oc.dapconstraint,dapcomm->cdf.ddsroot);
    if(ncstat != NC_NOERR) goto done;

    /* Canonicalize the constraint */
    ncstat = fixprojections(dapcomm->oc.dapconstraint->projections);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}

    /* Fill in segment information */
    ncstat = qualifyconstraints3(dapcomm->oc.dapconstraint);
    if(ncstat != NC_NOERR) goto done;

    /* using the modified constraint, rebuild the constraint string */
    if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
	/* ignore all constraints */
	dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,0);
    } else {
	char* constraintstring = buildconstraintstring3(dapcomm->oc.dapconstraint);
        nc_urisetconstraints(dapcomm->oc.url,constraintstring);
	nullfree(constraintstring);
        dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,NC_URICONSTRAINTS);
    }

#ifdef DEBUG
fprintf(stderr,"ncdap3: final constraint: %s\n",dapcomm->oc.url->constraint);
#endif

    /* Estimate the variable sizes */
    estimatevarsizes3(dapcomm);

    /* Build the meta data */
    ncstat = buildncstructures3(dapcomm);
    if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}

    /* Do any necessary data prefetch */
    if(FLAGSET(dapcomm->controls,NCF_PREFETCH)) {
        ncstat = prefetchdata3(dapcomm);
        if(ncstat != NC_NOERR) {
            del_from_NCList((NC*)drno); /* undefine here */
	    {THROWCHK(ncstat); goto done;}
	}
    }

    {
        /* Mark as no longer writable and no longer indef;
           requires breaking abstraction  */
	NC* nc;
        ncstat = NC_check_id(drno->substrate, &nc);
        /* Mark as no longer writeable */
        fClr(nc->nciop->ioflags, NC_WRITE);
        /* Mark as no longer indef;
           (do NOT use nc_enddef until diskless is working)*/
	fSet(nc->flags, NC_INDEF);	
    }

    if(ncpp) *ncpp = (NC*)drno;

    return ncstat;

done:
    if(drno != NULL) NCD3_abort(drno->ext_ncid);
    if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
    return THROW(ncstat);
}
示例#18
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);
}