QtGStreamer  1.2.0
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 #ifndef Q_MOC_RUN
28 #include <boost/type_traits.hpp>
29 #endif
30 #include <stdexcept>
31 #include <QtCore/QString>
32 #include <QtCore/QDebug>
33 #include <QtCore/QSharedData>
34 
35 namespace QGlib {
36 
44 struct QTGLIB_EXPORT ValueVTable
45 {
46  typedef void (*SetFunction)(Value & value, const void *data);
47  typedef void (*GetFunction)(const Value & value, void *data);
48 
49  inline ValueVTable() : set(NULL), get(NULL) {}
50  inline ValueVTable(SetFunction s, GetFunction g) : set(s), get(g) {}
51 
52  SetFunction set;
53  GetFunction get;
54 };
55 
56 
76 class QTGLIB_EXPORT Value
77 {
78 public:
80  Value();
81 
83  explicit Value(const GValue *gvalue);
84 
92  explicit Value(Type type);
93 
94  Value(bool val);
95  Value(char val);
96  Value(uchar val);
97  Value(int val);
98  Value(uint val);
99  Value(long val);
100  Value(ulong val);
101  Value(qint64 val);
102  Value(quint64 val);
103  Value(float val);
104  Value(double val);
105  Value(const char *val);
106  Value(const QByteArray & val);
107  Value(const QString & val);
108 
109  Value(const Value & other);
110  Value & operator=(const Value & other);
111 
112  virtual ~Value();
113 
114 
120  template <typename T>
121  static inline Value create(const T & data);
122 
123 
127  void init(Type type);
128 
134  template <typename T>
135  inline void init();
136 
137 
140  bool isValid() const;
141 
143  Type type() const;
144 
146  bool canTransformTo(Type type) const;
147 
152  Value transformTo(Type type) const;
153 
156  void clear();
157 
158 
180  template <typename T> T get(bool *ok = NULL) const;
181 
192  template <typename T> void set(const T & data);
193 
194 
196  inline bool toBool(bool *ok = NULL) const { return get<bool>(ok); }
197 
199  inline char toChar(bool *ok = NULL) const { return get<char>(ok); }
200 
202  inline uchar toUChar(bool *ok = NULL) const { return get<uchar>(ok); }
203 
205  inline int toInt(bool *ok = NULL) const { return get<int>(ok); }
206 
208  inline uint toUInt(bool *ok = NULL) const { return get<uint>(ok); }
209 
211  inline long toLong(bool *ok = NULL) const { return get<long>(ok); }
212 
214  inline ulong toULong(bool *ok = NULL) const { return get<ulong>(ok); }
215 
217  inline qint64 toInt64(bool *ok = NULL) const { return get<qint64>(ok); }
218 
220  inline quint64 toUInt64(bool *ok = NULL) const { return get<quint64>(ok); }
221 
223  inline QByteArray toByteArray(bool *ok = NULL) const { return get<QByteArray>(ok); }
224 
226  inline QString toString(bool *ok = NULL) const { return get<QString>(ok); }
227 
229  inline Error toError(bool *ok = NULL) const { return get<Error>(ok); }
230 
237  operator GValue*();
238  operator const GValue*() const;
239 
240 
247  static void registerValueVTable(Type type, const ValueVTable & vtable);
248 
249 private:
250  template <typename T>
251  friend struct ValueImpl;
252 
260  void getData(Type dataType, void *data) const;
261 
269  void setData(Type dataType, const void *data);
270 
271  struct Data;
272  QSharedDataPointer<Data> d;
273 };
274 
275 
284 template <typename T>
285 struct ValueImpl
286 {
287  static inline T get(const Value & value);
288  static inline void set(Value & value, const T & data);
289 };
290 
291 // -- template implementations --
292 
293 //static
294 template <typename T>
295 inline Value Value::create(const T & data)
296 {
297  Value v;
298  v.init<T>();
299  v.set(data);
300  return v;
301 }
302 
303 template <typename T>
304 inline void Value::init()
305 {
306  init(GetType<T>());
307 }
308 
309 template <typename T>
310 T Value::get(bool *ok) const
311 {
312  if (ok) {
313  *ok = true;
314  }
315 
316  try {
317  return ValueImpl<T>::get(*this);
318  } catch (const std::exception &) {
319  if (ok) {
320  *ok = false;
321  }
322  return T();
323  }
324 }
325 
326 template <typename T>
327 void Value::set(const T & data)
328 {
329  try {
330  ValueImpl<T>::set(*this, data);
331  } catch (const std::exception & e) {
332  qWarning() << "QGlib::Value::set:" << e.what();
333  }
334 }
335 
336 // -- default ValueImpl implementation --
337 
338 template <typename T>
339 inline T ValueImpl<T>::get(const Value & value)
340 {
341  //Use int for enums, T for everything else
342  typename boost::mpl::if_<
343  boost::is_enum<T>,
344  int, T
345  >::type result;
346 
347  value.getData(GetType<T>(), &result);
348  return static_cast<T>(result);
349 }
350 
351 template <typename T>
352 inline void ValueImpl<T>::set(Value & value, const T & data)
353 {
354  //Use const int for enums, const T for everything else
355  typename boost::mpl::if_<
356  boost::is_enum<T>,
357  const int, const T &
358  >::type dataRef = data;
359 
360  value.setData(GetType<T>(), &dataRef);
361 }
362 
363 // -- ValueImpl specialization for QFlags --
364 
365 template <class T>
366 struct ValueImpl< QFlags<T> >
367 {
368  static inline QFlags<T> get(const Value & value)
369  {
370  uint flags;
371  value.getData(GetType< QFlags<T> >(), &flags);
372  return QFlags<T>(QFlag(flags));
373  }
374 
375  static inline void set(Value & value, const QFlags<T> & data)
376  {
377  uint flags = data;
378  value.setData(GetType< QFlags<T> >(), &flags);
379  }
380 };
381 
382 // -- ValueImpl specialization for RefPointer --
383 
384 template <class T>
385 struct ValueImpl< RefPointer<T> >
386 {
387  static inline RefPointer<T> get(const Value & value)
388  {
389  typename T::CType *gobj;
390  value.getData(GetType<T>(), &gobj);
391  return RefPointer<T>::wrap(gobj);
392  }
393 
394  static inline void set(Value & value, const RefPointer<T> & data)
395  {
396  typename T::CType *gobj = static_cast<typename T::CType*>(data);
397  value.setData(GetType<T>(), &gobj);
398  }
399 };
400 
401 // -- ValueImpl specializations for string literals --
402 
403 template <int N>
404 struct ValueImpl<const char[N]> //ISO C++ string literals are const char[]
405 {
406  //No get method, obviously.
407 
408  static inline void set(Value & value, const char (&data)[N])
409  {
410  QByteArray str = QByteArray::fromRawData(data, N);
411  value.setData(Type::String, &str);
412  }
413 };
414 
415 template <int N>
416 struct ValueImpl<char[N]> //gcc string literals are char[]
417 {
418  //No get method, obviously.
419 
420  static inline void set(Value & value, const char (&data)[N])
421  {
422  QByteArray str = QByteArray::fromRawData(data, N);
423  value.setData(Type::String, &str);
424  }
425 };
426 
427 // -- ValueImpl specialization for const char* --
428 
429 template <>
430 struct ValueImpl<const char*>
431 {
432  //No get method, obviously.
433 
434  static inline void set(Value & value, const char *data)
435  {
436  QByteArray str = QByteArray::fromRawData(data, qstrlen(data));
437  value.setData(Type::String, &str);
438  }
439 };
440 
441 // -- ValueImpl specialization for QString --
442 
443 template <>
444 struct ValueImpl<QString>
445 {
446  static inline QString get(const Value & value)
447  {
448  QByteArray str;
449  value.getData(Type::String, &str);
450  return QString::fromUtf8(str);
451  }
452 
453  static inline void set(Value & value, const QString & data)
454  {
455  QByteArray str = data.toUtf8();
456  value.setData(Type::String, &str);
457  }
458 };
459 
460 // -- ValueImpl specialization for Value --
461 
462 template <>
463 struct ValueImpl<Value>
464 {
465  static inline Value get(const Value & value)
466  {
467  return value;
468  }
469 
470  static inline void set(Value & value, const Value & data)
471  {
472  value = data;
473  }
474 };
475 
476 // -- ValueImpl specialization for Error --
477 
478 template <>
479 struct ValueImpl<Error>
480 {
481  static inline Error get(const Value & value)
482  {
483  GError *error = 0;
484  value.getData(GetType<Error>(), &error);
485  return Error::copy(error);
486  }
487 
488  static inline void set(Value & value, const Error & data)
489  {
490  value.setData(GetType<Error>(), static_cast<const GError *>(data));
491  }
492 };
493 
494 // -- Exceptions thrown from getData/setData --
495 
496 namespace Private {
497 
498 class QTGLIB_EXPORT InvalidValueException : public std::logic_error
499 {
500 public:
501  inline InvalidValueException()
502  : std::logic_error("This Value instance has not been initialized") {}
503 };
504 
505 class QTGLIB_EXPORT InvalidTypeException : public std::logic_error
506 {
507 public:
508  inline InvalidTypeException(const std::string & dataType, const std::string & valueType)
509  : std::logic_error("Unable to handle value type \"" + dataType +
510  "\". This Value instance has been initialized to hold values of type \""
511  + valueType + "\" and no conversion is possible") {}
512 };
513 
514 class QTGLIB_EXPORT UnregisteredTypeException : public std::logic_error
515 {
516 public:
517  inline UnregisteredTypeException(const std::string & typeName)
518  : std::logic_error("Unable to handle unregistered type \"" + typeName + "\"") {}
519 };
520 
521 class QTGLIB_EXPORT TransformationFailedException : public std::runtime_error
522 {
523 public:
524  inline TransformationFailedException(const std::string & srcTypeName,
525  const std::string & destTypeName)
526  : std::runtime_error("Failed to transform value from type \""
527  + srcTypeName + "\" to type \"" + destTypeName + "\"") {}
528 };
529 
530 } //namespace Private
531 
532 // -- QDebug operator --
533 
535 QTGLIB_EXPORT QDebug operator<<(QDebug debug, const Value & value);
536 
537 } //namespace QGlib
538 
539 QGLIB_REGISTER_TYPE(QGlib::Value)
540 
541 #endif
Wrapper class for GError.
Definition: error.h:31
static RefPointer< T > wrap(typename T::CType *nativePtr, bool increaseRef=true)
Definition: refpointer.h:328
Wrapper class for GType.
Definition: type.h:64
Wrapper class for GValue.
Definition: value.h:77
uint toUInt(bool *ok=NULL) const
Definition: value.h:208
Value(char val)
Creates a new Value of Type::Char and sets it to hold val.
static Value create(const T &data)
Definition: value.h:295
ulong toULong(bool *ok=NULL) const
Definition: value.h:214
Value(qint64 val)
Creates a new Value of Type::Int64 and sets it to hold val.
Value(int val)
Creates a new Value of Type::Int and sets it to hold val.
Value(float val)
Creates a new Value of Type::Float and sets it to hold val.
Value(long val)
Creates a new Value of Type::Long and sets it to hold val.
Value(uint val)
Creates a new Value of Type::Uint and sets it to hold val.
Value(const QString &val)
Creates a new Value of Type::String and sets it to hold val.
Value(double val)
Creates a new Value of Type::Double and sets it to hold val.
Error toError(bool *ok=NULL) const
Definition: value.h:229
void set(const T &data)
Definition: value.h:327
Value(bool val)
Creates a new Value of Type::Bool and sets it to hold val.
int toInt(bool *ok=NULL) const
Definition: value.h:205
void init()
Definition: value.h:304
QByteArray toByteArray(bool *ok=NULL) const
Definition: value.h:223
Value(const char *val)
Creates a new Value of Type::String and sets it to hold val.
char toChar(bool *ok=NULL) const
Definition: value.h:199
T get(bool *ok=NULL) const
Definition: value.h:310
Value(const QByteArray &val)
Creates a new Value of Type::String and sets it to hold val.
QString toString(bool *ok=NULL) const
Definition: value.h:226
Value(quint64 val)
Creates a new Value of Type::Uint64 and sets it to hold val.
qint64 toInt64(bool *ok=NULL) const
Definition: value.h:217
Value(ulong val)
Creates a new Value of Type::Ulong and sets it to hold val.
long toLong(bool *ok=NULL) const
Definition: value.h:211
void init(Type type)
Definition: value.cpp:241
bool toBool(bool *ok=NULL) const
Definition: value.h:196
quint64 toUInt64(bool *ok=NULL) const
Definition: value.h:220
uchar toUChar(bool *ok=NULL) const
Definition: value.h:202
Value(uchar val)
Creates a new Value of Type::Uchar and sets it to hold val.
Wrappers for Glib and GObject classes.
void init()
Definition: init.cpp:27