Choreonoid  1.5
ValueTree.h
Go to the documentation of this file.
1 
5 #ifndef CNOID_UTIL_VALUE_TREE_H
6 #define CNOID_UTIL_VALUE_TREE_H
7 
8 #include "Referenced.h"
9 #include "UTF8.h"
10 #include <map>
11 #include <vector>
12 #include "exportdecl.h"
13 
14 namespace cnoid {
15 
16 class YAMLReaderImpl;
17 class YAMLWriter;
18 class ValueNode;
19 class ScalarNode;
20 class Mapping;
21 class Listing;
22 
23 #ifndef CNOID_BACKWARD_COMPATIBILITY
25 #else
26 enum StringStyle { PLAIN_STRING, YAML_PLAIN_STRING = PLAIN_STRING,
27  SINGLE_QUOTED, YAML_SINGLE_QUOTED = SINGLE_QUOTED,
28  DOUBLE_QUOTED, YAML_DOUBLE_QUOTED = DOUBLE_QUOTED,
29  LITERAL_STRING, YAML_LITERAL = LITERAL_STRING,
30  FOLDED_STRING, YAML_FOLDED = FOLDED_STRING
31 };
32 #endif
33 
35 {
36  struct Initializer {
37  Initializer();
38  };
39  static Initializer initializer;
40 
41 public:
42 
43  virtual ValueNode* clone() const;
44 
45 #ifndef CNOID_BACKWARD_COMPATIBILITY
46  enum TypeBit { INVALID_NODE = 0, SCALAR = 1, MAPPING = 2, LISTING = 4, INSERT_LF = 8, APPEND_LF = 16 };
47 #else
48  enum TypeBit { INVALID_NODE = 0, SCALAR = 1, MAPPING = 2, LISTING = 4, SEQUENCE = 4, INSERT_LF = 8, APPEND_LF = 16 };
49 #endif
50 
51  bool isValid() const { return typeBits; }
52  TypeBit LFType() const { return (TypeBit)(typeBits & (INSERT_LF | APPEND_LF)); }
53  TypeBit nodeType() const { return (TypeBit)(typeBits & 7); }
54 
55  int toInt() const;
56  double toDouble() const;
57  bool toBool() const;
58 
59  bool isScalar() const { return typeBits & SCALAR; }
60  bool isString() const { return typeBits & SCALAR; }
61 
62 #ifdef _WIN32
63  const std::string toString() const;
64  const std::string toUTF8String() const;
65 
66  operator const std::string () const {
67  return toString();
68  }
69 #else
70  const std::string& toString() const;
71  const std::string& toUTF8String() const;
72 
73  operator const std::string& () const {
74  return toString();
75  }
76 #endif
77 
78  //template<typename T> T to() const { return ""; }
79  template<typename T> T to() const;
80 
81  bool isMapping() const { return typeBits & MAPPING; }
82  const Mapping* toMapping() const;
83  Mapping* toMapping();
84 
85  bool isListing() const { return typeBits & LISTING; }
86  const Listing* toListing() const;
87  Listing* toListing();
88 
89 #ifdef CNOID_BACKWARD_COMPATIBILITY
90  bool isSequence() const { return typeBits & LISTING; }
91  const Listing* toSequence() const { return toListing(); }
92  Listing* toSequence() { return toListing(); }
93 #endif
94 
95  bool read(int &out_value) const;
96  bool read(double &out_value) const;
97  bool read(bool &out_value) const;
98  bool read(std::string &out_value) const;
99  bool readUTF8String(std::string& out_value) const;
100 
101  bool hasLineInfo() const { return (line_ >= 0); }
102  int line() const { return line_ + 1; }
103  int column() const { return column_ + 1; }
104 
105  void throwException(const std::string& message) const;
106 
111 public:
112  Exception();
113  virtual ~Exception();
114  int line() const { return line_; }
115  int column() const { return column_; }
116  std::string message() const;
117  void setPosition(int line, int column) {
118  line_ = line;
119  column_ = column;
120  }
121  void setMessage(const std::string& m){
122  message_ = m;
123  }
124 private:
125  int line_;
126  int column_;
127  std::string message_;
128  };
129 
131  public:
132  const std::string& key() { return key_; }
133  void setKey(const std::string& key) { key_ = key; }
134  private:
135  std::string key_;
136  };
137 
138  class EmptyKeyException : public Exception {
139  };
140 
141  class NotScalarException : public Exception {
142  };
143 
145  };
146 
148  };
149 
151  };
152 
153  class SyntaxException : public Exception {
154  };
155 
157  };
158 
159  class FileException : public Exception {
160  };
161 
163  };
164 
165 protected:
166 
167  ValueNode() { }
168  ValueNode(TypeBit type) : typeBits(type), line_(-1), column_(-1) { }
169 
170  virtual ~ValueNode() { }
171 
172  void throwNotScalrException() const;
173  void throwNotMappingException() const;
174  void throwNotListingException() const;
175 
176  int typeBits;
177 
178 private:
179  ValueNode(const ValueNode& org);
180  ValueNode& operator=(const ValueNode&);
181 
182  int line_;
183  int column_;
184  int indexInMapping; // used for YAMLWriter
185 
186  friend class YAMLReaderImpl;
187  friend class YAMLWriter;
188  friend class ScalarNode;
189  friend class Mapping;
190  friend class Listing;
191 };
192 
193 template<> inline double ValueNode::to<double>() const { return toDouble(); }
194 template<> inline int ValueNode::to<int>() const { return toInt(); }
195 template<> inline std::string ValueNode::to<std::string>() const { return toString(); }
196 
198 
199 
201 {
202 public:
203  ScalarNode(const std::string& value, StringStyle stringStyle = PLAIN_STRING);
204  ScalarNode(int value);
205 
206  virtual ValueNode* clone() const;
207 
208 private:
209  ScalarNode(const char* text, size_t length);
210  ScalarNode(const char* text, size_t length, StringStyle stringStyle);
211  ScalarNode(const ScalarNode& org);
212 
213  std::string stringValue;
214  StringStyle stringStyle;
215 
216  friend class YAMLReaderImpl;
217  friend class YAMLWriter;
218  friend class ValueNode;
219  friend class Mapping;
220  friend class Listing;
221 };
222 
223 
225 {
226  typedef std::map<std::string, ValueNodePtr> Container;
227 
228 public:
229 
230  typedef Container::iterator iterator;
231  typedef Container::const_iterator const_iterator;
232 
233  Mapping();
234  Mapping(int line, int column);
235  virtual ~Mapping();
236 
237  virtual ValueNode* clone() const;
238 
239  bool empty() const { return values.empty(); }
240  int size() const { return values.size(); }
241  void clear();
242 
243  void setFlowStyle(bool isFlowStyle = true) { isFlowStyle_ = isFlowStyle; }
244  bool isFlowStyle() const { return isFlowStyle_; }
245 
246  void setDoubleFormat(const char* format);
247  const char* doubleFormat() { return doubleFormat_; }
248 
249  void setKeyQuoteStyle(StringStyle style);
250 
251  ValueNode* find(const std::string& key) const;
252  Mapping* findMapping(const std::string& key) const;
253  Listing* findListing(const std::string& key) const;
254 
255  ValueNodePtr extract(const std::string& key);
256 
257  ValueNode& get(const std::string& key) const;
258 
259  ValueNode& operator[](const std::string& key) const {
260  return get(key);
261  }
262 
263  void insert(const std::string& key, ValueNode* node);
264 
265  void insert(const Mapping* other);
266 
267  Mapping* openMapping(const std::string& key) {
268  return openMapping(key, false);
269  }
270 
271  Mapping* openFlowStyleMapping(const std::string& key) {
272  return openFlowStyleMapping(key, false);
273  }
274 
275  Mapping* createMapping(const std::string& key) {
276  return openMapping(key, true);
277  }
278 
279  Mapping* createFlowStyleMapping(const std::string& key) {
280  return openFlowStyleMapping(key, true);
281  }
282 
283  Listing* openListing(const std::string& key) {
284  return openListing(key, false);
285  }
286 
287  Listing* openFlowStyleListing(const std::string& key){
288  return openFlowStyleListing(key, false);
289  }
290 
291  Listing* createListing(const std::string& key){
292  return openListing(key, true);
293  }
294 
295  Listing* createFlowStyleListing(const std::string& key){
296  return openFlowStyleListing(key, true);
297  }
298 
299  bool remove(const std::string& key);
300 
301  bool read(const std::string &key, std::string &out_value) const;
302  bool readUTF8(const std::string &key, std::string &out_value) const;
303  bool read(const std::string &key, bool &out_value) const;
304  bool read(const std::string &key, int &out_value) const;
305  bool read(const std::string &key, double &out_value) const;
306 
307  template <class T>
308  T read(const std::string& key) const {
309  T value;
310  if(read(key, value)){
311  return value;
312  } else {
313  throwKeyNotFoundException(key);
314  }
315  }
316 
317  template <class T>
318  T get(const std::string& key, const T& defaultValue) const {
319  T value;
320  if(read(key, value)){
321  return value;
322  } else {
323  return defaultValue;
324  }
325  }
326 
327  std::string get(const std::string& key, const char* defaultValue) const {
328  std::string value;
329  if(read(key, value)){
330  return value;
331  } else {
332  return defaultValue;
333  }
334  }
335 
336  void writeUTF8(const std::string &key, const std::string& value, StringStyle stringStyle = PLAIN_STRING);
337 
338  void write(const std::string &key, const std::string& value, StringStyle stringStyle = PLAIN_STRING) {
339  writeUTF8(key, toUTF8(value), stringStyle);
340  }
341 
342  void writeUTF8(const std::string &key, const char* value, StringStyle stringStyle = PLAIN_STRING){
343  writeUTF8(key, std::string(value), stringStyle);
344  }
345 
346  void write(const std::string &key, const char* value, StringStyle stringStyle = PLAIN_STRING){
347  write(key, std::string(value), stringStyle);
348  }
349 
350  void write(const std::string &key, bool value);
351  void write(const std::string &key, int value);
352  void write(const std::string &key, double value);
353  void writePath(const std::string &key, const std::string& value);
354 
355  typedef enum { READ_MODE, WRITE_MODE } AssignMode;
356 
357  void setAssignMode(AssignMode mode) { this->mode = mode; }
358 
359  template <class T>
360  void assign(const std::string& key, T& io_value, const T& defaultValue){
361  switch(mode){
362  case READ_MODE:
363  if(!read(key, io_value)){
364  io_value = defaultValue;
365  }
366  break;
367  case WRITE_MODE:
368  write(key, io_value);
369  break;
370  }
371  }
372 
373  iterator begin() { return values.begin(); }
374  iterator end() { return values.end(); }
375  const_iterator begin() const { return values.begin(); }
376  const_iterator end() const { return values.end(); }
377 
378  void throwKeyNotFoundException(const std::string& key) const;
379 
380 #ifdef CNOID_BACKWARD_COMPATIBILITY
381  Listing* findSequence(const std::string& key) const { return findListing(key); }
382  Listing* openSequence(const std::string& key) { return openListing(key); }
383  Listing* openFlowStyleSequence(const std::string& key){ return openFlowStyleListing(key); }
384  Listing* createSequence(const std::string& key){ return createListing(key); }
385  Listing* createFlowStyleSequence(const std::string& key){ return createFlowStyleListing(key); }
386 #endif
387 
388 private:
389 
390  Mapping(const Mapping& org);
391  Mapping& operator=(const Mapping&);
392 
393  Mapping* openMapping(const std::string& key, bool doOverwrite);
394  Mapping* openFlowStyleMapping(const std::string& key, bool doOverwrite);
395  Listing* openListing(const std::string& key, bool doOverwrite);
396  Listing* openFlowStyleListing(const std::string& key, bool doOverwrite);
397 
398  inline void insertSub(const std::string& key, ValueNode* node);
399 
400  void writeSub(const std::string &key, const char* text, size_t length, StringStyle stringStyle);
401 
402  static bool compareIters(const Mapping::const_iterator& it1, const Mapping::const_iterator& it2);
403 
404  Container values;
405  AssignMode mode;
406  int indexCounter;
407  const char* doubleFormat_;
408  bool isFlowStyle_;
409  StringStyle keyQuoteStyle;
410 
411  friend class Listing;
412  friend class YAMLReaderImpl;
413  friend class YAMLWriter;
414 };
415 
417 
418 
425 {
426  typedef std::vector<ValueNodePtr> Container;
427 
428 public:
429 
430  Listing();
431  Listing(int size);
432  ~Listing();
433 
434  virtual ValueNode* clone() const;
435 
436  typedef Container::iterator iterator;
437  typedef Container::const_iterator const_iterator;
438 
439  bool empty() const { return values.empty(); }
440  int size() const { return values.size(); }
441  void clear();
442  void reserve(int size);
443 
444  void setFlowStyle(bool isFlowStyle = true) { isFlowStyle_ = isFlowStyle; }
445  bool isFlowStyle() const { return isFlowStyle_; }
446 
447  void setDoubleFormat(const char* format);
448  const char* doubleFormat() { return doubleFormat_; }
449 
450  ValueNode* front() const {
451  return values.front();
452  }
453 
454  ValueNode* back() const {
455  return values.back();
456  }
457 
458  ValueNode* at(int i) const {
459  return values[i];
460  }
461 
465  ValueNode& get(int i) const {
466  return *values[i];
467  }
468 
469  void write(int i, int value);
470  void write(int i, const std::string& value, StringStyle stringStyle = PLAIN_STRING);
471 
475  ValueNode& operator[](int i) const {
476  return *values[i];
477  }
478 
480  //MappingPtr extractMapping(const std::string& key) const;
481 
482  Mapping* newMapping();
483 
484  void append(ValueNode* node) {
485  values.push_back(node);
486  }
487 
488  void insert(int index, ValueNode* node);
489 
490  void append(int value);
491 
497  void append(int value, int maxColumns, int numValues = 0) {
498  insertLF(maxColumns, numValues);
499  append(value);
500  }
501 
502  void append(size_t value);
503 
509  /*
510  void append(size_t value, int maxColumns, int numValues = 0){
511  insertLF(maxColumns, numValues);
512  append(value);
513  }
514  */
515 
516  void append(double value);
517 
523  void append(double value, int maxColumns, int numValues = 0) {
524  insertLF(maxColumns, numValues);
525  append(value);
526  }
527 
528  void append(const std::string& value, StringStyle stringStyle = PLAIN_STRING);
529 
535  void append(const std::string& value, int maxColumns, int numValues = 0, StringStyle stringStyle = PLAIN_STRING){
536  insertLF(maxColumns, numValues);
537  append(value, stringStyle);
538  }
539 
540  void appendLF();
541 
542  iterator begin() { return values.begin(); }
543  iterator end() { return values.end(); }
544  const_iterator begin() const { return values.begin(); }
545  const_iterator end() const { return values.end(); };
546 
547 private:
548 
549  Listing(int line, int column);
550  Listing(int line, int column, int reservedSize);
551 
552  Listing(const Listing& org);
553  Listing& operator=(const Listing&);
554 
555  void insertLF(int maxColumns, int numValues);
556 
557  Container values;
558  const char* doubleFormat_;
559  bool isFlowStyle_;
560  bool doInsertLFBeforeNextElement;
561 
562  friend class Mapping;
563  friend class YAMLReaderImpl;
564  friend class YAMLWriter;
565 };
566 
568 
569 #ifdef CNOID_BACKWARD_COMPATIBILITY
570 typedef ValueNode YamlNode;
571 typedef ValueNodePtr YamlNodePtr;
572 typedef ScalarNode YamlScalar;
573 typedef Mapping YamlMapping;
574 typedef MappingPtr YamlMappingPtr;
575 typedef Listing YamlSequence;
576 typedef ListingPtr YamlSequencePtr;
577 typedef Listing Sequence;
578 typedef ListingPtr SequencePtr;
579 #endif
580 }
581 
582 #endif
bool isFlowStyle() const
Definition: ValueTree.h:244
void setKey(const std::string &key)
Definition: ValueTree.h:133
void setAssignMode(AssignMode mode)
Definition: ValueTree.h:357
Definition: ValueTree.h:141
int column() const
Definition: ValueTree.h:103
int column() const
Definition: ValueTree.h:115
const std::string & toUTF8(const std::string &text)
Definition: UTF8.h:19
Listing * openListing(const std::string &key)
Definition: ValueTree.h:283
Listing * openFlowStyleListing(const std::string &key)
Definition: ValueTree.h:287
const char * doubleFormat()
Definition: ValueTree.h:247
void append(int value, int maxColumns, int numValues=0)
Definition: ValueTree.h:497
bool isMapping() const
Definition: ValueTree.h:81
Definition: ValueTree.h:224
void append(ValueNode *node)
Definition: ValueTree.h:484
int size() const
Definition: ValueTree.h:440
iterator begin()
Definition: ValueTree.h:542
Container::const_iterator const_iterator
Definition: ValueTree.h:231
const char * doubleFormat()
Definition: ValueTree.h:448
ValueNode(TypeBit type)
Definition: ValueTree.h:168
void write(const std::string &key, const char *value, StringStyle stringStyle=PLAIN_STRING)
Definition: ValueTree.h:346
ValueNode()
Definition: ValueTree.h:167
TypeBit LFType() const
Definition: ValueTree.h:52
Definition: YAMLWriter.h:18
Mapping * createMapping(const std::string &key)
Definition: ValueTree.h:275
void setFlowStyle(bool isFlowStyle=true)
Definition: ValueTree.h:444
bool isScalar() const
Definition: ValueTree.h:59
StringStyle
Definition: ValueTree.h:24
ValueNode & operator[](const std::string &key) const
Definition: ValueTree.h:259
Definition: Referenced.h:67
Container::iterator iterator
Definition: ValueTree.h:436
Definition: ValueTree.h:138
int line() const
Definition: ValueTree.h:114
bool empty() const
Definition: ValueTree.h:239
Listing & write(Mapping &mapping, const std::string &key, const Eigen::MatrixBase< Derived > &x)
Definition: EigenArchive.h:62
bool isFlowStyle() const
Definition: ValueTree.h:445
ValueNode * at(int i) const
Definition: ValueTree.h:458
const_iterator begin() const
Definition: ValueTree.h:375
Definition: ValueTree.h:24
void append(double value, int maxColumns, int numValues=0)
Definition: ValueTree.h:523
Mapping * openMapping(const std::string &key)
Definition: ValueTree.h:267
virtual ~ValueNode()
Definition: ValueTree.h:170
Definition: ValueTree.h:147
const std::string & key()
Definition: ValueTree.h:132
bool isListing() const
Definition: ValueTree.h:85
Definition: ValueTree.h:159
void writeUTF8(const std::string &key, const char *value, StringStyle stringStyle=PLAIN_STRING)
Definition: ValueTree.h:342
Definition: ValueTree.h:153
Listing * createListing(const std::string &key)
Definition: ValueTree.h:291
Definition: ValueTree.h:424
ValueNode & operator[](int i) const
Definition: ValueTree.h:475
bool isString() const
Definition: ValueTree.h:60
Listing * createFlowStyleListing(const std::string &key)
Definition: ValueTree.h:295
void append(const std::string &value, int maxColumns, int numValues=0, StringStyle stringStyle=PLAIN_STRING)
Definition: ValueTree.h:535
ref_ptr< ValueNode > ValueNodePtr
Definition: ValueTree.h:197
Mapping * openFlowStyleMapping(const std::string &key)
Definition: ValueTree.h:271
ref_ptr< Listing > ListingPtr
Definition: ValueTree.h:567
void read(const Listing &listing, Eigen::MatrixBase< Derived > &x)
Definition: EigenArchive.h:17
Defines the minimum processing for performing pasing file for STL.
Definition: AbstractSceneLoader.h:9
Definition: ValueTree.h:34
Definition: ValueTree.h:24
bool empty() const
Definition: ValueTree.h:439
Mapping * createFlowStyleMapping(const std::string &key)
Definition: ValueTree.h:279
Definition: ValueTree.h:150
bool hasLineInfo() const
Definition: ValueTree.h:101
Definition: ValueTree.h:130
void setPosition(int line, int column)
Definition: ValueTree.h:117
Definition: ValueTree.h:24
void setMessage(const std::string &m)
Definition: ValueTree.h:121
Container::const_iterator const_iterator
Definition: ValueTree.h:437
Definition: ValueTree.h:110
bool isValid() const
Definition: ValueTree.h:51
iterator end()
Definition: ValueTree.h:374
ref_ptr< Mapping > MappingPtr
Definition: ValueTree.h:416
void setFlowStyle(bool isFlowStyle=true)
Definition: ValueTree.h:243
int size() const
Definition: ValueTree.h:240
T read(const std::string &key) const
Definition: ValueTree.h:308
#define CNOID_EXPORT
Definition: Util/exportdecl.h:37
Definition: ValueTree.h:24
iterator begin()
Definition: ValueTree.h:373
const_iterator end() const
Definition: ValueTree.h:545
Container::iterator iterator
Definition: ValueTree.h:230
iterator end()
Definition: ValueTree.h:543
AssignMode
Definition: ValueTree.h:355
const_iterator end() const
Definition: ValueTree.h:376
int typeBits
Definition: ValueTree.h:176
TypeBit nodeType() const
Definition: ValueTree.h:53
ValueNode * front() const
Definition: ValueTree.h:450
const_iterator begin() const
Definition: ValueTree.h:544
void assign(const std::string &key, T &io_value, const T &defaultValue)
Definition: ValueTree.h:360
Definition: ValueTree.h:200
Definition: ValueTree.h:24
int line() const
Definition: ValueTree.h:102
void write(const std::string &key, const std::string &value, StringStyle stringStyle=PLAIN_STRING)
Definition: ValueTree.h:338
TypeBit
Definition: ValueTree.h:46
ValueNode * back() const
Definition: ValueTree.h:454