1 #include "bej_common.h" 2 3 uint64_t bejGetUnsignedInteger(const uint8_t* bytes, uint8_t numOfBytes) 4 { 5 uint64_t num = 0; 6 for (uint8_t i = 0; i < numOfBytes; ++i) 7 { 8 num |= (uint64_t)(*(bytes + i)) << (i * 8); 9 } 10 return num; 11 } 12 13 uint64_t bejGetNnint(const uint8_t* nnint) 14 { 15 // In nnint, first byte indicate how many bytes are there. Remaining bytes 16 // represent the value in little-endian format. 17 const uint8_t size = *nnint; 18 return bejGetUnsignedInteger(nnint + sizeof(uint8_t), size); 19 } 20 21 uint8_t bejGetNnintSize(const uint8_t* nnint) 22 { 23 // In nnint, first byte indicate how many bytes are there. 24 return *nnint + sizeof(uint8_t); 25 } 26 27 uint8_t bejIntLengthOfValue(int64_t val) 28 { 29 // Only need to encode 0x00 or 0xFF 30 if (val == 0 || val == -1) 31 { 32 return 1; 33 } 34 35 // Starts at the MSB. LSB index is 0. 36 uint8_t byteIndex = sizeof(uint64_t) - 1; 37 const uint8_t bitsPerByte = 8; 38 // The current byte being looked at. Starts at MSB. 39 uint8_t currentByte = (val >> (bitsPerByte * byteIndex)) & 0xFF; 40 uint8_t byteLength = sizeof(int64_t); 41 42 while ((val > 0 && currentByte == 0) || (val < 0 && currentByte == 0xFF)) 43 { 44 byteLength--; 45 byteIndex--; 46 currentByte = (val >> (bitsPerByte * byteIndex)) & 0xFF; 47 } 48 49 // If the value is positive and encoded MSBbit is 1 we need to add 0x00 to 50 // the encoded value as padding. 51 if (val > 0 && (currentByte & 0x80)) 52 { 53 byteLength++; 54 } 55 56 // If the value is negative and encoded MSBbit is 0 we need to add 0xFF to 57 // the encoded value as padding. 58 if (val < 0 && !(currentByte & 0x80)) 59 { 60 byteLength++; 61 } 62 63 return byteLength; 64 } 65 66 uint8_t bejNnintEncodingSizeOfUInt(uint64_t val) 67 { 68 uint8_t bytes = 0; 69 do 70 { 71 // Even if the value is 0, we need a byte for that. 72 ++bytes; 73 val = val >> 8; 74 } while (val != 0); 75 // Need 1 byte to add the nnint length. 76 return bytes + 1; 77 } 78 79 uint8_t bejNnintLengthFieldOfUInt(uint64_t val) 80 { 81 // From the size of the encoded value, we need 1 byte for the length field. 82 return bejNnintEncodingSizeOfUInt(val) - 1; 83 } 84