fix discovered bug in opaque data handling

This commit is contained in:
Dennis Heimbigner 2012-05-04 19:22:30 +00:00
parent c39c006039
commit 766b45b459
8 changed files with 509 additions and 503 deletions

View File

@ -1,13 +1,17 @@
netcdf ref_tst_opaque_data { netcdf ref_tst_opaque_data {
types: types:
opaque(11) raw_obs_t ; opaque(10) raw_obs_t ;
opaque(3) raw_obs2_t ;
dimensions: dimensions:
time = 5 ; time = 5 ;
variables: variables:
raw_obs_t raw_obs(time) ; raw_obs_t raw_obs(time) ;
raw_obs_t raw_obs:_FillValue = 0XCAFEBABECAFEBABECAFEBA ; raw_obs_t raw_obs:_FillValue = 0XCAFEBABECAFEBABECAF ;
raw_obs2_t raw_obs2(time) ;
raw_obs2_t raw_obs2:_FillValue = 0XABC;
data: data:
raw_obs = 0X0102030405060708090A0B, 0XAABBCCDDEEFFEEDDCCBBAA, raw_obs = 0X02030405060708090A0B, 0XAABBCCDDEEFFEEDDC,
0XFFFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACADE ; 0XFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACA ;
raw_obs2 = 0X123, _, 0XFFF, _, 0X357 ;
} }

View File

@ -1,13 +1,18 @@
netcdf ref_tst_opaque_data { netcdf ref_tst_opaque_data {
types: types:
opaque(11) raw_obs_t ; opaque(10) raw_obs_t ;
opaque(3) raw_obs2_t ;
dimensions: dimensions:
time = 5 ; time = 5 ;
variables: variables:
raw_obs_t raw_obs(time) ; raw_obs_t raw_obs(time) ;
raw_obs_t raw_obs:_FillValue = 0XCAFEBABECAFEBABECAFEBA ; raw_obs_t raw_obs:_FillValue = 0XCAFEBABECAFEBABECAF0 ;
raw_obs2_t raw_obs2(time) ;
raw_obs2_t raw_obs2:_FillValue = 0XABC000 ;
data: data:
raw_obs = 0X0102030405060708090A0B, 0XAABBCCDDEEFFEEDDCCBBAA, raw_obs = 0X02030405060708090A0B, 0XAABBCCDDEEFFEEDDC000,
0XFFFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACADE ; 0XFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACA ;
raw_obs2 = 0X123000, _, 0XFFF000, _, 0X357000 ;
} }

View File

@ -34,6 +34,7 @@ bin_constant(Generator* generator, Constant* con, Bytebuffer* buf,...)
case NC_OPAQUE: { case NC_OPAQUE: {
unsigned char* bytes; unsigned char* bytes;
size_t len; size_t len;
/* Assume the opaque string has been normalized */
bytes=makebytestring(con->value.opaquev.stringv,&len); bytes=makebytestring(con->value.opaquev.stringv,&len);
bbAppendn(buf,(void*)bytes,len); bbAppendn(buf,(void*)bytes,len);
} break; } break;

View File

@ -49,7 +49,6 @@ convert1(Constant* src, Constant* dst)
} }
if(src->nctype == NC_OPAQUE) { if(src->nctype == NC_OPAQUE) {
ASSERT(src->value.opaquev.len >= 16);
bytes = makebytestring(src->value.opaquev.stringv,&bytelen); bytes = makebytestring(src->value.opaquev.stringv,&bytelen);
} }
@ -524,7 +523,8 @@ case CASE(NC_OPAQUE,NC_DOUBLE):
tmp.doublev = *(double*)bytes; tmp.doublev = *(double*)bytes;
break; break;
case CASE(NC_OPAQUE,NC_OPAQUE): case CASE(NC_OPAQUE,NC_OPAQUE):
tmp.opaquev.stringv = nulldup(src->value.opaquev.stringv); tmp.opaquev.stringv = (char*)malloc(src->value.opaquev.len);
memcpy(tmp.opaquev.stringv,src->value.opaquev.stringv,src->value.opaquev.len);
tmp.opaquev.len = src->value.opaquev.len; tmp.opaquev.len = src->value.opaquev.len;
break; break;
@ -543,6 +543,7 @@ case CASE(NC_OPAQUE,NC_OPAQUE):
dst->value = tmp; dst->value = tmp;
} }
#ifdef IGNORE
/* Force an Opaque or string to conform to a given length*/ /* Force an Opaque or string to conform to a given length*/
void void
setprimlength(Constant* prim, unsigned long len) setprimlength(Constant* prim, unsigned long len)
@ -565,15 +566,16 @@ setprimlength(Constant* prim, unsigned long len)
prim->value.stringv.len = len; prim->value.stringv.len = len;
} }
} else if(prim->nctype == NC_OPAQUE) { } else if(prim->nctype == NC_OPAQUE) {
/* Note that expansion/contraction is in terms of whole
bytes = 2 nibbles */
ASSERT((len % 2) == 0);
if(prim->value.opaquev.len == len) { if(prim->value.opaquev.len == len) {
/* do nothing*/ /* do nothing*/
} else if(prim->value.opaquev.len > len) { /* truncate*/ } else if(prim->value.opaquev.len > len) { /* truncate*/
if((len % 2) != 0) len--;
prim->value.opaquev.stringv[len] = '\0'; prim->value.opaquev.stringv[len] = '\0';
prim->value.opaquev.len = len; prim->value.opaquev.len = len;
} else {/* prim->value.opaquev.len < len => expand*/ } else {/* prim->value.opaquev.len < len => expand*/
char* s; char* s;
if((len % 2) != 0) len++;
s = (char*)emalloc(len+1); s = (char*)emalloc(len+1);
memset(s,'0',len); memset(s,'0',len);
memcpy(s,prim->value.opaquev.stringv,prim->value.opaquev.len); memcpy(s,prim->value.opaquev.stringv,prim->value.opaquev.len);
@ -584,6 +586,7 @@ setprimlength(Constant* prim, unsigned long len)
} }
} }
} }
#endif
Datalist* Datalist*
convertstringtochars(Constant* str) convertstringtochars(Constant* str)

