Pick up effect and effect color.
[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         std::string optional_string_attribute (std::string);
42         int64_t int64_attribute (std::string);
43         int64_t optional_int64_attribute (std::string);
44         boost::optional<bool> optional_bool_attribute (std::string);
45         boost::optional<Color> optional_color_attribute (std::string);
46
47         std::string content ();
48
49         template <class T>
50         boost::shared_ptr<T> sub_node (std::string name) {
51                 return boost::shared_ptr<T> (new T (xml_node (name)));
52         }
53
54         template <class T>
55         boost::shared_ptr<T> optional_sub_node (std::string name) {
56                 std::list<xmlpp::Node*> n = xml_nodes (name);
57                 if (n.size() > 1) {
58                         throw XMLError ("duplicate XML tag");
59                 } else if (n.empty ()) {
60                         return boost::shared_ptr<T> ();
61                 }
62                 
63                 return boost::shared_ptr<T> (new T (n.front ()));
64         }
65         
66         template <class T>
67         std::list<boost::shared_ptr<T> > sub_nodes (std::string name) {
68                 std::list<xmlpp::Node*> n = xml_nodes (name);
69                 std::list<boost::shared_ptr<T> > r;
70                 for (typename std::list<xmlpp::Node*>::iterator i = n.begin(); i != n.end(); ++i) {
71                         r.push_back (boost::shared_ptr<T> (new T (*i)));
72                 }
73                 return r;
74         }
75
76         template <class T>
77         std::list<boost::shared_ptr<T> > sub_nodes (std::string name, std::string sub) {
78                 XMLNode p (xml_node (name));
79                 return p.sub_nodes<T> (sub);
80         }
81
82         xmlpp::Node const * _node;
83
84 private:
85         xmlpp::Node* xml_node (std::string);
86         std::list<xmlpp::Node*> xml_nodes (std::string);
87         std::list<Glib::ustring> _taken;
88 };
89
90 class XMLFile : public XMLNode
91 {
92 public:
93         XMLFile (std::string file, std::string root_name);
94         virtual ~XMLFile ();
95
96 private:
97         xmlpp::DomParser* _parser;
98 };
99
100 }
101
102 #endif