Exemple #1
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);
}
void
freenccachenode(NCDAPCOMMON* nccomm, NCcachenode* node)
{
    if(node == NULL) return;
    oc_data_free(nccomm->oc.conn,node->content);
    oc_data_free(nccomm->oc.conn,node->content);
    freencconstraint(node->constraint);
    freecdfroot34(node->datadds);
    nclistfree(node->vars);
    efree(node);
}
Exemple #3
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);
}
Exemple #4
0
void
freenccachenode(NCDAPCOMMON* nccomm, NCcachenode* node)
{
    if(node == NULL) return;
    oc_data_free(nccomm->oc.conn,node->content);
#ifdef IGNORE
    oc_root_free(nccomm->oc.conn,node->ocroot);
#endif
    dcefree((DCEnode*)node->constraint);
    freecdfroot34(node->datadds);
    nclistfree(node->vars);
    nullfree(node);
}
Exemple #5
0
void
freenccachenode(NCDAPCOMMON* nccomm, NCcachenode* node)
{
    if(node == NULL) return;
#ifdef DEBUG
fprintf(stderr,"freecachenode: %s\n",
	dumpcachenode(node));
#endif
    oc_data_free(nccomm->oc.conn,node->content);
    dcefree((DCEnode*)node->constraint);
    freecdfroot34(node->datadds);
    nclistfree(node->vars);
    nullfree(node);
}
Exemple #6
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);
}
Exemple #7
0
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);
}
Exemple #8
0
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;
}