1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#include <assert.h>
#include "scriptstdstring.h"
#include "../scriptarray/scriptarray.h"
#include <stdio.h>
#include <string.h>
using namespace std;
BEGIN_AS_NAMESPACE
// This function takes an input string and splits it into parts by looking
// for a specified delimiter. Example:
//
// string str = "A|B||D";
// array<string>@ array = str.split("|");
//
// The resulting array has the following elements:
//
// {"A", "B", "", "D"}
//
// AngelScript signature:
// array<string>@ string::split(const string &in delim) const
static CScriptArray *StringSplit(const string &delim, const string &str)
{
// Obtain a pointer to the engine
asIScriptContext *ctx = asGetActiveContext();
asIScriptEngine *engine = ctx->GetEngine();
// TODO: This should only be done once
// TODO: This assumes that CScriptArray was already registered
asITypeInfo *arrayType = engine->GetTypeInfoByDecl("array<string>");
// Create the array object
CScriptArray *array = CScriptArray::Create(arrayType);
// Find the existence of the delimiter in the input string
size_t pos = 0, prev = 0;
asUINT count = 0;
while( (pos = str.find(delim, prev)) != string::npos )
{
// Add the part to the array
array->Resize(array->GetSize()+1);
((string*)array->At(count))->assign(&str[prev], pos-prev);
// Find the next part
count++;
prev = pos + delim.length();
}
// Add the remaining part
array->Resize(array->GetSize()+1);
((string*)array->At(count))->assign(&str[prev]);
return array;
}
static void StringSplit_Generic(asIScriptGeneric *gen)
{
// Get the arguments
string *str = (string*)gen->GetObject();
string *delim = *(string**)gen->GetAddressOfArg(0);
// Return the array by handle
*(CScriptArray**)gen->GetAddressOfReturnLocation() = StringSplit(*delim, *str);
}
// This function takes as input an array of string handles as well as a
// delimiter and concatenates the array elements into one delimited string.
// Example:
//
// array<string> array = {"A", "B", "", "D"};
// string str = join(array, "|");
//
// The resulting string is:
//
// "A|B||D"
//
// AngelScript signature:
// string join(const array<string> &in array, const string &in delim)
static string StringJoin(const CScriptArray &array, const string &delim)
{
// Create the new string
string str = "";
if( array.GetSize() )
{
int n;
for( n = 0; n < (int)array.GetSize() - 1; n++ )
{
str += *(string*)array.At(n);
str += delim;
}
// Add the last part
str += *(string*)array.At(n);
}
return str;
}
static void StringJoin_Generic(asIScriptGeneric *gen)
{
// Get the arguments
CScriptArray *array = *(CScriptArray**)gen->GetAddressOfArg(0);
string *delim = *(string**)gen->GetAddressOfArg(1);
// Return the string
new(gen->GetAddressOfReturnLocation()) string(StringJoin(*array, *delim));
}
// This is where the utility functions are registered.
// The string type must have been registered first.
void RegisterStdStringUtils(asIScriptEngine *engine)
{
int r;
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
{
r = engine->RegisterObjectMethod("string", "array<string>@ split(const string &in) const", asFUNCTION(StringSplit_Generic), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterGlobalFunction("string join(const array<string> &in, const string &in)", asFUNCTION(StringJoin_Generic), asCALL_GENERIC); assert(r >= 0);
}
else
{
r = engine->RegisterObjectMethod("string", "array<string>@ split(const string &in) const", asFUNCTION(StringSplit), asCALL_CDECL_OBJLAST); assert(r >= 0);
r = engine->RegisterGlobalFunction("string join(const array<string> &in, const string &in)", asFUNCTION(StringJoin), asCALL_CDECL); assert(r >= 0);
}
}
END_AS_NAMESPACE
|