• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "dynamic_depth/app_info.h"
2 
3 #include <memory>
4 
5 #include "android-base/logging.h"
6 #include "dynamic_depth/const.h"
7 #include "strings/numbers.h"
8 #include "xmpmeta/base64.h"
9 #include "xmpmeta/xml/utils.h"
10 
11 using ::dynamic_depth::xmpmeta::xml::Deserializer;
12 using ::dynamic_depth::xmpmeta::xml::Serializer;
13 
14 namespace dynamic_depth {
15 namespace {
16 
17 const char kPropertyPrefix[] = "AppInfo";
18 const char kVersion[] = "Version";
19 const char kApplication[] = "Application";
20 const char kItemUri[] = "ItemURI";
21 
22 const char kTextMime[] = "text/plain";
23 
24 const char kNamespaceHref[] = "http://ns.google.com/photos/dd/1.0/appinfo/";
25 
26 }  // namespace
27 
28 // Private constructor.
AppInfo()29 AppInfo::AppInfo() : application_(""), version_(""), item_uri_("") {}
30 
31 // Public methods.
GetNamespaces(std::unordered_map<string,string> * ns_name_href_map)32 void AppInfo::GetNamespaces(
33     std::unordered_map<string, string>* ns_name_href_map) {
34   if (ns_name_href_map == nullptr) {
35     LOG(ERROR) << "Namespace list or own namespace is null";
36     return;
37   }
38   ns_name_href_map->insert(
39       std::pair<string, string>(kPropertyPrefix, kNamespaceHref));
40 }
41 
FromData(const string & application,const string & version,const string & data,const string & item_uri,std::vector<std::unique_ptr<Item>> * items)42 std::unique_ptr<AppInfo> AppInfo::FromData(
43     const string& application, const string& version, const string& data,
44     const string& item_uri, std::vector<std::unique_ptr<Item>>* items) {
45   if (application.empty()) {
46     LOG(ERROR) << "No application name given";
47     return nullptr;
48   }
49 
50   if (version.empty() && item_uri.empty() && items == nullptr) {
51     LOG(ERROR) << "One of version or item_uri must be present, but neither was "
52                << "found, or items is null while version is empty";
53     return nullptr;
54   }
55 
56   if (!item_uri.empty() && items == nullptr) {
57     LOG(ERROR) << "Item URI given, but no place to store the generated item "
58                   "element; returning null";
59     return nullptr;
60   }
61 
62   if (!item_uri.empty() && data.empty()) {
63     LOG(ERROR) << "Data provided, but no item URI given";
64     return nullptr;
65   }
66 
67   // Store the data with a text/plain mimetype.
68   if (!data.empty() && !item_uri.empty() && items != nullptr) {
69     ItemParams item_params(kTextMime, data.size(), item_uri);
70     item_params.payload_to_serialize = data;
71     items->emplace_back(Item::FromData(item_params));
72   }
73 
74   std::unique_ptr<AppInfo>
75       vendor_info(std::unique_ptr<AppInfo>(new AppInfo()));  // NOLINT
76   vendor_info->application_ = application;
77   vendor_info->version_ = version;
78   vendor_info->item_uri_ = item_uri;
79   return vendor_info;
80 }
81 
FromDeserializer(const Deserializer & parent_deserializer,const string & namespace_str)82 std::unique_ptr<AppInfo> AppInfo::FromDeserializer(
83     const Deserializer& parent_deserializer, const string& namespace_str) {
84   std::unique_ptr<Deserializer> deserializer =
85       parent_deserializer.CreateDeserializer(namespace_str, kPropertyPrefix);
86   if (deserializer == nullptr) {
87     return nullptr;
88   }
89 
90   std::unique_ptr<AppInfo>
91       vendor_info(std::unique_ptr<AppInfo>(new AppInfo()));  // NOLINT
92   if (!vendor_info->ParseFields(*deserializer)) {
93     return nullptr;
94   }
95   return vendor_info;
96 }
97 
GetApplication() const98 const string& AppInfo::GetApplication() const { return application_; }
GetVersion() const99 const string& AppInfo::GetVersion() const { return version_; }
GetItemUri() const100 const string& AppInfo::GetItemUri() const { return item_uri_; }
101 
Serialize(Serializer * serializer) const102 bool AppInfo::Serialize(Serializer* serializer) const {
103   if (serializer == nullptr) {
104     LOG(ERROR) << "Serializer is null";
105     return false;
106   }
107 
108   // Write required field.
109   if (!serializer->WriteProperty(DynamicDepthConst::AppInfo(), kApplication,
110                                  application_)) {
111     return false;
112   }
113 
114   // No error checking here, because we've already done that in the instantiator
115   // and deserializer.
116   if (!version_.empty()) {
117     serializer->WriteProperty(DynamicDepthConst::AppInfo(), kVersion, version_);
118   }
119 
120   if (!item_uri_.empty()) {
121     serializer->WriteProperty(DynamicDepthConst::AppInfo(), kItemUri,
122                               item_uri_);
123   }
124   return true;
125 }
126 
127 // Private methods.
ParseFields(const Deserializer & deserializer)128 bool AppInfo::ParseFields(const Deserializer& deserializer) {
129   // Required field.
130   if (!deserializer.ParseString(DynamicDepthConst::AppInfo(), kApplication,
131                                 &application_)) {
132     return false;
133   }
134 
135   // One of the following fields must be present.
136   bool success = deserializer.ParseString(DynamicDepthConst::AppInfo(),
137                                           kVersion, &version_);
138   success |= deserializer.ParseString(DynamicDepthConst::AppInfo(), kItemUri,
139                                       &item_uri_);
140   return success;
141 }
142 
143 }  // namespace dynamic_depth
144