Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

define uint64_t type grib_en/decode and use them #62

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/grib_accessor_class_bufr_data_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ static grib_darray* decode_double_array(grib_context* c, unsigned char* data, lo
{
grib_darray* ret = NULL;
int j;
size_t lval;
uint64_t lval;
int localReference, localWidth, modifiedWidth, modifiedReference;
double modifiedFactor, dval;
int bufr_multi_element_constant_arrays = c->bufr_multi_element_constant_arrays;
Expand All @@ -649,7 +649,7 @@ static grib_darray* decode_double_array(grib_context* c, unsigned char* data, lo
*err = 0;
return ret;
}
lval = grib_decode_size_t(data, pos, modifiedWidth);
lval = grib_decode_uint64_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=%d", localWidth);
Expand All @@ -666,7 +666,7 @@ static grib_darray* decode_double_array(grib_context* c, unsigned char* data, lo
return ret;
}
for (j = 0; j < self->numberOfSubsets; j++) {
lval = grib_decode_size_t(data, pos, localWidth);
lval = grib_decode_uint64_t(data, pos, localWidth);
if (canBeMissing && grib_is_all_bits_one(lval, localWidth)) {
dval = GRIB_MISSING_DOUBLE;
}
Expand Down Expand Up @@ -779,7 +779,7 @@ static int encode_double_array(grib_context* c, grib_buffer* buff, long* pos, bu
{
int err = 0;
int j, i;
size_t lval;
uint64_t lval;
long localReference = 0, localWidth = 0, modifiedWidth, modifiedReference;
long reference, allone;
double localRange, modifiedFactor, inverseFactor;
Expand Down Expand Up @@ -841,7 +841,7 @@ static int encode_double_array(grib_context* c, grib_buffer* buff, long* pos, bu
}
else {
lval = round(*v * inverseFactor) - modifiedReference;
grib_encode_size_tb(buff->data, lval, pos, modifiedWidth);
grib_encode_uint64_tb(buff->data, lval, pos, modifiedWidth);
}
}
grib_buffer_set_ulength_bits(c, buff, buff->ulength_bits + 6);
Expand Down Expand Up @@ -870,7 +870,7 @@ static int encode_double_array(grib_context* c, grib_buffer* buff, long* pos, bu
}
else {
lval = round(*v * inverseFactor) - modifiedReference;
grib_encode_size_tb(buff->data, lval, pos, modifiedWidth);
grib_encode_uint64_tb(buff->data, lval, pos, modifiedWidth);
}
grib_buffer_set_ulength_bits(c, buff, buff->ulength_bits + 6);
grib_encode_unsigned_longb(buff->data, localWidth, pos, 6);
Expand Down Expand Up @@ -967,7 +967,7 @@ static int encode_double_array(grib_context* c, grib_buffer* buff, long* pos, bu
}
else {
lval = localReference - modifiedReference;
grib_encode_size_tb(buff->data, lval, pos, modifiedWidth);
grib_encode_uint64_tb(buff->data, lval, pos, modifiedWidth);
}
}
grib_buffer_set_ulength_bits(c, buff, buff->ulength_bits + 6);
Expand All @@ -981,7 +981,7 @@ static int encode_double_array(grib_context* c, grib_buffer* buff, long* pos, bu
}
else {
lval = round(values[j] * inverseFactor) - reference;
grib_encode_size_tb(buff->data, lval, pos, localWidth);
grib_encode_uint64_tb(buff->data, lval, pos, localWidth);
}
}
}
Expand All @@ -994,7 +994,7 @@ static int encode_double_array(grib_context* c, grib_buffer* buff, long* pos, bu
static int encode_double_value(grib_context* c, grib_buffer* buff, long* pos, bufr_descriptor* bd,
grib_accessor_bufr_data_array* self, double value)
{
size_t lval;
uint64_t lval;
double maxAllowed, minAllowed;
int err = 0;
int modifiedWidth, modifiedReference;
Expand Down Expand Up @@ -1031,7 +1031,7 @@ static int encode_double_value(grib_context* c, grib_buffer* buff, long* pos, bu
lval = round(value / modifiedFactor) - modifiedReference;
if (c->debug)
grib_context_log(c, GRIB_LOG_DEBUG, "encode_double_value %s: value=%.15f lval=%lu\n", bd->shortName, value, lval);
grib_encode_size_tb(buff->data, lval, pos, modifiedWidth);
grib_encode_uint64_tb(buff->data, lval, pos, modifiedWidth);
}

return err;
Expand Down Expand Up @@ -1078,7 +1078,7 @@ static double decode_double_value(grib_context* c, unsigned char* data, long* po
bufr_descriptor* bd, int canBeMissing,
grib_accessor_bufr_data_array* self, int* err)
{
size_t lval;
uint64_t lval;
int modifiedWidth, modifiedReference;
double modifiedFactor;
double dval = 0;
Expand All @@ -1095,7 +1095,7 @@ static double decode_double_value(grib_context* c, unsigned char* data, long* po
return GRIB_MISSING_DOUBLE;
}

lval = grib_decode_size_t(data, pos, modifiedWidth);
lval = grib_decode_uint64_t(data, pos, modifiedWidth);
if (canBeMissing && grib_is_all_bits_one(lval, modifiedWidth)) {
dval = GRIB_MISSING_DOUBLE;
}
Expand Down
2 changes: 2 additions & 0 deletions src/grib_api_prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1536,8 +1536,10 @@ char* grib_decode_string(const unsigned char* bitStream, long* bitOffset, size_t
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);
uint64_t grib_decode_uint64_t(const unsigned char* p, long* bitp, long nbits);
int grib_encode_unsigned_longb(unsigned char* p, unsigned long val, long* bitp, long nb);
int grib_encode_size_tb(unsigned char* p, size_t val, long* bitp, long nb);
int grib_encode_uint64_tb(unsigned char* p, uint64_t val, long* bitp, long nb);


/* grib_bits_any_endian_simple.c */
Expand Down
18 changes: 12 additions & 6 deletions src/grib_bits.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,29 @@
#include "omp.h"
#endif

#define mask1(i) (1UL << i)
#define mask1(i) ((uint64_t)1 << i)
#define test(n, i) !!((n)&mask1(i))

long GRIB_MASK = -1; /* Mask of sword bits */
uint64_t GRIB_MASK = -1; /* Mask of sword bits */

#define VALUE(p, q, b) \
(((b) == max_nbits ? GRIB_MASK : ~(GRIB_MASK << (b))) & ((p) >> (max_nbits - ((q) + (b)))))
(((b) == max_nbits ? (unsigned long)GRIB_MASK : ~((unsigned long)GRIB_MASK << (b))) & ((p) >> (max_nbits - ((q) + (b)))))

#define MASKVALUE(q, b) \
((b) == max_nbits ? GRIB_MASK : (~(GRIB_MASK << (b)) << (max_nbits - ((q) + (b)))))
((b) == max_nbits ? (unsigned long)GRIB_MASK : (~((unsigned long)GRIB_MASK << (b)) << (max_nbits - ((q) + (b)))))


#define VALUE_SIZE_T(p, q, b) \
(((b) == max_nbits_size_t ? GRIB_MASK : ~(GRIB_MASK << (b))) & ((p) >> (max_nbits_size_t - ((q) + (b)))))
(((b) == max_nbits_size_t ? (size_t)GRIB_MASK : ~((size_t)GRIB_MASK << (b))) & ((p) >> (max_nbits_size_t - ((q) + (b)))))

#define MASKVALUE_SIZE_T(q, b) \
((b) == max_nbits_size_t ? GRIB_MASK : (~(GRIB_MASK << (b)) << (max_nbits_size_t - ((q) + (b)))))
((b) == max_nbits_size_t ? (size_t)GRIB_MASK : (~((size_t)GRIB_MASK << (b)) << (max_nbits_size_t - ((q) + (b)))))

#define VALUE_UINT64_T(p, q, b) \
(((b) == 64 ? GRIB_MASK : ~(GRIB_MASK << (b))) & ((p) >> (64 - ((q) + (b)))))

#define MASKVALUE_UINT64_T(q, b) \
((b) == 64 ? GRIB_MASK : (~(GRIB_MASK << (b)) << (64 - ((q) + (b)))))

static const unsigned long dmasks[] = {
0xFF,
Expand Down
93 changes: 93 additions & 0 deletions src/grib_bits_any_endian.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifdef ECCODES_ON_WINDOWS
#include <stdint.h>
#endif
#include <inttypes.h>

#if GRIB_PTHREADS
static pthread_once_t once = PTHREAD_ONCE_INIT;
Expand Down Expand Up @@ -365,6 +366,71 @@ size_t grib_decode_size_t(const unsigned char* p, long* bitp, long nbits)
return ret;
}

#define BIT_MASK_UINT64_T(x) \
(((x) == 64) ? (uint64_t)-1 : ((uint64_t)1 << (x)) - 1)

uint64_t grib_decode_uint64_t(const unsigned char* p, long* bitp, long nbits)
{
uint64_t ret = 0;
uint64_t ret_carry_up = 0;
long oc = *bitp / 8;
uint64_t mask = 0;
long pi = 0;
int usefulBitsInByte = 0;
long bitsToRead = 0;

if (nbits == 0)
return 0;

if (nbits > 64) {
int bits = nbits;
int mod = bits % 64;

if (mod != 0) {
int e = grib_decode_uint64_t(p, bitp, mod);
Assert(e == 0);
bits -= mod;
}

while (bits > 64) {
int e = grib_decode_uint64_t(p, bitp, 64);
Assert(e == 0);
bits -= 64;
}

return grib_decode_uint64_t(p, bitp, bits);
}

mask = BIT_MASK_UINT64_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_carry_up <<= 8;
ret_carry_up |= (ret >> (64-8));
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;
if (bitsToRead < 0) ret |= (ret_carry_up << (64 - (-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;
Expand Down Expand Up @@ -421,6 +487,33 @@ int grib_encode_size_tb(unsigned char* p, size_t val, long* bitp, long nb)
return GRIB_SUCCESS;
}

int grib_encode_uint64_tb(unsigned char* p, uint64_t val, long* bitp, long nb)
{
long i = 0;

if (nb > 64) {
fprintf(stderr, "Number of bits (%ld) exceeds maximum number of bits (%d)\n", nb, 64);
Assert(0);
}
#ifdef DEBUG
{
uint64_t maxV = grib_power(nb, 2);
if (val > maxV) {
fprintf(stderr, "grib_encode_uint64_tb: Value=%"PRIu64", but number of bits=%"PRIu64"!\n", val, nb);
Assert(0);
}
}
#endif
for (i = nb - 1; i >= 0; i--) {
if (test(val, i))
grib_set_bit_on(p, bitp);
else
grib_set_bit_off(p, bitp);
}
return GRIB_SUCCESS;
}


#if OMP_PACKING
#include "grib_bits_any_endian_omp.c"
#elif VECTOR
Expand Down
70 changes: 70 additions & 0 deletions src/grib_bits_fast_big_endian.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,37 @@ size_t grib_decode_size_t(const unsigned char* p, long* bitp, long nbits)
return val;
}

uint64_t grib_decode_uint64_t(const unsigned char* p, long* bitp, long nbits)
{
long countOfLeftmostBits = 0, leftmostBits = 0;
long startBit = *bitp;
long remainingBits = nbits;
long* pp = (long*)p;
uint64_t val = 0;

if (startBit >= 64) {
pp += startBit / 64;
startBit %= 64;
}

countOfLeftmostBits = startBit + remainingBits;
if (countOfLeftmostBits > 64) {
countOfLeftmostBits = 64 - startBit;
remainingBits -= countOfLeftmostBits;
leftmostBits = (VALUE_UINT64_T(*pp, startBit, countOfLeftmostBits)) << remainingBits;
startBit = 0;
pp++;
}
else
leftmostBits = 0;

val = leftmostBits + (VALUE_UINT64_T(*pp, startBit, remainingBits));

*bitp += nbits;

return val;
}

int grib_encode_unsigned_long(unsigned char* p, unsigned long val, long* bitp, long nbits)
{
long* destination = (long*)p;
Expand Down Expand Up @@ -249,11 +280,50 @@ int grib_encode_size_t(unsigned char* p, size_t val, long* bitp, long nbits)
return GRIB_SUCCESS;
}

int grib_encode_uint64_t(unsigned char* p, uint64_t val, long* bitp, long nbits)
{
long* destination = (long*)p;
long countOfLeftmostBits = 0, nextWord = 0, startBit = 0, remainingBits = 0, rightmostBits = 0;

startBit = *bitp;
remainingBits = nbits;

if (startBit >= 64) {
nextWord = startBit / 64;
startBit %= 64;
}
else
nextWord = 0;

countOfLeftmostBits = startBit + remainingBits;
if (countOfLeftmostBits > 64) {
countOfLeftmostBits = 64 - startBit;
startBit = 64 - remainingBits;
remainingBits -= countOfLeftmostBits;
destination[nextWord] =
((destination[nextWord] >> countOfLeftmostBits) << countOfLeftmostBits) + (VALUE_UINT64_T(val, startBit, countOfLeftmostBits));
startBit = 0;
nextWord++;
}

rightmostBits = VALUE_UINT64_T(val, 64 - remainingBits, remainingBits);
destination[nextWord] =
(destination[nextWord] & ~MASKVALUE_UINT64_T(startBit, remainingBits)) + (rightmostBits << 64 - (remainingBits + startBit));

*bitp += nbits;
return GRIB_SUCCESS;
}

int grib_encode_size_tb(unsigned char* p, size_t val, long* bitp, long nbits)
{
return grib_encode_size_t(p, val, bitp, nbits);
}

int grib_encode_uint64_tb(unsigned char* p, uint64_t val, long* bitp, long nbits)
{
return grib_encode_uint64_t(p, val, bitp, nbits);
}


#if VECTOR
#include "grib_bits_fast_big_endian_vector.c" /* Experimental */
Expand Down