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 {
types:
opaque(11) raw_obs_t ;
opaque(10) raw_obs_t ;
opaque(3) raw_obs2_t ;
dimensions:
time = 5 ;
variables:
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:
raw_obs = 0X0102030405060708090A0B, 0XAABBCCDDEEFFEEDDCCBBAA,
0XFFFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACADE ;
raw_obs = 0X02030405060708090A0B, 0XAABBCCDDEEFFEEDDC,
0XFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACA ;
raw_obs2 = 0X123, _, 0XFFF, _, 0X357 ;
}

View File

@ -1,13 +1,18 @@
netcdf ref_tst_opaque_data {
types:
opaque(11) raw_obs_t ;
opaque(10) raw_obs_t ;
opaque(3) raw_obs2_t ;
dimensions:
time = 5 ;
variables:
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:
raw_obs = 0X0102030405060708090A0B, 0XAABBCCDDEEFFEEDDCCBBAA,
0XFFFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACADE ;
raw_obs = 0X02030405060708090A0B, 0XAABBCCDDEEFFEEDDC000,
0XFFFFFFFFFFFFFFFFFFFF, _, 0XCF0DEFACED0CAFE0FACA ;
raw_obs2 = 0X123000, _, 0XFFF000, _, 0X357000 ;
}

View File

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

View File

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

View File

@ -80,6 +80,7 @@ generate_vardata(Symbol* vsym, Generator* generator, Writer writer, Bytebuffer*
Dimset* dimset = &vsym->typ.dimset;
int rank = dimset->ndims;
Symbol* basetype = vsym->typ.basetype;
Datalist* filler = getfiller(vsym);
if(vsym->data == NULL) return;
@ -88,10 +89,10 @@ generate_vardata(Symbol* vsym, Generator* generator, Writer writer, Bytebuffer*
if(rank == 0) {/*scalar case*/
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);
} 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;
#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))
@ -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
generate_primdata(Symbol* basetype, Constant* prim, Bytebuffer* codebuf,
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)");
} break;
case NC_OPAQUE:
setprimlength(&target,basetype->typ.size*2);
normalizeopaquelength(&target,basetype->typ.size);
break;
default:
break;

View File

@ -931,11 +931,12 @@ makeprimitivetype(nc_type nctype)
sym->objectclass=NC_TYPE;
sym->subclass=NC_PRIM;
sym->ncid = nctype;
sym->typ.basetype = NULL;
sym->typ.typecode = nctype;
sym->typ.size = ncsize(nctype);
sym->typ.nelems = 1;
sym->typ.alignment = nctypealignment(nctype);
/* Make the basetype circular so we can always ask for it */
sym->typ.basetype = sym;
sym->prefix = listnew();
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* b;
size_t slen = strlen(s);
size_t blen = slen/2;
size_t slen = strlen(s); /* # nibbles */
size_t blen = slen/2; /* # bytes */
int i;
ASSERT((slen%2) == 0);