Esempio n. 1
0
/* Used only for structure field arrays*/
static void
generate_fieldarray(Symbol* basetype, NCConstant* con, Dimset* dimset,
		 Bytebuffer* codebuf, Datalist* filler, Generator* generator)
{
    int i;
    int chartype = (basetype->typ.typecode == NC_CHAR);
    Datalist* data;

    ASSERT(dimset->ndims > 0);

    if(con != NULL && !isfillconst(con))
        data = con->value.compoundv;
    else
	data = NULL;

    if(chartype) {
	/* Collect the char field in a separate buffer */
	Bytebuffer* charbuf = bbNew();
        gen_chararray(dimset,data,charbuf,filler);
	generator->charconstant(generator,codebuf,charbuf);
	bbFree(charbuf);
    } else {
	int uid;
	size_t xproduct = crossproduct(dimset,0,0); /* compute total number of elements */
        generator->listbegin(generator,LISTFIELDARRAY,xproduct,codebuf,&uid);
        for(i=0;i<xproduct;i++) {
	    con = (data == NULL ? NULL : datalistith(data,i));
	    generator->list(generator,LISTFIELDARRAY,uid,i,codebuf);
            generate_basetype(basetype,con,codebuf,NULL,generator);
	}
        generator->listend(generator,LISTFIELDARRAY,uid,i,codebuf);
    }
}
Esempio n. 2
0
void
genbin_arraydata(Symbol* vsym, Bytebuffer* memory)
{
    Datasrc* src;
    Datalist* list;
    int i;
    int chartype = (vsym->typ.basetype->typ.typecode == NC_CHAR);
    nciter_t iter;
    Iterodom iterodom;

    if(vsym->data == NULL) return;

    if(chartype) {
        gen_chararray(vsym,memory);
	return;
    }

    list = vsym->data;
    ASSERT(list->dimdata != NULL);
    src = datalist2src(list);

    /* Create an iterator to generate blocks of data */
    nc_get_iter(vsym,databuffersize,&iter);
    nc_next_iter(&iter,iterodom.start,iterodom.count);
    iterodom.rank = vsym->typ.dimset.ndims;
    genbin_arraydatar(vsym,memory,src,iter,&iterodom,/*index=*/0)
}
Esempio n. 3
0
static void
generate_array(Symbol* vsym,
               Bytebuffer* code,
               Datalist* filler,
               Generator* generator,
	       Writer writer
              )
{
    Dimset* dimset = &vsym->typ.dimset;
    int rank = dimset->ndims;
    Symbol* basetype = vsym->typ.basetype;
    nc_type typecode = basetype->typ.typecode;
    Odometer* odom;
    nciter_t iter;

    ASSERT(rank > 0);

    /* Start by doing easy cases */

#ifdef CHARBUG
    if(typecode == NC_CHAR) { /* case: character typed variable, rank > 0 */
	Bytebuffer* charbuf = bbNew();
        gen_chararray(dimset,vsym->data,charbuf,filler);
	generator->charconstant(generator,code,charbuf);
	bbFree(charbuf);
        odom = newodometer(dimset,NULL,NULL);
        writer(generator,vsym,code,odom->rank,odom->start,odom->count);
    } else
#else /*!CHARBUG*/
    /* Case: char var && dim 1..n are not unlimited */
    if(findunlimited(dimset,1) == rank && typecode == NC_CHAR) {
	Bytebuffer* charbuf = bbNew();
	gen_leafchararray(dimset,0,vsym->data,charbuf,filler);
	generator->charconstant(generator,code,charbuf);
	bbFree(charbuf);
        odom = newodometer(dimset,NULL,NULL);
        writer(generator,vsym,code,odom->rank,odom->start,odom->count);
    } else
#endif
    /* Case 2: dim 1..n are not unlimited */
    if(findunlimited(dimset,1) == rank) {
	size_t offset = 0; /* where are we in the data list */
	size_t nelems = 0; /* # of data list items to read */
        /* Create an iterator and odometer and just walk the datalist */
        nc_get_iter(vsym,nciterbuffersize,&iter);
        odom = newodometer(dimset,NULL,NULL);
	for(;;offset+=nelems) {
	     int i,uid;
             nelems=nc_next_iter(&iter,odom->start,odom->count);
             if(nelems == 0) break;
	     bbClear(code);
             generator->listbegin(generator,LISTDATA,vsym->data->length,code,&uid);
	     for(i=0;i<nelems;i++) {
#ifdef ITERBUG
	 	Constant* con = datalistith(vsym->data,i);
#else
        NCConstant* con = datalistith(vsym->data,i+offset);
#endif
                generator->list(generator,LISTDATA,uid,i,code);
#ifdef USE_NOFILL
		if(nofill_flag && con == NULL)
		    break;
		else
#endif
                    generate_basetype(basetype,con,code,filler,generator);
 	    }
	    generator->listend(generator,LISTDATA,uid,i,code);
#ifdef USE_NOFILL
            writer(generator,vsym,code,rank,odom->start,odom->index);
#else
            writer(generator,vsym,code,rank,odom->start,odom->count);
#endif
	}
    } else

    { /* Hard case: multiple unlimited dimensions */
        /* Setup iterator and odometer */
#ifdef CHARBUG
        nc_get_iter(vsym,nciterbuffersize,&iter);
#else
	nc_get_iter(vsym,NC_MAX_UINT,&iter); /* effectively infinite */
#endif
        odom = newodometer(dimset,NULL,NULL);
	for(;;) {/* iterate in nelem chunks */
	    /* get nelems count and modify odometer */
   	    size_t nelems=nc_next_iter(&iter,odom->start,odom->count);
	    if(nelems == 0) break;
            generate_arrayr(vsym,code,vsym->data,
			    odom,
                            /*dim index=*/0,
			    filler,generator
			   );
#ifdef USE_NOFILL
            writer(generator,vsym,code,odom->rank,odom->start,odom->index);
#else
            writer(generator,vsym,code,odom->rank,odom->start,odom->count);
#endif
        }
    }
    odometerfree(odom);
}
Esempio n. 4
0
/**
The basic idea is to split the set of dimensions into groups
and iterate over each group.  A group is defined as the
range of indices starting at an unlimited dimension upto
(but not including) the next unlimited.  The first group
starts at index 0, even if dimension 0 is not unlimited.
The last group is everything from the last unlimited
dimension thru the last dimension (index rank-1).
*/
static void
generate_arrayr(Symbol* vsym,
               Bytebuffer* code,
               Datalist* list,
               Odometer* odom,
               int dimindex,
               Datalist* filler,
               Generator* generator
              )
{
    int uid,i;
    Symbol* basetype = vsym->typ.basetype;
    Dimset* dimset = &vsym->typ.dimset;
    int rank = dimset->ndims;
    int lastunlimited = findlastunlimited(dimset);
    int nextunlimited = findunlimited(dimset,dimindex+1);
    int typecode = basetype->typ.typecode;
    int islastgroup = (lastunlimited == rank || dimindex >= lastunlimited || dimindex == rank-1);
    Odometer* subodom = NULL;

    ASSERT(rank > 0);
    ASSERT((dimindex >= 0 && dimindex < rank));

    if(islastgroup) {
        /* Handle NC_CHAR case separately */
        if(typecode == NC_CHAR) {
            Bytebuffer* charbuf = bbNew();
            gen_chararray(dimset,dimindex,list,charbuf,filler);
	    generator->charconstant(generator,code,charbuf);
	    bbFree(charbuf);
	} else {
            /* build a special odometer to walk the last few dimensions */
            subodom = newsubodometer(odom,dimset,dimindex,rank);
            generator->listbegin(generator,LISTDATA,list->length,code,&uid);
            for(i=0;odometermore(subodom);i++) {
                size_t offset = odometeroffset(subodom);
                NCConstant* con = datalistith(list,offset);
                generator->list(generator,LISTDATA,uid,i,code);
                generate_basetype(basetype,con,code,filler,generator);
                odometerincr(subodom);
            }
            generator->listend(generator,LISTDATA,uid,i,code);
            odometerfree(subodom); subodom = NULL;
	}
    } else {/* !islastgroup */
        /* Our datalist must be a list of compounds representing
           the next unlimited; so walk the subarray from this index
           upto next unlimited.
        */
        ASSERT((dimindex < nextunlimited));
        ASSERT((isunlimited(dimset,nextunlimited)));
        /* build a sub odometer */
        subodom = newsubodometer(odom,dimset,dimindex,nextunlimited);
        for(i=0;odometermore(subodom);i++) {
            size_t offset = odometeroffset(subodom);
            NCConstant* con = datalistith(list,offset);
            if(con == NULL || con->nctype == NC_FILL) {
                if(filler == NULL)
                    filler = getfiller(vsym);
                generate_arrayr(vsym,code,filler,odom,nextunlimited,NULL,generator);

            } else if(islistconst(con)) {
                Datalist* sublist = compoundfor(con);
                generate_arrayr(vsym,code,sublist,odom,nextunlimited,filler,generator);
            } else {
                semerror(constline(con),"Expected {...} representing unlimited list");
                return;
            }
            odometerincr(subodom);
        }
        odometerfree(subodom); subodom = NULL;
    }
    if(subodom != NULL)
        odometerfree(subodom);
    return;
}
Esempio n. 5
0
static void
generate_array(Symbol* vsym,
               Bytebuffer* code,
               Datalist* filler,
               Generator* generator,
	       Writer writer
              )
{
    Dimset* dimset = &vsym->typ.dimset;
    int rank = dimset->ndims;
    Symbol* basetype = vsym->typ.basetype;
    nc_type typecode = basetype->typ.typecode;
    Odometer* odom = NULL;
    nciter_t iter;
    int firstunlim = findunlimited(dimset,1);
    int nunlim = countunlimited(dimset);
    int isnc3unlim = (nunlim <= 1 && (firstunlim == 0 || firstunlim == rank)); /* netcdf-3 case of at most 1 unlim in 0th dimension */

    ASSERT(rank > 0);

    if(isnc3unlim) {
        /* Handle NC_CHAR case separately */
        if(typecode == NC_CHAR) {
            Bytebuffer* charbuf = bbNew();
            gen_chararray(dimset,0,vsym->data,charbuf,filler);
	    generator->charconstant(generator,code,charbuf);
	    /* Create an odometer to get the dimension info */
            odom = newodometer(dimset,NULL,NULL);
            writer(generator,vsym,code,odom->rank,odom->start,odom->count);
//            writer(generator,vsym,code,odom->rank,0,bbLength(charbuf));
	    bbFree(charbuf);
	} else { /* typecode != NC_CHAR */
            /* Case: dim 1..rank-1 are not unlimited, dim 0 might be */
            size_t offset = 0; /* where are we in the data list */
            size_t nelems = 0; /* # of data list items to generate */
            /* Create an iterator and odometer and just walk the datalist */
            nc_get_iter(vsym,nciterbuffersize,&iter);
            odom = newodometer(dimset,NULL,NULL);
            for(;;offset+=nelems) {
                int i,uid;
                nelems=nc_next_iter(&iter,odometerstartvector(odom),odometercountvector(odom));
                if(nelems == 0)
		    break;
                bbClear(code);
                generator->listbegin(generator,LISTDATA,vsym->data->length,code,&uid);
                for(i=0;i<nelems;i++) {
                    NCConstant* con = datalistith(vsym->data,i+offset);
                    generator->list(generator,LISTDATA,uid,i,code);
                    generate_basetype(basetype,con,code,filler,generator);
                }
                generator->listend(generator,LISTDATA,uid,i,code);
                writer(generator,vsym,code,rank,odom->start,odom->count);
            }
	}
    } else { /* Hard case: multiple unlimited dimensions or unlim in dim > 0*/
        /* Setup iterator and odometer */
        nc_get_iter(vsym,NC_MAX_UINT,&iter); /* effectively infinite */
        odom = newodometer(dimset,NULL,NULL);
        for(;;) {/* iterate in nelem chunks */
            /* get nelems count and modify odometer */
            size_t nelems=nc_next_iter(&iter,odom->start,odom->count);
            if(nelems == 0) break;
            generate_arrayr(vsym,code,vsym->data,
                            odom,
                            /*dim index=*/0,
                            filler,generator
                           );
            writer(generator,vsym,code,odom->rank,odom->start,odom->count);
        }
    }
    if(odom != NULL)
        odometerfree(odom);
}
Esempio n. 6
0
void
gen_chararray(Symbol* vsym,
		Bytebuffer* databuf,
		Datasrc* src,
		Odometer* odom,
		int index)
{
    /* Assume that all dimensions from index+1 to rank-1 are !unlimited */
    int i;
    int rank = odom->rank;
    int lastdim = (index == (rank - 1)); /* last dimension*/
    int firstdim = (index == 0);
    int isunlimited = (odom->declsize[index] == NC_UNLIMITED);
    int exploded = 0;
    Constant* con;

    if(lastdim) {
	gen_chararraysuffix(vsym,databuf,src,odom,index);
	return;
    }

    ASSERT(index >= 0 && index < rank);
    odom->index[index] = odom->start[index]; /* reset */

    if(isunlimited) {
	size_t slicesize;
	Constant* con;
	if(!firstdim) {
	    if(!issublist(src)) {
		semerror(srcline(src),"Unlimited data must be enclosed in {..}");
		return;
	    }
	    srcpush(src); /* enter the unlimited data */
	}
	con=srcpeek(src);
        /* Break up the constant if it is too large */
	slicesize = odomsubarray(odom,index+1);
	if(con != NULL && con->value.stringv.len > slicesize) {
	    /* Constant is larger than just our slice */
	    /* Explode the constant into subchunks */
	    exploded = stringexplode(src,slicesize);
	}
	while((con=srcpeek(src))!=NULL) {
	    gen_chararray(vsym,databuf,src,odom,index+1);
	    odom->index[index]++;
	}
	odom->unlimitedsize[index] = odom->index[index];
	if(exploded) srcpop(src);
	if(!firstdim) srcpop(src);
    } else { /* !isunlimited*/
	size_t slicesize;
	con = srcpeek(src);
	ASSERT(!lastdim);
	/* Break up the constant if it is too large */
	slicesize = odomsubarray(odom,index+1);
	if(con != NULL && con->value.stringv.len > slicesize) {
	    /* Constant is larger than just our slice */
	    /* Explode the constant into subchunks */
	    exploded = stringexplode(src,slicesize);
	}
	for(i=0;i<odom->declsize[index];i++) {
	    gen_chararray(vsym,databuf,src,odom,index+1);
	}
	if(exploded) srcpop(src);
    }
}