コード例 #1
0
ファイル: dceconstraints.c プロジェクト: U-238/gempak
/*
Given two projection lists, merge
src into dst taking
overlapping projections into acct.
*/
int
dapmergeprojections(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,(ncelem)p);
    }    
    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(dcesamepath(target->var->segments,
			   p2->var->segments)!=0) continue;
	    /* This entry matches our current target; merge  */
	    ncstat = mergeprojection(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;
}
コード例 #2
0
ファイル: dceparse.c プロジェクト: BJangeofan/netcdf-c
/* Wrapper for ceparse */
int
dapceparse(char* input, DCEconstraint* constraint, char** errmsgp)
{
    DCEparsestate* state;
    int errcode = 0;

#ifdef PARSEDEBUG
dcedebug = 1;
#endif

    if(input != NULL) {
#ifdef DEBUG
fprintf(stderr,"dceeparse: input=%s\n",input);
#endif
        state = ce_parse_init(input,constraint);
        if(dceparse(state) == 0) {
#ifdef DEBUG
if(nclistlength(constraint->projections) > 0)
fprintf(stderr,"dceeparse: projections=%s\n",
        dcetostring((DCEnode*)constraint->projections));
#endif
#ifdef DEBUG
if(nclistlength(constraint->selections)  > 0)
fprintf(stderr,"dceeparse: selections=%s\n",
	dumpselections(constraint->selections));
#endif
	} else {
	    if(errmsgp) *errmsgp = nulldup(state->errorbuf);
	}
	errcode = state->errorcode;
        dce_parse_cleanup(state);
    }
    return errcode;
}
コード例 #3
0
ファイル: dapdump.c プロジェクト: rykroon/netcdf-c
char*
dumpconstraint(DCEconstraint* con)
{
    char* tmp;
    int v = dceverbose;
    dceverbose = 1;
    tmp = dcetostring((DCEnode*)con);
    dceverbose = v;
    return tmp;
}
コード例 #4
0
ファイル: dapdump.c プロジェクト: rykroon/netcdf-c
char*
dumpprojection(DCEprojection* proj)
{
    char* tmp;
    int v = dceverbose;
    dceverbose = 1;
    tmp = dcetostring((DCEnode*)proj);
    dceverbose = v;
    return tmp;
}
コード例 #5
0
ファイル: dceparse.c プロジェクト: BJangeofan/netcdf-c
void
selections(DCEparsestate* state, Object list0)
{
    NClist* list = (NClist*)list0;
    if(list != NULL) {
        nclistfree(state->constraint->selections);
        state->constraint->selections = list;
    }
#ifdef DEBUG
fprintf(stderr,"	ce.selections: %s\n",
	dcetostring((DCEnode*)state->constraint->selections));
#endif
}
コード例 #6
0
static void
slicedump(const char* prefix, DCEslice* s)
{
#if 1
    int v = dceverbose;
    dceverbose = 1;
    fprintf(stderr,"%s: %s\n",prefix,dcetostring((DCEnode*)s));
    dceverbose = v;
#else
    size_t last = (s->first+s->length)-1;
    fprintf(stderr,"%s: [%lu:%lu:%lu p=%lu l=%lu c=%lu]\n",
	prefix,s->first,s->stride,last,s->stop,s->length,s->count);
#endif
}
コード例 #7
0
ファイル: dceparse.c プロジェクト: BJangeofan/netcdf-c
Object
projection(DCEparsestate* state, Object varorfcn)
{
    DCEprojection* p = (DCEprojection*)dcecreate(CES_PROJECT);
    CEsort tag = *(CEsort*)varorfcn;
    if(tag == CES_FCN)
	p->fcn = varorfcn;
    else
	p->var = varorfcn;
    p->discrim = tag;
#ifdef DEBUG
fprintf(stderr,"	ce.projection: %s\n",
	dcetostring((DCEnode*)p));
#endif
    return p;
}
コード例 #8
0
ファイル: dceconstraints.c プロジェクト: U-238/gempak
/* Parse incoming url constraints, if any,
   to check for syntactic correctness
*/ 
int
dapparseconstraints(char* constraints, DCEconstraint* dapconstraint)
{
    int ncstat = NC_NOERR;
    char* errmsg;

    assert(dapconstraint != NULL);
    nclistclear(dapconstraint->projections);
    nclistclear(dapconstraint->selections);

    ncstat = dapceparse(constraints,dapconstraint,&errmsg);
    if(ncstat) {
	nclog(NCLOGWARN,"DAP constraint parse failure: %s",errmsg);
	if(errmsg) free(errmsg);
        nclistclear(dapconstraint->projections);
        nclistclear(dapconstraint->selections);
    }

#ifdef DEBUG
fprintf(stderr,"constraint: %s",dcetostring((DCEnode*)dapconstraint));
#endif
    return ncstat;
}
コード例 #9
0
ファイル: dapdump.c プロジェクト: U-238/gempak
/* This should be consistent with makeslicestring3 in constraints3.c */
char*
dumpslice(DCEslice* slice)
{
    return dcetostring((DCEnode*)slice);
}
コード例 #10
0
ファイル: dapdump.c プロジェクト: U-238/gempak
char*
dumpconstraint(DCEconstraint* con)
{
    return dcetostring((DCEnode*)con);
}
コード例 #11
0
ファイル: dapdump.c プロジェクト: U-238/gempak
char*
dumpselection(DCEselection* sel)
{
    return dcetostring((DCEnode*)sel);
}
コード例 #12
0
ファイル: dapdump.c プロジェクト: U-238/gempak
char*
dumpprojection(DCEprojection* proj)
{
    return dcetostring((DCEnode*)proj);
}
コード例 #13
0
ファイル: getvara3.c プロジェクト: brandontheis/netcdf-1
/* We are at a primitive variable or scalar that has no string dimensions.
   Extract the data. (This is way too complicated)
*/
static int
extract(
	NCDAPCOMMON* nccomm,
	Getvara* xgetvar,
	CDFnode* xnode,
        DCEsegment* segment,
	size_t dimindex,/*notused*/
        OClink conn,
        OCdatanode currentcontent,
	struct NCMEMORY* memory
       )
{
    OCerror ocstat = OC_NOERR;
    NCerror ncstat = NC_NOERR;
    size_t count,rank0;
    Dapodometer* odom = NULL;
    size_t externtypesize;
    size_t interntypesize;
    int requireconversion;
    char value[16]; 

    ASSERT((segment != NULL));

    requireconversion = conversionrequired(xgetvar->dsttype,xnode->etype);

    ASSERT(xgetvar->cache != NULL);
    externtypesize = nctypesizeof(xgetvar->dsttype);
    interntypesize = nctypesizeof(xnode->etype);

    rank0 = nclistlength(xnode->array.dimset0);

#ifdef DEBUG2
fprintf(stderr,"moveto: primitive: segment=%s",
                dcetostring((DCEnode*)segment));
fprintf(stderr," iswholevariable=%d",xgetvar->cache->wholevariable);
fprintf(stderr,"\n");
#endif

    if(rank0 == 0) {/* scalar */
	char* mem = (requireconversion?value:memory->next);
	ASSERT(externtypesize <= sizeof(value));
	/* Read the whole scalar directly into memory  */
	ocstat = oc_data_readscalar(conn,currentcontent,externtypesize,mem);
	if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	if(requireconversion) {
	    /* convert the value to external type */
            ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1);
            if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
        }
        memory->next += (externtypesize);
    } else if(xgetvar->cache->wholevariable) {/* && rank0 > 0 */
	/* There are multiple cases, assuming no conversion required.
           1) client is asking for whole variable
              => start=0, count=totalsize, stride=1
	      => read whole thing at one shot
           2) client is asking for non-strided subset
              and edges are maximal
              => start=x, count=y, stride=1
	      => read whole subset at one shot
           3) client is asking for strided subset or edges are not maximal
              => start=x, count=y, stride=s
	      => we have to use odometer on leading prefix.
           If conversion required, then read one-by-one
	*/
	int safeindex = dcesafeindex(segment,0,rank0);
	assert(safeindex >= 0 && safeindex <= rank0);

	if(!requireconversion && safeindex == 0) { /* can read whole thing */
            size_t internlen;
	    count = dcesegmentsize(segment,0,rank0); /* how many to read */
	    internlen = interntypesize*count;
            /* Read the whole variable directly into memory.*/
            ocstat = oc_data_readn(conn,currentcontent,dap_zero,count,internlen,memory->next);
	    /* bump memory pointer */
	    memory->next += internlen;
            if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	} else if(!requireconversion && safeindex > 0 && safeindex < rank0) {
	    size_t internlen;
	    /* We need to build an odometer for the unsafe prefix of the slices */
	    odom = dapodom_fromsegment(segment,0,safeindex);
	    count = dcesegmentsize(segment,safeindex,rank0); /* read in count chunks */
	    internlen = interntypesize*count;
	    while(dapodom_more(odom)) {
	        ocstat = oc_data_readn(conn,currentcontent,odom->index,count,internlen,memory->next);
	        if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	        memory->next += internlen;
	        dapodom_next(odom);
	    }
            dapodom_free(odom);
        } else {
	     /* Cover following cases, all of which require reading
                values one-by-one:
		1. requireconversion
		2. !requireconversion but safeindex == rank0 =>no safe indices
		Note that in case 2, we will do a no-op conversion.
	     */
            odom = dapodom_fromsegment(segment,0,rank0);
	    while(dapodom_more(odom)) {
	        char value[16]; /* Big enough to hold any numeric value */
	        ocstat = oc_data_readn(conn,currentcontent,odom->index,1,interntypesize,value);
	        if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	        ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1);
	        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
	        memory->next += (externtypesize);
	        dapodom_next(odom);
	    }
            dapodom_free(odom);
        }
    } else { /* !xgetvar->cache->wholevariable && rank0 > 0 */
	/* This is the case where the constraint was applied by the server,
           so we just read it in, possibly with conversion
	*/
	if(requireconversion) {
	    /* read one-by-one */
            odom = dapodom_fromsegment(segment,0,rank0);
	    while(dapodom_more(odom)) {
	        char value[16]; /* Big enough to hold any numeric value */
	        ocstat = oc_data_readn(conn,currentcontent,odom->index,1,interntypesize,value);
	        if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	        ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1);
	        if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
	        memory->next += (externtypesize);
	        dapodom_next(odom);
	    }
            dapodom_free(odom);
	} else {/* Read straight to memory */
            size_t internlen;
	    count = dcesegmentsize(segment,0,rank0); /* how many to read */
	    internlen = interntypesize*count;
            ocstat = oc_data_readn(conn,currentcontent,dap_zero,count,internlen,memory->next);
            if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
	}
    }
