blob: ca4a849c3f7d0fc1a5c6314da8054fc1a7c48ae9 [file] [log] [blame]
#include "bej_common.h"
uint64_t bejGetUnsignedInteger(const uint8_t* bytes, uint8_t numOfBytes)
{
uint64_t num = 0;
for (uint8_t i = 0; i < numOfBytes; ++i)
{
num |= (uint64_t)(*(bytes + i)) << (i * 8);
}
return num;
}
uint64_t bejGetNnint(const uint8_t* nnint)
{
// In nnint, first byte indicate how many bytes are there. Remaining bytes
// represent the value in little-endian format.
const uint8_t size = *nnint;
return bejGetUnsignedInteger(nnint + sizeof(uint8_t), size);
}
uint8_t bejGetNnintSize(const uint8_t* nnint)
{
// In nnint, first byte indicate how many bytes are there.
return *nnint + sizeof(uint8_t);
}
uint8_t bejIntLengthOfValue(int64_t val)
{
// Only need to encode 0x00 or 0xFF
if (val == 0 || val == -1)
{
return 1;
}
// Starts at the MSB. LSB index is 0.
uint8_t byteIndex = sizeof(uint64_t) - 1;
const uint8_t bitsPerByte = 8;
// The current byte being looked at. Starts at MSB.
uint8_t currentByte = (val >> (bitsPerByte * byteIndex)) & 0xFF;
uint8_t byteLength = sizeof(int64_t);
while ((val > 0 && currentByte == 0) || (val < 0 && currentByte == 0xFF))
{
byteLength--;
byteIndex--;
currentByte = (val >> (bitsPerByte * byteIndex)) & 0xFF;
}
// If the value is positive and encoded MSBbit is 1 we need to add 0x00 to
// the encoded value as padding.
if (val > 0 && (currentByte & 0x80))
{
byteLength++;
}
// If the value is negative and encoded MSBbit is 0 we need to add 0xFF to
// the encoded value as padding.
if (val < 0 && !(currentByte & 0x80))
{
byteLength++;
}
return byteLength;
}
uint8_t bejNnintEncodingSizeOfUInt(uint64_t val)
{
uint8_t bytes = 0;
do
{
// Even if the value is 0, we need a byte for that.
++bytes;
val = val >> 8;
} while (val != 0);
// Need 1 byte to add the nnint length.
return bytes + 1;
}
uint8_t bejNnintLengthFieldOfUInt(uint64_t val)
{
// From the size of the encoded value, we need 1 byte for the length field.
return bejNnintEncodingSizeOfUInt(val) - 1;
}