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