QtGStreamer  1.2.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
value.h
1 /*
2  Copyright (C) 2009-2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
3  Copyright (C) 2010 Collabora Ltd.
4  @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
5 
6  This library is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation; either version 2.1 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef QGLIB_VALUE_H
20 #define QGLIB_VALUE_H
21 
22 #include "global.h"
23 #include "type.h"
24 #include "refpointer.h"
25 #include "error.h"
26 #include <boost/mpl/if.hpp>
27 #include <boost/type_traits.hpp>
28 #include <stdexcept>
29 #include <QtCore/QString>
30 #include <QtCore/QDebug>
31 #include <QtCore/QSharedData>
32 
33 namespace QGlib {
34 
42 struct QTGLIB_EXPORT ValueVTable
43 {
44  typedef void (*SetFunction)(Value & value, const void *data);
45  typedef void (*GetFunction)(const Value & value, void *data);
46 
47  inline ValueVTable() : set(NULL), get(NULL) {}
48  inline ValueVTable(SetFunction s, GetFunction g) : set(s), get(g) {}
49 
50  SetFunction set;
51  GetFunction get;
52 };
53 
54 
74 class QTGLIB_EXPORT Value
75 {
76 public:
78  Value();
79 
81  explicit Value(const GValue *gvalue);
82 
90  explicit Value(Type type);
91 
92  Value(bool val);
93  Value(char val);
94  Value(uchar val);
95  Value(int val);
96  Value(uint val);
97  Value(long val);
98  Value(ulong val);
99  Value(qint64 val);
100  Value(quint64 val);
101  Value(float val);
102  Value(double val);
103  Value(const char *val);
104  Value(const QByteArray & val);
105  Value(const QString & val);
106 
107  Value(const Value & other);
108  Value & operator=(const Value & other);
109 
110  virtual ~Value();
111 
112 
118  template <typename T>
119  static inline Value create(const T & data);
120 
121 
125  void init(Type type);
126 
132  template <typename T>
133  inline void init();
134 
135 
138  bool isValid() const;
139 
141  Type type() const;
142 
144  bool canTransformTo(Type type) const;
145 
150  Value transformTo(Type type) const;
151 
154  void clear();
155 
156 
178  template <typename T> T get(bool *ok = NULL) const;
179 
190  template <typename T> void set(const T & data);
191 
192 
194  inline bool toBool(bool *ok = NULL) const { return get<bool>(ok); }
195 
197  inline char toChar(bool *ok = NULL) const { return get<char>(ok); }
198 
200  inline uchar toUChar(bool *ok = NULL) const { return get<uchar>(ok); }
201 
203  inline int toInt(bool *ok = NULL) const { return get<int>(ok); }
204 
206  inline uint toUInt(bool *ok = NULL) const { return get<uint>(ok); }
207 
209  inline long toLong(bool *ok = NULL) const { return get<long>(ok); }
210 
212  inline ulong toULong(bool *ok = NULL) const { return get<ulong>(ok); }
213 
215  inline qint64 toInt64(bool *ok = NULL) const { return get<qint64>(ok); }
216 
218  inline quint64 toUInt64(bool *ok = NULL) const { return get<quint64>(ok); }
219 
221  inline QByteArray toByteArray(bool *ok = NULL) const { return get<QByteArray>(ok); }
222 
224  inline QString toString(bool *ok = NULL) const { return get<QString>(ok); }
225 
227  inline Error toError(bool *ok = NULL) const { return get<Error>(ok); }
228 
235  operator GValue*();
236  operator const GValue*() const;
237 
238 
245  static void registerValueVTable(Type type, const ValueVTable & vtable);
246 
247 private:
248  template <typename T>
249  friend struct ValueImpl;
250 
258  void getData(Type dataType, void *data) const;
259 
267  void setData(Type dataType, const void *data);
268 
269  struct Data;
270  QSharedDataPointer<Data> d;
271 };
272 
273 
282 template <typename T>
283 struct ValueImpl
284 {
285  static inline T get(const Value & value);
286  static inline void set(Value & value, const T & data);
287 };
288 
289 // -- template implementations --
290 
291 //static
292 template <typename T>
293 inline Value Value::create(const T & data)
294 {
295  Value v;
296  v.init<T>();
297  v.set(data);
298  return v;
299 }
300 
301 template <typename T>
302 inline void Value::init()
303 {
304  init(GetType<T>());
305 }
306 
307 template <typename T>
308 T Value::get(bool *ok) const
309 {
310  if (ok) {
311  *ok = true;
312  }
313 
314  try {
315  return ValueImpl<T>::get(*this);
316  } catch (const std::exception &) {
317  if (ok) {
318  *ok = false;
319  }
320  return T();
321  }
322 }
323 
324 template <typename T>
325 void Value::set(const T & data)
326 {
327  try {
328  ValueImpl<T>::set(*this, data);
329  } catch (const std::exception & e) {
330  qWarning() << "QGlib::Value::set:" << e.what();
331  }
332 }
333 
334 // -- default ValueImpl implementation --
335 
336 template <typename T>
337 inline T ValueImpl<T>::get(const Value & value)
338 {
339  //Use int for enums, T for everything else
340  typename boost::mpl::if_<
341  boost::is_enum<T>,
342  int, T
343  >::type result;
344 
345  value.getData(GetType<T>(), &result);
346  return static_cast<T>(result);
347 }
348 
349 template <typename T>
350 inline void ValueImpl<T>::set(Value & value, const T & data)
351 {
352  //Use const int for enums, const T for everything else
353  typename boost::mpl::if_<
354  boost::is_enum<T>,
355  const int, const T &
356  >::type dataRef = data;
357 
358  value.setData(GetType<T>(), &dataRef);
359 }
360 
361 // -- ValueImpl specialization for QFlags --
362 
363 template <class T>
364 struct ValueImpl< QFlags<T> >
365 {
366  static inline QFlags<T> get(const Value & value)
367  {
368  uint flags;
369  value.getData(GetType< QFlags<T> >(), &flags);
370  return QFlags<T>(QFlag(flags));
371  }
372 
373  static inline void set(Value & value, const QFlags<T> & data)
374  {
375  uint flags = data;
376  value.setData(GetType< QFlags<T> >(), &flags);
377  }
378 };
379 
380 // -- ValueImpl specialization for RefPointer --
381 
382 template <class T>
383 struct ValueImpl< RefPointer<T> >
384 {
385  static inline RefPointer<T> get(const Value & value)
386  {
387  typename T::CType *gobj;
388  value.getData(GetType<T>(), &gobj);
389  return RefPointer<T>::wrap(gobj);
390  }
391 
392  static inline void set(Value & value, const RefPointer<T> & data)
393  {
394  typename T::CType *gobj = static_cast<typename T::CType*>(data);
395  value.setData(GetType<T>(), &gobj);
396  }
397 };
398 
399 // -- ValueImpl specializations for string literals --
400 
401 template <int N>
402 struct ValueImpl<const char[N]> //ISO C++ string literals are const char[]
403 {
404  //No get method, obviously.
405 
406  static inline void set(Value & value, const char (&data)[N])
407  {
408  QByteArray str = QByteArray::fromRawData(data, N);
409  value.setData(Type::String, &str);
410  }
411 };
412 
413 template <int N>
414 struct ValueImpl<char[N]> //gcc string literals are char[]
415 {
416  //No get method, obviously.
417 
418  static inline void set(Value & value, const char (&data)[N])
419  {
420  QByteArray str = QByteArray::fromRawData(data, N);
421  value.setData(Type::String, &str);
422  }
423 };
424 
425 // -- ValueImpl specialization for const char* --
426 
427 template <>
428 struct ValueImpl<const char*>
429 {
430  //No get method, obviously.
431 
432  static inline void set(Value & value, const char *data)
433  {
434  QByteArray str = QByteArray::fromRawData(data, qstrlen(data));
435  value.setData(Type::String, &str);
436  }
437 };
438 
439 // -- ValueImpl specialization for QString --
440 
441 template <>
442 struct ValueImpl<QString>
443 {
444  static inline QString get(const Value & value)
445  {
446  QByteArray str;
447  value.getData(Type::String, &str);
448  return QString::fromUtf8(str);
449  }
450 
451  static inline void set(Value & value, const QString & data)
452  {
453  QByteArray str = data.toUtf8();
454  value.setData(Type::String, &str);
455  }
456 };
457 
458 // -- ValueImpl specialization for Value --
459 
460 template <>
461 struct ValueImpl<Value>
462 {
463  static inline Value get(const Value & value)
464  {
465  return value;
466  }
467 
468  static inline void set(Value & value, const Value & data)
469  {
470  value = data;
471  }
472 };
473 
474 // -- ValueImpl specialization for Error --
475 
476 template <>
477 struct ValueImpl<Error>
478 {
479  static inline Error get(const Value & value)
480  {
481  GError *error = 0;
482  value.getData(GetType<Error>(), &error);
483  return Error::copy(error);
484  }
485 
486  static inline void set(Value & value, const Error & data)
487  {
488  value.setData(GetType<Error>(), static_cast<const GError *>(data));
489  }
490 };
491 
492 // -- Exceptions thrown from getData/setData --
493 
494 namespace Private {
495 
496 class QTGLIB_EXPORT InvalidValueException : public std::logic_error
497 {
498 public:
499  inline InvalidValueException()
500  : std::logic_error("This Value instance has not been initialized") {}
501 };
502 
503 class QTGLIB_EXPORT InvalidTypeException : public std::logic_error
504 {
505 public:
506  inline InvalidTypeException(const std::string & dataType, const std::string & valueType)
507  : std::logic_error("Unable to handle value type \"" + dataType +
508  "\". This Value instance has been initialized to hold values of type \""
509  + valueType + "\" and no conversion is possible") {}
510 };
511 
512 class QTGLIB_EXPORT UnregisteredTypeException : public std::logic_error
513 {
514 public:
515  inline UnregisteredTypeException(const std::string & typeName)
516  : std::logic_error("Unable to handle unregistered type \"" + typeName + "\"") {}
517 };
518 
519 class QTGLIB_EXPORT TransformationFailedException : public std::runtime_error
520 {
521 public:
522  inline TransformationFailedException(const std::string & srcTypeName,
523  const std::string & destTypeName)
524  : std::runtime_error("Failed to transform value from type \""
525  + srcTypeName + "\" to type \"" + destTypeName + "\"") {}
526 };
527 
528 } //namespace Private
529 
530 // -- QDebug operator --
531 
533 QTGLIB_EXPORT QDebug operator<<(QDebug debug, const Value & value);
534 
535 } //namespace QGlib
536 
537 QGLIB_REGISTER_TYPE(QGlib::Value)
538 
539 #endif
Error toError(bool *ok=NULL) const
Definition: value.h:227
uchar toUChar(bool *ok=NULL) const
Definition: value.h:200
static RefPointer< T > wrap(typename T::CType *nativePtr, bool increaseRef=true)
Definition: refpointer.h:326
void init()
Definition: init.cpp:27
static Value create(const T &data)
Definition: value.h:293
char toChar(bool *ok=NULL) const
Definition: value.h:197
Wrapper class for GValue.
Definition: value.h:74
long toLong(bool *ok=NULL) const
Definition: value.h:209
T get(bool *ok=NULL) const
Definition: value.h:308
QByteArray toByteArray(bool *ok=NULL) const
Definition: value.h:221
QString toString(bool *ok=NULL) const
Definition: value.h:224
ulong toULong(bool *ok=NULL) const
Definition: value.h:212
qint64 toInt64(bool *ok=NULL) const
Definition: value.h:215
void init(Type type)
Definition: value.cpp:239
int toInt(bool *ok=NULL) const
Definition: value.h:203
void set(const T &data)
Definition: value.h:325
void init()
Definition: value.h:302
bool toBool(bool *ok=NULL) const
Definition: value.h:194
uint toUInt(bool *ok=NULL) const
Definition: value.h:206
quint64 toUInt64(bool *ok=NULL) const
Definition: value.h:218
Wrapper class for GType.
Definition: type.h:63
Wrapper class for GError.
Definition: error.h:30