mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-01-12 15:45:21 +08:00
fix discovered bug in opaque data handling
This commit is contained in:
parent
c39c006039
commit
766b45b459
@ -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 ;
|
||||||
}
|
}
|
||||||
|
@ -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 ;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
11
ncgen/cvt.c
11
ncgen/cvt.c
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
828
ncgen/ncgentab.c
828
ncgen/ncgentab.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user