Various tweaks for a real-life DCP.
[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
12 namespace xmlpp {
13         class Node;
14         class DomParser;
15 }
16
17 namespace libdcp {
18
19 class XMLNode
20 {
21 public:
22         XMLNode ();
23         XMLNode (xmlpp::Node const * node);
24
25 protected:
26         std::string string_node (std::string);
27         std::string optional_string_node (std::string);
28         ContentKind kind_node (std::string);
29         Fraction fraction_node (std::string);
30         int64_t int64_node (std::string);
31         int64_t optional_int64_node (std::string);
32         float float_node (std::string);
33         void ignore_node (std::string);
34         void done ();
35
36         template <class T>
37         boost::shared_ptr<T> sub_node (std::string name) {
38                 return boost::shared_ptr<T> (new T (xml_node (name)));
39         }
40
41         template <class T>
42         boost::shared_ptr<T> optional_sub_node (std::string name) {
43                 std::list<xmlpp::Node*> n = xml_nodes (name);
44                 if (n.size() > 1) {
45                         throw XMLError ("duplicate XML tag");
46                 } else if (n.empty ()) {
47                         return boost::shared_ptr<T> ();
48                 }
49                 
50                 return boost::shared_ptr<T> (new T (n.front ()));
51         }
52         
53         template <class T>
54         std::list<boost::shared_ptr<T> > sub_nodes (std::string name, std::string sub) {
55                 XMLNode p (xml_node (name));
56                 std::list<xmlpp::Node*> n = p.xml_nodes (sub);
57                 std::list<boost::shared_ptr<T> > r;
58                 for (typename std::list<xmlpp::Node*>::iterator i = n.begin(); i != n.end(); ++i) {
59                         r.push_back (boost::shared_ptr<T> (new T (*i)));
60                 }
61                 return r;
62         }
63
64         xmlpp::Node const * _node;
65
66 private:
67         xmlpp::Node* xml_node (std::string);
68         std::list<xmlpp::Node*> xml_nodes (std::string);
69         std::list<Glib::ustring> _taken;
70 };
71
72 class XMLFile : public XMLNode
73 {
74 public:
75         XMLFile (std::string file, std::string root_name);
76         virtual ~XMLFile ();
77
78 private:
79         xmlpp::DomParser* _parser;
80 };
81
82 }
83
84 #endif