Use libcxml. Lump all static configuration flags into one.
[libdcp.git] / src / xml.h
1 /*
2     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef LIBDCP_XML_H
21 #define LIBDCP_XML_H
22
23 #include <libcxml/cxml.h>
24 #include "exceptions.h"
25
26 namespace libdcp
27 {
28
29 template <class T>
30 boost::shared_ptr<T>
31 optional_type_child (cxml::Node const & node, std::string name)
32 {
33         std::list<boost::shared_ptr<cxml::Node> > n = node.node_children (name);
34         if (n.size() > 1) {
35                 throw XMLError ("duplicate XML tag");
36         } else if (n.empty ()) {
37                 return boost::shared_ptr<T> ();
38         }
39
40         return boost::shared_ptr<T> (new T (n.front ()));
41 }
42
43 template <class T>
44 boost::shared_ptr<T> type_child (boost::shared_ptr<const cxml::Node> node, std::string name) {
45         return boost::shared_ptr<T> (new T (node->node_child (name)));
46 }
47         
48 template <class T>
49 boost::shared_ptr<T>
50 optional_type_child (boost::shared_ptr<const cxml::Node> node, std::string name)
51 {
52         return optional_type_child<T> (*node.get(), name);
53 }
54
55 template <class T>
56 std::list<boost::shared_ptr<T> >
57 type_children (cxml::Node const & node, std::string name)
58 {
59         std::list<boost::shared_ptr<cxml::Node> > n = node.node_children (name);
60         std::list<boost::shared_ptr<T> > r;
61         for (typename std::list<boost::shared_ptr<cxml::Node> >::iterator i = n.begin(); i != n.end(); ++i) {
62                 r.push_back (boost::shared_ptr<T> (new T (*i)));
63         }
64         return r;
65 }
66
67 template <class T>
68 std::list<boost::shared_ptr<T> >
69 type_children (boost::shared_ptr<const cxml::Node> node, std::string name)
70 {
71         return type_children<T> (*node.get(), name);
72 }
73         
74 template <class T>
75 std::list<boost::shared_ptr<T> >
76 type_grand_children (cxml::Node const & node, std::string name, std::string sub)
77 {
78         boost::shared_ptr<const cxml::Node> p = node.node_child (name);
79         return type_children<T> (p, sub);
80 }
81
82 template <class T>
83 std::list<boost::shared_ptr<T> >
84 type_grand_children (boost::shared_ptr<const cxml::Node> node, std::string name, std::string sub)
85 {
86         return type_grand_children<T> (*node.get(), name, sub);
87 }
88         
89 }
90
91 #endif