diff --git a/src/framework/luaengine/luainterface.cpp b/src/framework/luaengine/luainterface.cpp index e533be08..db3c34e8 100644 --- a/src/framework/luaengine/luainterface.cpp +++ b/src/framework/luaengine/luainterface.cpp @@ -962,10 +962,10 @@ void LuaInterface::pop(int n) } } -int LuaInterface::popInteger() +long LuaInterface::popInteger() { assert(hasIndex(-1)); - int v = toInteger(-1); + long v = toInteger(-1); pop(); return v; } @@ -1021,7 +1021,7 @@ void LuaInterface::pushNil() checkStack(); } -void LuaInterface::pushInteger(int v) +void LuaInterface::pushInteger(long v) { lua_pushinteger(L, v); checkStack(); diff --git a/src/framework/luaengine/luainterface.h b/src/framework/luaengine/luainterface.h index 5a5261b8..86175baa 100644 --- a/src/framework/luaengine/luainterface.h +++ b/src/framework/luaengine/luainterface.h @@ -270,7 +270,7 @@ public: void* newUserdata(int size); void pop(int n = 1); - int popInteger(); + long popInteger(); double popNumber(); bool popBoolean(); std::string popString(); @@ -279,7 +279,7 @@ public: LuaObjectPtr popObject(); void pushNil(); - void pushInteger(int v); + void pushInteger(long v); void pushNumber(double v); void pushBoolean(bool v); void pushCString(const char* v); diff --git a/src/framework/luaengine/luavaluecasts.cpp b/src/framework/luaengine/luavaluecasts.cpp index cf1d0ad3..d82920f2 100644 --- a/src/framework/luaengine/luavaluecasts.cpp +++ b/src/framework/luaengine/luavaluecasts.cpp @@ -112,13 +112,13 @@ bool luavalue_cast(int index, Color& color) { if(g_lua.isTable(index)) { g_lua.getField("r", index); - color.setRed(g_lua.popInteger()); + color.setRed((int)g_lua.popInteger()); g_lua.getField("g", index); - color.setGreen(g_lua.popInteger()); + color.setGreen((int)g_lua.popInteger()); g_lua.getField("b", index); - color.setBlue(g_lua.popInteger()); + color.setBlue((int)g_lua.popInteger()); g_lua.getField("a", index); - color.setAlpha(g_lua.popInteger()); + color.setAlpha((int)g_lua.popInteger()); return true; } else if(g_lua.isString()) { return stdext::cast(g_lua.toString(index), color); @@ -225,11 +225,20 @@ bool luavalue_cast(int index, Size& size) void push_otml_subnode_luavalue(const OTMLNodePtr& node) { if(node->hasValue()) { - // convert boolean types - if(node->value() == "true" || node->value() == "false") - g_lua.pushBoolean(node->value()); + union { + bool b; + double d; + long l; + }; + std::string value = node->rawValue(); + if(stdext::cast(value, b)) + g_lua.pushBoolean(b); + else if(stdext::cast(value, l)) + g_lua.pushInteger(l); + else if(stdext::cast(value, d)) + g_lua.pushNumber(d); else - g_lua.pushString(node->value()); + g_lua.pushString(value); } else if(node->hasChildren()) { g_lua.newTable(); bool pushedChild = false; diff --git a/src/framework/otml/otmlnode.cpp b/src/framework/otml/otmlnode.cpp index e0bbf216..dbd1be8e 100644 --- a/src/framework/otml/otmlnode.cpp +++ b/src/framework/otml/otmlnode.cpp @@ -150,7 +150,7 @@ bool OTMLNode::replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newC void OTMLNode::copy(const OTMLNodePtr& node) { setTag(node->tag()); - setValue(node->value()); + setValue(node->rawValue()); setUnique(node->isUnique()); setNull(node->isNull()); setSource(node->source()); diff --git a/src/framework/otml/otmlnode.h b/src/framework/otml/otmlnode.h index 734df4b5..82fc088d 100644 --- a/src/framework/otml/otmlnode.h +++ b/src/framework/otml/otmlnode.h @@ -37,6 +37,7 @@ public: int size() { return m_children.size(); } OTMLNodePtr parent() { return m_parent.lock(); } std::string source() { return m_source; } + std::string rawValue() { return m_value; } bool isUnique() { return m_unique; } bool isNull() { return m_null; } @@ -104,11 +105,25 @@ protected: #include "otmlexception.h" +template<> +inline std::string OTMLNode::value() { + std::string value = m_value; + if(boost::starts_with(value, "\"") && boost::ends_with(value, "\"")) { + value = value.substr(1, value.length()-2); + boost::replace_all(value, "\\\\", "\\"); + boost::replace_all(value, "\\\"", "\""); + boost::replace_all(value, "\\t", "\t"); + boost::replace_all(value, "\\n", "\n"); + boost::replace_all(value, "\\'", "\'"); + } + return value; +} + template T OTMLNode::value() { T ret; if(!stdext::cast(m_value, ret)) - throw OTMLException(shared_from_this(), stdext::mkstr("failed to cast node value to type '%s'", stdext::demangle_type())); + throw OTMLException(shared_from_this(), stdext::format("failed to cast node value '%s' to type '%s'", m_value, stdext::demangle_type())); return ret; } diff --git a/src/framework/stdext/cast.h b/src/framework/stdext/cast.h index 8ee136d5..2126af22 100644 --- a/src/framework/stdext/cast.h +++ b/src/framework/stdext/cast.h @@ -62,20 +62,71 @@ inline bool cast(const std::string& in, std::string& out) { // special cast from string to boolean template<> inline bool cast(const std::string& in, bool& b) { - static std::string validNames[2][4] = {{"true","yes","on","1"}, {"false","no","off","0"}}; - bool ret = false; - for(int i=0;i<4;++i) { - if(in == validNames[0][i]) { - b = true; - ret = true; - break; - } else if(in == validNames[1][i]) { - b = false; - ret = true; - break; - } + if(in == "true") + b = true; + else if(in == "false") + b = false; + else + return false; + return true; +} + +// special cast from string to char +template<> +inline bool cast(const std::string& in, char& c) { + if(in.length() != 1) + return false; + c = in[0]; + return true; +} + +// special cast from string to long +template<> +inline bool cast(const std::string& in, long& l) { + if(in.find_first_not_of("-0123456789") != std::string::npos) + return false; + std::size_t t = in.find_last_of('-'); + if(t != std::string::npos && t != 0) + return false; + l = atol(in.c_str()); + return true; +} + +// special cast from string to int +template<> +inline bool cast(const std::string& in, int& i) { + long l; + if(cast(in, l)) { + i=l; + return true; + } + return false; +} + +// special cast from string to double +template<> +inline bool cast(const std::string& in, double& d) { + if(in.find_first_not_of("-0123456789.") != std::string::npos) + return false; + std::size_t t = in.find_last_of('-'); + if(t != std::string::npos && t != 0) + return false; + t = in.find_first_of('.'); + if(t != std::string::npos && (t == 0 || t == in.length()-1 || in.find_first_of('.', t+1) != std::string::npos)) + return false; + d = atof(in.c_str()); + return true; +} + +// special cast from string to float +template<> +inline bool cast(const std::string& in, float& f) { + double d; + if(cast(in, d)) { + f=d; + return true; } - return ret; + return false; } // special cast from boolean to string