Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "ScriptWString.h"
- #include <assert.h> // assert()
- #include <sstream> // std::stringstream
- #include <string.h> // strstr()
- #include <stdio.h> // sprintf()
- #include <stdlib.h> // strtod()
- #include <locale.h> // setlocale()
- #include <map> // std::map
- using namespace std;
- BEGIN_AS_NAMESPACE
- #if AS_USE_STRINGPOOL == 1
- // By keeping the literal strings in a pool the application
- // performance is improved as there are less string copies created.
- // The string pool will be kept as user data in the engine. We'll
- // need a specific type to identify the string pool user data.
- // We just define a number here that we assume nobody else is using for
- // object type user data. The add-ons have reserved the numbers 1000
- // through 1999 for this purpose, so we should be fine.
- const asPWORD STRING_POOL = 1001;
- static const wstring &StringFactory(asUINT length, const wchar_t *s)
- {
- static wstring dummy;
- // Each engine instance has its own string pool
- asIScriptContext *ctx = asGetActiveContext();
- if( ctx == 0 )
- {
- // The string factory can only be called from a script
- assert( ctx );
- return dummy;
- }
- asIScriptEngine *engine = ctx->GetEngine();
- // TODO: runtime optimize: Use unordered_map if C++11 is supported, i.e. MSVC10+, gcc 4.?+
- map<const wchar_t *, wstring> *pool = reinterpret_cast< map<const wchar_t *, wstring>* >(engine->GetUserData(STRING_POOL));
- if( !pool )
- {
- // The string pool hasn't been created yet, so we'll create it now
- asAcquireExclusiveLock();
- // Make sure the string pool wasn't created while we were waiting for the lock
- pool = reinterpret_cast< map<const wchar_t *, wstring>* >(engine->GetUserData(STRING_POOL));
- if( !pool )
- {
- #if defined(AS_MARMALADE)
- pool = new map<const wchar_t *, wstring>;
- #else
- pool = new (nothrow) map<const wchar_t *, wstring>;
- #endif
- if( pool == 0 )
- {
- ctx->SetException("Out of memory");
- asReleaseExclusiveLock();
- return dummy;
- }
- engine->SetUserData(pool, STRING_POOL);
- }
- asReleaseExclusiveLock();
- }
- // We can't let other threads modify the pool while we query it
- asAcquireSharedLock();
- // First check if a string object hasn't been created already
- map<const wchar_t *, wstring>::iterator it;
- it = pool->find(s);
- if( it != pool->end() )
- {
- asReleaseSharedLock();
- return it->second;
- }
- asReleaseSharedLock();
- // Acquire an exclusive lock so we can add the new string to the pool
- asAcquireExclusiveLock();
- // Make sure the string wasn't created while we were waiting for the exclusive lock
- it = pool->find(s);
- if( it == pool->end() )
- {
- // Create a new string object
- // Divide length in 2 for wstring
- pool->insert(map<const wchar_t *, wstring>::value_type(s, wstring(s, length/2)));
- it = pool->find(s);
- }
- asReleaseExclusiveLock();
- return it->second;
- }
- static void CleanupEngineStringPool(asIScriptEngine *engine)
- {
- map<const wchar_t *, wstring> *pool = reinterpret_cast< map<const wchar_t *, wstring>* >(engine->GetUserData(STRING_POOL));
- if( pool )
- delete pool;
- }
- #else
- static wstring StringFactory(asUINT length, const wchar_t *s)
- {
- return wstring(s, length/2);
- }
- #endif
- static void ConstructString(wstring *thisPointer)
- {
- new(thisPointer) wstring();
- }
- static void CopyConstructString(const wstring &other, wstring *thisPointer)
- {
- new(thisPointer) wstring(other);
- }
- static void DestructString(wstring *thisPointer)
- {
- thisPointer->~wstring();
- }
- static wstring &AssignUIntToString(unsigned int i, wstring &dest)
- {
- wostringstream stream;
- stream << i;
- dest = stream.str();
- return dest;
- }
- static wstring &AddAssignUIntToString(unsigned int i, wstring &dest)
- {
- wostringstream stream;
- stream << i;
- dest += stream.str();
- return dest;
- }
- static wstring AddStringUInt(const wstring &str, unsigned int i)
- {
- wostringstream stream;
- stream << i;
- return str + stream.str();
- }
- static wstring AddIntString(int i, const wstring &str)
- {
- wostringstream stream;
- stream << i;
- return stream.str() + str;
- }
- static wstring &AssignIntToString(int i, wstring &dest)
- {
- wostringstream stream;
- stream << i;
- dest = stream.str();
- return dest;
- }
- static wstring &AddAssignIntToString(int i, wstring &dest)
- {
- wostringstream stream;
- stream << i;
- dest += stream.str();
- return dest;
- }
- static wstring AddStringInt(const wstring &str, int i)
- {
- wostringstream stream;
- stream << i;
- return str + stream.str();
- }
- static wstring AddUIntString(unsigned int i, const wstring &str)
- {
- wostringstream stream;
- stream << i;
- return stream.str() + str;
- }
- static wstring &AssignDoubleToString(double f, wstring &dest)
- {
- wostringstream stream;
- stream << f;
- dest = stream.str();
- return dest;
- }
- static wstring &AddAssignDoubleToString(double f, wstring &dest)
- {
- wostringstream stream;
- stream << f;
- dest += stream.str();
- return dest;
- }
- static wstring &AssignBoolToString(bool b, wstring &dest)
- {
- wostringstream stream;
- stream << (b ? "true" : "false");
- dest = stream.str();
- return dest;
- }
- static wstring &AddAssignBoolToString(bool b, wstring &dest)
- {
- wostringstream stream;
- stream << (b ? "true" : "false");
- dest += stream.str();
- return dest;
- }
- static wstring AddStringDouble(const wstring &str, double f)
- {
- wostringstream stream;
- stream << f;
- return str + stream.str();
- }
- static wstring AddDoubleString(double f, const wstring &str)
- {
- wostringstream stream;
- stream << f;
- return stream.str() + str;
- }
- static wstring AddStringBool(const wstring &str, bool b)
- {
- wostringstream stream;
- stream << (b ? "true" : "false");
- return str + stream.str();
- }
- static wstring AddBoolString(bool b, const wstring &str)
- {
- wostringstream stream;
- stream << (b ? "true" : "false");
- return stream.str() + str;
- }
- static wchar_t *StringCharAt(unsigned int i, wstring &str)
- {
- if( i >= str.size() )
- {
- // Set a script exception
- asIScriptContext *ctx = asGetActiveContext();
- ctx->SetException("Out of range");
- // Return a null pointer
- return 0;
- }
- return &str[i];
- }
- // AngelScript signature:
- // int wstring::opCmp(const wstring &in) const
- static int StringCmp(const wstring &a, const wstring &b)
- {
- int cmp = 0;
- if( a < b ) cmp = -1;
- else if( a > b ) cmp = 1;
- return cmp;
- }
- // This function returns the index of the first position where the substring
- // exists in the input string. If the substring doesn't exist in the input
- // string -1 is returned.
- //
- // AngelScript signature:
- // int wstring::findFirst(const wstring &in sub, uint start = 0) const
- static int StringFindFirst(const wstring &sub, asUINT start, const wstring &str)
- {
- // We don't register the method directly because the argument types change between 32bit and 64bit platforms
- return (int)str.find(sub, start);
- }
- // This function returns the index of the last position where the substring
- // exists in the input string. If the substring doesn't exist in the input
- // string -1 is returned.
- //
- // AngelScript signature:
- // int wstring::findLast(const wstring &in sub, int start = -1) const
- static int StringFindLast(const wstring &sub, int start, const wstring &str)
- {
- // We don't register the method directly because the argument types change between 32bit and 64bit platforms
- return (int)str.rfind(sub, (size_t)start);
- }
- // AngelScript signature:
- // uint wstring::length() const
- static asUINT StringLength(const wstring &str)
- {
- // We don't register the method directly because the return type changes between 32bit and 64bit platforms
- return (asUINT)str.length();
- }
- // AngelScript signature:
- // void wstring::resize(uint l)
- static void StringResize(asUINT l, wstring &str)
- {
- // We don't register the method directly because the argument types change between 32bit and 64bit platforms
- str.resize(l);
- }
- // AngelScript signature:
- // wstring formatInt(int64 val, const wstring &in options, uint width)
- static wstring formatInt(asINT64 value, const wstring &options, asUINT width)
- {
- bool leftJustify = options.find(L"l") != -1;
- bool padWithZero = options.find(L"0") != -1;
- bool alwaysSign = options.find(L"+") != -1;
- bool spaceOnSign = options.find(L" ") != -1;
- bool hexSmall = options.find(L"h") != -1;
- bool hexLarge = options.find(L"H") != -1;
- wstring fmt = L"%";
- if( leftJustify ) fmt += L"-";
- if( alwaysSign ) fmt += L"+";
- if( spaceOnSign ) fmt += L" ";
- if( padWithZero ) fmt += L"0";
- #ifdef __GNUC__
- #ifdef _LP64
- fmt += L"*l";
- #else
- fmt += L"*ll";
- #endif
- #else
- fmt += L"*I64";
- #endif
- if( hexSmall ) fmt += L"x";
- else if( hexLarge ) fmt += L"X";
- else fmt += L"d";
- wstring buf;
- buf.resize(width+20);
- #if _MSC_VER >= 1400 && !defined(AS_MARMALADE)// MSVC 8.0 / 2005
- swprintf_s(&buf[0], buf.size(), fmt.c_str(), width, value);
- #else
- sprintf(&buf[0], fmt.c_str(), width, value);
- #endif
- buf.resize(wcslen(&buf[0]));
- return buf;
- }
- // AngelScript signature:
- // wstring formatFloat(double val, const wstring &in options, uint width, uint precision)
- static wstring formatFloat(double value, const wstring &options, asUINT width, asUINT precision)
- {
- bool leftJustify = options.find(L"l") != -1;
- bool padWithZero = options.find(L"0") != -1;
- bool alwaysSign = options.find(L"+") != -1;
- bool spaceOnSign = options.find(L" ") != -1;
- bool expSmall = options.find(L"e") != -1;
- bool expLarge = options.find(L"E") != -1;
- wstring fmt = L"%";
- if( leftJustify ) fmt += L"-";
- if( alwaysSign ) fmt += L"+";
- if( spaceOnSign ) fmt += L" ";
- if( padWithZero ) fmt += L"0";
- fmt += L"*.*";
- if( expSmall ) fmt += L"e";
- else if( expLarge ) fmt += L"E";
- else fmt += L"f";
- wstring buf;
- buf.resize(width+precision+50);
- #if _MSC_VER >= 1400 && !defined(AS_MARMALADE)// MSVC 8.0 / 2005
- swprintf_s(&buf[0], buf.size(), fmt.c_str(), width, precision, value);
- #else
- swprintf(&buf[0], fmt.c_str(), width, precision, value);
- #endif
- buf.resize(wcslen(&buf[0]));
- return buf;
- }
- // AngelScript signature:
- // int64 parseInt(const wstring &in val, uint base = 10, uint &out byteCount = 0)
- static asINT64 parseInt(const wstring &val, asUINT base, asUINT *byteCount)
- {
- // Only accept base 10 and 16
- if( base != 10 && base != 16 )
- {
- if( byteCount ) *byteCount = 0;
- return 0;
- }
- const wchar_t *end = &val[0];
- // Determine the sign
- bool sign = false;
- if( *end == '-' )
- {
- sign = true;
- *end++;
- }
- else if( *end == '+' )
- *end++;
- asINT64 res = 0;
- if( base == 10 )
- {
- while( *end >= '0' && *end <= '9' )
- {
- res *= 10;
- res += *end++ - '0';
- }
- }
- else if( base == 16 )
- {
- while( (*end >= '0' && *end <= '9') ||
- (*end >= 'a' && *end <= 'f') ||
- (*end >= 'A' && *end <= 'F') )
- {
- res *= 16;
- if( *end >= '0' && *end <= '9' )
- res += *end++ - '0';
- else if( *end >= 'a' && *end <= 'f' )
- res += *end++ - 'a' + 10;
- else if( *end >= 'A' && *end <= 'F' )
- res += *end++ - 'A' + 10;
- }
- }
- if( byteCount )
- *byteCount = asUINT(size_t(end - val.c_str()));
- if( sign )
- res = -res;
- return res;
- }
- // AngelScript signature:
- // double parseFloat(const wstring &in val, uint &out byteCount = 0)
- double parseFloat(const wstring &val, asUINT *byteCount)
- {
- char *end;
- // WinCE doesn't have setlocale. Some quick testing on my current platform
- // still manages to parse the numbers such as "3.14" even if the decimal for the
- // locale is ",".
- #if !defined(_WIN32_WCE) && !defined(ANDROID)
- // Set the locale to C so that we are guaranteed to parse the float value correctly
- char *orig = setlocale(LC_NUMERIC, 0);
- setlocale(LC_NUMERIC, "C");
- #endif
- // Used wstring->string conversion here:
- std::string tmpstring(val.begin(),val.end());
- double res = strtod(tmpstring.c_str(), &end);
- #if !defined(_WIN32_WCE) && !defined(ANDROID)
- // Restore the locale
- setlocale(LC_NUMERIC, orig);
- #endif
- // returned letter count here, not 'bytes'
- if( byteCount )
- *byteCount = asUINT(size_t(end - tmpstring.c_str()));
- return res;
- }
- // This function returns a string containing the substring of the input string
- // determined by the starting index and count of characters.
- //
- // AngelScript signature:
- // wstring wstring::substr(uint start = 0, int count = -1) const
- static wstring StringSubString(asUINT start, int count, const wstring &str)
- {
- // Check for out-of-bounds
- wstring ret;
- if( start < str.length() && count != 0 )
- ret = str.substr(start, count);
- return ret;
- }
- void RegisterStdWString_Native(asIScriptEngine *engine)
- {
- int r;
- // Register the string type
- r = engine->RegisterObjectType("string", sizeof(wstring), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
- #if AS_USE_STRINGPOOL == 1
- // Register the string factory
- r = engine->RegisterStringFactory("const string &", asFUNCTION(StringFactory), asCALL_CDECL); assert( r >= 0 );
- // Register the cleanup callback for the string pool
- engine->SetEngineUserDataCleanupCallback(CleanupEngineStringPool, STRING_POOL);
- #else
- // Register the string factory
- r = engine->RegisterStringFactory("string", asFUNCTION(StringFactory), asCALL_CDECL); assert( r >= 0 );
- #endif
- // Register the object operator overloads
- r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f(const string &in)", asFUNCTION(CopyConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asMETHODPR(wstring, operator =, (const wstring&), wstring&), asCALL_THISCALL); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asMETHODPR(wstring, operator+=, (const wstring&), wstring&), asCALL_THISCALL); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTIONPR(operator ==, (const wstring &, const wstring &), bool), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmp), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTIONPR(operator +, (const wstring &, const wstring &), wstring), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
- // The string length can be accessed through methods or through virtual property
- r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "void resize(uint)", asFUNCTION(StringResize), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "uint get_length() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "void set_length(uint)", asFUNCTION(StringResize), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "bool isEmpty() const", asMETHOD(wstring, empty), asCALL_THISCALL); assert( r >= 0 );
- // Register the index operator, both as a mutator and as an inspector
- // Note that we don't register the operator[] directly, as it doesn't do bounds checking
- r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) const", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- // Automatic conversion from values
- r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddStringDouble), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDoubleString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(int)", asFUNCTION(AssignIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(int)", asFUNCTION(AddAssignIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(int) const", asFUNCTION(AddStringInt), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(int) const", asFUNCTION(AddIntString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(uint)", asFUNCTION(AssignUIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint)", asFUNCTION(AddAssignUIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(uint) const", asFUNCTION(AddStringUInt), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(uint) const", asFUNCTION(AddUIntString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", asFUNCTION(AssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", asFUNCTION(AddAssignBoolToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", asFUNCTION(AddStringBool), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) const", asFUNCTION(AddBoolString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- // Utilities
- r = engine->RegisterObjectMethod("string", "string substr(uint start = 0, int count = -1) const", asFUNCTION(StringSubString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "int findFirst(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "int findLast(const string &in, int start = -1) const", asFUNCTION(StringFindLast), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- r = engine->RegisterGlobalFunction("string formatInt(int64 val, const string &in options, uint width = 0)", asFUNCTION(formatInt), asCALL_CDECL); assert(r >= 0);
- r = engine->RegisterGlobalFunction("string formatFloat(double val, const string &in options, uint width = 0, uint precision = 0)", asFUNCTION(formatFloat), asCALL_CDECL); assert(r >= 0);
- r = engine->RegisterGlobalFunction("int64 parseInt(const string &in, uint base = 10, uint &out byteCount = 0)", asFUNCTION(parseInt), asCALL_CDECL); assert(r >= 0);
- r = engine->RegisterGlobalFunction("double parseFloat(const string &in, uint &out byteCount = 0)", asFUNCTION(parseFloat), asCALL_CDECL); assert(r >= 0);
- #if AS_USE_STLNAMES == 1
- // Same as length
- r = engine->RegisterObjectMethod("string", "uint size() const", asFUNCTION(StringLength), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- // Same as isEmpty
- r = engine->RegisterObjectMethod("string", "bool empty() const", asMETHOD(wstring, empty), asCALL_THISCALL); assert( r >= 0 );
- // Same as findFirst
- r = engine->RegisterObjectMethod("string", "int find(const string &in, uint start = 0) const", asFUNCTION(StringFindFirst), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- // Same as findLast
- r = engine->RegisterObjectMethod("string", "int rfind(const string &in, int start = -1) const", asFUNCTION(StringFindLast), asCALL_CDECL_OBJLAST); assert( r >= 0 );
- #endif
- // TODO: Implement the following
- // findFirstOf
- // findLastOf
- // findFirstNotOf
- // findLastNotOf
- // findAndReplace - replaces a text found in the string
- // replaceRange - replaces a range of bytes in the string
- // trim/trimLeft/trimRight
- // multiply/times/opMul/opMul_r - takes the string and multiplies it n times, e.g. "-".multiply(5) returns "-----"
- }
- #if AS_USE_STRINGPOOL == 1
- static void StringFactoryGeneric(asIScriptGeneric *gen) {
- asUINT length = gen->GetArgDWord(0);
- const wchar_t *s = (const wchar_t*)gen->GetArgAddress(1);
- // Return a reference to a string
- gen->SetReturnAddress(const_cast<wstring*>(&StringFactory(length/2, s)));
- }
- #else
- static void StringFactoryGeneric(asIScriptGeneric *gen) {
- asUINT length = gen->GetArgDWord(0);
- const wchar_t *s = (const wchar_t*)gen->GetArgAddress(1);
- // Return a string value
- new (gen->GetAddressOfReturnLocation()) wstring(StringFactory(length/2, s));
- }
- #endif
- static void ConstructStringGeneric(asIScriptGeneric * gen) {
- new (gen->GetObject()) wstring();
- }
- static void CopyConstructStringGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetArgObject(0));
- new (gen->GetObject()) wstring(*a);
- }
- static void DestructStringGeneric(asIScriptGeneric * gen) {
- wstring * ptr = static_cast<wstring *>(gen->GetObject());
- ptr->~wstring();
- }
- static void AssignStringGeneric(asIScriptGeneric *gen) {
- wstring * a = static_cast<wstring *>(gen->GetArgObject(0));
- wstring * self = static_cast<wstring *>(gen->GetObject());
- *self = *a;
- gen->SetReturnAddress(self);
- }
- static void AddAssignStringGeneric(asIScriptGeneric *gen) {
- wstring * a = static_cast<wstring *>(gen->GetArgObject(0));
- wstring * self = static_cast<wstring *>(gen->GetObject());
- *self += *a;
- gen->SetReturnAddress(self);
- }
- static void StringEqualsGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetObject());
- wstring * b = static_cast<wstring *>(gen->GetArgAddress(0));
- *(bool*)gen->GetAddressOfReturnLocation() = (*a == *b);
- }
- static void StringCmpGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetObject());
- wstring * b = static_cast<wstring *>(gen->GetArgAddress(0));
- int cmp = 0;
- if( *a < *b ) cmp = -1;
- else if( *a > *b ) cmp = 1;
- *(int*)gen->GetAddressOfReturnLocation() = cmp;
- }
- static void StringAddGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetObject());
- wstring * b = static_cast<wstring *>(gen->GetArgAddress(0));
- wstring ret_val = *a + *b;
- gen->SetReturnObject(&ret_val);
- }
- static void StringLengthGeneric(asIScriptGeneric * gen) {
- wstring * self = static_cast<wstring *>(gen->GetObject());
- *static_cast<asUINT *>(gen->GetAddressOfReturnLocation()) = (asUINT)self->length();
- }
- static void StringResizeGeneric(asIScriptGeneric * gen) {
- wstring * self = static_cast<wstring *>(gen->GetObject());
- self->resize(*static_cast<asUINT *>(gen->GetAddressOfArg(0)));
- }
- static void StringCharAtGeneric(asIScriptGeneric * gen) {
- unsigned int index = gen->GetArgDWord(0);
- wstring * self = static_cast<wstring *>(gen->GetObject());
- if (index >= self->size()) {
- // Set a script exception
- asIScriptContext *ctx = asGetActiveContext();
- ctx->SetException("Out of range");
- gen->SetReturnAddress(0);
- } else {
- gen->SetReturnAddress(&(self->operator [](index)));
- }
- }
- static void AssignInt2StringGeneric(asIScriptGeneric *gen)
- {
- int *a = static_cast<int*>(gen->GetAddressOfArg(0));
- wstring *self = static_cast<wstring*>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a;
- *self = sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AssignUInt2StringGeneric(asIScriptGeneric *gen)
- {
- unsigned int *a = static_cast<unsigned int*>(gen->GetAddressOfArg(0));
- wstring *self = static_cast<wstring*>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a;
- *self = sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AssignDouble2StringGeneric(asIScriptGeneric *gen)
- {
- double *a = static_cast<double*>(gen->GetAddressOfArg(0));
- wstring *self = static_cast<wstring*>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a;
- *self = sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AssignBool2StringGeneric(asIScriptGeneric *gen)
- {
- bool *a = static_cast<bool*>(gen->GetAddressOfArg(0));
- wstring *self = static_cast<wstring*>(gen->GetObject());
- std::wstringstream sstr;
- sstr << (*a ? "true" : "false");
- *self = sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AddAssignDouble2StringGeneric(asIScriptGeneric * gen) {
- double * a = static_cast<double *>(gen->GetAddressOfArg(0));
- wstring * self = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a;
- *self += sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AddAssignInt2StringGeneric(asIScriptGeneric * gen) {
- int * a = static_cast<int *>(gen->GetAddressOfArg(0));
- wstring * self = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a;
- *self += sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AddAssignUInt2StringGeneric(asIScriptGeneric * gen) {
- unsigned int * a = static_cast<unsigned int *>(gen->GetAddressOfArg(0));
- wstring * self = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a;
- *self += sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AddAssignBool2StringGeneric(asIScriptGeneric * gen) {
- bool * a = static_cast<bool *>(gen->GetAddressOfArg(0));
- wstring * self = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << (*a ? "true" : "false");
- *self += sstr.str();
- gen->SetReturnAddress(self);
- }
- static void AddString2DoubleGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetObject());
- double * b = static_cast<double *>(gen->GetAddressOfArg(0));
- std::wstringstream sstr;
- sstr << *a << *b;
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void AddString2IntGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetObject());
- int * b = static_cast<int *>(gen->GetAddressOfArg(0));
- std::wstringstream sstr;
- sstr << *a << *b;
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void AddString2UIntGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetObject());
- unsigned int * b = static_cast<unsigned int *>(gen->GetAddressOfArg(0));
- std::wstringstream sstr;
- sstr << *a << *b;
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void AddString2BoolGeneric(asIScriptGeneric * gen) {
- wstring * a = static_cast<wstring *>(gen->GetObject());
- bool * b = static_cast<bool *>(gen->GetAddressOfArg(0));
- std::wstringstream sstr;
- sstr << *a << (*b ? "true" : "false");
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void AddDouble2StringGeneric(asIScriptGeneric * gen) {
- double* a = static_cast<double *>(gen->GetAddressOfArg(0));
- wstring * b = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a << *b;
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void AddInt2StringGeneric(asIScriptGeneric * gen) {
- int* a = static_cast<int *>(gen->GetAddressOfArg(0));
- wstring * b = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a << *b;
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void AddUInt2StringGeneric(asIScriptGeneric * gen) {
- unsigned int* a = static_cast<unsigned int *>(gen->GetAddressOfArg(0));
- wstring * b = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << *a << *b;
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void AddBool2StringGeneric(asIScriptGeneric * gen) {
- bool* a = static_cast<bool *>(gen->GetAddressOfArg(0));
- wstring * b = static_cast<wstring *>(gen->GetObject());
- std::wstringstream sstr;
- sstr << (*a ? "true" : "false") << *b;
- std::wstring ret_val = sstr.str();
- gen->SetReturnObject(&ret_val);
- }
- static void StringSubString_Generic(asIScriptGeneric *gen)
- {
- // Get the arguments
- wstring *str = (wstring*)gen->GetObject();
- asUINT start = *(int*)gen->GetAddressOfArg(0);
- int count = *(int*)gen->GetAddressOfArg(1);
- // Return the substring
- new(gen->GetAddressOfReturnLocation()) wstring(StringSubString(start, count, *str));
- }
- void RegisterStdWString_Generic(asIScriptEngine *engine)
- {
- int r;
- // Register the string type
- r = engine->RegisterObjectType("string", sizeof(wstring), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
- #if AS_USE_STRINGPOOL == 1
- // Register the string factory
- r = engine->RegisterStringFactory("const string &", asFUNCTION(StringFactoryGeneric), asCALL_GENERIC); assert( r >= 0 );
- // Register the cleanup callback for the string pool
- engine->SetEngineUserDataCleanupCallback(CleanupEngineStringPool, STRING_POOL);
- #else
- // Register the string factory
- r = engine->RegisterStringFactory("string", asFUNCTION(StringFactoryGeneric), asCALL_GENERIC); assert( r >= 0 );
- #endif
- // Register the object operator overloads
- r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructStringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f(const string &in)", asFUNCTION(CopyConstructStringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructStringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asFUNCTION(AssignStringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asFUNCTION(AddAssignStringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTION(StringEqualsGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmpGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTION(StringAddGeneric), asCALL_GENERIC); assert( r >= 0 );
- // Register the object methods
- r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLengthGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "void resize(uint)", asFUNCTION(StringResizeGeneric), asCALL_GENERIC); assert( r >= 0 );
- // Register the index operator, both as a mutator and as an inspector
- r = engine->RegisterObjectMethod("string", "uint8 &opIndex(uint)", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "const uint8 &opIndex(uint) const", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 );
- // Automatic conversion from values
- r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddString2DoubleGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(int)", asFUNCTION(AssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(int)", asFUNCTION(AddAssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(int) const", asFUNCTION(AddString2IntGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(int) const", asFUNCTION(AddInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(uint)", asFUNCTION(AssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint)", asFUNCTION(AddAssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(uint) const", asFUNCTION(AddString2UIntGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(uint) const", asFUNCTION(AddUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAssign(bool)", asFUNCTION(AssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string &opAddAssign(bool)", asFUNCTION(AddAssignBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd(bool) const", asFUNCTION(AddString2BoolGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string opAdd_r(bool) const", asFUNCTION(AddBool2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
- r = engine->RegisterObjectMethod("string", "string substr(uint start = 0, int count = -1) const", asFUNCTION(StringSubString_Generic), asCALL_GENERIC); assert( r >= 0 );
- }
- void RegisterStdWString(asIScriptEngine * engine)
- {
- if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY"))
- RegisterStdWString_Generic(engine);
- else
- RegisterStdWString_Native(engine);
- }
- END_AS_NAMESPACE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement