diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/common/Variant.cpp | 64 | ||||
| -rw-r--r-- | src/core/common/Variant.hpp | 209 | ||||
| -rw-r--r-- | src/core/common/VariantConverter.cpp | 76 | ||||
| -rw-r--r-- | src/core/common/VariantConverter.hpp | 69 | ||||
| -rw-r--r-- | src/core/common/VariantWriter.cpp | 20 | 
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);  | 
