xref: /openbmc/libbej/src/bej_common.c (revision 2bc745a3)
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