diff --git a/configuration/src/hll.c b/configuration/src/hll.c index ddc6354..d4fa502 100644 --- a/configuration/src/hll.c +++ b/configuration/src/hll.c @@ -248,16 +248,39 @@ typedef struct uint32_t brc_mask; // Read mask. uint8_t const * brc_curp; // Current byte. size_t brc_used; // Used bits. + void * brc_past_end_of_bitstream; // Enable special handling of end bytes } bitstream_read_cursor_t; + static uint32_t bitstream_unpack(bitstream_read_cursor_t * brcp) { uint32_t retval; + uint64_t qw = 0; + + uint64_t * past_qw = (uint64_t *)brcp->brc_curp; + past_qw++; - // Fetch the quadword containing our data. - uint64_t qw = * (uint64_t const *) brcp->brc_curp; + /* Fetch the quadword containing our data. */ + if ((void*)past_qw <= brcp->brc_past_end_of_bitstream) + { + /* Quadword is entirely within the allocated size, so do a quadword read */ + qw = * (uint64_t const *) brcp->brc_curp; + } + else + { + /* Not enough bytes remain to do a full quadword read, so do it one byte at a time */ + uint8_t * source_byte_ptr = (uint8_t *)brcp->brc_curp; + uint8_t * target_byte_array = (uint8_t *)(&qw); + for (int k=0; k= brcp->brc_past_end_of_bitstream) + break; + target_byte_array[k] = *source_byte_ptr; + source_byte_ptr++; + } + } // Swap the bytes. qw = bswap_64(qw); @@ -353,12 +376,15 @@ sparse_unpack(compreg_t * i_regp, brc.brc_mask = (1 << chunksz) - 1; brc.brc_curp = i_bitp; brc.brc_used = 0; + brc.brc_past_end_of_bitstream = (void*)(&(i_bitp[i_size])); for (ssize_t ii = 0; ii < i_nfilled; ++ii) { - uint32_t buffer = bitstream_unpack(&brc); - uint32_t val = buffer & regmask; - uint32_t ndx = buffer >> i_width; + uint32_t buffer, val, ndx; + Assert((void*)brc.brc_curp < brc.brc_past_end_of_bitstream); + buffer = bitstream_unpack(&brc); + val = buffer & regmask; + ndx = buffer >> i_width; i_regp[ndx] = val; } }