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