summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-11 13:05:21 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-11 13:05:21 +0100
commitfcd8e06ade6116730630d9800523637b96aedf32 (patch)
treed398b587aa665c2fb25db2c4e7bac227dcce2b17
parent498fd2737a32fde11062c7177d8326c665f7feef (diff)
Renamed Variant::Type to VariantType to allow forward declaration
-rw-r--r--src/core/common/Variant.cpp64
-rw-r--r--src/core/common/Variant.hpp209
-rw-r--r--src/core/common/VariantConverter.cpp76
-rw-r--r--src/core/common/VariantConverter.hpp69
-rw-r--r--src/core/common/VariantWriter.cpp20
5 files changed, 245 insertions, 193 deletions
diff --git a/src/core/common/Variant.cpp b/src/core/common/Variant.cpp
index b1a65ea..c5c7b80 100644
--- a/src/core/common/Variant.cpp
+++ b/src/core/common/Variant.cpp
@@ -30,7 +30,7 @@ namespace ousia {
/* Class Variant::TypeException */
-Variant::TypeException::TypeException(Type actualType, Type requestedType)
+Variant::TypeException::TypeException(VariantType actualType, VariantType requestedType)
: OusiaException(std::string("Variant: Requested \"") +
Variant::getTypeName(requestedType) +
std::string("\" but is \"") +
@@ -42,28 +42,28 @@ Variant::TypeException::TypeException(Type actualType, Type requestedType)
/* Class Variant */
-const char *Variant::getTypeName(Type type)
+const char *Variant::getTypeName(VariantType type)
{
switch (type) {
- case Type::NULLPTR:
+ case VariantType::NULLPTR:
return "null";
- case Type::BOOL:
+ case VariantType::BOOL:
return "boolean";
- case Type::INT:
+ case VariantType::INT:
return "integer";
- case Type::DOUBLE:
+ case VariantType::DOUBLE:
return "double";
- case Type::STRING:
+ case VariantType::STRING:
return "string";
- case Type::MAGIC:
+ case VariantType::MAGIC:
return "magic";
- case Type::ARRAY:
+ case VariantType::ARRAY:
return "array";
- case Type::MAP:
+ case VariantType::MAP:
return "map";
- case Type::OBJECT:
+ case VariantType::OBJECT:
return "object";
- case Type::FUNCTION:
+ case VariantType::FUNCTION:
return "function";
}
return "unknown";
@@ -118,24 +118,24 @@ bool operator<(const Variant &lhs, const Variant &rhs)
throw Variant::TypeException(lhs.getType(), rhs.getType());
}
switch (lhs.getType()) {
- case Variant::Type::NULLPTR:
+ case VariantType::NULLPTR:
return false;
- case Variant::Type::BOOL:
+ case VariantType::BOOL:
return lhs.boolVal < rhs.boolVal;
- case Variant::Type::INT:
+ case VariantType::INT:
return lhs.intVal < rhs.intVal;
- case Variant::Type::DOUBLE:
+ case VariantType::DOUBLE:
return lhs.doubleVal < rhs.doubleVal;
- case Variant::Type::MAGIC:
- case Variant::Type::STRING:
+ case VariantType::MAGIC:
+ case VariantType::STRING:
return lhs.asString() < rhs.asString();
- case Variant::Type::ARRAY:
+ case VariantType::ARRAY:
return lhs.asArray() < rhs.asArray();
- case Variant::Type::MAP:
+ case VariantType::MAP:
return lhs.asMap() < rhs.asMap();
- case Variant::Type::OBJECT:
+ case VariantType::OBJECT:
return lhs.asObject().get() < rhs.asObject().get();
- case Variant::Type::FUNCTION:
+ case VariantType::FUNCTION:
return lhs.asFunction() < rhs.asFunction();
}
throw OusiaException("Internal Error! Unknown type!");
@@ -162,24 +162,24 @@ bool operator==(const Variant &lhs, const Variant &rhs)
return false;
}
switch (lhs.getType()) {
- case Variant::Type::NULLPTR:
+ case VariantType::NULLPTR:
return true;
- case Variant::Type::BOOL:
+ case VariantType::BOOL:
return lhs.boolVal == rhs.boolVal;
- case Variant::Type::INT:
+ case VariantType::INT:
return lhs.intVal == rhs.intVal;
- case Variant::Type::DOUBLE:
+ case VariantType::DOUBLE:
return lhs.doubleVal == rhs.doubleVal;
- case Variant::Type::STRING:
- case Variant::Type::MAGIC:
+ case VariantType::STRING:
+ case VariantType::MAGIC:
return lhs.asString() == rhs.asString();
- case Variant::Type::ARRAY:
+ case VariantType::ARRAY:
return lhs.asArray() == rhs.asArray();
- case Variant::Type::MAP:
+ case VariantType::MAP:
return lhs.asMap() == rhs.asMap();
- case Variant::Type::OBJECT:
+ case VariantType::OBJECT:
return lhs.asObject() == rhs.asObject();
- case Variant::Type::FUNCTION:
+ case VariantType::FUNCTION:
return lhs.asFunction() == rhs.asFunction();
}
throw OusiaException("Internal Error! Unknown type!");
diff --git a/src/core/common/Variant.hpp b/src/core/common/Variant.hpp
index 254e748..9f6ec7a 100644
--- a/src/core/common/Variant.hpp
+++ b/src/core/common/Variant.hpp
@@ -46,8 +46,25 @@
namespace ousia {
-/* Forward declaration of the Function class */
+// Forward declarations
class Function;
+class RttiBase;
+
+/**
+ * Enum containing the possible types a variant may have.
+ */
+enum class VariantType : int16_t {
+ NULLPTR,
+ BOOL,
+ INT,
+ DOUBLE,
+ STRING,
+ MAGIC,
+ ARRAY,
+ MAP,
+ OBJECT,
+ FUNCTION
+};
/**
* Instances of the Variant class represent any kind of data that is exchanged
@@ -56,22 +73,6 @@ class Function;
class Variant {
public:
/**
- * Enum containing the possible types a variant may have.
- */
- enum class Type : int16_t {
- NULLPTR,
- BOOL,
- INT,
- DOUBLE,
- STRING,
- MAGIC,
- ARRAY,
- MAP,
- OBJECT,
- FUNCTION
- };
-
- /**
* Exception thrown whenever a variant is accessed via a getter function
* that is not supported for the current variant type.
*/
@@ -86,12 +87,12 @@ public:
/**
* Contains the actual type of the variant.
*/
- const Type actualType;
+ const VariantType actualType;
/**
* Contains the requested type of the variant.
*/
- const Type requestedType;
+ const VariantType requestedType;
/**
* Constructor of the TypeException.
@@ -100,7 +101,7 @@ public:
* @param requestedType describes the type in which the variant was
* requested.
*/
- TypeException(Type actualType, Type requestedType);
+ TypeException(VariantType actualType, VariantType requestedType);
};
using boolType = bool;
@@ -116,28 +117,28 @@ private:
/**
* Used to store the actual type of the variant.
*/
- Type type = Type::NULLPTR;
+ VariantType type = VariantType::NULLPTR;
/**
* Anonymous union containing the possible value of the variant.
*/
union {
/**
- * The boolean value. Only valid if type is Type::BOOL.
+ * The boolean value. Only valid if type is VariantType::BOOL.
*/
boolType boolVal;
/**
- * The integer value. Only valid if type is Type::INT.
+ * The integer value. Only valid if type is VariantType::INT.
*/
intType intVal;
/**
- * The number value. Only valid if type is Type::DOUBLE.
+ * The number value. Only valid if type is VariantType::DOUBLE.
*/
doubleType doubleVal;
/**
* Pointer to the more complex data structures on the free store. Only
- * valid if type is one of Type::STRING, Type::ARRAY,
- * Type::MAP.
+ * valid if type is one of VariantType::STRING, VariantType::ARRAY,
+ * VariantType::MAP.
*/
void *ptrVal;
};
@@ -147,9 +148,9 @@ private:
* the specified type.
*/
template <typename T>
- T &asObj(Type requestedType) const
+ T &asObj(VariantType requestedType) const
{
- const Type actualType = getType();
+ const VariantType actualType = getType();
if (actualType == requestedType) {
return *(static_cast<T *>(ptrVal));
}
@@ -167,31 +168,31 @@ private:
destroy();
type = v.type;
switch (type) {
- case Type::NULLPTR:
+ case VariantType::NULLPTR:
break;
- case Type::BOOL:
+ case VariantType::BOOL:
boolVal = v.boolVal;
break;
- case Type::INT:
+ case VariantType::INT:
intVal = v.intVal;
break;
- case Type::DOUBLE:
+ case VariantType::DOUBLE:
doubleVal = v.doubleVal;
break;
- case Type::STRING:
- case Type::MAGIC:
+ case VariantType::STRING:
+ case VariantType::MAGIC:
ptrVal = new stringType(v.asString());
break;
- case Type::ARRAY:
+ case VariantType::ARRAY:
ptrVal = new arrayType(v.asArray());
break;
- case Type::MAP:
+ case VariantType::MAP:
ptrVal = new mapType(v.asMap());
break;
- case Type::OBJECT:
+ case VariantType::OBJECT:
ptrVal = new objectType(v.asObject());
break;
- case Type::FUNCTION:
+ case VariantType::FUNCTION:
ptrVal = new functionType(v.asFunction());
break;
}
@@ -208,28 +209,28 @@ private:
destroy();
type = v.type;
switch (type) {
- case Type::NULLPTR:
+ case VariantType::NULLPTR:
break;
- case Type::BOOL:
+ case VariantType::BOOL:
boolVal = v.boolVal;
break;
- case Type::INT:
+ case VariantType::INT:
intVal = v.intVal;
break;
- case Type::DOUBLE:
+ case VariantType::DOUBLE:
doubleVal = v.doubleVal;
break;
- case Type::STRING:
- case Type::MAGIC:
- case Type::ARRAY:
- case Type::MAP:
- case Type::OBJECT:
- case Type::FUNCTION:
+ case VariantType::STRING:
+ case VariantType::MAGIC:
+ case VariantType::ARRAY:
+ case VariantType::MAP:
+ case VariantType::OBJECT:
+ case VariantType::FUNCTION:
ptrVal = v.ptrVal;
v.ptrVal = nullptr;
break;
}
- v.type = Type::NULLPTR;
+ v.type = VariantType::NULLPTR;
}
/**
@@ -239,20 +240,20 @@ private:
{
if (ptrVal) {
switch (type) {
- case Type::STRING:
- case Type::MAGIC:
+ case VariantType::STRING:
+ case VariantType::MAGIC:
delete static_cast<stringType *>(ptrVal);
break;
- case Type::ARRAY:
+ case VariantType::ARRAY:
delete static_cast<arrayType *>(ptrVal);
break;
- case Type::MAP:
+ case VariantType::MAP:
delete static_cast<mapType *>(ptrVal);
break;
- case Type::OBJECT:
+ case VariantType::OBJECT:
delete static_cast<objectType *>(ptrVal);
break;
- case Type::FUNCTION:
+ case VariantType::FUNCTION:
delete static_cast<functionType *>(ptrVal);
break;
default:
@@ -281,7 +282,7 @@ public:
Variant(Variant &&v) : ptrVal(nullptr) { move(std::move(v)); }
/**
- * Default constructor. Type is set to Type:null.
+ * Default constructor. VariantType is set to VariantType:NULLPTR.
*/
Variant() : ptrVal(nullptr) { setNull(); }
@@ -433,28 +434,28 @@ public:
* @return true if the Variant instance represents the nullptr, false
* otherwise.
*/
- bool isNull() const { return type == Type::NULLPTR; }
+ bool isNull() const { return type == VariantType::NULLPTR; }
/**
* Checks whether this Variant instance is a boolean.
*
* @return true if the Variant instance is a boolean, false otherwise.
*/
- bool isBool() const { return type == Type::BOOL; }
+ bool isBool() const { return type == VariantType::BOOL; }
/**
* Checks whether this Variant instance is an integer.
*
* @return true if the Variant instance is an integer, false otherwise.
*/
- bool isInt() const { return type == Type::INT; }
+ bool isInt() const { return type == VariantType::INT; }
/**
* Checks whether this Variant instance is a double.
*
* @return true if the Variant instance is a double, false otherwise.
*/
- bool isDouble() const { return type == Type::DOUBLE; }
+ bool isDouble() const { return type == VariantType::DOUBLE; }
/**
* Checks whether this Variant instance is a string or a magic string.
@@ -463,7 +464,7 @@ public:
*/
bool isString() const
{
- return type == Type::STRING || type == Type::MAGIC;
+ return type == VariantType::STRING || type == VariantType::MAGIC;
}
/**
@@ -473,35 +474,35 @@ public:
*
* @return true if the Variant instance is a string, false otherwise.
*/
- bool isMagic() const { return type == Type::MAGIC; }
+ bool isMagic() const { return type == VariantType::MAGIC; }
/**
* Checks whether this Variant instance is an array.
*
* @return true if the Variant instance is an array, false otherwise.
*/
- bool isArray() const { return type == Type::ARRAY; }
+ bool isArray() const { return type == VariantType::ARRAY; }
/**
* Checks whether this Variant instance is a map.
*
* @return true if the Variant instance is a map, false otherwise.
*/
- bool isMap() const { return type == Type::MAP; }
+ bool isMap() const { return type == VariantType::MAP; }
/**
* Checks whether this Variant instance is an object.
*
* @return true if the Variant instance is an object, false otherwise.
*/
- bool isObject() const { return type == Type::OBJECT; }
+ bool isObject() const { return type == VariantType::OBJECT; }
/**
* Checks whether this Variant instance is a function.
*
* @return true if the Variant instance is a function, false otherwise.
*/
- bool isFunction() const { return type == Type::FUNCTION; }
+ bool isFunction() const { return type == VariantType::FUNCTION; }
/**
* Checks whether this Variant instance is a primitive type.
@@ -511,11 +512,11 @@ public:
bool isPrimitive() const
{
switch (type) {
- case Type::NULLPTR:
- case Type::BOOL:
- case Type::INT:
- case Type::DOUBLE:
- case Type::STRING:
+ case VariantType::NULLPTR:
+ case VariantType::BOOL:
+ case VariantType::INT:
+ case VariantType::DOUBLE:
+ case VariantType::STRING:
return true;
default:
return false;
@@ -533,7 +534,7 @@ public:
if (isBool()) {
return boolVal;
}
- throw TypeException{getType(), Type::BOOL};
+ throw TypeException{getType(), VariantType::BOOL};
}
/**
@@ -547,7 +548,7 @@ public:
if (isInt()) {
return intVal;
}
- throw TypeException{getType(), Type::INT};
+ throw TypeException{getType(), VariantType::INT};
}
/**
@@ -561,7 +562,7 @@ public:
if (isDouble()) {
return doubleVal;
}
- throw TypeException{getType(), Type::DOUBLE};
+ throw TypeException{getType(), VariantType::DOUBLE};
}
/**
@@ -572,7 +573,7 @@ public:
*/
const stringType &asString() const
{
- return asObj<stringType>(Type::STRING);
+ return asObj<stringType>(VariantType::STRING);
}
/**
@@ -581,7 +582,7 @@ public:
*
* @return the string value as reference.
*/
- stringType &asString() { return asObj<stringType>(Type::STRING); }
+ stringType &asString() { return asObj<stringType>(VariantType::STRING); }
/**
* Returns a const reference to the magic string value. Performs no type
@@ -592,10 +593,10 @@ public:
*/
const stringType &asMagic() const
{
- if (type == Type::MAGIC) {
- return asObj<stringType>(Type::STRING);
+ if (type == VariantType::MAGIC) {
+ return asObj<stringType>(VariantType::STRING);
}
- throw TypeException{getType(), Type::MAGIC};
+ throw TypeException{getType(), VariantType::MAGIC};
}
/**
@@ -607,10 +608,10 @@ public:
*/
stringType &asMagic()
{
- if (type == Type::MAGIC) {
- return asObj<stringType>(Type::STRING);
+ if (type == VariantType::MAGIC) {
+ return asObj<stringType>(VariantType::STRING);
}
- throw TypeException{getType(), Type::MAGIC};
+ throw TypeException{getType(), VariantType::MAGIC};
}
/**
@@ -619,7 +620,7 @@ public:
*
* @return the array value as const reference.
*/
- const arrayType &asArray() const { return asObj<arrayType>(Type::ARRAY); }
+ const arrayType &asArray() const { return asObj<arrayType>(VariantType::ARRAY); }
/**
* Returns a const reference to the array value. Performs no type
@@ -627,7 +628,7 @@ public:
*
* @return the array value as reference.
*/
- arrayType &asArray() { return asObj<arrayType>(Type::ARRAY); }
+ arrayType &asArray() { return asObj<arrayType>(VariantType::ARRAY); }
/**
* Returns a const reference to the map value. Performs no type
@@ -635,7 +636,7 @@ public:
*
* @return the map value as const reference.
*/
- const mapType &asMap() const { return asObj<mapType>(Type::MAP); }
+ const mapType &asMap() const { return asObj<mapType>(VariantType::MAP); }
/**
* Returns a pointer pointing at the stored managed object. Performs no type
@@ -644,7 +645,7 @@ public:
*
* @return pointer at the stored managed object.
*/
- objectType asObject() { return asObj<objectType>(Type::OBJECT); }
+ objectType asObject() { return asObj<objectType>(VariantType::OBJECT); }
/**
* Returns a pointer pointing at the stored managed object. Performs no type
@@ -655,7 +656,7 @@ public:
*/
const objectType asObject() const
{
- return asObj<objectType>(Type::OBJECT);
+ return asObj<objectType>(VariantType::OBJECT);
}
/**
@@ -664,7 +665,7 @@ public:
*
* @return the map value as reference.
*/
- mapType &asMap() { return asObj<mapType>(Type::MAP); }
+ mapType &asMap() { return asObj<mapType>(VariantType::MAP); }
/**
* Returns a shared pointer pointing at the stored function object. Performs
@@ -673,7 +674,7 @@ public:
*
* @return pointer at the stored managed object.
*/
- functionType &asFunction() { return asObj<functionType>(Type::FUNCTION); }
+ functionType &asFunction() { return asObj<functionType>(VariantType::FUNCTION); }
/**
* Returns a shared pointer pointing at the stored function object. Performs
@@ -684,7 +685,7 @@ public:
*/
const functionType &asFunction() const
{
- return asObj<functionType>(Type::FUNCTION);
+ return asObj<functionType>(VariantType::FUNCTION);
}
/**
@@ -723,7 +724,7 @@ public:
void setNull()
{
destroy();
- type = Type::NULLPTR;
+ type = VariantType::NULLPTR;
ptrVal = nullptr;
}
@@ -735,7 +736,7 @@ public:
void setBool(boolType b)
{
destroy();
- type = Type::BOOL;
+ type = VariantType::BOOL;
boolVal = b;
}
@@ -747,7 +748,7 @@ public:
void setInt(intType i)
{
destroy();
- type = Type::INT;
+ type = VariantType::INT;
intVal = i;
}
@@ -759,7 +760,7 @@ public:
void setDouble(doubleType d)
{
destroy();
- type = Type::DOUBLE;
+ type = VariantType::DOUBLE;
doubleVal = d;
}
@@ -771,11 +772,11 @@ public:
void setString(const char *s)
{
if (isString()) {
- type = Type::STRING;
+ type = VariantType::STRING;
asString().assign(s);
} else {
destroy();
- type = Type::STRING;
+ type = VariantType::STRING;
ptrVal = new stringType(s);
}
}
@@ -788,11 +789,11 @@ public:
void setMagic(const char *s)
{
if (isString()) {
- type = Type::MAGIC;
+ type = VariantType::MAGIC;
asString().assign(s);
} else {
destroy();
- type = Type::MAGIC;
+ type = VariantType::MAGIC;
ptrVal = new stringType(s);
}
}
@@ -808,7 +809,7 @@ public:
asArray().swap(a);
} else {
destroy();
- type = Type::ARRAY;
+ type = VariantType::ARRAY;
ptrVal = new arrayType(std::move(a));
}
}
@@ -824,7 +825,7 @@ public:
asMap().swap(m);
} else {
destroy();
- type = Type::MAP;
+ type = VariantType::MAP;
ptrVal = new mapType(std::move(m));
}
}
@@ -837,7 +838,7 @@ public:
void setObject(Handle<T> o)
{
destroy();
- type = Type::OBJECT;
+ type = VariantType::OBJECT;
ptrVal = new objectType(o);
}
@@ -846,10 +847,10 @@ public:
*
* @return the current type of the Variant.
*/
- Type getType() const
+ VariantType getType() const
{
if (isMagic()) {
- return Type::STRING;
+ return VariantType::STRING;
}
return type;
}
@@ -857,7 +858,7 @@ public:
/**
* Returns the name of the given variant type as C-style string.
*/
- static const char *getTypeName(Type type);
+ static const char *getTypeName(VariantType type);
/**
* Returns the name of the type of this variant instance.
diff --git a/src/core/common/VariantConverter.cpp b/src/core/common/VariantConverter.cpp
index f9d465e..795612b 100644
--- a/src/core/common/VariantConverter.cpp
+++ b/src/core/common/VariantConverter.cpp
@@ -28,8 +28,8 @@
namespace ousia {
-static std::string msgUnexpectedType(Variant::Type actualType,
- Variant::Type requestedType)
+static std::string msgUnexpectedType(VariantType actualType,
+ VariantType requestedType)
{
return std::string("Cannot convert ") + Variant::getTypeName(actualType) +
std::string(" to ") + Variant::getTypeName(requestedType);
@@ -38,9 +38,9 @@ static std::string msgUnexpectedType(Variant::Type actualType,
bool VariantConverter::toBool(Variant &var, Logger &logger, Mode mode)
{
// Perform safe conversions
- const Variant::Type type = var.getType();
+ const VariantType type = var.getType();
switch (type) {
- case Variant::Type::BOOL:
+ case VariantType::BOOL:
// No conversion needed if "var" already is a boolean
return true;
default:
@@ -50,13 +50,13 @@ bool VariantConverter::toBool(Variant &var, Logger &logger, Mode mode)
// Perform potentially dangerous conversions in the "ALL" mode
if (mode == Mode::ALL) {
switch (var.getType()) {
- case Variant::Type::NULLPTR:
+ case VariantType::NULLPTR:
var = false;
return true;
- case Variant::Type::INT:
+ case VariantType::INT:
var = var.asInt() != 0;
return true;
- case Variant::Type::DOUBLE:
+ case VariantType::DOUBLE:
var = var.asDouble() != 0.0;
return true;
default:
@@ -66,7 +66,7 @@ bool VariantConverter::toBool(Variant &var, Logger &logger, Mode mode)
}
// No conversion possible, assign default value and log error
- logger.error(msgUnexpectedType(var.getType(), Variant::Type::BOOL));
+ logger.error(msgUnexpectedType(var.getType(), VariantType::BOOL));
var = false;
return false;
}
@@ -74,9 +74,9 @@ bool VariantConverter::toBool(Variant &var, Logger &logger, Mode mode)
bool VariantConverter::toInt(Variant &var, Logger &logger, Mode mode)
{
// Perform safe conversions
- const Variant::Type type = var.getType();
+ const VariantType type = var.getType();
switch (type) {
- case Variant::Type::INT:
+ case VariantType::INT:
// No conversion needed if "var" already is an integer
return true;
default:
@@ -86,17 +86,17 @@ bool VariantConverter::toInt(Variant &var, Logger &logger, Mode mode)
// Perform all potentially dangerous conversions in the "ALL" mode
if (mode == Mode::ALL) {
switch (type) {
- case Variant::Type::NULLPTR:
+ case VariantType::NULLPTR:
var = 0;
return true;
- case Variant::Type::BOOL:
+ case VariantType::BOOL:
var = var.asBool() ? 1 : 0;
return true;
- case Variant::Type::DOUBLE:
+ case VariantType::DOUBLE:
var = (Variant::intType)var.asDouble();
return true;
- case Variant::Type::STRING:
- case Variant::Type::MAGIC: {
+ case VariantType::STRING:
+ case VariantType::MAGIC: {
Number n;
n.parse(var.asString(), logger);
if (n.isInt()) {
@@ -106,7 +106,7 @@ bool VariantConverter::toInt(Variant &var, Logger &logger, Mode mode)
}
return true;
}
- case Variant::Type::ARRAY: {
+ case VariantType::ARRAY: {
try {
// JavaScript behaviour when converting arrays to doubles
const Variant::arrayType &a = var.asArray();
@@ -123,7 +123,7 @@ bool VariantConverter::toInt(Variant &var, Logger &logger, Mode mode)
}
// No conversion possible, assign default value and log error
- logger.error(msgUnexpectedType(var.getType(), Variant::Type::INT));
+ logger.error(msgUnexpectedType(var.getType(), VariantType::INT));
var = 0;
return false;
}
@@ -131,12 +131,12 @@ bool VariantConverter::toInt(Variant &var, Logger &logger, Mode mode)
bool VariantConverter::toDouble(Variant &var, Logger &logger, Mode mode)
{
// Perform safe conversions
- const Variant::Type type = var.getType();
+ const VariantType type = var.getType();
switch (type) {
- case Variant::Type::DOUBLE:
+ case VariantType::DOUBLE:
// No conversion needed if "var" already is a double
return true;
- case Variant::Type::INT:
+ case VariantType::INT:
// Converting integers to doubles is safe
var = (Variant::doubleType)var.asInt();
return true;
@@ -147,20 +147,20 @@ bool VariantConverter::toDouble(Variant &var, Logger &logger, Mode mode)
// Perform all potentially dangerous conversions in the "ALL" mode
if (mode == Mode::ALL) {
switch (type) {
- case Variant::Type::NULLPTR:
+ case VariantType::NULLPTR:
var = 0.0;
return true;
- case Variant::Type::BOOL:
+ case VariantType::BOOL:
var = var.asBool() ? 1.0 : 0.0;
return true;
- case Variant::Type::STRING:
- case Variant::Type::MAGIC: {
+ case VariantType::STRING:
+ case VariantType::MAGIC: {
Number n;
n.parse(var.asString(), logger);
var = (Variant::doubleType)n.doubleValue();
return true;
}
- case Variant::Type::ARRAY: {
+ case VariantType::ARRAY: {
try {
// JavaScript behaviour when converting arrays to doubles
const Variant::arrayType &a = var.asArray();
@@ -177,7 +177,7 @@ bool VariantConverter::toDouble(Variant &var, Logger &logger, Mode mode)
}
// No conversion possible, assign default value and log error
- logger.error(msgUnexpectedType(var.getType(), Variant::Type::DOUBLE));
+ logger.error(msgUnexpectedType(var.getType(), VariantType::DOUBLE));
var = 0.0;
return false;
}
@@ -185,28 +185,28 @@ bool VariantConverter::toDouble(Variant &var, Logger &logger, Mode mode)
bool VariantConverter::toString(Variant &var, Logger &logger, Mode mode)
{
// Perform safe conversions (all these operations are considered "lossless")
- const Variant::Type type = var.getType();
+ const VariantType type = var.getType();
switch (type) {
- case Variant::Type::NULLPTR:
+ case VariantType::NULLPTR:
var = "null";
return true;
- case Variant::Type::BOOL:
+ case VariantType::BOOL:
var = var.asBool() ? "true" : "false";
return true;
- case Variant::Type::INT: {
+ case VariantType::INT: {
std::stringstream ss;
ss << var.asInt();
var = ss.str().c_str();
return true;
}
- case Variant::Type::DOUBLE: {
+ case VariantType::DOUBLE: {
std::stringstream ss;
ss << var.asDouble();
var = ss.str().c_str();
return true;
}
- case Variant::Type::MAGIC:
- case Variant::Type::STRING:
+ case VariantType::MAGIC:
+ case VariantType::STRING:
// No conversion needed if "var" already is a string (or a magic
// string value)
return true;
@@ -217,14 +217,14 @@ bool VariantConverter::toString(Variant &var, Logger &logger, Mode mode)
// Perform lossy conversions
if (mode == Mode::ALL) {
switch (type) {
- case Variant::Type::ARRAY:
- case Variant::Type::MAP: {
+ case VariantType::ARRAY:
+ case VariantType::MAP: {
std::stringstream ss;
VariantWriter::writeJson(var, ss, false);
var = ss.str().c_str();
return true;
}
- case Variant::Type::OBJECT: {
+ case VariantType::OBJECT: {
// Print object address and type
Variant::objectType obj = var.asObject();
std::stringstream ss;
@@ -233,7 +233,7 @@ bool VariantConverter::toString(Variant &var, Logger &logger, Mode mode)
var = ss.str().c_str();
return true;
}
- case Variant::Type::FUNCTION: {
+ case VariantType::FUNCTION: {
// Print function pointer address
Variant::functionType obj = var.asFunction();
std::stringstream ss;
@@ -247,7 +247,7 @@ bool VariantConverter::toString(Variant &var, Logger &logger, Mode mode)
}
// No conversion possible, assign default value and log error
- logger.error(msgUnexpectedType(var.getType(), Variant::Type::STRING));
+ logger.error(msgUnexpectedType(var.getType(), VariantType::STRING));
var = "";
return false;
}
diff --git a/src/core/common/VariantConverter.hpp b/src/core/common/VariantConverter.hpp
index b683083..e5014bd 100644
--- a/src/core/common/VariantConverter.hpp
+++ b/src/core/common/VariantConverter.hpp
@@ -22,8 +22,10 @@
namespace ousia {
// Forward declaration
-class Variant;
class Logger;
+class RttiBase;
+class Variant;
+enum class VariantType : int16_t;
/**
* The VariantConverter class is used to convert a variant to a certain
@@ -31,21 +33,18 @@ class Logger;
* type, even if the conversion fails.
*/
class VariantConverter {
-
public:
/**
* Enumeration used to define the mode of conversion -- either only safe
* conversions (without any data loss) are performed, or all possible
* conversions are tried (with possible data loss).
*/
- enum class Mode {
- SAFE, ALL
- };
+ enum class Mode { SAFE, ALL };
/**
- * Makes sure the given variant is a boolean. If the "mode" parameter is
- * set to Mode::SAFE, only booleans can be converted to booleans. For all
- * other types the conversion fails. If "mode" is set to Mode::ALL, nullptr
+ * Converts the given variant to a boolean. If the "mode" parameter is set
+ * to Mode::SAFE, only booleans can be converted to booleans. For all other
+ * types the conversion fails. If "mode" is set to Mode::ALL, nullptr
* values and zero numeric values are treated as "false", all other values
* are treated as "true".
*
@@ -58,14 +57,66 @@ public:
*/
static bool toBool(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
+ /**
+ * Converts the given variant to an integer. If the "mode" parameter is set
+ * to Mode::SAFE, only integers can be converted to integers. For all other
+ * types the conversion fails. If "mode" is set to Mode::ALL, booleans are
+ * converted to 0, 1, nullptr is converted to 0, doubles are truncated,
+ * strings are parsed and truncated, arrays with one element are converted
+ * to an integer. Conversion fails for objects, functions, maps and arrays
+ * with zero or more than one entry.
+ *
+ * @param var is instance of the Variant class that should be converted to
+ * the requested type.
+ * @param logger is a reference to the logger instance into which messages
+ * should be logged.
+ * @param mode is the conversion mode. See method description for the exact
+ * effect.
+ */
static bool toInt(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
+ /**
+ * Converts the given variant to a double. If the "mode" parameter is set
+ * to Mode::SAFE, only integers and doubles can be converted to doubles. For
+ * all other types the conversion fails. If "mode" is set to Mode::ALL,
+ * booleans are converted to 0.0, 1.0, nullptr is converted to 0.0, strings
+ * are parsed, arrays with one element are converted to a double.
+ * Conversion fails for objects, functions, maps and arrays with zero or
+ * more than one entry.
+ *
+ * @param var is instance of the Variant class that should be converted to
+ * the requested type.
+ * @param logger is a reference to the logger instance into which messages
+ * should be logged.
+ * @param mode is the conversion mode. See method description for the exact
+ * effect.
+ */
static bool toDouble(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
+ /**
+ * Converts the given variant to a double. If the "mode" parameter is set
+ * to Mode::SAFE, all primitive types can be converted to strings. For
+ * all other types the conversion fails. If "mode" is set to Mode::ALL,
+ * maps and arrays are converted to a JSON representation, objects and
+ * functions are converted to an informative string containing their pointer
+ * and type.
+ *
+ * @param var is instance of the Variant class that should be converted to
+ * the requested type.
+ * @param logger is a reference to the logger instance into which messages
+ * should be logged.
+ * @param mode is the conversion mode. See method description for the exact
+ * effect.
+ */
static bool toString(Variant &var, Logger &logger, Mode mode = Mode::SAFE);
-};
+ static bool convert(Variant &var, VariantType requestedType,
+ const RttiBase &rttiType, Logger &logger,
+ Mode mode = Mode::SAFE);
+ static bool convert(Variant &var, VariantType requestedType,
+ Logger &logger, Mode mode = Mode::SAFE);
+};
}
#endif /* _OUSIA_VARIANT_CONVERTER_HPP_ */
diff --git a/src/core/common/VariantWriter.cpp b/src/core/common/VariantWriter.cpp
index 39dfc3b..713ec01 100644
--- a/src/core/common/VariantWriter.cpp
+++ b/src/core/common/VariantWriter.cpp
@@ -106,19 +106,19 @@ static void writeJsonInternal(const Variant &var, std::ostream &stream,
bool pretty, int level)
{
switch (var.getType()) {
- case Variant::Type::NULLPTR:
- case Variant::Type::BOOL:
- case Variant::Type::INT:
- case Variant::Type::DOUBLE:
- case Variant::Type::FUNCTION:
- case Variant::Type::OBJECT:
+ case VariantType::NULLPTR:
+ case VariantType::BOOL:
+ case VariantType::INT:
+ case VariantType::DOUBLE:
+ case VariantType::FUNCTION:
+ case VariantType::OBJECT:
stream << var.toString();
return;
- case Variant::Type::STRING:
- case Variant::Type::MAGIC:
+ case VariantType::STRING:
+ case VariantType::MAGIC:
writeJsonString(var.toString(), stream);
return;
- case Variant::Type::ARRAY: {
+ case VariantType::ARRAY: {
stream << "[";
writeLinebreak(stream, pretty);
const Variant::arrayType &arr = var.asArray();
@@ -134,7 +134,7 @@ static void writeJsonInternal(const Variant &var, std::ostream &stream,
stream << "]";
return;
}
- case Variant::Type::MAP: {
+ case VariantType::MAP: {
writeIndentation(stream, pretty, level);
stream << "{";
writeLinebreak(stream, pretty);