done:
    return THROW(ncstat);
}
コード例 #14
0
ファイル: getvara3.c プロジェクト: brandontheis/netcdf-1
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);
}
コード例 #15
0
ファイル: getvara3.c プロジェクト: qingu/WRF-Libraries
static NCerror
movetor(NCDAPCOMMON* nccomm,
	OCdata currentcontent,
	NClist* path,
        int depth, /* depth is position in segment list*/
	Getvara* xgetvar,
        int dimindex, /* dimindex is position in xgetvar->slices*/
	struct NCMEMORY* memory,
	NClist* segments)
{
    int i;
    OCerror ocstat = OC_NOERR;
    NCerror ncstat = NC_NOERR;
    size_t fieldindex,gridindex,rank;
    OCconnection conn = nccomm->oc.conn;
    CDFnode* xnode = (CDFnode*)nclistget(path,depth);
    OCdata reccontent = OCNULL;
    OCdata dimcontent = OCNULL;
    OCdata fieldcontent = OCNULL;
    Dapodometer* odom = OCNULL;
    OCmode currentmode = OCNULLMODE;
    CDFnode* xnext;
    int hasstringdim = 0;
    size_t dimoffset;
    DCEsegment* segment;
    int newdepth;
    int caching = FLAGSET(nccomm->controls,NCF_CACHE);
    int unconstrainable = FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE);

    /* 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;

    ocstat = oc_data_mode(conn,currentcontent,&currentmode);

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

    /* Switch on the combination of nctype and mode */
