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