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); }
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); }
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); }
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); }
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); }
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); }
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; }