#define CASE(nc1,nc2) (nc1*1024+nc2)

    /* This must be consistent with the oc mode transition function */
    switch (CASE(xnode->nctype,currentmode)) {

    default:
	PANIC2("Illegal combination: nctype=%d mode=%d",
		(int)xnode->nctype,(int)currentmode);
	break;

    case CASE(NC_Sequence,OCFIELDMODE):
    case CASE(NC_Dataset,OCFIELDMODE):
    case CASE(NC_Grid,OCFIELDMODE):
    case CASE(NC_Structure,OCFIELDMODE):
	/* currentcontent points to the grid/dataset/structure instance */
	xnext = (CDFnode*)nclistget(path,depth+1);
	ASSERT((xnext != NULL));
	fieldindex = findfield(xnode,xnext);
	/* If the next node is a virtual node, then
	   we need to effectively
	   ignore it and use the appropriate subnode.
	   If the next node is a structuregrid node, then
	   use it as is.
	*/
        if(xnext->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;
	}
        fieldcontent = oc_data_new(conn);
        ocstat = oc_data_ith(conn,currentcontent,fieldindex,fieldcontent);
	if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
	ncstat = movetor(nccomm,fieldcontent,
                         path,newdepth,xgetvar,dimindex,memory,
			 segments);
	break;

    case CASE(NC_Sequence,OCARRAYMODE): /* will actually always be scalar, but will have
                                           rank == 1 to account for the sequence dim */
    case CASE(NC_Grid,OCARRAYMODE): /* will actually always be scalar */
    case CASE(NC_Structure,OCARRAYMODE):
        /* figure out which slices refer to this node:
           dimindex upto dimindex+rank; */
        ASSERT((segment != NULL));
        rank = segment->rank;
	if(xnode->nctype == NC_Sequence)
	    rank--; /* ignore the sequence dim */
	if(rank == 0) {
            odom = newdapodometer1(1);
	} else if(caching || unconstrainable) {	
            odom = newdapodometer(segment->slices,0,rank);	    
	} else { /*Since vara was projected out, build a simple odometer*/
            odom = newsimpledapodometer(segment,rank);
	}
        while(dapodometermore(odom)) {
            OCmode mode;
            /* Compute which instance to move to*/
            dimoffset = dapodometercount(odom);
            dimcontent = oc_data_new(conn);
            ocstat = oc_data_ith(conn,currentcontent,dimoffset,dimcontent);
            if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
            ocstat = oc_data_mode(conn,dimcontent,&mode);
            ASSERT((mode == OCFIELDMODE
		    || (mode == OCSEQUENCEMODE && xnode->nctype == NC_Sequence)));
            ncstat = movetor(nccomm,dimcontent,
                                 path,depth,
                                 xgetvar,dimindex+rank,
                                 memory,segments);
            dapodometerincr(odom);
        }
        freedapodometer(odom);
        break;

    case CASE(NC_Sequence,OCSEQUENCEMODE): {
        DCEslice* uslice;
        ASSERT((segment != NULL));
        /* Get and check the corresponding sequence dimension from DDS */
        ASSERT((xnode->attachment != NULL));
        /* use uslice to walk 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 */
        uslice = &segment->slices[0];
        reccontent = oc_data_new(conn);
        for(i=uslice->first;i<uslice->stop;i+=uslice->stride) {
	    OCmode eos;
            ocstat = oc_data_ith(conn,currentcontent,i,reccontent);
	    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
	    ocstat = oc_data_mode(conn,reccontent,&eos);
	    if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
	    if(eos == OCNULLMODE) {
                /* We asked for too much */
                ncstat = THROW(NC_EINVALCOORDS);
                goto fail;
            }
            ncstat = movetor(nccomm,reccontent,
                                 path,depth,
                                 xgetvar,dimindex+1,
                                 memory,segments);
            if(ncstat != OC_NOERR) {THROWCHK(ncstat); goto fail;}
        }
        } break;

    case CASE(NC_Primitive,OCPRIMITIVEMODE):
        if(hasstringdim)
	    ncstat = extractstring(nccomm, xgetvar, xnode, segment, conn, currentcontent, memory);
	else	
	    ncstat = extract(nccomm, xgetvar, xnode, segment, conn, currentcontent, memory);
	break;

    }