neoWidgets
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
Config.h
1 #ifndef NEO_CONFIG_H
2 #define NEO_CONFIG_H
3 
4 namespace neo
5 {
6 
14 class Config
15 {
16 public:
17  virtual ~Config() {}
18 
22  bool Write(const tstring& key, const tstring& value)
23  {
24  return _SetStringImp(key, value);
25  }
29  bool Read(const tstring& key, tstring& result) const
30  {
31  return _GetStringImp(key, result);
32  }
33 
61  template<typename T>
62  bool Write(const tstring& key, const T& value)
63  {
64  return configStructWrite(*this, key, value);
65  }
66 
94  template<typename T>
95  bool Read(const tstring& key, T& result) const
96  {
97  return configStructRead(*this, key, result);
98  }
99 
103  void SaveWindowPosition(const tstring& key, HWND window)
104  {
105  Rect r;
106  GetWindowRect(window, &r);
107  Write(key, r);
108  }
109 
113  void RestoreWindowPosition(const tstring& key, HWND window)
114  {
115  Rect r;
116  if(Read(key, r))
117  MoveWindow(window, r.left, r.top, r.Width(), r.Height(), TRUE);
118  }
119 
123  virtual bool Remove(const tstring& key) { return false; }
127  virtual bool RemoveEntireConfig() { return false; }
128 protected:
132  virtual bool _SetStringImp(const tstring& key, const tstring& value) = 0;
136  virtual bool _GetStringImp(const tstring& key, tstring& result) const = 0;
137 
141  static std::string ToUtf8(const tstring& text)
142  {
143  static_assert(sizeof(TCHAR) == sizeof(wchar_t), "The config classes only work correctly if the project is setup as Unicode");
144  int n = WideCharToMultiByte(CP_UTF8, 0, text.c_str(), -1, 0, 0, 0, 0);
145  std::string result;
146  if(n > 0)
147  {
148  result.resize(n-1);
149  n = WideCharToMultiByte(CP_UTF8, 0, text.c_str(), -1, &result[0], n, 0, 0);
150  }
151  return result;
152  }
156  static tstring FromUtf8(const std::string& text)
157  {
158  static_assert(sizeof(TCHAR) == sizeof(wchar_t), "The config classes only work correctly if the project is setup as Unicode");
159  int n = MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, 0, 0);
160  tstring result;
161  if(n > 0)
162  {
163  result.resize(n-1);
164  n = MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, &result[0], n);
165  }
166  return result;
167  }
168 private:
169  // Read with generic type and conversion.
170  template<class T, class FROMSTRING>
171  bool Read(const tstring& key, T& result, FROMSTRING fromString) const
172  {
173  tstring buffer;
174  if(_GetStringImp(key, buffer))
175  {
176  result = fromString(buffer);
177  return true;
178  }
179  return false;
180  }
181 };
182 
186 class RegistryConfig : public Config
187 {
188 public:
192  RegistryConfig();
196  RegistryConfig(const tstring& subKey, HKEY topKey = HKEY_CURRENT_USER);
205  ~RegistryConfig();
206 
211  bool Open(const tstring& subKey, HKEY topKey = HKEY_CURRENT_USER);
212 
213  virtual bool Remove(const tstring& key);
214  virtual bool RemoveEntireConfig();
215 protected:
216  bool _SetStringImp(const tstring& key, const tstring& value);
217  bool _GetStringImp(const tstring& key, tstring& result) const;
218 private:
219  HKEY openedKey;
220 };
221 
227 class iniConfig : public Config
228 {
229 public:
233  iniConfig();
237  iniConfig(const tstring& filepath);
238  ~iniConfig();
239 
243  bool Open(const tstring& filepath);
247  bool Save();
248 
256  void SetCurrentSection(const tstring& section);
257 
258  virtual bool Remove(const tstring& key);
259  virtual bool RemoveEntireConfig();
260 protected:
261  bool _SetStringImp(const tstring& key, const tstring& value);
262  bool _GetStringImp(const tstring& key, tstring& result) const;
263 private:
264  tstring Trim(const tstring& text);
265 
266  struct iniLine
267  {
268  iniLine()
269  {
270  isSection = false;
271  isKey = false;
272  }
273  iniLine(const iniLine& rhs)
274  : text1(rhs.text1)
275  , text2(rhs.text2)
276  , isSection(rhs.isSection)
277  , isKey(rhs.isKey)
278  {}
279  iniLine& operator=(const iniLine& rhs)
280  {
281  text1 = rhs.text1;
282  text2 = rhs.text2;
283  isSection = std::move(rhs.isSection);
284  isKey = std::move(rhs.isKey);
285  return *this;
286  }
287  iniLine(iniLine&& rhs)
288  : text1(std::move(rhs.text1))
289  , text2(std::move(rhs.text2))
290  , isSection(rhs.isSection)
291  , isKey(rhs.isKey)
292  {}
293  iniLine& operator=(iniLine&& rhs)
294  {
295  text1 = std::move(rhs.text1);
296  text2 = std::move(rhs.text2);
297  isSection = std::move(rhs.isSection);
298  isKey = std::move(rhs.isKey);
299  return *this;
300  }
301 
302  tstring text1;
303  tstring text2;
304  bool isSection;
305  bool isKey;
306  };
307 
308  typedef std::vector<iniLine> LINES;
309  typedef std::vector<size_t> SECTION_INDEX;
310  typedef std::vector<size_t> KEY_INDEX;
311 
312  LINES lines; // hold every line of the file separately
313  SECTION_INDEX sections; // maintain index buffer to sections, for fast lookup
314  SECTION_INDEX::iterator currentSectionIt;
315  tstring filepath; // remember the file
316  bool modified; // remember modification for automatic saving
317 
318  SECTION_INDEX::iterator _FindSection(size_t index);
319  SECTION_INDEX::iterator _FindSection(const tstring& section);
320  SECTION_INDEX::const_iterator _FindSection(const tstring& section) const;
321  size_t _FindValue(SECTION_INDEX::iterator section, const tstring& key) const;
322  void _AppendSection(const tstring& section);
323  void _AppendLine(const iniLine& line);
324  void _RebuildSectionIndices();
325 };
326 
327 } // namespace neo
328 
329 #endif
Configuration that writes to an ini-file.
Definition: Config.h:227
virtual bool RemoveEntireConfig()
Removes all values in the config, but the config can still used afterwards.
Definition: Config.h:127
virtual bool Remove(const tstring &key)
Remove a single value.
Definition: Config.inl:193
bool Read(const tstring &key, tstring &result) const
Basic read function.
Definition: Config.h:29
iniConfig()
Unusable until Open() is called.
Definition: Config.inl:92
bool _SetStringImp(const tstring &key, const tstring &value)
Every config value is internally saved as a string.
Definition: Config.inl:40
bool _GetStringImp(const tstring &key, tstring &result) const
Every config value is internally saved as a string.
Definition: Config.inl:241
bool Write(const tstring &key, const tstring &value)
Basic write function.
Definition: Config.h:22
virtual bool _SetStringImp(const tstring &key, const tstring &value)=0
Every config value is internally saved as a string.
void SetCurrentSection(const tstring &section)
Set the section used by Read() and Write()
Definition: Config.inl:179
bool _SetStringImp(const tstring &key, const tstring &value)
Every config value is internally saved as a string.
Definition: Config.inl:222
Interface for all configuration classes.
Definition: Config.h:14
RegistryConfig & operator=(RegistryConfig &&other)
Move assignment.
Definition: Config.inl:21
virtual bool _GetStringImp(const tstring &key, tstring &result) const =0
Every config value is internally saved as a string.
bool Open(const tstring &subKey, HKEY topKey=HKEY_CURRENT_USER)
Definition: Config.inl:34
bool Open(const tstring &filepath)
Opens an ini file.
Definition: Config.inl:114
bool _GetStringImp(const tstring &key, tstring &result) const
Every config value is internally saved as a string.
Definition: Config.inl:51
virtual bool RemoveEntireConfig()
Removes all values in the config, but the config can still used afterwards.
Definition: Config.inl:213
virtual bool Remove(const tstring &key)
Remove a single value.
Definition: Config.h:123
Windows RECT structure with constructor.
Definition: Rect.h:108
virtual bool Remove(const tstring &key)
Remove a single value.
Definition: Config.inl:75
Configuration that writes to the Window registry.
Definition: Config.h:186
bool Save()
The config is saved in the destructor. This function allows to manually start the saving...
Definition: Config.inl:155
static std::string ToUtf8(const tstring &text)
All config should be saved as UTF-8 for portability.
Definition: Config.h:141
RegistryConfig()
Unusable until Open() is called.
Definition: Config.inl:4
static tstring FromUtf8(const std::string &text)
All config should be saved as UTF-8 for portability.
Definition: Config.h:156
bool Write(const tstring &key, const T &value)
Extendable version of Write.
Definition: Config.h:62
bool Read(const tstring &key, T &result) const
Extendable version of Read.
Definition: Config.h:95
virtual bool RemoveEntireConfig()
Removes all values in the config, but the config can still used afterwards.
Definition: Config.inl:82
void SaveWindowPosition(const tstring &key, HWND window)
Convenience function for window position.
Definition: Config.h:103
void RestoreWindowPosition(const tstring &key, HWND window)
Convenience function for window position.
Definition: Config.h:113