libqutim  0.3.1.0
config.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** qutIM - instant messenger
4 **
5 ** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
6 **
7 *****************************************************************************
8 **
9 ** $QUTIM_BEGIN_LICENSE$
10 ** This program is free software: you can redistribute it and/or modify
11 ** it under the terms of the GNU General Public License as published by
12 ** the Free Software Foundation, either version 3 of the License, or
13 ** (at your option) any later version.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 ** See the GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program. If not, see http://www.gnu.org/licenses/.
22 ** $QUTIM_END_LICENSE$
23 **
24 ****************************************************************************/
25 
26 #ifndef CONFIG_H
27 #define CONFIG_H
28 
29 #include "libqutim_global.h"
30 #include <QVariant>
31 #include <QSharedData>
32 #include <QMetaTypeId>
33 
34 namespace qutim_sdk_0_3
35 {
36 #ifndef Q_QDOC
37 namespace EnumDetectorHelper
38 {
39  typedef quint8 Yes;
40  typedef quint16 No;
41 
42  // Check if type can be casted to int
43  inline Yes is_int_type(int) { return Yes(); }
44  inline No is_int_type(...) { return No(); }
45 
46  template <int Defined, int Size>
47  class Helper
48  {
49  public:
50  static No value() { return No(); }
51  };
52 
53  template <>
54  class Helper<0, sizeof(Yes)>
55  {
56  public:
57  static Yes value() { return Yes(); }
58  };
59 
60  template <typename T, int IsEnum>
61  class VariantCastHelper
62  {
63  public:
64  static QVariant convertToVariant(const T &t)
65  { return QVariant::fromValue(t); }
66  static T convertFromVariant(const QVariant &t)
67  { return t.value<T>(); }
68  };
69 
70  template <typename T>
71  class VariantCastHelper <T, sizeof(Yes)>
72  {
73  public:
74  static QVariant convertToVariant(const T &t)
75  { return QVariant::fromValue(int(t)); }
76  static T convertFromVariant(const QVariant &v)
77  { return static_cast<T>(v.toInt()); }
78  };
79 
80  template <typename T, int Defined>
81  class VariantCastHelper3
82  {
83  public:
84  static QVariant convertToVariant(const T &t)
85  {
86  return VariantCastHelper<T, sizeof(No)>::convertToVariant(t);
87  }
88  static T convertFromVariant(const QVariant &v)
89  {
90  return VariantCastHelper<T, sizeof(No)>::convertFromVariant(v);
91  }
92  };
93 
94  // Enums are not registered in Qt meta system and they can be casted to int easily
95  template <typename T>
96  class VariantCastHelper3 <T, 0>
97  {
98  public:
99  static QVariant convertToVariant(const T &t)
100  {
101  return VariantCastHelper<T, sizeof(Helper<QMetaTypeId2<T>::Defined, sizeof(is_int_type(*reinterpret_cast<T*>(0)))>::value())>::convertToVariant(t);
102  }
103  static T convertFromVariant(const QVariant &v)
104  {
105  return VariantCastHelper<T, sizeof(Helper<QMetaTypeId2<T>::Defined, sizeof(is_int_type(*reinterpret_cast<T*>(0)))>::value())>::convertFromVariant(v);
106  }
107  };
108 
109  // Enums are not registered in Qt meta system, so check it before possibility of cast to int
110  // because QByteArray has "operator int()" in private section
111  template <typename T>
112  class VariantCastHelper2
113  {
114  public:
115  static QVariant convertToVariant(const T &t)
116  {
117  return VariantCastHelper3<T, QMetaTypeId2<T>::Defined>::convertToVariant(t);
118  }
119  static T convertFromVariant(const QVariant &v)
120  {
121  return VariantCastHelper3<T, QMetaTypeId2<T>::Defined>::convertFromVariant(v);
122  }
123  };
124 }
125 #endif
126 class ConfigPrivate;
127 class ConfigBackend;
128 class ConfigBackendPrivate;
129 
131 {
132  Q_DECLARE_PRIVATE(Config)
133 public:
134  enum ValueFlag { Normal = 0x00, Crypted = 0x01 };
135  Q_DECLARE_FLAGS(ValueFlags, ValueFlag)
136 
137  Config(const QVariantList &list);
138  Config(QVariantList *list);
139  Config(const QVariantMap &map);
140  Config(QVariantMap *map);
141  Config(const QString &path = QString());
142  Config(const QString &path, ConfigBackend *backend);
143  Config(const QStringList &paths);
144  Config(const QString &path, const QVariantList &fallbacks);
145  Config(const QString &path, const QVariant &fallback);
146  Config(const Config &other);
147  Config &operator =(const Config &other);
148  virtual ~Config();
149 
150  Config group(const QString &name) Q_REQUIRED_RESULT;
151  QStringList childGroups() const Q_REQUIRED_RESULT;
152  QStringList childKeys() const Q_REQUIRED_RESULT;
153  bool hasChildGroup(const QString &name) const Q_REQUIRED_RESULT;
154  bool hasChildKey(const QString &name) const Q_REQUIRED_RESULT;
155  void beginGroup(const QString &name);
156  void endGroup();
157  void remove(const QString &name);
158 
159  Config arrayElement(int index) Q_REQUIRED_RESULT;
160  int beginArray(const QString &name);
161  void endArray();
162  int arraySize() const Q_REQUIRED_RESULT;
163  void setArrayIndex(int index);
164  void remove(int index);
165 
166  QVariant rootValue(const QVariant &def = QVariant(), ValueFlags type = Normal) const Q_REQUIRED_RESULT;
167  template<typename T>
168  T value(const QString &key, const T &def = T(), ValueFlags type = Normal) const Q_REQUIRED_RESULT;
169  QVariant value(const QString &key, const QVariant &def = QVariant(), ValueFlags type = Normal) const Q_REQUIRED_RESULT;
170  inline QString value(const QString &key, const QLatin1String &def, ValueFlags type = Normal) const Q_REQUIRED_RESULT;
171  inline QString value(const QString &key, const char *def, ValueFlags type = Normal) const Q_REQUIRED_RESULT;
172  template <int N>
173  QString value(const QString &key, const char (&def)[N], ValueFlags type = Normal) const Q_REQUIRED_RESULT;
174  template<typename T>
175  void setValue(const QString &key, const T &value, ValueFlags type = Normal);
176  void setValue(const QString &key, const QVariant &value, ValueFlags type = Normal);
177  inline void setValue(const QString &key, const QLatin1String &value, ValueFlags type = Normal);
178  inline void setValue(const QString &key, const char *value, ValueFlags type = Normal);
179  template <int N>
180  void setValue(const QString &key, const char (&value)[N], ValueFlags type = Normal);
181 
182  void sync();
183 
184  typedef void (*SaveOperator)(QVariant &, const void *);
185  typedef void (*LoadOperator)(const QVariant &, void *);
186  static void registerType(int type, SaveOperator saveOp, LoadOperator loadOp);
187 private:
188  QExplicitlySharedDataPointer<ConfigPrivate> d_ptr;
189 };
190 
191 template <typename T>
192 void configSaveHelper(QVariant &var, const T *t)
193 {
194  var = QVariant::fromValue(t);
195 }
196 
197 template <typename T>
198 void configLoadHelper(const QVariant &var, T *t)
199 {
200  *t = var.value<T>();
201 }
202 
203 template <typename T>
204 void registerConfigType(T * /* dummy */ = 0)
205 {
206  typedef void (*SavePtr)(QVariant &, const T *);
207  typedef void (*LoadPtr)(const QVariant &, T *);
208  SavePtr sptr = configSaveHelper<T>();
209  LoadPtr lptr = configLoadHelper<T>();
210 
211  Config::registerType(qRegisterMetaType<T>(),
212  reinterpret_cast<Config::SaveOperator>(sptr),
213  reinterpret_cast<Config::LoadOperator>(lptr));
214 }
215 
218 
219 class LIBQUTIM_EXPORT ConfigBackend : public QObject
220 {
221  Q_OBJECT
222  Q_DECLARE_PRIVATE(ConfigBackend)
223 public:
224  ConfigBackend();
225  virtual ~ConfigBackend();
226 
227  virtual QVariant load(const QString &file) = 0;
228  virtual void save(const QString &file, const QVariant &entry) = 0;
229 
230  QByteArray name() const;
231 protected:
232  virtual void virtual_hook(int id, void *data);
233 private:
234  QScopedPointer<ConfigBackendPrivate> d_ptr;
235 };
236 
237 template<typename T>
238 Q_INLINE_TEMPLATE T Config::value(const QString &key, const T &def, Config::ValueFlags type) const
239 {
240  QVariant defVar = EnumDetectorHelper::VariantCastHelper2<T>::convertToVariant(def);
241  return EnumDetectorHelper::VariantCastHelper2<T>::convertFromVariant(value(key, defVar, type));
242 }
243 
244 template<typename T>
245 Q_INLINE_TEMPLATE void Config::setValue(const QString &key, const T &value, Config::ValueFlags type)
246 {
247  setValue(key, EnumDetectorHelper::VariantCastHelper2<T>::convertToVariant(value), type);
248 }
249 
250 QString Config::value(const QString &key, const QLatin1String &def, ValueFlags type) const
251 {
252  return value(key, QString(def), type);
253 }
254 
255 QString Config::value(const QString &key, const char *def, ValueFlags type) const
256 {
257  return value(key, QString::fromUtf8(def), type);
258 }
259 
260 template <int N>
261 Q_INLINE_TEMPLATE QString Config::value(const QString &key, const char (&def)[N], ValueFlags type) const
262 {
263  return value(key, QString::fromUtf8(def, N-1), type);
264 }
265 
266 void Config::setValue(const QString &key, const QLatin1String &value, ValueFlags type)
267 {
268  setValue(key, QString(value), type);
269 }
270 
271 void Config::setValue(const QString &key, const char *value, ValueFlags type)
272 {
273  setValue(key, QString::fromUtf8(value), type);
274 }
275 
276 template <int N>
277 Q_INLINE_TEMPLATE void Config::setValue(const QString &key, const char (&value)[N], ValueFlags type)
278 {
279  setValue(key, QString::fromUtf8(value, N-1), type);
280 }
281 }
282 
283 // Config() is synonym for Config("profile"), so redefine construct method for it
284 template <>
285 Q_INLINE_TEMPLATE void *qMetaTypeConstructHelper<qutim_sdk_0_3::Config>(const qutim_sdk_0_3::Config *t)
286 {
287 if (!t) {
288  return new qutim_sdk_0_3::Config(QVariantMap());
289 }
290 return new qutim_sdk_0_3::Config(*t);
291 }
292 
294 
295 #endif // CONFIG_H
296 

Generated by Doxygen