Esempio n. 1
0
/*
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);
}
Esempio n. 2
0
/* 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);
}