Asha
Asha

Reputation: 4361

Convert unknow Bits from Byte array to int

private int bitToIntParser
(byte[] recordData, int byteOffset, int byteLength, int bitOffset, int bitLength)
        {
            //step1:Byte[] selectedBytes = recordData[byteOffset to byteOffset + Length]  
            //step2:BitArray selectedBits=selectdBytes.bits[bitOffset to bitOffset+bitLength]
            //step3:convert selectedBit to Int          
        }

The above function should be able to extract bytes[byteOffset] to bytes[byteOffset+length] from recordData and then extract bit[bitOffset] to bit[bitOffset+BitLength] from the previous result and convert it to int.

Can any one please help me with this?

Upvotes: 1

Views: 1104

Answers (2)

Adam Robinson
Adam Robinson

Reputation: 185703

Wow, this has turned into some very messy code. We'll have to do the bit shifting manually, since you could potentially involve more than four bytes in this operation depending upon your bit location. Assuming little endian byte order (LSB first):

// No need for byte length, since you're passing in a bit count
private int ParseByteArray(byte[] recordData, int offset, int bitOffset, 
       int bitCount)
{
    if(bitCount < 1 || bitCount > 32) 
    {
        throw new ArgumentException("bitCount must be between 1 and 32");
    }

     int output = 0;
    int byteCount = 0;

    byte rightMask = (byte)(((1 << bitOffset) - 1) << (8 - bitOffset));
    byte leftMask = (byte)(255 ^ rightMask);

    while (bitCount > 0)
    {
        byte data = (byte)(((recordData[offset] & leftMask) << bitOffset) + 
                    ((bitCount > 8 - bitOffset ? 
                    ((recordData[offset + 1] & rightMask) >> (8 - bitOffset)) 
                    : 0)));

        if (bitCount < 8)
        {
            byte mask = (byte)(255^((1 << (8 - bitCount)) - 1));

            data = (byte)((data & mask) >> (8 - bitCount));
        }

        offset++;

        output += data << (byteCount * 8);

        byteCount++;

        bitCount -= Math.Min(bitCount, 8);
    }

    return output;
}

Upvotes: 2

Henk Holterman
Henk Holterman

Reputation: 273864

It seems to me that the byteLength and bitLength are redundant (the offsets too).

But as it stands, I would say:

  • make an 8 byte intermediate array
  • copy byteLength bytes (1..4) to that array, probably from offset 7-byteLength
  • use BitConvertor.ToInt64() to turn it into a long
  • value = (int) (longValue >> bitOffset)

This still has open ends (do you expect signed or unsigned int32's ? )

I didn't test this, you may have endian issues as well.

Upvotes: 1

Related Questions