/usr/include/Qt5GStreamer/QGlib/value.h is in libqt5gstreamer-dev 1.2.0-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | /*
Copyright (C) 2009-2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
Copyright (C) 2010 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QGLIB_VALUE_H
#define QGLIB_VALUE_H
#include "global.h"
#include "type.h"
#include "refpointer.h"
#include "error.h"
#include <boost/mpl/if.hpp>
#include <boost/type_traits.hpp>
#include <stdexcept>
#include <QtCore/QString>
#include <QtCore/QDebug>
#include <QtCore/QSharedData>
namespace QGlib {
/*! This structure holds the set and get methods that are used internally
* by Value to handle data of a specific type. If you want to provide
* support for a custom type, you need to write two such methods, create
* a new ValueVTable instance that holds pointers to them and register it
* using Value::registerValueVTable().
* \sa \ref value_design
*/
struct QTGLIB_EXPORT ValueVTable
{
typedef void (*SetFunction)(Value & value, const void *data);
typedef void (*GetFunction)(const Value & value, void *data);
inline ValueVTable() : set(NULL), get(NULL) {}
inline ValueVTable(SetFunction s, GetFunction g) : set(s), get(g) {}
SetFunction set;
GetFunction get;
};
/*! \headerfile value.h <QGlib/Value>
* \brief Wrapper class for GValue
*
* This class serves as a wrapper for GValue. GValue is a data type that can hold different
* types of values inside, like a QVariant.
*
* A Value object holds a single value of a single type() at a time. To create a new Value,
* use the static create() method or one of the constructors. To get the held value, use
* the template get() method or one of the toT() functions (ex. toInt()).
*
* To set a value to an invalid Value (on which isValid() returns false), you must first
* initialize this Value using one of the init() methods (preferably the template one) in order
* to tell it what kind of value it is going to hold. Once initialized to hold a specific type,
* you can use the set() method to set a value. To change the type that this value holds, you
* can call the init() method again at any time. In this case, though, any previously held value
* will be lost.
*
* \note This class is implicitly shared.
*/
class QTGLIB_EXPORT Value
{
public:
/*! Creates a new invalid Value \sa isValid() */
Value();
/*! Creates a new Value that holds a copy of the given \a gvalue */
explicit Value(const GValue *gvalue);
/*! Creates a new Value and initializes it to hold values of the given \a type.
* This is equivalent to:
* \code
* Value v;
* v.init(type);
* \endcode
*/
explicit Value(Type type);
Value(bool val); ///< Creates a new Value of Type::Bool and sets it to hold \a val
Value(char val); ///< Creates a new Value of Type::Char and sets it to hold \a val
Value(uchar val); ///< Creates a new Value of Type::Uchar and sets it to hold \a val
Value(int val); ///< Creates a new Value of Type::Int and sets it to hold \a val
Value(uint val); ///< Creates a new Value of Type::Uint and sets it to hold \a val
Value(long val); ///< Creates a new Value of Type::Long and sets it to hold \a val
Value(ulong val); ///< Creates a new Value of Type::Ulong and sets it to hold \a val
Value(qint64 val); ///< Creates a new Value of Type::Int64 and sets it to hold \a val
Value(quint64 val); ///< Creates a new Value of Type::Uint64 and sets it to hold \a val
Value(float val); ///< Creates a new Value of Type::Float and sets it to hold \a val
Value(double val); ///< Creates a new Value of Type::Double and sets it to hold \a val
Value(const char *val); ///< Creates a new Value of Type::String and sets it to hold \a val
Value(const QByteArray & val); ///< Creates a new Value of Type::String and sets it to hold \a val
Value(const QString & val); ///< Creates a new Value of Type::String and sets it to hold \a val
Value(const Value & other);
Value & operator=(const Value & other);
virtual ~Value();
/*! Creates a new Value that is intialized to hold data
* of type T and sets it to hold \a data.
* \note T must be a type registered with the QtGLib type system. Attempting
* to use a type that is not properly registered will fail to compile.
*/
template <typename T>
static inline Value create(const T & data);
/*! Initializes or re-initializes this Value to hold data of the given \a type.
* If this Value was previously holding any data, this data will be freed.
*/
void init(Type type);
/*! Initializes or re-initializes this Value to hold data of type T.
* If this Value was previously holding any data, this data will be freed.
* \note T must be a type registered with the QtGLib type system. Attempting
* to use a type that is not properly registered will fail to compile.
*/
template <typename T>
inline void init();
/*! \returns whether this Value instance is initialized to hold a certain type
* \sa init() */
bool isValid() const;
/*! \returns the type that this Value instance has been initialized to hold */
Type type() const;
/*! \returns whether it is possible to transform this Value to a Value of another type */
bool canTransformTo(Type type) const;
/*! Transforms the current value into a value of the specified \a type, if possible.
* Possible transformations are, for example, int to float, int to string, etc...
* The original Value remains unaffected and the transformed Value is returned.
*/
Value transformTo(Type type) const;
/*! Clears the current value in this Value instance and resets it to the
* default value (as if the Value had just been initialized). */
void clear();
/*! Retrieves the value stored in this Value instance, as the specified type T.
* The bindings take care of calling the appropriate g_value_get_* method depending
* on the type T. Note though that this is only meant to be used with the types of
* the bindings, not their C types. This means that if for example the Value has
* been initialized to hold a GstObject pointer, you can use:
* \code
* QGst::ObjectPtr object = value.get<QGst::ObjectPtr>();
* \endcode
* but \em not this:
* \code
* GstObject *object = value.get<GstObject*>(); //will cause compilation error
* \endcode
*
* If the underlying stored value is not of the type T, this method will attempt
* to convert it to type T. If this is not possible, a default constructed value
* will be returned.
*
* If \a ok has been specified, it is set to true if the value was retrieved
* successfully or false if there was an error (probably conversion error) and
* a default constructed value has been returned.
*/
template <typename T> T get(bool *ok = NULL) const;
/*! Sets this Value instance to hold the specified \a data.
* As with get(), the bindings take care of calling the appropriate g_value_set_*
* method depending on the type T, but note that this is only meant to be used
* with the types of the bindings.
*
* If this Value instance has been initialized to hold a different type of data
* than T, a conversion to the correct type() will be attempted. If the conversion
* fails, the Value will remain unaffected and a warning will be printed.
* \sa get()
*/
template <typename T> void set(const T & data);
/*! Returns the held value as a bool. Equivalent to get<bool>(ok); \sa get() */
inline bool toBool(bool *ok = NULL) const { return get<bool>(ok); }
/*! Returns the held value as a char. Equivalent to get<char>(ok); \sa get() */
inline char toChar(bool *ok = NULL) const { return get<char>(ok); }
/*! Returns the held value as a uchar. Equivalent to get<uchar>(ok); \sa get() */
inline uchar toUChar(bool *ok = NULL) const { return get<uchar>(ok); }
/*! Returns the held value as an int. Equivalent to get<int>(ok); \sa get() */
inline int toInt(bool *ok = NULL) const { return get<int>(ok); }
/*! Returns the held value as a uint. Equivalent to get<uint>(ok); \sa get() */
inline uint toUInt(bool *ok = NULL) const { return get<uint>(ok); }
/*! Returns the held value as a long. Equivalent to get<long>(ok); \sa get() */
inline long toLong(bool *ok = NULL) const { return get<long>(ok); }
/*! Returns the held value as a ulong. Equivalent to get<ulong>(ok); \sa get() */
inline ulong toULong(bool *ok = NULL) const { return get<ulong>(ok); }
/*! Returns the held value as a qint64. Equivalent to get<qint64>(ok); \sa get() */
inline qint64 toInt64(bool *ok = NULL) const { return get<qint64>(ok); }
/*! Returns the held value as a quint64. Equivalent to get<quint64>(ok); \sa get() */
inline quint64 toUInt64(bool *ok = NULL) const { return get<quint64>(ok); }
/*! Returns the held value as a QByteAray. Equivalent to get<QByteArray>(ok); \sa get() */
inline QByteArray toByteArray(bool *ok = NULL) const { return get<QByteArray>(ok); }
/*! Returns the held value as a QString. Equivalent to get<QString>(ok); \sa get() */
inline QString toString(bool *ok = NULL) const { return get<QString>(ok); }
/*! Returns the held value as a QGlib::Error. Equivalent to get<QGlib::Error>(ok); \sa get() */
inline Error toError(bool *ok = NULL) const { return get<Error>(ok); }
/*! This is a cast operator that gives access to the underlying GValue instance.
* It is provided for convenience, to be able to pass this Value as argument to C
* functions that expect a GValue pointer. Use this feature with care. Do not store
* the pointer, as it may go away at any time. This Value instance keeps control of
* this pointer. If you need to store it, use g_value_copy() to copy it first.
*/
operator GValue*();
operator const GValue*() const; ///< \overload
/*! Registers the given ValueVTable \a vtable for the given \a type.
* This is provided to let you add support for a custom type, if necessary.
* You should normally not need to do that, as most types are handled
* by the handlers of their parent types.
* \sa \ref value_design
*/
static void registerValueVTable(Type type, const ValueVTable & vtable);
private:
template <typename T>
friend struct ValueImpl;
/*! Retrieves the data from this Value and places it into the memory position
* pointed to by \a data. \a dataType indicates the actual data type of \a data
* and is used, among others, to cast \a data back to the actual C++ type that
* it points to and assign it.
* \note This method should only be accessed from ValueImpl.
* \sa \ref value_design
*/
void getData(Type dataType, void *data) const;
/*! Sets the data of this Value to be the data pointed to by \a data.
* \a dataType indicates the actual data type of \a data and is used,
* among others, to cast \a data back to the actual C++ type that
* it points to and retrieve its value.
* \note This method should only be accessed from ValueImpl.
* \sa \ref value_design
*/
void setData(Type dataType, const void *data);
struct Data;
QSharedDataPointer<Data> d;
};
/*! This struct provides the implementation for the Value::get() and Value::set() methods.
* If you want to provide support for a custom type, you may want to provide a template
* specialization of this class to handle your type in a different way than the default
* implementation. You should normally not need to be concerned at all with this.
* \note this struct is declared as friend in Value and as a result it has access to
* Value::setData() and Value::getData()
* \sa \ref value_design
*/
template <typename T>
struct ValueImpl
{
static inline T get(const Value & value);
static inline void set(Value & value, const T & data);
};
// -- template implementations --
//static
template <typename T>
inline Value Value::create(const T & data)
{
Value v;
v.init<T>();
v.set(data);
return v;
}
template <typename T>
inline void Value::init()
{
init(GetType<T>());
}
template <typename T>
T Value::get(bool *ok) const
{
if (ok) {
*ok = true;
}
try {
return ValueImpl<T>::get(*this);
} catch (const std::exception &) {
if (ok) {
*ok = false;
}
return T();
}
}
template <typename T>
void Value::set(const T & data)
{
try {
ValueImpl<T>::set(*this, data);
} catch (const std::exception & e) {
qWarning() << "QGlib::Value::set:" << e.what();
}
}
// -- default ValueImpl implementation --
template <typename T>
inline T ValueImpl<T>::get(const Value & value)
{
//Use int for enums, T for everything else
typename boost::mpl::if_<
boost::is_enum<T>,
int, T
>::type result;
value.getData(GetType<T>(), &result);
return static_cast<T>(result);
}
template <typename T>
inline void ValueImpl<T>::set(Value & value, const T & data)
{
//Use const int for enums, const T for everything else
typename boost::mpl::if_<
boost::is_enum<T>,
const int, const T &
>::type dataRef = data;
value.setData(GetType<T>(), &dataRef);
}
// -- ValueImpl specialization for QFlags --
template <class T>
struct ValueImpl< QFlags<T> >
{
static inline QFlags<T> get(const Value & value)
{
uint flags;
value.getData(GetType< QFlags<T> >(), &flags);
return QFlags<T>(QFlag(flags));
}
static inline void set(Value & value, const QFlags<T> & data)
{
uint flags = data;
value.setData(GetType< QFlags<T> >(), &flags);
}
};
// -- ValueImpl specialization for RefPointer --
template <class T>
struct ValueImpl< RefPointer<T> >
{
static inline RefPointer<T> get(const Value & value)
{
typename T::CType *gobj;
value.getData(GetType<T>(), &gobj);
return RefPointer<T>::wrap(gobj);
}
static inline void set(Value & value, const RefPointer<T> & data)
{
typename T::CType *gobj = static_cast<typename T::CType*>(data);
value.setData(GetType<T>(), &gobj);
}
};
// -- ValueImpl specializations for string literals --
template <int N>
struct ValueImpl<const char[N]> //ISO C++ string literals are const char[]
{
//No get method, obviously.
static inline void set(Value & value, const char (&data)[N])
{
QByteArray str = QByteArray::fromRawData(data, N);
value.setData(Type::String, &str);
}
};
template <int N>
struct ValueImpl<char[N]> //gcc string literals are char[]
{
//No get method, obviously.
static inline void set(Value & value, const char (&data)[N])
{
QByteArray str = QByteArray::fromRawData(data, N);
value.setData(Type::String, &str);
}
};
// -- ValueImpl specialization for const char* --
template <>
struct ValueImpl<const char*>
{
//No get method, obviously.
static inline void set(Value & value, const char *data)
{
QByteArray str = QByteArray::fromRawData(data, qstrlen(data));
value.setData(Type::String, &str);
}
};
// -- ValueImpl specialization for QString --
template <>
struct ValueImpl<QString>
{
static inline QString get(const Value & value)
{
QByteArray str;
value.getData(Type::String, &str);
return QString::fromUtf8(str);
}
static inline void set(Value & value, const QString & data)
{
QByteArray str = data.toUtf8();
value.setData(Type::String, &str);
}
};
// -- ValueImpl specialization for Value --
template <>
struct ValueImpl<Value>
{
static inline Value get(const Value & value)
{
return value;
}
static inline void set(Value & value, const Value & data)
{
value = data;
}
};
// -- ValueImpl specialization for Error --
template <>
struct ValueImpl<Error>
{
static inline Error get(const Value & value)
{
GError *error = 0;
value.getData(GetType<Error>(), &error);
return Error::copy(error);
}
static inline void set(Value & value, const Error & data)
{
value.setData(GetType<Error>(), static_cast<const GError *>(data));
}
};
// -- Exceptions thrown from getData/setData --
namespace Private {
class QTGLIB_EXPORT InvalidValueException : public std::logic_error
{
public:
inline InvalidValueException()
: std::logic_error("This Value instance has not been initialized") {}
};
class QTGLIB_EXPORT InvalidTypeException : public std::logic_error
{
public:
inline InvalidTypeException(const std::string & dataType, const std::string & valueType)
: std::logic_error("Unable to handle value type \"" + dataType +
"\". This Value instance has been initialized to hold values of type \""
+ valueType + "\" and no conversion is possible") {}
};
class QTGLIB_EXPORT UnregisteredTypeException : public std::logic_error
{
public:
inline UnregisteredTypeException(const std::string & typeName)
: std::logic_error("Unable to handle unregistered type \"" + typeName + "\"") {}
};
class QTGLIB_EXPORT TransformationFailedException : public std::runtime_error
{
public:
inline TransformationFailedException(const std::string & srcTypeName,
const std::string & destTypeName)
: std::runtime_error("Failed to transform value from type \""
+ srcTypeName + "\" to type \"" + destTypeName + "\"") {}
};
} //namespace Private
// -- QDebug operator --
/*! \relates QGlib::Value */
QTGLIB_EXPORT QDebug operator<<(QDebug debug, const Value & value);
} //namespace QGlib
QGLIB_REGISTER_TYPE(QGlib::Value)
#endif
|