views:

96

answers:

2

Hi everyone,

I have a multi-byte primitive type called s32 which I want to read from a byte array.

The specifications are:

  • It is a 32-bit signed integer value, stored in little-endian order.

  • Negative integers are represented using 2's complement.

  • It uses 1 to 5 bytes depending on the magnitude. Each byte contributes its low seven bits to the value. If the high (8th) bit is set, then the next byte is also a part of the value.

  • Sign extension is applied: the seventh bit of the last byte of the encoding is propagated to fill out the 32 bits of the decoded value.

In the case of U32 - unsigned 32-bit I come up with this (any comments welcomed!) but not sure how to modify it for S32.

char temp = 0; 
u32 value = 0;
size_t index = 0;

for(int i = 0; i < 5; i++)
{
    if(i < 4)
    {
        temp  = 0x7F & buffer[index];
    }
    else
    {
        temp = 0x0F & buffer[index];
    }

    value |= temp << (7 * i);

    if(!(0x80 & buffer[index])) break;

    ++index;
}

Thanks everyone!

A: 

Are you working on a little-endian system?
If so following should do the trick.

if(!(0x80 & buffer[index])) 
{
  if(0x40 & buffer[index])  value = -value;
  break;
}

If you need the negative of a little endian value on a big endian system, then it is a bit more tricky, but that requirement would seem very strange to me

stefaanv
A: 

I posted a SIGN_EXTEND macro in an answer to this question. For your code, I'd change your u32 value to s32 value, and apply SIGN_EXTEND as

// after loop close
SIGN_EXTEND(value, index * 7, u32);

using the accepted answer for the question, you'd say:

if(value > (1 << (index * 7 - 1))
    value -= (1 << (index * 7));
Aidan Cully