Example #1
0
void
gen_chararray(Dimset* dimset, int dimindex, Datalist* data, Bytebuffer* charbuf, Datalist* fillsrc)
{
    int fillchar = getfillchar(fillsrc);
    int rank = rankfor(dimset);
    int firstunlim = findunlimited(dimset,0);
    int nunlim = countunlimited(dimset);
    int nc3unlim = (nunlim <= 1 && (firstunlim == 0 || firstunlim == rank)); /* netcdf-3 case of at most 1 unlim in 0th dimension */

    /* Case: netcdf3 case */
    if(nc3unlim) {
	gen_leafchararray(dimset,0,data,charbuf,fillchar);
	return;
    }

    /* else generate should have done all the hard work */
    gen_leafchararray(dimset,dimindex,data,charbuf,fillchar);
}
Example #2
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);
}
Example #3
0
static void
generate_arrayr(Symbol* vsym,
               Bytebuffer* code,
               Datalist* list,
	       Odometer* odom,
               int dimindex,
               Datalist* filler,
               Generator* generator
              )
{
    Symbol* basetype = vsym->typ.basetype;
    Dimset* dimset = &vsym->typ.dimset;
    int rank = dimset->ndims;
    int lastunlimited;
    int typecode = basetype->typ.typecode;

    lastunlimited = findlastunlimited(dimset);
    if(lastunlimited == rank) lastunlimited = 0;

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

#ifdef CHARBUG
    ASSERT(typecode != NC_CHAR);
#else /*!CHARBUG*/
    if(dimindex == lastunlimited && typecode == NC_CHAR) {
	Bytebuffer* charbuf = bbNew();
	gen_leafchararray(dimset,dimindex,list,charbuf,filler);
	generator->charconstant(generator,code,charbuf);
	bbFree(charbuf);
    } else
#endif /*!CHARBUG*/
    if(dimindex == lastunlimited) {
	int uid,i;
	Odometer* slabodom;
	/* build a special odometer to walk the last few dimensions
	   (similar to case 2 above)
	*/
        slabodom = newsubodometer(odom,dimset,dimindex,rank);
	/* compute the starting offset in our datalist
	   (Assumes that slabodom->index[i] == slabodom->start[i])
        */
        generator->listbegin(generator,LISTDATA,list->length,code,&uid);
	for(i=0;odometermore(slabodom);i++) {
	    size_t offset = odometeroffset(slabodom);
        NCConstant* con = datalistith(list,offset);
#ifdef USE_NOFILL
	    if(nofill_flag && con == NULL)
		break;
#endif
            generator->list(generator,LISTDATA,uid,i,code);
            generate_basetype(basetype,con,code,filler,generator);
	    odometerincr(slabodom);
        }
        generator->listend(generator,LISTDATA,uid,i,code);
	odometerfree(slabodom);
    } else {
        /* If we are strictly to the left of the next unlimited
           then our datalist is a list of compounds representing
           the next unlimited; so walk the subarray from this index
	   upto next unlimited.
        */
	int i;
	Odometer* slabodom;
        int nextunlimited = findunlimited(dimset,dimindex+1);
	ASSERT((dimindex < nextunlimited
                && (dimset->dimsyms[nextunlimited]->dim.isunlimited)));
	/* build a sub odometer */
        slabodom = newsubodometer(odom,dimset,dimindex,nextunlimited);
	/* compute the starting offset in our datalist
	   (Assumes that slabodom->index[i] == slabodom->start[i])
        */
	for(i=0;odometermore(slabodom);i++) {
	    size_t offset = odometeroffset(slabodom);
        NCConstant* con = datalistith(list,offset);
#ifdef USE_NOFILL
	    if(nofill_flag && con == NULL)
		break;
#endif
	    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))
	        semwarn(constline(con),"Expected {...} representing unlimited list");
	    else {
	        Datalist* sublist = con->value.compoundv;
	        generate_arrayr(vsym,code,sublist,odom,nextunlimited,filler,generator);
	    }
	    odometerincr(slabodom);
        }
	odometerfree(slabodom);
    }
    return;
}