DSL
config2.h
1 //@AUTOHEADER@BEGIN@
2 /***********************************************************************\
3 | Drift Standard Libraries v1.01 |
4 | Copyright 2010-2024 Drift Solutions / Indy Sams |
5 | Docs and more information available at https://www.driftsolutions.dev |
6 | This file released under the 3-clause BSD license, |
7 | see included DSL.LICENSE.TXT file for details. |
8 \***********************************************************************/
9 //@AUTOHEADER@END@
10 
11 #ifndef __UNIVERSAL_CONFIG2_H__
12 #define __UNIVERSAL_CONFIG2_H__
13 
14 /*
15 enum DS_VALUE_TYPE {
16  DS_TYPE_LONG,
17  DS_TYPE_FLOAT,
18  DS_TYPE_STRING,
19  DS_TYPE_BINARY
20 };
21 */
22 
23 class ConfigSection;
24 
25 class DSL_API_CLASS ConfigValue {
26  friend class ConfigSection;
27 private:
28  bool isBool(const char * buf, bool * val = NULL);
29  bool isInt(const char * text);
30  bool isFloat(const char * text);
31 
32 protected:
33  string sString;
34  union {
35  int64 Int;
36  double Float;
37  };
38 
39 public:
40  ConfigValue();
41  ~ConfigValue();
42 
43  DS_VALUE_TYPE Type;
44 
45  int64 AsInt() const;
46  double AsFloat() const;
47  string AsString() const;
48  bool AsBool() const; /* true if it is an int > 0, double >= 1.00, or the strings "true" or "on" */
49 
50  void SetValue(const ConfigValue& val);
51  void SetValue(int64 val);
52  void SetValue(double val);
53  void SetValue(const char * val);
54  void SetValue(const string& val);
55  void SetValue(const uint8_t * val, size_t len);
56  void SetValue(bool val);
57 
58  void Reset();
59  void ParseString(const char * value);
60 };
61 
62 // case-independent (ci) string less_than
63 // returns true if s1 < s2
64 #if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
65 struct uc_less {
66  // case-independent (ci) compare_less binary function
67  struct nocase_compare {
68  bool operator() (const unsigned char& c1, const unsigned char& c2) const {
69  return tolower(c1) < tolower(c2);
70  }
71  };
72  bool operator() (const std::string & s1, const std::string & s2) const {
73  return std::lexicographical_compare
74  (s1.begin(), s1.end(), // source range
75  s2.begin(), s2.end(), // dest range
76  nocase_compare()); // comparison
77  }
78  };
79 #else
80 struct uc_less {
81 
82  // case-independent (ci) compare_less binary function
83  struct nocase_compare : public binary_function<unsigned char, unsigned char, bool> {
84  bool operator() (const unsigned char& c1, const unsigned char& c2) const {
85  return tolower(c1) < tolower(c2);
86  }
87  };
88 
89  bool operator() (const string & s1, const string & s2) const {
90 
91  return lexicographical_compare
92  (s1.begin(), s1.end(), // source range
93  s2.begin(), s2.end(), // dest range
94  nocase_compare()); // comparison
95  }
96 }; // end of uc_less
97 #endif
98 
99 class DSL_API_CLASS ConfigSection {
100 protected:
101  typedef map<string, ConfigValue *, uc_less> valueList;
102  typedef map<string, ConfigSection *, uc_less> sectionList;
103 
104  valueList _values;
105  sectionList _sections; // sub-sections
106 
107  virtual bool loadFromString(const char ** config, size_t& line, const char * fn);
108 
109  virtual void writeSection(stringstream& sstr, int level, bool single = false) const;
110  void printSection(size_t level) const;
111  /*
112  void FreeSection(ConfigSection * Scan);
113  void WriteBinarySection(FILE * fp, ConfigSection * sec);
114  */
115 public:
116  string name;
117  const sectionList& sections = _sections;
118  const valueList& values = _values;
119 
120  void Clear();
121  void PrintConfigTree() const;
122 
123  bool LoadFromString(const string& config, const string& filename);
124  bool LoadFromFile(const string& filename);
125  bool LoadFromFile(FILE * fp, const string& filename);
126  string WriteToString() const;
127  bool WriteToFile(const string& filename) const;
128  bool WriteToFile(FILE * fp) const;
129 
130  ConfigSection * GetSection(const string& name);
131  const ConfigValue * GetValue(const string& name) const;
132  bool GetValue(const string& name, ConfigValue& value) const;
133  bool HasValue(const string& name) const;
134  void SetValue(const string& name, const ConfigValue& val);
135 
136  // advanced commands
137  virtual ConfigSection * FindOrAddSection(const string& name);
138 
139  ~ConfigSection();
140 };
141 
142 class DSL_API_CLASS ConfigINI: public ConfigSection {
143 protected:
144  ConfigINI * parent = NULL;
145  virtual bool loadFromString(const char ** config, size_t& line, const char * fn);
146  virtual void writeSection(stringstream& sstr, int level, bool single = false) const;
147 public:
148  virtual ConfigINI * FindOrAddSection(const string& name);
149 };
150 
151 #endif // __UNIVERSAL_CONFIG2_H__