Recursively scan font tags in subtitles.
[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 "types.h"
10 #include "exceptions.h"
11 #include "dcp_time.h"
12
13 namespace xmlpp {
14         class Node;
15         class DomParser;
16 }
17
18 namespace libdcp {
19
20 class XMLNode
21 {
22 public:
23         XMLNode ();
24         XMLNode (xmlpp::Node const * node);
25
26 protected:
27         std::string string_node (std::string);
28         std::string optional_string_node (std::string);
29         ContentKind kind_node (std::string);
30         Fraction fraction_node (std::string);
31         int64_t int64_node (std::string);
32         int64_t optional_int64_node (std::string);
33         float float_node (std::string);
34         void ignore_node (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         int64_t int64_attribute (std::string);
41         int64_t optional_int64_attribute (std::string);
42
43         std::string content ();
44
45         template <class T>
46         boost::shared_ptr<T> sub_node (std::string name) {
47                 return boost::shared_ptr<T> (new T (xml_node (name)));
48         }
49
50         template <class T>
51         boost::shared_ptr<T> optional_sub_node (std::string name) {
52                 std::list<xmlpp::Node*> n = xml_nodes (name);
53                 if (n.size() > 1) {
54                         throw XMLError ("duplicate XML tag");
55                 } else if (n.empty ()) {
56                         return boost::shared_ptr<T> ();
57                 }
58                 
59                 return boost::shared_ptr<T> (new T (n.front ()));
60         }
61         
62         template <class T>
63         std::list<boost::shared_ptr<T> > sub_nodes (std::string name) {
64                 std::list<xmlpp::Node*> n = xml_nodes (name);
65                 std::list<boost::shared_ptr<T> > r;
66                 for (typename std::list<xmlpp::Node*>::iterator i = n.begin(); i != n.end(); ++i) {
67                         r.push_back (boost::shared_ptr<T> (new T (*i)));
68                 }
69                 return r;
70         }
71
72         template <class T>
73         std::list<boost::shared_ptr<T> > sub_nodes (std::string name, std::string sub) {
74                 XMLNode p (xml_node (name));
75                 return p.sub_nodes<T> (sub);
76         }
77
78         xmlpp::Node const * _node;
79
80 private:
81         xmlpp::Node* xml_node (std::string);
82         std::list<xmlpp::Node*> xml_nodes (std::string);
83         std::list<Glib::ustring> _taken;
84 };
85
86 class XMLFile : public XMLNode
87 {
88 public:
89         XMLFile (std::string file, std::string root_name);
90         virtual ~XMLFile ();
91
92 private:
93         xmlpp::DomParser* _parser;
94 };
95
96 }
97
98 #endif