Windows: BUFR decoding

This commit is contained in:
Shahram Najm 2019-12-17 14:34:56 +00:00
parent 530855ecfe
commit b4b287aa6e
4 changed files with 74 additions and 5 deletions

View File

@ -606,7 +606,7 @@ static grib_darray* decode_double_array(grib_context* c,unsigned char* data,long
{
grib_darray* ret=NULL;
int j;
unsigned long lval;
size_t lval;
int localReference,localWidth,modifiedWidth,modifiedReference;
double modifiedFactor,dval;
int bufr_multi_element_constant_arrays = c->bufr_multi_element_constant_arrays;
@ -627,7 +627,7 @@ static grib_darray* decode_double_array(grib_context* c,unsigned char* data,long
*err=0;
return ret;
}
lval=grib_decode_unsigned_long(data,pos,modifiedWidth);
lval=grib_decode_size_t(data,pos,modifiedWidth);
localReference=(long)lval+modifiedReference;
localWidth=grib_decode_unsigned_long(data,pos,6);
grib_context_log(c, GRIB_LOG_DEBUG,"BUFR data decoding: \tlocalWidth=%ld",localWidth);
@ -644,7 +644,7 @@ static grib_darray* decode_double_array(grib_context* c,unsigned char* data,long
return ret;
}
for (j=0;j<self->numberOfSubsets;j++) {
lval=grib_decode_unsigned_long(data,pos,localWidth);
lval=grib_decode_size_t(data,pos,localWidth);
if (grib_is_all_bits_one(lval,localWidth) && canBeMissing) {
dval=GRIB_MISSING_DOUBLE;
} else {
@ -1012,7 +1012,7 @@ static double decode_double_value(grib_context* c,unsigned char* data,long* pos,
bufr_descriptor* bd,int canBeMissing,
grib_accessor_bufr_data_array* self,int* err)
{
unsigned long lval;
size_t lval;
int modifiedWidth,modifiedReference;
double modifiedFactor;
double dval=0;
@ -1026,7 +1026,7 @@ static double decode_double_value(grib_context* c,unsigned char* data,long* pos,
CHECK_END_DATA_RETURN(c, self, modifiedWidth, 0);
if (*err) {*err=0; return GRIB_MISSING_DOUBLE;}
lval=grib_decode_unsigned_long(data,pos,modifiedWidth);
lval=grib_decode_size_t(data,pos,modifiedWidth);
if (grib_is_all_bits_one(lval,modifiedWidth) && canBeMissing) {
dval=GRIB_MISSING_DOUBLE;
} else {

View File

@ -1552,6 +1552,7 @@ int grib_encode_string(unsigned char *bitStream, long *bitOffset, size_t numberO
char *grib_decode_string(const unsigned char *bitStream, long *bitOffset, size_t numberOfCharacters, char *string);
unsigned long grib_decode_unsigned_long(const unsigned char *p, long *bitp, long nbits);
int grib_encode_unsigned_long(unsigned char *p, unsigned long val, long *bitp, long nbits);
size_t grib_decode_size_t(const unsigned char* p, long* bitp, long nbits);
int grib_encode_unsigned_longb(unsigned char *p, unsigned long val, long *bitp, long nb);
/* grib_bits_any_endian_simple.c */

View File

@ -33,6 +33,7 @@ long GRIB_MASK = -1; /* Mask of sword bits */
static const unsigned long dmasks[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, };
static const int max_nbits = sizeof(unsigned long)*8;
static const int max_nbits_size_t = sizeof(size_t)*8;
unsigned long grib_decode_unsigned_byte_long(const unsigned char* p, long o, int l)
{

View File

@ -298,6 +298,73 @@ int grib_encode_unsigned_long(unsigned char* p, unsigned long val ,long *bitp, l
return GRIB_SUCCESS;
}
/*
* Note: On x64 Micrsoft Windows a "long" is 32 bits but "size_t" is 64 bits
*/
#define BIT_MASK_SIZE_T(x) \
(((x) == max_nbits_size_t) ? \
(size_t) -1UL : (1UL << (x)) - 1)
size_t grib_decode_size_t(const unsigned char* p, long *bitp, long nbits)
{
size_t ret = 0;
long oc = *bitp / 8;
size_t mask = 0;
long pi = 0;
int usefulBitsInByte = 0;
long bitsToRead = 0;
if (nbits == 0) return 0;
if (nbits > max_nbits_size_t)
{
int bits = nbits;
int mod = bits % max_nbits_size_t;
if (mod != 0)
{
int e = grib_decode_size_t(p, bitp, mod);
Assert(e == 0);
bits -= mod;
}
while (bits > max_nbits_size_t)
{
int e = grib_decode_size_t(p, bitp, max_nbits_size_t);
Assert(e == 0);
bits -= max_nbits_size_t;
}
return grib_decode_size_t(p, bitp, bits);
}
mask = BIT_MASK_SIZE_T(nbits);
/* pi: position of bitp in p[]. >>3 == /8 */
pi = oc;
/* number of useful bits in current byte */
usefulBitsInByte = 8 - (*bitp & 7);
/* read at least enough bits (byte by byte) from input */
bitsToRead = nbits;
while (bitsToRead > 0) {
ret <<= 8;
/* ret += p[pi]; */
DebugAssert((ret & p[pi]) == 0);
ret = ret | p[pi];
pi++;
bitsToRead -= usefulBitsInByte;
usefulBitsInByte = 8;
}
*bitp += nbits;
/* bitsToRead might now be negative (too many bits read) */
/* remove those which are too much */
ret >>= -1 * bitsToRead;
/* remove leading bits (from previous value) */
ret &= mask;
return ret;
}
int grib_encode_unsigned_longb(unsigned char* p, unsigned long val ,long *bitp, long nb)
{
long i = 0;