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