#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; }