Gaia
yamlcpp.h
1 /*
2  * Copyright (C) 2006-2013 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Gaia
5  *
6  * Gaia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef YAMLCPP_H
21 #define YAMLCPP_H
22 
23 #include <algorithm> // for lexicographical_compare
24 #include <QList>
25 #include <QMap>
26 #include <QString>
27 #include <QTextStream>
28 #include "gaia.h"
29 
30 namespace gaia2 {
31 namespace yaml {
32 class Node;
33 }
34 }
35 
36 //std::ostream& operator<<(std::ostream& out, const gaia2::yaml::Node& node);
37 
38 
39 namespace gaia2 {
40 namespace yaml {
41 
46 GAIA_DEFINE_EXCEPTION(YamlException);
47 
48 
52 typedef enum {
53  ScalarType,
54  SequenceType,
55  MappingType
56 } NodeType;
57 
58 
59 // Mappings used from the Yaml types to our C++ types; use Qt's classes.
60 typedef QString Scalar;
61 typedef QList<Node> Sequence;
62 typedef GaiaMap<Node, Node, YamlException> Mapping;
63 
64 
65 // should probably be implemented like this
66 /*
67 class YamlNode;
68 class ScalarTypeNode : public YamlNode;
69 class SequenceTypeNode : public YamlNode;
70 class MappingTypeNode : public YamlNode;
71 */
72 // or even better, just as a QVariant, and that would also remove the hack for
73 // knowing whether a scalar is quoted or not
74 
75 #define yamlCheckType(input_type) if (type() != input_type##Type) throw YamlException("Type is not a "#input_type)
76 
77 class Node {
78  protected:
79  NodeType _type;
80 
81  Scalar _scalar;
82  Sequence _sequence;
83  Mapping _mapping;
84 
85  public:
86 
87  Node() : _type(ScalarType), _scalar("") {}
88  Node(const QString& str) : _type(ScalarType), _scalar(str) {}
89  Node(const char* str) : _type(ScalarType), _scalar(QString::fromUtf8(str)) {}
90  Node(const std::string& str) : _type(ScalarType), _scalar(QString::fromUtf8(str.c_str(), (int)str.size())) {}
91  Node(const Sequence& seq) : _type(SequenceType), _sequence(seq) {}
92  Node(const Mapping& mapping) : _type(MappingType), _mapping(mapping) {}
93 
94  Node(const Node& n) : _type(n._type),
95  _scalar(n._scalar),
96  _sequence(n._sequence),
97  _mapping(n._mapping) {}
98 
99 
100  QString toString() const {
101  return scalar();
102  }
103 
104  /*
105  template<typename T> const T as() const {
106  //return boost::lexical_cast<T>(asString().toAscii());
107  return T();
108  }
109  */
110 
111  operator QString() const {
112  return toString();
113  }
114 
115  bool operator==(const Node& rhs) const {
116  if (_type != rhs._type) return false;
117 
118  switch (_type) {
119  case ScalarType: return _scalar == rhs._scalar;
120  case SequenceType: return _sequence == rhs._sequence;
121  case MappingType: return _mapping == rhs._mapping;
122  }
123 
124  // weird, g++ complains if there's no return value here...
125  return false;
126  }
127 
131  bool operator<(const Node& rhs) const {
132  if (_type != rhs._type) return _type < rhs._type;
133 
134  switch (_type) {
135  case ScalarType: return _scalar < rhs._scalar;
136  case SequenceType:
137  return std::lexicographical_compare(_sequence.begin(), _sequence.end(),
138  rhs._sequence.begin(), rhs._sequence.end());
139  case MappingType:
140  return std::lexicographical_compare(_mapping.begin(), _mapping.end(),
141  rhs._mapping.begin(), rhs._mapping.end());
142  }
143 
144  // weird, g++ complains if there's no return value here...
145  return false;
146  }
147 
148  NodeType type() const { return _type; }
149 
150  // ---------------- Conversion functions ---------------- //
151 
152  const Scalar& scalar() const {
153  yamlCheckType(Scalar);
154  return _scalar;
155  }
156 
157  Scalar& scalar() {
158  yamlCheckType(Scalar);
159  return _scalar;
160  }
161 
162  const Sequence& sequence() const {
163  yamlCheckType(Sequence);
164  return _sequence;
165  }
166 
167  Sequence& sequence() {
168  yamlCheckType(Sequence);
169  return _sequence;
170  }
171 
172  const Mapping& mapping() const {
173  yamlCheckType(Mapping);
174  return _mapping;
175  }
176 
177  Mapping& mapping() {
178  yamlCheckType(Mapping);
179  return _mapping;
180  }
181 
182  // ---------------- Shortcut convenience functions ---------------- //
183 
184  const Node& operator[](int i) const {
185  return sequence()[i];
186  }
187 
188  Node& operator[](int i) {
189  return sequence()[i];
190  }
191 
192  const Node& operator[](const Node& node) const {
193  return mapping()[node];
194  }
195 
196  Node& operator[](const Node& node) {
197  return mapping()[node];
198  }
199 
200 
201  friend std::ostream& operator<<(std::ostream& out, const gaia2::yaml::Node& node);
202 
203 };
204 
205 
212 Node loadFromString(const std::string& str, bool markQuotedScalars = false);
213 
214 Node load(const char* str, uint size, bool markQuotedScalars = false);
215 
216 Node load(const QString& str);
217 
218 QByteArray dump(const Node& node);
219 
225 Node loadFromFile(const QString& filename, bool markQuotedScalars = false);
226 
227 
228 inline Stringifier& operator<<(Stringifier& out, const Node& node) {
229  switch (node.type()) {
230  case yaml::ScalarType: return out << node.scalar();
231  case yaml::MappingType: return out << node.mapping();
232  case yaml::SequenceType: return out << node.sequence();
233  }
234 
235  return out << "Unknown Type";
236 }
237 
238 } // namespace yaml
239 } // namespace gaia2
240 
241 
242 #endif // YAMLCPP_H
Definition: debugging.h:82
bool operator<(const Node &rhs) const
Definition: yamlcpp.h:131
Main Gaia namespace, which contains all the library functions.
Definition: addfield.cpp:22
Definition: yamlcpp.h:77