blob: a86720b60224f4e32454fbaf49c1a4d8b73059d0 [file] [log] [blame]
kasunathd073aa12022-05-12 16:08:49 -07001#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 */
13static 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 */
25static 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
49uint16_t bejDictGetPropertyHeadOffset()
50{
51 // First property is present soon after the dictionary header.
52 return sizeof(struct BejDictionaryHeader);
53}
54
55uint16_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
64int 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
92const 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}