summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.co.uk>2010-12-13 13:55:24 +0200
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.co.uk>2010-12-13 13:58:14 +0200
commit832bb77ecdb2a9e8fbce8d9208aa89d16be23bbf (patch)
tree2d04e7646df0100a52227c434bee5e49a3b6d6be /src
parentfcb89ab31e2ce48ec090b1ea380d03ab9b2be792 (diff)
Fix Value exceptions.
* Move the exceptions out of ValueBase. * Add more exceptions, improve their wordings. * Re-check all cases in which they can be thrown into signals/slots code and adjust their handling.
Diffstat (limited to 'src')
-rw-r--r--src/QGlib/emitimpl.h67
-rw-r--r--src/QGlib/signal.cpp6
-rw-r--r--src/QGlib/value.cpp33
-rw-r--r--src/QGlib/value.h52
4 files changed, 91 insertions, 67 deletions
diff --git a/src/QGlib/emitimpl.h b/src/QGlib/emitimpl.h
index 3d2529f..0d295ab 100644
--- a/src/QGlib/emitimpl.h
+++ b/src/QGlib/emitimpl.h
@@ -52,13 +52,12 @@ inline QList<Value> packArguments()
template <typename Arg1, typename... Args>
QList<Value> packArguments(Arg1 && a1, Args&&... args)
{
- typedef typename boost::add_const<
- typename boost::add_reference<Arg1>::type
- >::type ConstArg1Ref;
-
QList<Value> result = packArguments(std::forward<Args>(args)...);
+ Value v;
+ v.init<Arg1>();
+ ValueImpl<Arg1>::set(v, a1);
//prepend, since we are packing from the last to the first argument
- result.prepend(Value(static_cast<ConstArg1Ref>(a1)));
+ result.prepend(v);
return result;
}
@@ -70,14 +69,12 @@ struct EmitImpl<R (Args...)>
{
static inline R emit(void *instance, const char *detailedSignal, Args&&... args)
{
- Value && returnValue = Signal::emit(instance, detailedSignal,
- packArguments(std::forward<Args>(args)...));
-
try {
+ Value && returnValue = Signal::emit(instance, detailedSignal,
+ packArguments(std::forward<Args>(args)...));
return ValueImpl<R>::get(returnValue);
- } catch(const std::logic_error &) {
- qCritical() << "Error during emission of signal" << detailedSignal
- << "The returned value from emit is of different type than the one requested";
+ } catch(const std::exception & e) {
+ qCritical() << "Error during emission of signal" << detailedSignal << ":" << e.what();
return R();
}
}
@@ -88,11 +85,15 @@ struct EmitImpl<void (Args...)>
{
static inline void emit(void *instance, const char *detailedSignal, Args&&... args)
{
- Value && returnValue = Signal::emit(instance, detailedSignal,
- packArguments(std::forward<Args>(args)...));
-
- if (returnValue.isValid()) {
- qWarning() << "Ignoring return value from emission of signal" << detailedSignal;
+ try {
+ Value && returnValue = Signal::emit(instance, detailedSignal,
+ packArguments(std::forward<Args>(args)...));
+
+ if (returnValue.isValid()) {
+ qWarning() << "Ignoring return value from emission of signal" << detailedSignal;
+ }
+ } catch(const std::exception & e) {
+ qCritical() << "Error during emission of signal" << detailedSignal << ":" << e.what();
}
}
};
@@ -161,7 +162,12 @@ namespace Private {
//BEGIN ******** boostpp EmitImpl ********
# define QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP(z, n, list) \
- list.append(Value(static_cast< typename boost::add_const< typename boost::add_reference<A ##n>::type >::type >(a ##n)));
+ { \
+ Value v; \
+ v.init<A##n>(); \
+ ValueImpl<A##n>::set(v, a##n); \
+ list.append(v); \
+ }
# define QGLIB_SIGNAL_IMPL_PACK_ARGS(list) \
BOOST_PP_REPEAT(QGLIB_SIGNAL_IMPL_NUM_ARGS, QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP, list)
@@ -173,15 +179,13 @@ struct EmitImpl<R (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)>
static inline R emit(void *instance, const char *detailedSignal
QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS)
{
- QList<Value> values;
- QGLIB_SIGNAL_IMPL_PACK_ARGS(values)
- Value returnValue = Signal::emit(instance, detailedSignal, values);
-
try {
+ QList<Value> values;
+ QGLIB_SIGNAL_IMPL_PACK_ARGS(values)
+ Value returnValue = Signal::emit(instance, detailedSignal, values);
return ValueImpl<R>::get(returnValue);
- } catch(const std::logic_error &) {
- qCritical() << "Error during emission of signal" << detailedSignal
- << "The returned value from emit is of different type than the one requested";
+ } catch(const std::exception & e) {
+ qCritical() << "Error during emission of signal" << detailedSignal << ":" << e.what();
return R();
}
}
@@ -193,12 +197,15 @@ struct EmitImpl<void (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)>
static inline void emit(void *instance, const char *detailedSignal
QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS)
{
- QList<Value> values;
- QGLIB_SIGNAL_IMPL_PACK_ARGS(values)
- Value returnValue = Signal::emit(instance, detailedSignal, values);
-
- if (returnValue.isValid()) {
- qWarning() << "Ignoring return value from emission of signal" << detailedSignal;
+ try {
+ QList<Value> values;
+ QGLIB_SIGNAL_IMPL_PACK_ARGS(values)
+ Value returnValue = Signal::emit(instance, detailedSignal, values);
+ if (returnValue.isValid()) {
+ qWarning() << "Ignoring return value from emission of signal" << detailedSignal;
+ }
+ } catch(const std::exception & e) {
+ qCritical() << "Error during emission of signal" << detailedSignal << ":" << e.what();
}
}
};
diff --git a/src/QGlib/signal.cpp b/src/QGlib/signal.cpp
index 684d810..06da8f8 100644
--- a/src/QGlib/signal.cpp
+++ b/src/QGlib/signal.cpp
@@ -266,7 +266,7 @@ static void c_marshaller(GClosure *closure, GValue *returnValue, uint paramValue
try {
SharedValue result(returnValue);
cdata->marshaller(result, params);
- } catch (const std::logic_error & e) {
+ } catch (const std::exception & e) {
QString signalName;
if (hint != NULL) {
GSignalInvocationHint *ihint = static_cast<GSignalInvocationHint*>(hint);
@@ -293,13 +293,13 @@ static void c_marshaller(GClosure *closure, GValue *returnValue, uint paramValue
QString msg;
try {
//dynamic_cast will throw an std::bad_cast if it fails
- dynamic_cast<const ValueBase::InvalidTypeException &>(e);
+ dynamic_cast<const InvalidTypeException &>(e);
//cast succeded, e is indeed an InvalidTypeException
msg = QLatin1String("One or more of the arguments of the signal are of different "
"type than the type that the closure expects");
} catch (...) {
try {
- dynamic_cast<const ValueBase::InvalidValueException &>(e);
+ dynamic_cast<const InvalidValueException &>(e);
//cast succeded, e is indeed an InvalidValueException
//this is most likely to happen because the signal returns void
//but the closure returns something non-void. check this first.
diff --git a/src/QGlib/value.cpp b/src/QGlib/value.cpp
index e353ca0..9178db9 100644
--- a/src/QGlib/value.cpp
+++ b/src/QGlib/value.cpp
@@ -158,58 +158,53 @@ void ValueBase::registerValueVTable(Type type, const ValueVTable & vtable)
void ValueBase::getData(Type dataType, void *data) const
{
if (!isValid()) {
- throw InvalidValueException();
+ throw Private::InvalidValueException();
} else if (g_value_type_compatible(type(), dataType)) {
ValueVTable vtable = s_dispatcher()->getVTable(dataType);
if (vtable.get != NULL) {
vtable.get(*this, data);
} else {
- throw std::logic_error("Unable to handle the given type. Type is not registered");
+ throw Private::UnregisteredTypeException(dataType.name().toStdString());
}
} else if (dataType.isValueType() && g_value_type_transformable(type(), dataType)) {
Value v;
v.init(dataType);
if (!g_value_transform(m_value, v.m_value)) {
- throw InvalidTypeException();
+ throw Private::TransformationFailedException(type().name().toStdString(),
+ dataType.name().toStdString());
}
- try {
- v.getData(dataType, data);
- } catch (const InvalidTypeException &) {
- Q_ASSERT(false); //This must never happen
- }
+ v.getData(dataType, data);
} else {
- throw InvalidTypeException();
+ throw Private::InvalidTypeException(dataType.name().toStdString(),
+ type().name().toStdString());
}
}
void ValueBase::setData(Type dataType, const void *data)
{
if (!isValid()) {
- throw InvalidValueException();
+ throw Private::InvalidValueException();
} else if (g_value_type_compatible(dataType, type())) {
ValueVTable vtable = s_dispatcher()->getVTable(dataType);
if (vtable.set != NULL) {
vtable.set(*this, data);
} else {
- throw std::logic_error("Unable to handle the given type. Type is not registered");
+ throw Private::UnregisteredTypeException(dataType.name().toStdString());
}
} else if (dataType.isValueType() && g_value_type_transformable(dataType, type())) {
Value v;
v.init(dataType);
-
- try {
- v.setData(dataType, data);
- } catch (const InvalidTypeException &) {
- Q_ASSERT(false); //This must never happen
- }
+ v.setData(dataType, data);
if (!g_value_transform(v.m_value, m_value)) {
- throw InvalidTypeException();
+ throw Private::TransformationFailedException(dataType.name().toStdString(),
+ type().name().toStdString());
}
} else {
- throw InvalidTypeException();
+ throw Private::InvalidTypeException(dataType.name().toStdString(),
+ type().name().toStdString());
}
}
diff --git a/src/QGlib/value.h b/src/QGlib/value.h
index 3ad59c7..014225b 100644
--- a/src/QGlib/value.h
+++ b/src/QGlib/value.h
@@ -56,21 +56,6 @@ struct ValueVTable
class ValueBase
{
public:
- class InvalidValueException : public std::logic_error
- {
- public:
- inline InvalidValueException()
- : std::logic_error("This ValueBase instance has not been initialized") {}
- };
-
- class InvalidTypeException : public std::logic_error
- {
- public:
- inline InvalidTypeException()
- : std::logic_error("This ValueBase instance has been initialized to hold a different "
- "type of data than the one that you are trying to access") {}
- };
-
/*! \returns whether this ValueBase instance wraps a valid GValue instance or not */
bool isValid() const;
@@ -380,6 +365,43 @@ struct ValueImpl<QString>
}
};
+// -- Exceptions thrown from getData/setData --
+
+namespace Private {
+
+class InvalidValueException : public std::logic_error
+{
+public:
+ inline InvalidValueException()
+ : std::logic_error("This Value instance has not been initialized") {}
+};
+
+class 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 UnregisteredTypeException : public std::logic_error
+{
+public:
+ inline UnregisteredTypeException(const std::string & typeName)
+ : std::logic_error("Unable to handle unregistered type \"" + typeName + "\"") {}
+};
+
+class 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
} //namespace QGlib
/*! \relates QGlib::ValueBase */