xref: /openbmc/libbej/src/bej_dictionary.c (revision e8946af6)
1 #include "bej_dictionary.h"
2 
3 #include <stdbool.h>
4 #include <stdio.h>
5 
6 /**
7  * @brief Get the index for a property offset. First property will be at index
8  * 0.
9  *
10  * @param[in] propertyOffset - a valid property offset.
11  * @return index of the property.
12  */
13 static uint16_t bejGetPropertyEntryIndex(uint16_t propertyOffset)
14 {
15     return (propertyOffset - bejDictGetPropertyHeadOffset()) /
16            sizeof(struct BejDictionaryProperty);
17 }
18 
19 /**
20  * @brief  Validate a property offset.
21  *
22  * @param[in] propertyOffset - offset needed to be validated.
23  * @return true if propertyOffset is a valid offset.
24  */
25 static bool bejValidatePropertyOffset(uint16_t propertyOffset)
26 {
27     // propertyOffset should be greater than or equal to first property offset.
28     if (propertyOffset < bejDictGetPropertyHeadOffset())
29     {
30         fprintf(
31             stderr,
32             "Invalid property offset. Pointing to Dictionary header data\n");
33         return false;
34     }
35 
36     // propertyOffset should be a multiple of sizeof(BejDictionaryProperty)
37     // starting from first property within the dictionary.
38     if ((propertyOffset - bejDictGetPropertyHeadOffset()) %
39         sizeof(struct BejDictionaryProperty))
40     {
41         fprintf(stderr, "Invalid property offset. Does not point to beginning "
42                         "of property\n");
43         return false;
44     }
45 
46     return true;
47 }
48 
49 uint16_t bejDictGetPropertyHeadOffset()
50 {
51     // First property is present soon after the dictionary header.
52     return sizeof(struct BejDictionaryHeader);
53 }
54 
55 uint16_t bejDictGetFirstAnnotatedPropertyOffset()
56 {
57     // The first property available is the "Annotations" set which is the parent
58     // for all properties. Next immediate property is the first property we
59     // need.
60     return sizeof(struct BejDictionaryHeader) +
61            sizeof(struct BejDictionaryProperty);
62 }
63 
64 int bejDictGetProperty(const uint8_t* dictionary,
65                        uint16_t startingPropertyOffset, uint16_t sequenceNumber,
66                        const struct BejDictionaryProperty** property)
67 {
68     uint16_t propertyOffset = startingPropertyOffset;
69     const struct BejDictionaryHeader* header =
70         (const struct BejDictionaryHeader*)dictionary;
71 
72     if (!bejValidatePropertyOffset(propertyOffset))
73     {
74         return bejErrorInvalidPropertyOffset;
75     }
76     uint16_t propertyIndex = bejGetPropertyEntryIndex(propertyOffset);
77 
78     for (uint16_t index = propertyIndex; index < header->entryCount; ++index)
79     {
80         const struct BejDictionaryProperty* p =
81             (const struct BejDictionaryProperty*)(dictionary + propertyOffset);
82         if (p->sequenceNumber == sequenceNumber)
83         {
84             *property = p;
85             return 0;
86         }
87         propertyOffset += sizeof(struct BejDictionaryProperty);
88     }
89     return bejErrorUnknownProperty;
90 }
91 
92 const char* bejDictGetPropertyName(const uint8_t* dictionary,
93                                    uint16_t nameOffset, uint8_t nameLength)
94 {
95     if (nameLength == 0)
96     {
97         return "";
98     }
99     return (const char*)(dictionary + nameOffset);
100 }
101