QtGStreamer 0.10.1
|
00001 /* 00002 Copyright (C) 2009-2010 George Kiagiadakis <kiagiadakis.george@gmail.com> 00003 Copyright (C) 2010 Collabora Ltd. 00004 @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk> 00005 00006 This library is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU Lesser General Public License as published 00008 by the Free Software Foundation; either version 2.1 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 #ifndef QGLIB_VALUE_H 00020 #define QGLIB_VALUE_H 00021 00022 #include "global.h" 00023 #include "type.h" 00024 #include "refpointer.h" 00025 #include <boost/mpl/if.hpp> 00026 #include <boost/type_traits.hpp> 00027 #include <stdexcept> 00028 #include <QtCore/QString> 00029 #include <QtCore/QDebug> 00030 #include <QtCore/QSharedData> 00031 00032 namespace QGlib { 00033 00041 struct QTGLIB_EXPORT ValueVTable 00042 { 00043 typedef void (*SetFunction)(Value & value, const void *data); 00044 typedef void (*GetFunction)(const Value & value, void *data); 00045 00046 inline ValueVTable() : set(NULL), get(NULL) {} 00047 inline ValueVTable(SetFunction s, GetFunction g) : set(s), get(g) {} 00048 00049 SetFunction set; 00050 GetFunction get; 00051 }; 00052 00053 00073 class QTGLIB_EXPORT Value 00074 { 00075 public: 00077 Value(); 00078 00080 explicit Value(const GValue *gvalue); 00081 00089 explicit Value(Type type); 00090 00091 Value(bool val); 00092 Value(char val); 00093 Value(uchar val); 00094 Value(int val); 00095 Value(uint val); 00096 Value(long val); 00097 Value(ulong val); 00098 Value(qint64 val); 00099 Value(quint64 val); 00100 Value(float val); 00101 Value(double val); 00102 Value(const char *val); 00103 Value(const QByteArray & val); 00104 Value(const QString & val); 00105 00106 Value(const Value & other); 00107 Value & operator=(const Value & other); 00108 00109 virtual ~Value(); 00110 00111 00117 template <typename T> 00118 static inline Value create(const T & data); 00119 00120 00124 void init(Type type); 00125 00131 template <typename T> 00132 inline void init(); 00133 00134 00137 bool isValid() const; 00138 00140 Type type() const; 00141 00143 bool canTransformTo(Type type) const; 00144 00149 Value transformTo(Type type) const; 00150 00153 void clear(); 00154 00155 00177 template <typename T> T get(bool *ok = NULL) const; 00178 00189 template <typename T> void set(const T & data); 00190 00191 00193 inline bool toBool(bool *ok = NULL) const { return get<bool>(ok); } 00194 00196 inline char toChar(bool *ok = NULL) const { return get<char>(ok); } 00197 00199 inline uchar toUChar(bool *ok = NULL) const { return get<uchar>(ok); } 00200 00202 inline int toInt(bool *ok = NULL) const { return get<int>(ok); } 00203 00205 inline uint toUInt(bool *ok = NULL) const { return get<uint>(ok); } 00206 00208 inline long toLong(bool *ok = NULL) const { return get<long>(ok); } 00209 00211 inline ulong toULong(bool *ok = NULL) const { return get<ulong>(ok); } 00212 00214 inline qint64 toInt64(bool *ok = NULL) const { return get<qint64>(ok); } 00215 00217 inline quint64 toUInt64(bool *ok = NULL) const { return get<quint64>(ok); } 00218 00220 inline QByteArray toByteArray(bool *ok = NULL) const { return get<QByteArray>(ok); } 00221 00223 inline QString toString(bool *ok = NULL) const { return get<QString>(ok); } 00224 00225 00232 operator GValue*(); 00233 operator const GValue*() const; 00234 00235 00242 static void registerValueVTable(Type type, const ValueVTable & vtable); 00243 00244 private: 00245 template <typename T> 00246 friend struct ValueImpl; 00247 00255 void getData(Type dataType, void *data) const; 00256 00264 void setData(Type dataType, const void *data); 00265 00266 struct Data; 00267 QSharedDataPointer<Data> d; 00268 }; 00269 00270 00279 template <typename T> 00280 struct ValueImpl 00281 { 00282 static inline T get(const Value & value); 00283 static inline void set(Value & value, const T & data); 00284 }; 00285 00286 // -- template implementations -- 00287 00288 //static 00289 template <typename T> 00290 inline Value Value::create(const T & data) 00291 { 00292 Value v; 00293 v.init<T>(); 00294 v.set(data); 00295 return v; 00296 } 00297 00298 template <typename T> 00299 inline void Value::init() 00300 { 00301 init(GetType<T>()); 00302 } 00303 00304 template <typename T> 00305 T Value::get(bool *ok) const 00306 { 00307 if (ok) { 00308 *ok = true; 00309 } 00310 00311 try { 00312 return ValueImpl<T>::get(*this); 00313 } catch (const std::exception &) { 00314 if (ok) { 00315 *ok = false; 00316 } 00317 return T(); 00318 } 00319 } 00320 00321 template <typename T> 00322 void Value::set(const T & data) 00323 { 00324 try { 00325 ValueImpl<T>::set(*this, data); 00326 } catch (const std::exception & e) { 00327 qWarning() << "QGlib::Value::set:" << e.what(); 00328 } 00329 } 00330 00331 // -- default ValueImpl implementation -- 00332 00333 template <typename T> 00334 inline T ValueImpl<T>::get(const Value & value) 00335 { 00336 //Use int for enums, T for everything else 00337 typename boost::mpl::if_< 00338 boost::is_enum<T>, 00339 int, T 00340 >::type result; 00341 00342 value.getData(GetType<T>(), &result); 00343 return static_cast<T>(result); 00344 } 00345 00346 template <typename T> 00347 inline void ValueImpl<T>::set(Value & value, const T & data) 00348 { 00349 //Use const int for enums, const T for everything else 00350 typename boost::mpl::if_< 00351 boost::is_enum<T>, 00352 const int, const T & 00353 >::type dataRef = data; 00354 00355 value.setData(GetType<T>(), &dataRef); 00356 } 00357 00358 // -- ValueImpl specialization for QFlags -- 00359 00360 template <class T> 00361 struct ValueImpl< QFlags<T> > 00362 { 00363 static inline QFlags<T> get(const Value & value) 00364 { 00365 uint flags; 00366 value.getData(GetType< QFlags<T> >(), &flags); 00367 return QFlags<T>(QFlag(flags)); 00368 } 00369 00370 static inline void set(Value & value, const QFlags<T> & data) 00371 { 00372 uint flags = data; 00373 value.setData(GetType< QFlags<T> >(), &flags); 00374 } 00375 }; 00376 00377 // -- ValueImpl specialization for RefPointer -- 00378 00379 template <class T> 00380 struct ValueImpl< RefPointer<T> > 00381 { 00382 static inline RefPointer<T> get(const Value & value) 00383 { 00384 typename T::CType *gobj; 00385 value.getData(GetType<T>(), &gobj); 00386 return RefPointer<T>::wrap(gobj); 00387 } 00388 00389 static inline void set(Value & value, const RefPointer<T> & data) 00390 { 00391 typename T::CType *gobj = static_cast<typename T::CType*>(data); 00392 value.setData(GetType<T>(), &gobj); 00393 } 00394 }; 00395 00396 // -- ValueImpl specializations for string literals -- 00397 00398 template <int N> 00399 struct ValueImpl<const char[N]> //ISO C++ string literals are const char[] 00400 { 00401 //No get method, obviously. 00402 00403 static inline void set(Value & value, const char (&data)[N]) 00404 { 00405 QByteArray str = QByteArray::fromRawData(data, N); 00406 value.setData(Type::String, &str); 00407 } 00408 }; 00409 00410 template <int N> 00411 struct ValueImpl<char[N]> //gcc string literals are char[] 00412 { 00413 //No get method, obviously. 00414 00415 static inline void set(Value & value, const char (&data)[N]) 00416 { 00417 QByteArray str = QByteArray::fromRawData(data, N); 00418 value.setData(Type::String, &str); 00419 } 00420 }; 00421 00422 // -- ValueImpl specialization for const char* -- 00423 00424 template <> 00425 struct ValueImpl<const char*> 00426 { 00427 //No get method, obviously. 00428 00429 static inline void set(Value & value, const char *data) 00430 { 00431 QByteArray str = QByteArray::fromRawData(data, qstrlen(data)); 00432 value.setData(Type::String, &str); 00433 } 00434 }; 00435 00436 // -- ValueImpl specialization for QString -- 00437 00438 template <> 00439 struct ValueImpl<QString> 00440 { 00441 static inline QString get(const Value & value) 00442 { 00443 QByteArray str; 00444 value.getData(Type::String, &str); 00445 return QString::fromUtf8(str); 00446 } 00447 00448 static inline void set(Value & value, const QString & data) 00449 { 00450 QByteArray str = data.toUtf8(); 00451 value.setData(Type::String, &str); 00452 } 00453 }; 00454 00455 // -- ValueImpl specialization for Value -- 00456 00457 template <> 00458 struct ValueImpl<Value> 00459 { 00460 static inline Value get(const Value & value) 00461 { 00462 return value; 00463 } 00464 00465 static inline void set(Value & value, const Value & data) 00466 { 00467 value = data; 00468 } 00469 }; 00470 00471 // -- Exceptions thrown from getData/setData -- 00472 00473 namespace Private { 00474 00475 class QTGLIB_EXPORT InvalidValueException : public std::logic_error 00476 { 00477 public: 00478 inline InvalidValueException() 00479 : std::logic_error("This Value instance has not been initialized") {} 00480 }; 00481 00482 class QTGLIB_EXPORT InvalidTypeException : public std::logic_error 00483 { 00484 public: 00485 inline InvalidTypeException(const std::string & dataType, const std::string & valueType) 00486 : std::logic_error("Unable to handle value type \"" + dataType + 00487 "\". This Value instance has been initialized to hold values of type \"" 00488 + valueType + "\" and no conversion is possible") {} 00489 }; 00490 00491 class QTGLIB_EXPORT UnregisteredTypeException : public std::logic_error 00492 { 00493 public: 00494 inline UnregisteredTypeException(const std::string & typeName) 00495 : std::logic_error("Unable to handle unregistered type \"" + typeName + "\"") {} 00496 }; 00497 00498 class QTGLIB_EXPORT TransformationFailedException : public std::runtime_error 00499 { 00500 public: 00501 inline TransformationFailedException(const std::string & srcTypeName, 00502 const std::string & destTypeName) 00503 : std::runtime_error("Failed to transform value from type \"" 00504 + srcTypeName + "\" to type \"" + destTypeName + "\"") {} 00505 }; 00506 00507 } //namespace Private 00508 00509 // -- QDebug operator -- 00510 00512 QTGLIB_EXPORT QDebug operator<<(QDebug debug, const Value & value); 00513 00514 } //namespace QGlib 00515 00516 QGLIB_REGISTER_TYPE(QGlib::Value) 00517 00518 #endif