View File

@ -80,6 +80,7 @@ generate_vardata(Symbol* vsym, Generator* generator, Writer writer, Bytebuffer*
Dimset* dimset = &vsym->typ.dimset; Dimset* dimset = &vsym->typ.dimset;
int rank = dimset->ndims; int rank = dimset->ndims;
Symbol* basetype = vsym->typ.basetype; Symbol* basetype = vsym->typ.basetype;
Datalist* filler = getfiller(vsym);
if(vsym->data == NULL) return; if(vsym->data == NULL) return;
@ -88,10 +89,10 @@ generate_vardata(Symbol* vsym, Generator* generator, Writer writer, Bytebuffer*
if(rank == 0) {/*scalar case*/ if(rank == 0) {/*scalar case*/
Constant* c0 = datalistith(vsym->data,0); Constant* c0 = datalistith(vsym->data,0);
generate_basetype(basetype,c0,code,NULL,generator); generate_basetype(basetype,c0,code,filler,generator);
writer(generator,vsym,code,0,NULL,NULL); writer(generator,vsym,code,0,NULL,NULL);
} else {/*rank > 0*/ } else {/*rank > 0*/
generate_array(vsym,code,NULL,generator,writer); generate_array(vsym,code,filler,generator,writer);
} }
} }
@ -277,6 +278,8 @@ generate_arrayr(Symbol* vsym,
break; break;
#endif #endif
if(con == NULL || con->nctype == NC_FILL) { if(con == NULL || con->nctype == NC_FILL) {
if(filler == NULL)
filler = getfiller(vsym);
generate_arrayr(vsym,code,filler,odom,nextunlimited,NULL,generator); generate_arrayr(vsym,code,filler,odom,nextunlimited,NULL,generator);
} else if(!islistconst(con)) } else if(!islistconst(con))
@ -418,6 +421,35 @@ generate_fieldarray(Symbol* basetype, Constant* con, Dimset* dimset,
} }
} }
/* An opaque string value might not conform
to the size of the opaque to which it is being
assigned. Normalize it to match the required
opaque length (in bytes).
Note that the string is a sequence of nibbles (4 bits).
*/
static void
normalizeopaquelength(Constant* prim, unsigned long nbytes)
{
int nnibs = 2*nbytes;
ASSERT(prim->nctype==NC_OPAQUE);
if(prim->value.opaquev.len == nnibs) {
/* do nothing*/
} else if(prim->value.opaquev.len > nnibs) { /* truncate*/
prim->value.opaquev.stringv[nnibs] = '\0';
prim->value.opaquev.len = nnibs;
} else {/* prim->value.opaquev.len < nnibs => expand*/
char* s;
s = (char*)emalloc(nnibs+1);
memset(s,'0',nnibs);
memcpy(s,prim->value.opaquev.stringv,prim->value.opaquev.len);
s[nnibs] = '\0';
efree(prim->value.opaquev.stringv);
prim->value.opaquev.stringv=s;
prim->value.opaquev.len = nnibs;
}
}
static void static void
generate_primdata(Symbol* basetype, Constant* prim, Bytebuffer* codebuf, generate_primdata(Symbol* basetype, Constant* prim, Bytebuffer* codebuf,
Datalist* filler, Generator* generator) Datalist* filler, Generator* generator)
@ -444,7 +476,7 @@ generate_primdata(Symbol* basetype, Constant* prim, Bytebuffer* codebuf,
semerror(constline(prim),"Conversion to enum not supported (yet)"); semerror(constline(prim),"Conversion to enum not supported (yet)");
} break; } break;
case NC_OPAQUE: case NC_OPAQUE:
setprimlength(&target,basetype->typ.size*2); normalizeopaquelength(&target,basetype->typ.size);
break; break;
default: default:
break; break;

View File

@ -931,11 +931,12 @@ makeprimitivetype(nc_type nctype)
sym->objectclass=NC_TYPE; sym->objectclass=NC_TYPE;
sym->subclass=NC_PRIM; sym->subclass=NC_PRIM;
sym->ncid = nctype; sym->ncid = nctype;
sym->typ.basetype = NULL;
sym->typ.typecode = nctype; sym->typ.typecode = nctype;
sym->typ.size = ncsize(nctype); sym->typ.size = ncsize(nctype);
sym->typ.nelems = 1; sym->typ.nelems = 1;
sym->typ.alignment = nctypealignment(nctype); sym->typ.alignment = nctypealignment(nctype);
/* Make the basetype circular so we can always ask for it */
sym->typ.basetype = sym;
sym->prefix = listnew(); sym->prefix = listnew();
return sym; return sym;
} }

File diff suppressed because it is too large Load Diff

View File

@ -439,8 +439,8 @@ makebytestring(char* s, size_t* lenp)
{ {
unsigned char* bytes; unsigned char* bytes;
unsigned char* b; unsigned char* b;
size_t slen = strlen(s); size_t slen = strlen(s); /* # nibbles */
size_t blen = slen/2; size_t blen = slen/2; /* # bytes */
int i; int i;
ASSERT((slen%2) == 0); ASSERT((slen%2) == 0);