| #include "dynamic_depth/item.h" |
| |
| #include "android-base/logging.h" |
| #include "dynamic_depth/const.h" |
| |
| using ::dynamic_depth::xmpmeta::xml::Deserializer; |
| using ::dynamic_depth::xmpmeta::xml::Serializer; |
| |
| namespace dynamic_depth { |
| namespace { |
| |
| constexpr char kNamespaceHref[] = "http://ns.google.com/photos/dd/1.0/item/"; |
| |
| constexpr char kMime[] = "Mime"; |
| constexpr char kLength[] = "Length"; |
| constexpr char kPadding[] = "Padding"; |
| constexpr char kDataUri[] = "DataURI"; |
| |
| } // namespace |
| |
| // Private constructor. |
| Item::Item(const ItemParams& params) : params_(params) {} |
| |
| // Private instantiator. |
| |
| std::unique_ptr<Item> Item::FromDataInternal(const ItemParams& params, |
| bool check_filepath) { |
| if (check_filepath && params.length != params.payload_to_serialize.size()) { |
| LOG(ERROR) << "Length does not match payload's size"; |
| return nullptr; |
| } |
| |
| if (params.mime.empty()) { |
| LOG(ERROR) << "Mime is empty"; |
| return nullptr; |
| } |
| |
| if (params.length < 0) { |
| LOG(ERROR) << "Item length must be non-negative"; |
| return nullptr; |
| } |
| |
| if (params.padding > 0 && |
| static_cast<int>(params.length - params.padding) <= 0) { |
| LOG(ERROR) << "Item length must be larger than padding; found padding=" |
| << params.padding << ", length=" << params.length; |
| return nullptr; |
| } |
| |
| // TODO(miraleung): Check for only supported mime types? |
| |
| return std::unique_ptr<Item>(new Item(params)); // NOLINT |
| } |
| |
| void Item::GetNamespaces(std::unordered_map<string, string>* ns_name_href_map) { |
| if (ns_name_href_map == nullptr) { |
| LOG(ERROR) << "Namespace list or own namespace is null"; |
| return; |
| } |
| |
| ns_name_href_map->emplace(DynamicDepthConst::Item(), kNamespaceHref); |
| } |
| |
| std::unique_ptr<Item> Item::FromData(const ItemParams& params) { |
| return FromDataInternal(params, true); |
| } |
| |
| std::unique_ptr<Item> Item::FromDeserializer( |
| const Deserializer& parent_deserializer) { |
| std::unique_ptr<Deserializer> deserializer = |
| parent_deserializer.CreateDeserializer( |
| DynamicDepthConst::Namespace(DynamicDepthConst::Item()), |
| DynamicDepthConst::Item()); |
| if (deserializer == nullptr) { |
| return nullptr; |
| } |
| |
| string mime; |
| int length; |
| int padding = 0; |
| string data_uri; |
| |
| if (!deserializer->ParseString(DynamicDepthConst::Item(), kMime, &mime) || |
| !deserializer->ParseInt(DynamicDepthConst::Item(), kLength, &length)) { |
| return nullptr; |
| } |
| |
| deserializer->ParseInt(DynamicDepthConst::Item(), kPadding, &padding); |
| deserializer->ParseString(DynamicDepthConst::Item(), kDataUri, &data_uri); |
| |
| ItemParams params(mime, length); |
| if (!data_uri.empty()) { |
| params.data_uri = data_uri; |
| } |
| if (padding > 0) { |
| params.padding = padding; |
| } |
| |
| return Item::FromDataInternal(params, false); |
| } |
| |
| // Getters. |
| const string& Item::GetMime() const { return params_.mime; } |
| unsigned int Item::GetLength() const { return params_.length; } |
| const string& Item::GetDataUri() const { return params_.data_uri; } |
| unsigned int Item::GetPadding() const { return params_.padding; } |
| const string& Item::GetPayloadToSerialize() const { |
| return params_.payload_to_serialize; |
| } |
| |
| bool Item::Serialize(Serializer* serializer) const { |
| if (serializer == nullptr) { |
| LOG(ERROR) << "Serializer is null"; |
| return false; |
| } |
| |
| // No error-checking for the mime or length here, since it's assumed to be |
| // taken care of in the instantiator. |
| bool success = serializer->WriteProperty(DynamicDepthConst::Item(), kMime, |
| params_.mime) && |
| serializer->WriteProperty(DynamicDepthConst::Item(), kLength, |
| std::to_string(params_.length)); |
| if (!params_.data_uri.empty()) { |
| success &= serializer->WriteProperty(DynamicDepthConst::Item(), kDataUri, |
| params_.data_uri); |
| } |
| |
| if (params_.padding > 0) { |
| success &= serializer->WriteProperty(DynamicDepthConst::Item(), kPadding, |
| std::to_string(params_.padding)); |
| } |
| |
| return success; |
| } |
| |
| } // namespace dynamic_depth |