65eb73994b2528a076fa2d835116ba82a8a1006b
[libdcp.git] / src / xml.h
1 #ifndef LIBDCP_XML_H
2 #define LIBDCP_XML_H
3
4 #include <string>
5 #include <list>
6 #include <stdint.h>
7 #include <glibmm.h>
8 #include <boost/shared_ptr.hpp>
9 #include <boost/optional.hpp>
10 #include "types.h"
11 #include "exceptions.h"
12 #include "dcp_time.h"
13
14 namespace xmlpp {
15         class Node;
16         class DomParser;
17 }
18
19 namespace libdcp {
20
21 class XMLNode
22 {
23 public:
24         XMLNode ();
25         XMLNode (xmlpp::Node const * node);
26
27 protected:
28         std::string string_node (std::string);
29         std::string optional_string_node (std::string);
30         ContentKind kind_node (std::string);
31         Fraction fraction_node (std::string);
32         int64_t int64_node (std::string);
33         int64_t optional_int64_node (std::string);
34         float float_node (std::string);
35         void ignore_node (std::string);
36         void done ();
37
38         Time time_attribute (std::string);
39         float float_attribute (std::string);
40         std::string string_attribute (std::string);
41         int64_t int64_attribute (std::string);
42         int64_t optional_int64_attribute (std::string);
43         boost::optional<bool> optional_bool_attribute (std::string);
44         boost::optional<Color> optional_color_attribute (std::string);
45
46         std::string content ();
47
48         template <class T>
49         boost::shared_ptr<T> sub_node (std::string name) {
50                 return boost::shared_ptr<T> (new T (xml_node (name)));
51         }
52
53         template <class T>
54         boost::shared_ptr<T> optional_sub_node (std::string name) {
55                 std::list<xmlpp::Node*> n = xml_nodes (name);
56                 if (n.size() > 1) {
57                         throw XMLError ("duplicate XML tag");
58                 } else if (n.empty ()) {
59                         return boost::shared_ptr<T> ();
60                 }
61                 
62                 return boost::shared_ptr<T> (new T (n.front ()));
63         }
64         
65         template <class T>
66         std::list<boost::shared_ptr<T> > sub_nodes (std::string name) {
67                 std::list<xmlpp::Node*> n = xml_nodes (name);
68                 std::list<boost::shared_ptr<T> > r;
69                 for (typename std::list<xmlpp::Node*>::iterator i = n.begin(); i != n.end(); ++i) {
70                         r.push_back (boost::shared_ptr<T> (new T (*i)));
71                 }
72                 return r;
73         }
74
75         template <class T>
76         std::list<boost::shared_ptr<T> > sub_nodes (std::string name, std::string sub) {
77                 XMLNode p (xml_node (name));
78                 return p.sub_nodes<T> (sub);
79         }
80
81         xmlpp::Node const * _node;
82
83 private:
84         xmlpp::Node* xml_node (std::string);
85         std::list<xmlpp::Node*> xml_nodes (std::string);
86         std::list<Glib::ustring> _taken;
87 };
88
89 class XMLFile : public XMLNode
90 {
91 public:
92         XMLFile (std::string file, std::string root_name);
93         virtual ~XMLFile ();
94
95 private:
96         xmlpp::DomParser* _parser;
97 };
98
99 }
100
101 #endif