backport 1d85ab27a7e and ba128eea from cairocanvas branch to remove GIO (possible...
[ardour.git] / libs / pbd / pbd / xml++.h
1 /*
2     Copyright (C) 2012 Paul Davis 
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 /* xml++.h
21  * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and
22  * are covered by the GNU Lesser General Public License, which should be
23  * included with libxml++ as the file COPYING.
24  * Modified for Ardour and released under the same terms.
25  */
26
27 #include <string>
28 #include <list>
29 #include <map>
30 #include <cstdio>
31 #include <cstdarg>
32
33 #include <libxml/parser.h>
34 #include <libxml/tree.h>
35 #include <boost/shared_ptr.hpp>
36
37 #ifndef __XML_H
38 #define __XML_H
39
40 class XMLTree;
41 class XMLNode;
42 class XMLProperty;
43
44 typedef std::list<XMLNode *>                   XMLNodeList;
45 typedef std::list<boost::shared_ptr<XMLNode> > XMLSharedNodeList;
46 typedef XMLNodeList::iterator                  XMLNodeIterator;
47 typedef XMLNodeList::const_iterator            XMLNodeConstIterator;
48 typedef std::list<XMLProperty*>                XMLPropertyList;
49 typedef XMLPropertyList::iterator              XMLPropertyIterator;
50 typedef XMLPropertyList::const_iterator        XMLPropertyConstIterator;
51 typedef std::map<std::string, XMLProperty*>    XMLPropertyMap;
52
53 class XMLTree {
54 public:
55         XMLTree();
56         XMLTree(const std::string& fn, bool validate = false);
57         XMLTree(const XMLTree*);
58         ~XMLTree();
59
60         XMLNode* root() const         { return _root; }
61         XMLNode* set_root(XMLNode* n) { return _root = n; }
62
63         const std::string& filename() const               { return _filename; }
64         const std::string& set_filename(const std::string& fn) { return _filename = fn; }
65
66         int compression() const { return _compression; }
67         int set_compression(int);
68
69         bool read() { return read_internal(false); }
70         bool read(const std::string& fn) { set_filename(fn); return read_internal(false); }
71         bool read_and_validate() { return read_internal(true); }
72         bool read_and_validate(const std::string& fn) { set_filename(fn); return read_internal(true); }
73         bool read_buffer(const std::string&);
74
75         bool write() const;
76         bool write(const std::string& fn) { set_filename(fn); return write(); }
77
78         void debug (FILE*) const;
79
80         const std::string& write_buffer() const;
81
82         boost::shared_ptr<XMLSharedNodeList> find(const std::string xpath, XMLNode* = 0) const;
83
84 private:
85         bool read_internal(bool validate);
86         
87         std::string _filename;
88         XMLNode*    _root;
89         xmlDocPtr   _doc;
90         int         _compression;
91 };
92
93 class XMLNode {
94 public:
95         XMLNode(const std::string& name);
96         XMLNode(const std::string& name, const std::string& content);
97         XMLNode(const XMLNode& other);
98         ~XMLNode();
99
100         XMLNode& operator= (const XMLNode& other);
101
102         const std::string& name() const { return _name; }
103
104         bool          is_content() const { return _is_content; }
105         const std::string& content()    const { return _content; }
106         const std::string& set_content(const std::string&);
107         XMLNode*      add_content(const std::string& s = std::string());
108
109         const XMLNodeList& children(const std::string& str = std::string()) const;
110         XMLNode* child(const char*) const;
111         XMLNode* add_child(const char *);
112         XMLNode* add_child_copy(const XMLNode&);
113         void     add_child_nocopy(XMLNode&);
114
115         std::string attribute_value();
116
117         const XMLPropertyList& properties() const { return _proplist; }
118         XMLProperty*       property(const char*);
119         XMLProperty*       property(const std::string&);
120         const XMLProperty* property(const char* n)   const { return const_cast<XMLNode*>(this)->property(n); }
121         const XMLProperty* property(const std::string& n) const { return const_cast<XMLNode*>(this)->property(n); }
122         
123         XMLProperty* add_property(const char* name, const std::string& value);
124         XMLProperty* add_property(const char* name, const char* value = "");
125         XMLProperty* add_property(const char* name, const long value);
126
127         void remove_property(const std::string&);
128         void remove_property_recursively(const std::string&);
129
130         /** Remove all nodes with the name passed to remove_nodes */
131         void remove_nodes(const std::string&);
132         /** Remove and delete all nodes with the name passed to remove_nodes */
133         void remove_nodes_and_delete(const std::string&);
134         /** Remove and delete all nodes with property prop matching val */
135         void remove_nodes_and_delete(const std::string& propname, const std::string& val);
136
137         void dump (std::ostream &, std::string p = "") const;
138
139 private:
140         std::string         _name;
141         bool                _is_content;
142         std::string         _content;
143         XMLNodeList         _children;
144         XMLPropertyList     _proplist;
145         XMLPropertyMap      _propmap;
146         mutable XMLNodeList _selected_children;
147
148         void clear_lists ();
149 };
150
151 class XMLProperty {
152 public:
153         XMLProperty(const std::string& n, const std::string& v = std::string());
154         ~XMLProperty();
155
156         const std::string& name() const { return _name; }
157         const std::string& value() const { return _value; }
158         const std::string& set_value(const std::string& v) { return _value = v; }
159
160 private:
161         std::string _name;
162         std::string _value;
163 };
164
165 class XMLException: public std::exception {
166 public:
167         explicit XMLException(const std::string msg) : _message(msg) {}
168         virtual ~XMLException() throw() {}
169
170         virtual const char* what() const throw() { return _message.c_str(); }
171
172 private:
173         std::string _message;
174 };
175
176 #endif /* __XML_H */
177