1 #ifndef DYNAMIC_DEPTH_INTERNAL_XMPMETA_XML_DESERIALIZER_IMPL_H_  // NOLINT
2 #define DYNAMIC_DEPTH_INTERNAL_XMPMETA_XML_DESERIALIZER_IMPL_H_  // NOLINT
3 
4 #include <libxml/tree.h>
5 
6 #include <map>
7 #include <mutex>  // NOLINT(build/c++11)
8 #include <string>
9 
10 #include "base/port.h"
11 #include "xmpmeta/xml/deserializer.h"
12 
13 namespace dynamic_depth {
14 namespace xmpmeta {
15 namespace xml {
16 
17 // Deserializes an XML node.
18 // Example:
19 //   xmlNodePtr device_node =
20 //       DepthFirstSearch(xmp.ExtendedSection(), "Device", "Description");
21 //   DeserializerImpl deserializer(device_node);
22 //   string revision;
23 //   deserializer.ParseString("Device", "Revision", &revision);
24 // TODO(miraleung): Add example for list node deserializer.
25 class DeserializerImpl : public Deserializer {
26  public:
27   // Creates a deserializer with a null rdf:Seq node.
28   explicit DeserializerImpl(const xmlNodePtr node);
29 
30   // Returns a Deserializer.
31   // If prefix is empty, the deserializer will be created on the first node
32   // found with a name that matches child_name.
33   // child_name is the name of the next node to deserialize.
34   std::unique_ptr<Deserializer> CreateDeserializer(
35       const string& prefix, const string& child_name) const override;
36 
37   // Returns a Deserializer from a list element node, if one is available as
38   // a descendant of node_.
39   // If prefix is empty, the deserializer will be created on the first node
40   // found with a name that matches child_name.
41   // Returns null if seq_node_ is null or if the index is out of range.
42   std::unique_ptr<Deserializer> CreateDeserializerFromListElementAt(
43       const string& prefix, const string& list_name, int index) const override;
44 
45   // Parsers for XML properties.
46   // If prefix is empty, the node's namespace may be null. Otherwise, it must
47   // not be null.
48   bool ParseBase64(const string& prefix, const string& name,
49                    string* value) const override;
50   bool ParseIntArrayBase64(const string& prefix, const string& name,
51                            std::vector<int>* values) const override;
52   bool ParseFloatArrayBase64(const string& prefix, const string& name,
53                              std::vector<float>* values) const override;
54   bool ParseDoubleArrayBase64(const string& prefix, const string& name,
55                               std::vector<double>* values) const override;
56   bool ParseBoolean(const string& prefix, const string& name,
57                     bool* value) const override;
58   bool ParseDouble(const string& prefix, const string& name,
59                    double* value) const override;
60   bool ParseInt(const string& prefix, const string& name,
61                 int* value) const override;
62   bool ParseFloat(const string& prefix, const string& name,
63                   float* value) const override;
64   bool ParseLong(const string& prefix, const string& name,
65                  int64* value) const override;
66   bool ParseString(const string& prefix, const string& name,
67                    string* value) const override;
68 
69   // Parses the numbers in an rdf:Seq list into the values collection.
70   // The given collection is cleared of any existing values, and the
71   // parsed numbers are written to it.
72   bool ParseIntArray(const string& prefix, const string& list_name,
73                      std::vector<int>* values) const override;
74   bool ParseDoubleArray(const string& prefix, const string& list_name,
75                         std::vector<double>* values) const override;
76 
77   // Disallow copying.
78   DeserializerImpl(const DeserializerImpl&) = delete;
79   void operator=(const DeserializerImpl&) = delete;
80 
81  private:
82   xmlNodePtr node_;
83   // Remembers the parent node of the last deserializer created on the rdf:Seq
84   // node. For performance reasons only, to avoid unnessarily traversing
85   // the XML document tree.
86   mutable xmlNodePtr list_node_;
87   // Lock modifications of list_node_ in const functions to make it thread-safe.
88   mutable std::mutex mtx_;
89 };
90 
91 }  // namespace xml
92 }  // namespace xmpmeta
93 }  // namespace dynamic_depth
94 
95 #endif // DYNAMIC_DEPTH_INTERNAL_XMPMETA_XML_DESERIALIZER_IMPL_H_  // NOLINT
96