mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-03 08:01:25 +08:00
252 lines
6.6 KiB
C
252 lines
6.6 KiB
C
/*********************************************************************
|
|
* Copyright 2009, UCAR/Unidata
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*********************************************************************/
|
|
/* $Id: jdatastd.c,v 1.2 2010/05/24 19:59:57 dmh Exp $ */
|
|
/* $Header: /upc/share/CVS/netcdf-3/ncgen/jdatastd.c,v 1.2 2010/05/24 19:59:57 dmh Exp $ */
|
|
|
|
#include "includes.h"
|
|
#include "offsets.h"
|
|
|
|
extern List* vlenconstants; /* List<Constant*>;*/
|
|
|
|
/* Forward*/
|
|
static void genjstd_primdata(Symbol*, Datasrc*, Datalist*, char*, Bytebuffer*);
|
|
static void genjstd_data(Symbol* sym, Datasrc*, Datalist*, char*, Bytebuffer*);
|
|
static void genjstd_arraydatar(Symbol* basetype,
|
|
Datasrc* src,
|
|
Odometer* odom,
|
|
Putvar* closure,
|
|
int index,
|
|
int checkpoint,
|
|
Bytebuffer* code);
|
|
|
|
/**************************************************/
|
|
/* Code for generating Java language data lists*/
|
|
/**************************************************/
|
|
/* Datalist rules: see the rules on the man page */
|
|
|
|
/* Specialty wrappers for genjstd_data */
|
|
void
|
|
genjstd_attrdata(Symbol* asym, Bytebuffer* databuf)
|
|
{
|
|
Datasrc* src;
|
|
int typecode = asym->typ.basetype->typ.typecode;
|
|
char* memname = "memory";
|
|
|
|
if(asym->data == NULL) return;
|
|
if(typecode == NC_CHAR) {
|
|
gen_charattr(asym,databuf);
|
|
} else {
|
|
src = datalist2src(asym->data);
|
|
while(srcmore(src)) {
|
|
genjstd_data(asym->typ.basetype,src,NULL,memname,databuf);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
genjstd_scalardata(Symbol* vsym, Bytebuffer* databuf)
|
|
{
|
|
Datasrc* src;
|
|
char* memname = "memory";
|
|
|
|
if(vsym->data == NULL) return;
|
|
src = datalist2src(vsym->data);
|
|
genjstd_data(vsym->typ.basetype,src,
|
|
vsym->var.special._Fillvalue,memname,databuf);
|
|
if(srcmore(src)) {
|
|
semerror(srcline(src),"Extra data at end of datalist");
|
|
}
|
|
}
|
|
|
|
void
|
|
genjstd_fillvalue(Symbol* tsym, Datalist* fillsrc, Datasrc* src,
|
|
char* memname, Bytebuffer* databuf)
|
|
{
|
|
Datalist* list = NULL;
|
|
|
|
ASSERT(tsym->objectclass == NC_TYPE);
|
|
list = fillsrc;
|
|
if(list == NULL) list = getfiller(tsym);
|
|
srcpushlist(src,list);
|
|
genjstd_data(tsym,src,NULL,memname,databuf);
|
|
srcpop(src);
|
|
}
|
|
|
|
void
|
|
genjstd_arraydata(Symbol* vsym, Putvar* closure, Bytebuffer* databuf)
|
|
{
|
|
Datasrc* src;
|
|
Datalist* list;
|
|
int i,checkpoint;
|
|
nc_type typecode = vsym->typ.basetype->typ.typecode;
|
|
|
|
if(vsym->data == NULL) return;
|
|
|
|
list = vsym->data;
|
|
ASSERT(list->dimdata != NULL);
|
|
|
|
src = datalist2src(list);
|
|
|
|
/* Locate checkpoint */
|
|
checkpoint=0;
|
|
for(i=0;i<vsym->typ.dimset.ndims;i++) {
|
|
if(vsym->typ.dimset.dimsyms[i]->dim.size == NC_UNLIMITED) {
|
|
checkpoint = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(typecode == NC_CHAR) {
|
|
Odometer* odom = list->dimdata;
|
|
gen_chararray(vsym,closure,databuf);
|
|
/* Compute the unlimited size */
|
|
vsym->typ.dimset.dimsyms[0]->dim.unlimitedsize
|
|
= odom->dims[0].datasize;
|
|
jquotestring(databuf,'"');
|
|
} else {
|
|
genjstd_arraydatar(vsym,src,list->dimdata,closure,0,checkpoint,databuf);
|
|
vsym->typ.dimset.dimsyms[0]->dim.unlimitedsize
|
|
= list->dimdata->dims[0].datasize;
|
|
}
|
|
}
|
|
|
|
static void
|
|
genjstd_arraydatar(Symbol* vsym,
|
|
Datasrc* src,
|
|
Odometer* odom,
|
|
Putvar* closure,
|
|
int index,
|
|
int checkpoint,
|
|
Bytebuffer* databuf)
|
|
{
|
|
int i;
|
|
int rank = odom->rank;
|
|
int lastdim = (index == (rank - 1)); /* last dimension*/
|
|
int firstdim = (index == 0);
|
|
int declsize = odom->dims[index].declsize;
|
|
Symbol* basetype = vsym->typ.basetype;
|
|
Datalist* fillsrc = vsym->var.special._Fillvalue;
|
|
Constant* con;
|
|
char* memname = "memory";
|
|
int isunlimited = (declsize == 0);
|
|
|
|
ASSERT(index >= 0 && index < rank);
|
|
|
|
odom->dims[index].index = 0; /* reset*/
|
|
|
|
if(isunlimited) {
|
|
Constant* con;
|
|
if(!firstdim) {
|
|
if(!issublist(src)) {
|
|
semerror(srcline(src),"Unlimited data must be enclosed in {..}");
|
|
goto done;
|
|
}
|
|
srcpush(src); /* enter the unlimited data */
|
|
}
|
|
while((con=srcpeek(src))!=NULL) {
|
|
/* lastdim is unlimited => lastdim == firstdim */
|
|
if(lastdim) {
|
|
bbCat(databuf," ");
|
|
genjstd_primdata(basetype,src,fillsrc,memname,databuf);
|
|
} else {
|
|
genjstd_arraydatar(vsym,src,odom,closure,index+1,
|
|
checkpoint,databuf);
|
|
}
|
|
odom->dims[index].index++;
|
|
}
|
|
odom->dims[index].datasize = odom->dims[index].index;
|
|
if(!firstdim) srcpop(src);
|
|
} else { /* !isunlimited*/
|
|
for(i=0;i<declsize;i++) {
|
|
con = srcpeek(src);
|
|
if(lastdim) {
|
|
bbCat(databuf," ");
|
|
genjstd_primdata(basetype,src,fillsrc,memname,databuf);
|
|
} else { /* ! lastdim*/
|
|
(void)genjstd_arraydatar(vsym,src,odom,closure,
|
|
index+1,checkpoint,
|
|
databuf);
|
|
}
|
|
odom->dims[index].index++;
|
|
}
|
|
}
|
|
done:
|
|
return;
|
|
}
|
|
|
|
/**************************************************/
|
|
/* This is the general datalist processing procedure */
|
|
static void
|
|
genjstd_data(Symbol* tsym, Datasrc* datasrc, Datalist* fillsrc,
|
|
char* memname, Bytebuffer* databuf)
|
|
{
|
|
int iscmpd;
|
|
Constant* con = srcpeek(datasrc);
|
|
|
|
if(con == NULL || con->nctype == NC_FILLVALUE) {
|
|
srcnext(datasrc);
|
|
genjstd_fillvalue(tsym,fillsrc,datasrc,memname,databuf);
|
|
return;
|
|
}
|
|
|
|
switch (tsym->subclass) {
|
|
|
|
case NC_PRIM:
|
|
if((iscmpd = issublist(datasrc))) {
|
|
semerror(srcline(datasrc),"Expected primitive found {..}");
|
|
srcpush(datasrc);
|
|
}
|
|
bbCat(databuf," ");
|
|
genjstd_primdata(tsym,datasrc,NULL,memname,databuf);
|
|
if(iscmpd) srcpop(datasrc);
|
|
break;
|
|
|
|
default: PANIC1("genjstd_data: unexpected subclass %d",tsym->subclass);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************/
|
|
static void
|
|
genjstd_primdata(Symbol* tsym, Datasrc* src, Datalist* filler,
|
|
char* memname, Bytebuffer* databuf)
|
|
{
|
|
Constant target, *prim;
|
|
|
|
prim = srcnext(src);
|
|
|
|
if(prim == NULL || prim->nctype == NC_FILLVALUE) {
|
|
genjstd_fillvalue(tsym,filler,src,memname,databuf);
|
|
return;
|
|
}
|
|
|
|
target.nctype = tsym->typ.typecode;
|
|
|
|
if(prim == NULL) {
|
|
#ifdef GENFILL
|
|
/* generate a fill value*/
|
|
nc_getfill(&target);
|
|
/* fall thru*/
|
|
#else
|
|
return;
|
|
#endif
|
|
}
|
|
|
|
ASSERT(prim->nctype != NC_COMPOUND);
|
|
|
|
switch (target.nctype) {
|
|
case NC_CHAR:
|
|
/* Hack to handle the char case as a string */
|
|
target = cloneconstant(prim);
|
|
break;
|
|
default:
|
|
convert1(prim,&target);
|
|
break;
|
|
}
|
|
/* add hack for java bug in converting floats */
|
|
if(target.nctype == NC_FLOAT) bbCat(databuf," (float)");
|
|
bbCat(databuf,jconst(&target));
|
|
}
|