Initial work on subtitle writing.
[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         std::string string_child (std::string);
28         std::string optional_string_child (std::string);
29         ContentKind kind_child (std::string);
30         Fraction fraction_child (std::string);
31         int64_t int64_child (std::string);
32         int64_t optional_int64_child (std::string);
33         float float_child (std::string);
34         void ignore_child (std::string);
35         void done ();
36
37         Time time_attribute (std::string);
38         float float_attribute (std::string);
39         std::string string_attribute (std::string);
40         std::string optional_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> type_child (std::string name) {
50                 return boost::shared_ptr<T> (new T (node_child (name)));
51         }
52
53         template <class T>
54         boost::shared_ptr<T> optional_type_child (std::string name) {
55                 std::list<xmlpp::Node*> n = node_children (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> > type_children (std::string name) {
67                 std::list<xmlpp::Node*> n = node_children (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> > type_grand_children (std::string name, std::string sub) {
77                 XMLNode p (node_child (name));
78                 return p.type_children<T> (sub);
79         }
80
81         xmlpp::Node const * _node;
82
83 private:
84         xmlpp::Node* node_child (std::string);
85         std::list<xmlpp::Node*> node_children (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