00001 #include "../../../config.h"
00002 #ifdef __COMPILE_WITH_ANGELSCRIPT__
00003
00004 #include <assert.h>
00005 #include <sstream>
00006 #include "scriptstdstring.h"
00007 #include <string.h>
00008
00009 using namespace std;
00010
00011 BEGIN_AS_NAMESPACE
00012
00013 static void StringFactoryGeneric(asIScriptGeneric *gen) {
00014 asUINT length = gen->GetArgDWord(0);
00015 const char *s = (const char*)gen->GetArgAddress(1);
00016 string str(s, length);
00017 gen->SetReturnObject(&str);
00018 }
00019
00020 static void ConstructStringGeneric(asIScriptGeneric * gen) {
00021 new (gen->GetObject()) string();
00022 }
00023
00024 static void DestructStringGeneric(asIScriptGeneric * gen) {
00025 string * ptr = static_cast<string *>(gen->GetObject());
00026 ptr->~string();
00027 }
00028
00029 static void AssignStringGeneric(asIScriptGeneric *gen) {
00030 string * a = static_cast<string *>(gen->GetArgObject(0));
00031 string * self = static_cast<string *>(gen->GetObject());
00032 *self = *a;
00033 gen->SetReturnAddress(self);
00034 }
00035
00036 static void AddAssignStringGeneric(asIScriptGeneric *gen) {
00037 string * a = static_cast<string *>(gen->GetArgObject(0));
00038 string * self = static_cast<string *>(gen->GetObject());
00039 *self += *a;
00040 gen->SetReturnAddress(self);
00041 }
00042
00043 static void StringEqualGeneric(asIScriptGeneric * gen) {
00044 string * a = static_cast<string *>(gen->GetArgAddress(0));
00045 string * b = static_cast<string *>(gen->GetArgAddress(1));
00046 *(bool*)gen->GetAddressOfReturnLocation() = (*a == *b);
00047 }
00048
00049 static void StringEqualsGeneric(asIScriptGeneric * gen) {
00050 string * a = static_cast<string *>(gen->GetObject());
00051 string * b = static_cast<string *>(gen->GetArgAddress(0));
00052 *(bool*)gen->GetAddressOfReturnLocation() = (*a == *b);
00053 }
00054
00055 static void StringCmpGeneric(asIScriptGeneric * gen) {
00056 string * a = static_cast<string *>(gen->GetObject());
00057 string * b = static_cast<string *>(gen->GetArgAddress(0));
00058
00059 int cmp = 0;
00060 if( *a < *b ) cmp = -1;
00061 else if( *a > *b ) cmp = 1;
00062
00063 *(int*)gen->GetAddressOfReturnLocation() = cmp;
00064 }
00065
00066 static void StringNotEqualGeneric(asIScriptGeneric * gen) {
00067 string * a = static_cast<string *>(gen->GetArgAddress(0));
00068 string * b = static_cast<string *>(gen->GetArgAddress(1));
00069 *(bool*)gen->GetAddressOfReturnLocation() = (*a != *b);
00070 }
00071
00072 static void StringLEqualGeneric(asIScriptGeneric * gen) {
00073 string * a = static_cast<string *>(gen->GetArgAddress(0));
00074 string * b = static_cast<string *>(gen->GetArgAddress(1));
00075 *(bool*)gen->GetAddressOfReturnLocation() = (*a <= *b);
00076 }
00077
00078 static void StringGEqualGeneric(asIScriptGeneric * gen) {
00079 string * a = static_cast<string *>(gen->GetArgAddress(0));
00080 string * b = static_cast<string *>(gen->GetArgAddress(1));
00081 *(bool*)gen->GetAddressOfReturnLocation() = (*a >= *b);
00082 }
00083
00084 static void StringLessThanGeneric(asIScriptGeneric * gen) {
00085 string * a = static_cast<string *>(gen->GetArgAddress(0));
00086 string * b = static_cast<string *>(gen->GetArgAddress(1));
00087 *(bool*)gen->GetAddressOfReturnLocation() = (*a < *b);
00088 }
00089
00090 static void StringGreaterThanGeneric(asIScriptGeneric * gen) {
00091 string * a = static_cast<string *>(gen->GetArgAddress(0));
00092 string * b = static_cast<string *>(gen->GetArgAddress(1));
00093 *(bool*)gen->GetAddressOfReturnLocation() = (*a > *b);
00094 }
00095
00096 static void StringAddGeneric(asIScriptGeneric * gen) {
00097 string * a = static_cast<string *>(gen->GetObject());
00098 string * b = static_cast<string *>(gen->GetArgAddress(0));
00099 string ret_val = *a + *b;
00100 gen->SetReturnObject(&ret_val);
00101 }
00102
00103 static void StringLengthGeneric(asIScriptGeneric * gen) {
00104 string * self = static_cast<string *>(gen->GetObject());
00105 *static_cast<size_t *>(gen->GetAddressOfReturnLocation()) = self->length();
00106 }
00107
00108 static void StringResizeGeneric(asIScriptGeneric * gen) {
00109 string * self = static_cast<string *>(gen->GetObject());
00110 self->resize(*static_cast<size_t *>(gen->GetAddressOfArg(0)));
00111 }
00112
00113 static void StringCharAtGeneric(asIScriptGeneric * gen) {
00114 unsigned int index = gen->GetArgDWord(0);
00115 string * self = static_cast<string *>(gen->GetObject());
00116
00117 if (index >= self->size()) {
00118
00119 asIScriptContext *ctx = asGetActiveContext();
00120 ctx->SetException("Out of range");
00121
00122 gen->SetReturnAddress(0);
00123 } else {
00124 gen->SetReturnAddress(&(self->operator [](index)));
00125 }
00126 }
00127
00128 void AssignInt2StringGeneric(asIScriptGeneric *gen)
00129 {
00130 int *a = static_cast<int*>(gen->GetAddressOfArg(0));
00131 string *self = static_cast<string*>(gen->GetObject());
00132 std::stringstream sstr;
00133 sstr << *a;
00134 *self = sstr.str();
00135 gen->SetReturnAddress(self);
00136 }
00137
00138 void AssignUInt2StringGeneric(asIScriptGeneric *gen)
00139 {
00140 unsigned int *a = static_cast<unsigned int*>(gen->GetAddressOfArg(0));
00141 string *self = static_cast<string*>(gen->GetObject());
00142 std::stringstream sstr;
00143 sstr << *a;
00144 *self = sstr.str();
00145 gen->SetReturnAddress(self);
00146 }
00147
00148 void AssignDouble2StringGeneric(asIScriptGeneric *gen)
00149 {
00150 double *a = static_cast<double*>(gen->GetAddressOfArg(0));
00151 string *self = static_cast<string*>(gen->GetObject());
00152 std::stringstream sstr;
00153 sstr << *a;
00154 *self = sstr.str();
00155 gen->SetReturnAddress(self);
00156 }
00157
00158 void AddAssignDouble2StringGeneric(asIScriptGeneric * gen) {
00159 double * a = static_cast<double *>(gen->GetAddressOfArg(0));
00160 string * self = static_cast<string *>(gen->GetObject());
00161 std::stringstream sstr;
00162 sstr << *a;
00163 *self += sstr.str();
00164 gen->SetReturnAddress(self);
00165 }
00166
00167 void AddAssignInt2StringGeneric(asIScriptGeneric * gen) {
00168 int * a = static_cast<int *>(gen->GetAddressOfArg(0));
00169 string * self = static_cast<string *>(gen->GetObject());
00170 std::stringstream sstr;
00171 sstr << *a;
00172 *self += sstr.str();
00173 gen->SetReturnAddress(self);
00174 }
00175
00176 void AddAssignUInt2StringGeneric(asIScriptGeneric * gen) {
00177 unsigned int * a = static_cast<unsigned int *>(gen->GetAddressOfArg(0));
00178 string * self = static_cast<string *>(gen->GetObject());
00179 std::stringstream sstr;
00180 sstr << *a;
00181 *self += sstr.str();
00182 gen->SetReturnAddress(self);
00183 }
00184
00185 void AddString2DoubleGeneric(asIScriptGeneric * gen) {
00186 string * a = static_cast<string *>(gen->GetObject());
00187 double * b = static_cast<double *>(gen->GetAddressOfArg(0));
00188 std::stringstream sstr;
00189 sstr << *a << *b;
00190 std::string ret_val = sstr.str();
00191 gen->SetReturnObject(&ret_val);
00192 }
00193
00194 void AddString2IntGeneric(asIScriptGeneric * gen) {
00195 string * a = static_cast<string *>(gen->GetObject());
00196 int * b = static_cast<int *>(gen->GetAddressOfArg(0));
00197 std::stringstream sstr;
00198 sstr << *a << *b;
00199 std::string ret_val = sstr.str();
00200 gen->SetReturnObject(&ret_val);
00201 }
00202
00203 void AddString2UIntGeneric(asIScriptGeneric * gen) {
00204 string * a = static_cast<string *>(gen->GetObject());
00205 unsigned int * b = static_cast<unsigned int *>(gen->GetAddressOfArg(0));
00206 std::stringstream sstr;
00207 sstr << *a << *b;
00208 std::string ret_val = sstr.str();
00209 gen->SetReturnObject(&ret_val);
00210 }
00211
00212 void AddDouble2StringGeneric(asIScriptGeneric * gen) {
00213 double* a = static_cast<double *>(gen->GetAddressOfArg(0));
00214 string * b = static_cast<string *>(gen->GetObject());
00215 std::stringstream sstr;
00216 sstr << *a << *b;
00217 std::string ret_val = sstr.str();
00218 gen->SetReturnObject(&ret_val);
00219 }
00220
00221 void AddInt2StringGeneric(asIScriptGeneric * gen) {
00222 int* a = static_cast<int *>(gen->GetAddressOfArg(0));
00223 string * b = static_cast<string *>(gen->GetObject());
00224 std::stringstream sstr;
00225 sstr << *a << *b;
00226 std::string ret_val = sstr.str();
00227 gen->SetReturnObject(&ret_val);
00228 }
00229
00230 void AddUInt2StringGeneric(asIScriptGeneric * gen) {
00231 unsigned int* a = static_cast<unsigned int *>(gen->GetAddressOfArg(0));
00232 string * b = static_cast<string *>(gen->GetObject());
00233 std::stringstream sstr;
00234 sstr << *a << *b;
00235 std::string ret_val = sstr.str();
00236 gen->SetReturnObject(&ret_val);
00237 }
00238
00239
00240 void RegisterStdString_Generic(asIScriptEngine *engine) {
00241 int r;
00242
00243
00244 r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asOBJ_APP_CLASS_CDA); assert( r >= 0 );
00245
00246
00247 r = engine->RegisterStringFactory("string", asFUNCTION(StringFactoryGeneric), asCALL_GENERIC); assert( r >= 0 );
00248
00249
00250 r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructStringGeneric), asCALL_GENERIC); assert( r >= 0 );
00251 r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructStringGeneric), asCALL_GENERIC); assert( r >= 0 );
00252 r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asFUNCTION(AssignStringGeneric), asCALL_GENERIC); assert( r >= 0 );
00253 r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asFUNCTION(AddAssignStringGeneric), asCALL_GENERIC); assert( r >= 0 );
00254
00255 r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTION(StringEqualsGeneric), asCALL_GENERIC); assert( r >= 0 );
00256 r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmpGeneric), asCALL_GENERIC); assert( r >= 0 );
00257 r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTION(StringAddGeneric), asCALL_GENERIC); assert( r >= 0 );
00258
00259
00260 if (sizeof(size_t) == 4) {
00261 r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLengthGeneric), asCALL_GENERIC); assert( r >= 0 );
00262 r = engine->RegisterObjectMethod("string", "void resize(uint)", asFUNCTION(StringResizeGeneric), asCALL_GENERIC); assert( r >= 0 );
00263 } else {
00264 r = engine->RegisterObjectMethod("string", "uint64 length() const", asFUNCTION(StringLengthGeneric), asCALL_GENERIC); assert( r >= 0 );
00265 r = engine->RegisterObjectMethod("string", "void resize(uint64)", asFUNCTION(StringResizeGeneric), asCALL_GENERIC); assert( r >= 0 );
00266 }
00267
00268
00269 r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "uint8 &f(uint)", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 );
00270 r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "const uint8 &f(uint) const", asFUNCTION(StringCharAtGeneric), asCALL_GENERIC); assert( r >= 0 );
00271
00272
00273 r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00274 r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00275 r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddString2DoubleGeneric), asCALL_GENERIC); assert( r >= 0 );
00276 r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDouble2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00277
00278 r = engine->RegisterObjectMethod("string", "string &opAssign(int)", asFUNCTION(AssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00279 r = engine->RegisterObjectMethod("string", "string &opAddAssign(int)", asFUNCTION(AddAssignInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00280 r = engine->RegisterObjectMethod("string", "string opAdd(int) const", asFUNCTION(AddString2IntGeneric), asCALL_GENERIC); assert( r >= 0 );
00281 r = engine->RegisterObjectMethod("string", "string opAdd_r(int) const", asFUNCTION(AddInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00282
00283 r = engine->RegisterObjectMethod("string", "string &opAssign(uint)", asFUNCTION(AssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00284 r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint)", asFUNCTION(AddAssignUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00285 r = engine->RegisterObjectMethod("string", "string opAdd(uint) const", asFUNCTION(AddString2UIntGeneric), asCALL_GENERIC); assert( r >= 0 );
00286 r = engine->RegisterObjectMethod("string", "string opAdd_r(uint) const", asFUNCTION(AddUInt2StringGeneric), asCALL_GENERIC); assert( r >= 0 );
00287 }
00288
00289 static string StringFactory(asUINT length, const char *s)
00290 {
00291 return string(s, length);
00292 }
00293
00294 static void ConstructString(string *thisPointer)
00295 {
00296 new(thisPointer) string();
00297 }
00298
00299 static void DestructString(string *thisPointer)
00300 {
00301 thisPointer->~string();
00302 }
00303
00304 static string &AssignUIntToString(unsigned int i, string &dest)
00305 {
00306 ostringstream stream;
00307 stream << i;
00308 dest = stream.str();
00309 return dest;
00310 }
00311
00312 static string &AddAssignUIntToString(unsigned int i, string &dest)
00313 {
00314 ostringstream stream;
00315 stream << i;
00316 dest += stream.str();
00317 return dest;
00318 }
00319
00320 static string AddStringUInt(string &str, unsigned int i)
00321 {
00322 ostringstream stream;
00323 stream << i;
00324 str += stream.str();
00325 return str;
00326 }
00327
00328 static string AddIntString(int i, string &str)
00329 {
00330 ostringstream stream;
00331 stream << i;
00332 return stream.str() + str;
00333 }
00334
00335 static string &AssignIntToString(int i, string &dest)
00336 {
00337 ostringstream stream;
00338 stream << i;
00339 dest = stream.str();
00340 return dest;
00341 }
00342
00343 static string &AddAssignIntToString(int i, string &dest)
00344 {
00345 ostringstream stream;
00346 stream << i;
00347 dest += stream.str();
00348 return dest;
00349 }
00350
00351 static string AddStringInt(string &str, int i)
00352 {
00353 ostringstream stream;
00354 stream << i;
00355 str += stream.str();
00356 return str;
00357 }
00358
00359 static string AddUIntString(unsigned int i, string &str)
00360 {
00361 ostringstream stream;
00362 stream << i;
00363 return stream.str() + str;
00364 }
00365
00366 static string &AssignDoubleToString(double f, string &dest)
00367 {
00368 ostringstream stream;
00369 stream << f;
00370 dest = stream.str();
00371 return dest;
00372 }
00373
00374 static string &AddAssignDoubleToString(double f, string &dest)
00375 {
00376 ostringstream stream;
00377 stream << f;
00378 dest += stream.str();
00379 return dest;
00380 }
00381
00382 static string AddStringDouble(string &str, double f)
00383 {
00384 ostringstream stream;
00385 stream << f;
00386 str += stream.str();
00387 return str;
00388 }
00389
00390 static string AddDoubleString(double f, string &str)
00391 {
00392 ostringstream stream;
00393 stream << f;
00394 return stream.str() + str;
00395 }
00396
00397 static char *StringCharAt(unsigned int i, string &str)
00398 {
00399 if( i >= str.size() )
00400 {
00401
00402 asIScriptContext *ctx = asGetActiveContext();
00403 ctx->SetException("Out of range");
00404
00405
00406 return 0;
00407 }
00408
00409 return &str[i];
00410 }
00411
00412 static int StringCmp(const string &a, const string &b)
00413 {
00414 int cmp = 0;
00415 if( a < b ) cmp = -1;
00416 else if( a > b ) cmp = 1;
00417 return cmp;
00418 }
00419
00420 void RegisterStdString_Native(asIScriptEngine *engine)
00421 {
00422 int r;
00423
00424
00425 r = engine->RegisterObjectType("string", sizeof(string), asOBJ_VALUE | asOBJ_APP_CLASS_CDA); assert( r >= 0 );
00426
00427
00428 r = engine->RegisterStringFactory("string", asFUNCTION(StringFactory), asCALL_CDECL); assert( r >= 0 );
00429
00430
00431 r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00432 r = engine->RegisterObjectBehaviour("string", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00433 r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asMETHODPR(string, operator =, (const string&), string&), asCALL_THISCALL); assert( r >= 0 );
00434 r = engine->RegisterObjectMethod("string", "string &opAddAssign(const string &in)", asMETHODPR(string, operator+=, (const string&), string&), asCALL_THISCALL); assert( r >= 0 );
00435
00436 r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTIONPR(operator ==, (const string &, const string &), bool), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
00437 r = engine->RegisterObjectMethod("string", "int opCmp(const string &in) const", asFUNCTION(StringCmp), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
00438 r = engine->RegisterObjectMethod("string", "string opAdd(const string &in) const", asFUNCTIONPR(operator +, (const string &, const string &), string), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
00439
00440
00441 if( sizeof(size_t) == 4 )
00442 {
00443 r = engine->RegisterObjectMethod("string", "uint length() const", asMETHOD(string,size), asCALL_THISCALL); assert( r >= 0 );
00444 r = engine->RegisterObjectMethod("string", "void resize(uint)", asMETHODPR(string,resize,(size_t),void), asCALL_THISCALL); assert( r >= 0 );
00445 }
00446 else
00447 {
00448 r = engine->RegisterObjectMethod("string", "uint64 length() const", asMETHOD(string,size), asCALL_THISCALL); assert( r >= 0 );
00449 r = engine->RegisterObjectMethod("string", "void resize(uint64)", asMETHODPR(string,resize,(size_t),void), asCALL_THISCALL); assert( r >= 0 );
00450 }
00451
00452
00453
00454 r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "uint8 &f(uint)", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00455 r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "const uint8 &f(uint) const", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00456
00457
00458 r = engine->RegisterObjectMethod("string", "string &opAssign(double)", asFUNCTION(AssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00459 r = engine->RegisterObjectMethod("string", "string &opAddAssign(double)", asFUNCTION(AddAssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00460 r = engine->RegisterObjectMethod("string", "string opAdd(double) const", asFUNCTION(AddStringDouble), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
00461 r = engine->RegisterObjectMethod("string", "string opAdd_r(double) const", asFUNCTION(AddDoubleString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00462
00463 r = engine->RegisterObjectMethod("string", "string &opAssign(int)", asFUNCTION(AssignIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00464 r = engine->RegisterObjectMethod("string", "string &opAddAssign(int)", asFUNCTION(AddAssignIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00465 r = engine->RegisterObjectMethod("string", "string opAdd(int) const", asFUNCTION(AddStringInt), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
00466 r = engine->RegisterObjectMethod("string", "string opAdd_r(int) const", asFUNCTION(AddIntString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00467
00468 r = engine->RegisterObjectMethod("string", "string &opAssign(uint)", asFUNCTION(AssignUIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00469 r = engine->RegisterObjectMethod("string", "string &opAddAssign(uint)", asFUNCTION(AddAssignUIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00470 r = engine->RegisterObjectMethod("string", "string opAdd(uint) const", asFUNCTION(AddStringUInt), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
00471 r = engine->RegisterObjectMethod("string", "string opAdd_r(uint) const", asFUNCTION(AddUIntString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
00472 }
00473
00474 void RegisterStdString(asIScriptEngine * engine)
00475 {
00476 if (strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY"))
00477 RegisterStdString_Generic(engine);
00478 else
00479 RegisterStdString_Native(engine);
00480 }
00481
00482 END_AS_NAMESPACE
00483
00484
00485
00486
00487 #endif // __COMPILE_WITH_ANGELSCRIPT__