xref: /aosp_15_r20/external/dynamic_depth/internal/dynamic_depth/container.cc (revision a62be0856e8e1158f43b03e41bbad10f4d005fde)
1*a62be085SSadaf Ebrahimi #include "dynamic_depth/container.h"
2*a62be085SSadaf Ebrahimi 
3*a62be085SSadaf Ebrahimi #include "android-base/logging.h"
4*a62be085SSadaf Ebrahimi #include "dynamic_depth/const.h"
5*a62be085SSadaf Ebrahimi #include "xmpmeta/xml/const.h"
6*a62be085SSadaf Ebrahimi 
7*a62be085SSadaf Ebrahimi using ::dynamic_depth::xmpmeta::xml::Deserializer;
8*a62be085SSadaf Ebrahimi using ::dynamic_depth::xmpmeta::xml::Serializer;
9*a62be085SSadaf Ebrahimi using ::dynamic_depth::xmpmeta::xml::XmlConst;
10*a62be085SSadaf Ebrahimi 
11*a62be085SSadaf Ebrahimi namespace dynamic_depth {
12*a62be085SSadaf Ebrahimi 
13*a62be085SSadaf Ebrahimi constexpr char kNamespaceHref[] =
14*a62be085SSadaf Ebrahimi     "http://ns.google.com/photos/dd/1.0/container/";
15*a62be085SSadaf Ebrahimi constexpr char kDirectory[] = "Directory";
16*a62be085SSadaf Ebrahimi constexpr char kResourceType[] = "Resource";
17*a62be085SSadaf Ebrahimi 
18*a62be085SSadaf Ebrahimi // Private constructor.
Container()19*a62be085SSadaf Ebrahimi Container::Container() {}
20*a62be085SSadaf Ebrahimi 
GetNamespaces(std::unordered_map<string,string> * ns_name_href_map)21*a62be085SSadaf Ebrahimi void Container::GetNamespaces(
22*a62be085SSadaf Ebrahimi     std::unordered_map<string, string>* ns_name_href_map) {
23*a62be085SSadaf Ebrahimi   if (ns_name_href_map == nullptr || items_.empty()) {
24*a62be085SSadaf Ebrahimi     LOG(ERROR) << "Namespace list is null or item list is empty";
25*a62be085SSadaf Ebrahimi     return;
26*a62be085SSadaf Ebrahimi   }
27*a62be085SSadaf Ebrahimi   ns_name_href_map->emplace(DynamicDepthConst::Container(), kNamespaceHref);
28*a62be085SSadaf Ebrahimi   items_[0]->GetNamespaces(ns_name_href_map);
29*a62be085SSadaf Ebrahimi }
30*a62be085SSadaf Ebrahimi 
FromItems(std::vector<std::unique_ptr<Item>> * items)31*a62be085SSadaf Ebrahimi std::unique_ptr<Container> Container::FromItems(
32*a62be085SSadaf Ebrahimi     std::vector<std::unique_ptr<Item>>* items) {
33*a62be085SSadaf Ebrahimi   if (items == nullptr || items->empty()) {
34*a62be085SSadaf Ebrahimi     LOG(ERROR) << "Item list is empty";
35*a62be085SSadaf Ebrahimi     return nullptr;
36*a62be085SSadaf Ebrahimi   }
37*a62be085SSadaf Ebrahimi 
38*a62be085SSadaf Ebrahimi   std::unique_ptr<Container> container(new Container());
39*a62be085SSadaf Ebrahimi   container->items_ = std::move(*items);
40*a62be085SSadaf Ebrahimi   // Purge item elements that are null.
41*a62be085SSadaf Ebrahimi   container->items_.erase(
42*a62be085SSadaf Ebrahimi       std::remove_if(
43*a62be085SSadaf Ebrahimi           container->items_.begin(), container->items_.end(),
44*a62be085SSadaf Ebrahimi           [](const std::unique_ptr<Item>& item) { return item == nullptr; }),
45*a62be085SSadaf Ebrahimi       container->items_.end());
46*a62be085SSadaf Ebrahimi   if (container->items_.empty()) {
47*a62be085SSadaf Ebrahimi     LOG(ERROR) << "No non-null elements in items";
48*a62be085SSadaf Ebrahimi     return nullptr;
49*a62be085SSadaf Ebrahimi   }
50*a62be085SSadaf Ebrahimi 
51*a62be085SSadaf Ebrahimi   return container;
52*a62be085SSadaf Ebrahimi }
53*a62be085SSadaf Ebrahimi 
FromDeserializer(const Deserializer & parent_deserializer)54*a62be085SSadaf Ebrahimi std::unique_ptr<Container> Container::FromDeserializer(
55*a62be085SSadaf Ebrahimi     const Deserializer& parent_deserializer) {
56*a62be085SSadaf Ebrahimi   std::unique_ptr<Container> container(new Container());
57*a62be085SSadaf Ebrahimi   int i = 0;
58*a62be085SSadaf Ebrahimi   std::unique_ptr<Deserializer> deserializer =
59*a62be085SSadaf Ebrahimi       parent_deserializer.CreateDeserializerFromListElementAt(
60*a62be085SSadaf Ebrahimi           DynamicDepthConst::Namespace(DynamicDepthConst::Container()),
61*a62be085SSadaf Ebrahimi           DynamicDepthConst::Container(), 0);
62*a62be085SSadaf Ebrahimi   while (deserializer) {
63*a62be085SSadaf Ebrahimi     std::unique_ptr<Item> item = Item::FromDeserializer(*deserializer);
64*a62be085SSadaf Ebrahimi     if (item == nullptr) {
65*a62be085SSadaf Ebrahimi       LOG(ERROR) << "Unable to deserialize a item";
66*a62be085SSadaf Ebrahimi       return nullptr;
67*a62be085SSadaf Ebrahimi     }
68*a62be085SSadaf Ebrahimi     container->items_.emplace_back(std::move(item));
69*a62be085SSadaf Ebrahimi     deserializer = parent_deserializer.CreateDeserializerFromListElementAt(
70*a62be085SSadaf Ebrahimi         DynamicDepthConst::Namespace(DynamicDepthConst::Container()),
71*a62be085SSadaf Ebrahimi         DynamicDepthConst::Container(), ++i);
72*a62be085SSadaf Ebrahimi   }
73*a62be085SSadaf Ebrahimi 
74*a62be085SSadaf Ebrahimi   if (container->items_.empty()) {
75*a62be085SSadaf Ebrahimi     return nullptr;
76*a62be085SSadaf Ebrahimi   }
77*a62be085SSadaf Ebrahimi   return container;
78*a62be085SSadaf Ebrahimi }
79*a62be085SSadaf Ebrahimi 
GetItems() const80*a62be085SSadaf Ebrahimi const std::vector<const Item*> Container::GetItems() const {
81*a62be085SSadaf Ebrahimi   std::vector<const Item*> items;
82*a62be085SSadaf Ebrahimi   for (const auto& item : items_) {
83*a62be085SSadaf Ebrahimi     items.push_back(item.get());
84*a62be085SSadaf Ebrahimi   }
85*a62be085SSadaf Ebrahimi   return items;
86*a62be085SSadaf Ebrahimi }
87*a62be085SSadaf Ebrahimi 
Serialize(Serializer * serializer) const88*a62be085SSadaf Ebrahimi bool Container::Serialize(Serializer* serializer) const {
89*a62be085SSadaf Ebrahimi   if (items_.empty()) {
90*a62be085SSadaf Ebrahimi     LOG(ERROR) << "Item list is empty";
91*a62be085SSadaf Ebrahimi     return false;
92*a62be085SSadaf Ebrahimi   }
93*a62be085SSadaf Ebrahimi 
94*a62be085SSadaf Ebrahimi   std::unique_ptr<Serializer> container_serializer =
95*a62be085SSadaf Ebrahimi       serializer->CreateSerializer(
96*a62be085SSadaf Ebrahimi           DynamicDepthConst::Namespace(DynamicDepthConst::Container()),
97*a62be085SSadaf Ebrahimi           DynamicDepthConst::Container());
98*a62be085SSadaf Ebrahimi   if (!container_serializer->WriteProperty(XmlConst::RdfPrefix(),
99*a62be085SSadaf Ebrahimi                                            XmlConst::RdfParseType(),
100*a62be085SSadaf Ebrahimi                                            kResourceType)) {
101*a62be085SSadaf Ebrahimi     return false;
102*a62be085SSadaf Ebrahimi   }
103*a62be085SSadaf Ebrahimi 
104*a62be085SSadaf Ebrahimi   std::unique_ptr<Serializer> directory_serializer =
105*a62be085SSadaf Ebrahimi       container_serializer->CreateListSerializer(DynamicDepthConst::Container(),
106*a62be085SSadaf Ebrahimi                                                  kDirectory);
107*a62be085SSadaf Ebrahimi   if (directory_serializer == nullptr) {
108*a62be085SSadaf Ebrahimi     // Error is logged in Serializer.
109*a62be085SSadaf Ebrahimi     return false;
110*a62be085SSadaf Ebrahimi   }
111*a62be085SSadaf Ebrahimi 
112*a62be085SSadaf Ebrahimi   for (int i = 0; i < items_.size(); i++) {
113*a62be085SSadaf Ebrahimi     std::unique_ptr<Serializer> item_serializer =
114*a62be085SSadaf Ebrahimi         directory_serializer->CreateItemSerializer(
115*a62be085SSadaf Ebrahimi             DynamicDepthConst::Namespace(DynamicDepthConst::Item()),
116*a62be085SSadaf Ebrahimi             DynamicDepthConst::Item());
117*a62be085SSadaf Ebrahimi     if (item_serializer == nullptr) {
118*a62be085SSadaf Ebrahimi       LOG(ERROR) << "Could not create a list item serializer for Item";
119*a62be085SSadaf Ebrahimi       return false;
120*a62be085SSadaf Ebrahimi     }
121*a62be085SSadaf Ebrahimi     if (!items_[i]->Serialize(item_serializer.get())) {
122*a62be085SSadaf Ebrahimi       LOG(ERROR) << "Could not serialize item " << i;
123*a62be085SSadaf Ebrahimi       return false;
124*a62be085SSadaf Ebrahimi     }
125*a62be085SSadaf Ebrahimi   }
126*a62be085SSadaf Ebrahimi   return true;
127*a62be085SSadaf Ebrahimi }
128*a62be085SSadaf Ebrahimi 
129*a62be085SSadaf Ebrahimi }  // namespace dynamic_depth
130