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