Fixed bitreader to work correctly for signed 64-bit integers

This commit is contained in:
Dan Hirsch 2012-05-23 01:02:31 +02:00
parent 38db7a2cf5
commit 54b0f9f7b2
2 changed files with 9 additions and 2 deletions

View file

@ -31,7 +31,7 @@ long long read_bits(input_stream_t* state, int count, char signed_p) {
long long out = 0; long long out = 0;
int offset = 0; int offset = 0;
int final_shift = 0; int final_shift = 0;
long long msb = (!!signed_p) << (count - 1); // 0 if unsigned, else 1 << (nbits - 1) long long msb = ((signed_p ? 1LL:0) << (count - 1)); // 0 if unsigned, else 1 << (nbits - 1)
// overflow check... // overflow check...
@ -120,6 +120,12 @@ long long read_bits(input_stream_t* state, int count, char signed_p) {
.endianness = endianness_ \ .endianness = endianness_ \
} }
static void test_bitreader_ints(void) {
input_stream_t is = MK_INPUT_STREAM("\xFF\xFF\xFF\xFE\x00\x00\x00\x00", 8, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN);
g_check_cmplong(read_bits(&is, 64, true), ==, -0x200000000);
}
static void test_bitreader_be(void) { static void test_bitreader_be(void) {
input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN); input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN);
g_check_cmpint(read_bits(&is, 3, false), ==, 0x03); g_check_cmpint(read_bits(&is, 3, false), ==, 0x03);
@ -165,6 +171,7 @@ void register_bitreader_tests(void) {
g_test_add_func("/core/bitreader/largebits-le", test_largebits_le); g_test_add_func("/core/bitreader/largebits-le", test_largebits_le);
g_test_add_func("/core/bitreader/offset-largebits-be", test_offset_largebits_be); g_test_add_func("/core/bitreader/offset-largebits-be", test_offset_largebits_be);
g_test_add_func("/core/bitreader/offset-largebits-le", test_offset_largebits_le); g_test_add_func("/core/bitreader/offset-largebits-le", test_offset_largebits_le);
g_test_add_func("/core/bitreader/ints", test_bitreader_ints);
} }
#endif // #ifdef INCLUDE_TESTS #endif // #ifdef INCLUDE_TESTS

View file

@ -895,7 +895,7 @@ static void test_int32(void) {
static void test_int16(void) { static void test_int16(void) {
const parser_t *int16_ = int16(); const parser_t *int16_ = int16();
g_check_parse_ok(int16_, "\xfe\x00", 2, "s0x200"); g_check_parse_ok(int16_, "\xfe\x00", 2, "s-0x200");
g_check_parse_failed(int16_, "\xfe", 1); g_check_parse_failed(int16_, "\xfe", 1);
} }