diff --git a/Libraries/libcar/Headers/car/AttributeList.h b/Libraries/libcar/Headers/car/AttributeList.h index 3de361abc..297c30e93 100644 --- a/Libraries/libcar/Headers/car/AttributeList.h +++ b/Libraries/libcar/Headers/car/AttributeList.h @@ -75,6 +75,13 @@ class AttributeList { size_t count, uint32_t const *identifiers) const; + /* + * Write an attribute list into an a vector of bytes using the identifier + * order in keyfmt->identifiers. + */ + std::vector write( + car_key_format const *keyfmt) const; + public: /* * Print debugging information about the list. @@ -90,6 +97,14 @@ class AttributeList { uint32_t const *identifiers, uint16_t const *values); + /* + * Load an attribute list from packed struct car_key_format members and + * a car_rendition_key buffer. + */ + static AttributeList Load( + car_key_format const *keyfmt, + car_rendition_key const *values); + /* * Load an attribute list from a buffer of identifier value pairs. */ diff --git a/Libraries/libcar/Sources/AttributeList.cpp b/Libraries/libcar/Sources/AttributeList.cpp index 1aff336c3..d164b5d3c 100644 --- a/Libraries/libcar/Sources/AttributeList.cpp +++ b/Libraries/libcar/Sources/AttributeList.cpp @@ -66,6 +66,16 @@ Load(size_t count, uint32_t const *identifiers, uint16_t const *values) return AttributeList(attributes); } +AttributeList AttributeList:: +Load(car_key_format const *keyfmt, car_rendition_key const *values) +{ + std::unordered_map attributes; + for (size_t i = 0; i < keyfmt->num_identifiers; ++i) { + attributes.insert({ (enum car_attribute_identifier)keyfmt->identifier_list[i], values[i] }); + } + return AttributeList(attributes); +} + AttributeList AttributeList:: Load(size_t count, struct car_attribute_pair const *pairs) { @@ -95,3 +105,20 @@ write(size_t count, uint32_t const *identifiers) const return output; } +std::vector AttributeList:: +write(car_key_format const *keyfmt) const +{ + std::vector output = std::vector(sizeof(uint16_t) * keyfmt->num_identifiers); + uint16_t *values = reinterpret_cast(output.data()); + std::unordered_map attributes; + for (size_t i = 0; i < keyfmt->num_identifiers; ++i) { + enum car_attribute_identifier identifier = (enum car_attribute_identifier) keyfmt->identifier_list[i]; + auto result = _values.find(identifier); + if (result != _values.end()) { + values[i] = result->second; + } else { + values[i] = 0; + } + } + return output; +} diff --git a/Libraries/libcar/Sources/Reader.cpp b/Libraries/libcar/Sources/Reader.cpp index 2e39db6a1..c92cf95ae 100644 --- a/Libraries/libcar/Sources/Reader.cpp +++ b/Libraries/libcar/Sources/Reader.cpp @@ -82,7 +82,7 @@ renditionIterate(std::function const &iterator) const KeyValuePair kv = (KeyValuePair)it.second; car_rendition_key *rendition_key = (car_rendition_key *)kv.key; struct car_rendition_value *rendition_value = (struct car_rendition_value *)kv.value; - AttributeList attributes = AttributeList::Load(keyfmt->num_identifiers, keyfmt->identifier_list, rendition_key); + AttributeList attributes = AttributeList::Load(keyfmt, rendition_key); Rendition rendition = Rendition::Load(attributes, rendition_value); iterator(rendition); } @@ -264,7 +264,7 @@ lookupRenditions(Facet const &facet) const KeyValuePair value = (KeyValuePair)it->second; car_rendition_key *rendition_key = (car_rendition_key *)value.key; struct car_rendition_value *rendition_value = (struct car_rendition_value *)value.value; - AttributeList attributes = AttributeList::Load(keyfmt->num_identifiers, keyfmt->identifier_list, rendition_key); + AttributeList attributes = AttributeList::Load(keyfmt, rendition_key); Rendition rendition = Rendition::Load(attributes, rendition_value); result.push_back(rendition); } diff --git a/Libraries/libcar/Sources/Writer.cpp b/Libraries/libcar/Sources/Writer.cpp index 3bcbafd5e..400f0877b 100644 --- a/Libraries/libcar/Sources/Writer.cpp +++ b/Libraries/libcar/Sources/Writer.cpp @@ -162,7 +162,7 @@ write() const bom_tree_reserve(renditions_tree_context, rendition_count); if (renditions_tree_context != NULL) { for (auto const &item : _renditions) { - auto attributes_value = item.second.attributes().write(keyfmt->num_identifiers, keyfmt->identifier_list); + auto attributes_value = item.second.attributes().write(keyfmt); auto rendition_value = item.second.write(); bom_tree_add( renditions_tree_context,