Added iterators to Setting sequences.
[platform/upstream/libconfig.git] / lib / libconfig.h++
1 /* ----------------------------------------------------------------------------
2    libconfig - A library for processing structured configuration files
3    Copyright (C) 2005-2010  Mark A Lindner
4
5    This file is part of libconfig.
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public License
9    as published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Library General Public
18    License along with this library; if not, see
19    <http://www.gnu.org/licenses/>.
20    ----------------------------------------------------------------------------
21 */
22
23 #ifndef __libconfig_hpp
24 #define __libconfig_hpp
25
26 #include <stdio.h>
27 #include <exception>
28 #include <string>
29
30 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
31 #if defined(LIBCONFIGXX_STATIC)
32 #define LIBCONFIGXX_API
33 #elif defined(LIBCONFIGXX_EXPORTS)
34 #define LIBCONFIGXX_API __declspec(dllexport)
35 #else /* ! LIBCONFIGXX_EXPORTS */
36 #define LIBCONFIGXX_API __declspec(dllimport)
37 #endif /* LIBCONFIGXX_STATIC */
38 #else /* ! WIN32 */
39 #define LIBCONFIGXX_API
40 #endif /* WIN32 */
41
42 #define LIBCONFIGXX_VER_MAJOR    1
43 #define LIBCONFIGXX_VER_MINOR    4
44 #define LIBCONFIGXX_VER_REVISION 9
45
46 struct config_t; // fwd decl
47 struct config_setting_t; // fwd decl
48
49 namespace libconfig {
50
51 class LIBCONFIGXX_API ConfigException : public std::exception { };
52
53 class Setting; // fwd decl
54 class SettingIterator;
55 class SettingConstIterator;
56
57 class LIBCONFIGXX_API SettingException : public ConfigException
58 {
59   friend class Config;
60
61   public:
62
63   SettingException(const SettingException &other);
64   SettingException& operator=(const SettingException &other);
65
66   virtual ~SettingException() throw();
67
68   const char *getPath() const;
69
70   virtual const char *what() const throw();
71
72   protected:
73
74   SettingException(const Setting &setting);
75   SettingException(const Setting &setting, int idx);
76   SettingException(const Setting &setting, const char *name);
77   SettingException(const char *path);
78
79   private:
80
81   char *_path;
82 };
83
84 class LIBCONFIGXX_API SettingTypeException : public SettingException
85 {
86   friend class Config;
87   friend class Setting;
88
89   public:
90
91   virtual const char *what() const throw();
92
93   private:
94
95   SettingTypeException(const Setting &setting);
96   SettingTypeException(const Setting &setting, int idx);
97   SettingTypeException(const Setting &setting, const char *name);
98 };
99
100 class LIBCONFIGXX_API SettingNotFoundException : public SettingException
101 {
102   friend class Config;
103   friend class Setting;
104
105   public:
106
107   virtual const char *what() const throw();
108
109   private:
110
111   SettingNotFoundException(const Setting &setting, int idx);
112   SettingNotFoundException(const Setting &setting, const char *name);
113   SettingNotFoundException(const char *path);
114 };
115
116 class LIBCONFIGXX_API SettingNameException : public SettingException
117 {
118   friend class Config;
119   friend class Setting;
120
121   public:
122
123   virtual const char *what() const throw();
124
125   private:
126
127   SettingNameException(const Setting &setting, const char *name);
128 };
129
130 class LIBCONFIGXX_API FileIOException : public ConfigException
131 {
132   public:
133
134   virtual const char *what() const throw();
135 };
136
137 class LIBCONFIGXX_API ParseException : public ConfigException
138 {
139   friend class Config;
140
141   public:
142
143   ParseException(const ParseException &other);
144
145   virtual ~ParseException() throw();
146
147   inline const char *getFile() const throw()
148   { return(_file); }
149
150   inline int getLine() const throw()
151   { return(_line); }
152
153   inline const char *getError() const throw()
154   { return(_error); }
155
156   virtual const char *what() const throw();
157
158   private:
159
160   ParseException(const char *file, int line, const char *error);
161
162   const char *_file;
163   int _line;
164   const char *_error;
165 };
166
167 class LIBCONFIGXX_API Setting
168 {
169   friend class Config;
170
171   public:
172
173   enum Type
174   {
175     TypeNone = 0,
176     // scalar types
177     TypeInt,
178     TypeInt64,
179     TypeFloat,
180     TypeString,
181     TypeBoolean,
182     // aggregate types
183     TypeGroup,
184     TypeArray,
185     TypeList
186   };
187
188   enum Format
189   {
190     FormatDefault = 0,
191     FormatHex = 1
192   };
193
194   typedef SettingIterator iterator;
195   typedef SettingConstIterator const_iterator;
196
197   private:
198
199   config_setting_t *_setting;
200   Type _type;
201   Format _format;
202
203   Setting(config_setting_t *setting);
204
205   void assertType(Type type) const throw(SettingTypeException);
206   static Setting & wrapSetting(config_setting_t *setting);
207
208   Setting(const Setting& other); // not supported
209   Setting& operator=(const Setting& other); // not supported
210
211   public:
212
213   virtual ~Setting() throw();
214
215   inline Type getType() const throw() { return(_type); }
216
217   inline Format getFormat() const throw() { return(_format); }
218   void setFormat(Format format) throw();
219
220   operator bool() const throw(SettingTypeException);
221   operator int() const throw(SettingTypeException);
222   operator unsigned int() const throw(SettingTypeException);
223   operator long() const throw(SettingTypeException);
224   operator unsigned long() const throw(SettingTypeException);
225   operator long long() const throw(SettingTypeException);
226   operator unsigned long long() const throw(SettingTypeException);
227   operator double() const throw(SettingTypeException);
228   operator float() const throw(SettingTypeException);
229   operator std::string() const throw(SettingTypeException);
230
231   const char *c_str() const throw(SettingTypeException);
232
233   Setting & operator=(bool value) throw(SettingTypeException);
234   Setting & operator=(int value) throw(SettingTypeException);
235   Setting & operator=(long value) throw(SettingTypeException);
236   Setting & operator=(const long long &value) throw(SettingTypeException);
237   Setting & operator=(const double &value) throw(SettingTypeException);
238   Setting & operator=(float value) throw(SettingTypeException);
239   Setting & operator=(const char *value) throw(SettingTypeException);
240   Setting & operator=(const std::string &value) throw(SettingTypeException);
241
242   Setting & lookup(const std::string &key) const;
243
244   inline Setting & operator[](const char *key) const
245   { return(lookup(key)); }
246
247   Setting & operator[](int index) const;
248
249   bool lookupValue(const char *name, bool &value) const throw();
250   bool lookupValue(const char *name, int &value) const throw();
251   bool lookupValue(const char *name, unsigned int &value) const throw();
252   bool lookupValue(const char *name, long long &value) const throw();
253   bool lookupValue(const char *name, unsigned long long &value)
254     const throw();
255   bool lookupValue(const char *name, double &value) const throw();
256   bool lookupValue(const char *name, float &value) const throw();
257   bool lookupValue(const char *name, const char *&value) const throw();
258   bool lookupValue(const char *name, std::string &value) const throw();
259
260   inline bool lookupValue(const std::string &name, bool &value)
261     const throw()
262   { return(lookupValue(name.c_str(), value)); }
263
264   inline bool lookupValue(const std::string &name, int &value)
265     const throw()
266   { return(lookupValue(name.c_str(), value)); }
267
268   inline bool lookupValue(const std::string &name, unsigned int &value)
269     const throw()
270   { return(lookupValue(name.c_str(), value)); }
271
272   inline bool lookupValue(const std::string &name, long long &value)
273     const throw()
274   { return(lookupValue(name.c_str(), value)); }
275
276   inline bool lookupValue(const std::string &name,
277                           unsigned long long &value) const throw()
278   { return(lookupValue(name.c_str(), value)); }
279
280   inline bool lookupValue(const std::string &name, double &value) const
281     throw()
282   { return(lookupValue(name.c_str(), value)); }
283
284   inline bool lookupValue(const std::string &name, float &value) const
285     throw()
286   { return(lookupValue(name.c_str(), value)); }
287
288   inline bool lookupValue(const std::string &name, const char *&value) const
289     throw()
290   { return(lookupValue(name.c_str(), value)); }
291
292   inline bool lookupValue(const std::string &name, std::string &value) const
293     throw()
294   { return(lookupValue(name.c_str(), value)); }
295
296   void remove(const char *name)
297     throw(SettingTypeException, SettingNotFoundException);
298
299   inline void remove(const std::string & name)
300     throw(SettingTypeException, SettingNotFoundException)
301   { remove(name.c_str()); }
302
303   void remove(unsigned int idx)
304     throw(SettingTypeException, SettingNotFoundException);
305
306   inline Setting & add(const std::string & name, Type type)
307     throw(SettingNameException, SettingTypeException)
308   { return(add(name.c_str(), type)); }
309
310   Setting & add(const char *name, Type type)
311     throw(SettingNameException, SettingTypeException);
312
313   Setting & add(Type type) throw(SettingTypeException);
314
315   inline bool exists(const std::string &name) const throw()
316   { return(exists(name.c_str())); }
317
318   bool exists(const char *name) const throw();
319
320   int getLength() const throw();
321   const char *getName() const throw();
322   std::string getPath() const;
323   int getIndex() const throw();
324
325   const Setting & getParent() const throw(SettingNotFoundException);
326   Setting & getParent() throw(SettingNotFoundException);
327
328   bool isRoot() const throw();
329
330   inline bool isGroup() const throw()
331   { return(_type == TypeGroup); }
332
333   inline bool isArray() const throw()
334   { return(_type == TypeArray); }
335
336   inline bool isList() const throw()
337   { return(_type == TypeList); }
338
339   inline bool isAggregate() const throw()
340   { return(_type >= TypeGroup); }
341
342   inline bool isScalar() const throw()
343   { return((_type > TypeNone) && (_type < TypeGroup)); }
344
345   inline bool isNumber() const throw()
346   { return((_type == TypeInt) || (_type == TypeInt64)
347            || (_type == TypeFloat)); }
348
349   unsigned int getSourceLine() const throw();
350   const char *getSourceFile() const throw();
351
352   iterator begin();
353   iterator end();
354
355   const_iterator begin() const;
356   const_iterator end() const;
357 };
358
359
360 class LIBCONFIGXX_API SettingIterator
361 {
362   private:
363
364   Setting *_setting;
365
366   int _count;
367   int _idx;
368
369   public:
370
371   SettingIterator(Setting &setting, bool endIterator = false);
372   SettingIterator(const SettingIterator &rhs);
373   SettingIterator& operator=(const SettingIterator &rhs);
374
375   // Equality comparison.
376   inline bool operator ==(SettingIterator const& rhs) const
377   { return _idx == rhs._idx; }
378
379   inline bool operator !=(SettingIterator const& rhs) const
380   { return ! (*this == rhs); }
381
382   bool operator <(SettingIterator const& rhs) const;
383
384   // Dereference operators.
385   inline Setting & operator *()  { return (*_setting)[_idx]; }
386   inline Setting * operator ->() { return &(*_setting)[_idx]; }
387
388   inline const Setting & operator *()  const { return (*_setting)[_idx]; }
389   inline const Setting * operator ->() const { return &(*_setting)[_idx]; }
390
391   // Increment and decrement operators.
392   SettingIterator& operator ++();
393   SettingIterator  operator ++(int);
394
395   SettingIterator& operator --();
396   SettingIterator  operator --(int);
397
398   // Arithmetic operators.
399   SettingIterator operator +(int offset) const;
400   SettingIterator& operator +=(int offset);
401
402   SettingIterator operator -(int offset) const;
403   SettingIterator& operator -=(int offset);
404
405   int operator -(const SettingIterator &rhs) const;
406 };
407
408 SettingIterator operator +(int offset, const SettingIterator &si);
409
410 class LIBCONFIGXX_API SettingConstIterator
411 {
412   private:
413
414   const Setting *_setting;
415
416   int _count;
417   int _idx;
418
419   public:
420
421   SettingConstIterator(const Setting &setting, bool endIterator = false);
422   SettingConstIterator(const SettingConstIterator &rhs);
423   SettingConstIterator& operator=(const SettingConstIterator &rhs);
424
425   // Equality comparison.
426   bool operator ==(SettingConstIterator const& rhs) const
427   { return _idx == rhs._idx; }
428
429   inline bool operator !=(SettingConstIterator const& rhs) const
430   { return ! (*this == rhs); }
431
432   // Dereference operators.
433   inline Setting const& operator *()  { return (*_setting)[_idx]; }
434   inline Setting const* operator ->() { return &(*_setting)[_idx]; }
435
436   inline const Setting& operator *()  const { return (*_setting)[_idx]; }
437   inline const Setting* operator ->() const { return &(*_setting)[_idx]; }
438
439   // Increment and decrement operators.
440   SettingConstIterator& operator ++();
441   SettingConstIterator  operator ++(int);
442
443   SettingConstIterator& operator --();
444   SettingConstIterator  operator --(int);
445
446   // Arithmetic operators.
447   SettingConstIterator operator +(int offset) const;
448   SettingConstIterator& operator +=(int offset);
449
450   SettingConstIterator operator -(int offset) const;
451   SettingConstIterator& operator -=(int offset);
452
453   int operator -(const SettingConstIterator &rhs) const;
454 };
455
456 SettingConstIterator operator +(int offset, const SettingConstIterator &si);
457
458 class LIBCONFIGXX_API Config
459 {
460   private:
461
462   config_t *_config;
463
464   static void ConfigDestructor(void *arg);
465   Config(const Config& other); // not supported
466   Config& operator=(const Config& other); // not supported
467
468   public:
469
470   Config();
471   Config(std::string const& cfgFile);
472
473   virtual ~Config();
474
475   void setAutoConvert(bool flag);
476   bool getAutoConvert() const;
477
478   void setDefaultFormat(Setting::Format format);
479   inline Setting::Format getDefaultFormat() const
480   { return(_defaultFormat); }
481
482   void setTabWidth(unsigned short width) throw();
483   unsigned short getTabWidth() const throw();
484
485   void setIncludeDir(const char *includeDir) throw();
486   const char *getIncludeDir() const throw();
487
488   void read(FILE *stream) throw(ParseException);
489   void write(FILE *stream) const;
490
491   void readString(const char *str) throw(ParseException);
492   inline void readString(const std::string &str) throw(ParseException)
493   { return(readString(str.c_str())); }
494
495   void readFile(const char *filename) throw(FileIOException, ParseException);
496   void writeFile(const char *filename) throw(FileIOException);
497
498   Setting & lookup(const std::string &path) const;
499
500   inline Setting & operator[](const char *path) const
501   { return(lookup(path)); }
502
503   inline bool exists(const std::string & path) const throw()
504   { return(exists(path.c_str())); }
505
506   bool exists(const char *path) const throw();
507
508   bool lookupValue(const char *path, bool &value) const throw();
509   bool lookupValue(const char *path, int &value) const throw();
510   bool lookupValue(const char *path, unsigned int &value) const throw();
511   bool lookupValue(const char *path, long long &value) const throw();
512   bool lookupValue(const char *path, unsigned long long &value)
513     const throw();
514   bool lookupValue(const char *path, double &value) const throw();
515   bool lookupValue(const char *path, float &value) const throw();
516   bool lookupValue(const char *path, const char *&value) const throw();
517   bool lookupValue(const char *path, std::string &value) const throw();
518
519   inline bool lookupValue(const std::string &path, bool &value) const throw()
520   { return(lookupValue(path.c_str(), value)); }
521
522   inline bool lookupValue(const std::string &path, int &value) const throw()
523   { return(lookupValue(path.c_str(), value)); }
524
525   inline bool lookupValue(const std::string &path, unsigned int &value)
526     const throw()
527   { return(lookupValue(path.c_str(), value)); }
528
529   inline bool lookupValue(const std::string &path, long long &value)
530     const throw()
531   { return(lookupValue(path.c_str(), value)); }
532
533   inline bool lookupValue(const std::string &path,
534                           unsigned long long &value) const throw()
535   { return(lookupValue(path.c_str(), value)); }
536
537   inline bool lookupValue(const std::string &path, double &value)
538     const throw()
539   { return(lookupValue(path.c_str(), value)); }
540
541   inline bool lookupValue(const std::string &path, float &value)
542     const throw()
543   { return(lookupValue(path.c_str(), value)); }
544
545   inline bool lookupValue(const std::string &path, const char *&value)
546     const throw()
547   { return(lookupValue(path.c_str(), value)); }
548
549   inline bool lookupValue(const std::string &path, std::string &value)
550     const throw()
551   { return(lookupValue(path.c_str(), value)); }
552
553   Setting & getRoot() const;
554
555   private:
556
557   Setting::Format _defaultFormat;
558
559   void handleError() const;
560 };
561
562 } // namespace libconfig
563
564 #endif // __libconfig_hpp