2016-02-20 23:25:00 +01:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
2015-09-30 02:56:11 +02:00
|
|
|
#include "Library/String.hpp"
|
2016-02-20 23:25:00 +01:00
|
|
|
#include "Base/Shared.hpp"
|
|
|
|
#include "Base/Buffer.hpp"
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
#include <sqstdstring.h>
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
#include <algorithm>
|
2015-09-30 02:56:11 +02:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
namespace SqMod {
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2016-02-20 23:25:00 +01:00
|
|
|
CSStr LeftStr(CSStr t, SQChar f, Uint32 w)
|
|
|
|
{
|
|
|
|
// Allocate a buffer with the requested width
|
|
|
|
Buffer b(w * sizeof(SQChar));
|
|
|
|
Uint32 n = !t ? 0 : strlen(t);
|
|
|
|
// Populate the entire buffer with the fill character
|
|
|
|
memset(b.Data(), f, w * sizeof(SQChar));
|
|
|
|
// Is the specified width valid?
|
|
|
|
if (w >= b.Size< SQChar >())
|
|
|
|
{
|
|
|
|
SqThrow("Invalid width specified: %d > %d", w, b.Size< SQChar >());
|
|
|
|
w = 0;
|
|
|
|
}
|
|
|
|
// Is the specified string valid?
|
|
|
|
else if (n == 0)
|
|
|
|
{
|
|
|
|
SqThrow("Invalid string length: %d < 0", n);
|
|
|
|
}
|
|
|
|
// Is the specified string within width range?
|
|
|
|
else if (n > w)
|
|
|
|
{
|
|
|
|
SqThrow("String is out of bounds: %d > %d", n, w);
|
|
|
|
}
|
|
|
|
// Insert the specified string
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strncpy(b.Data(), t, n);
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(w) = 0;
|
|
|
|
// Return the resulted string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
|
|
|
CSStr LeftStr(CSStr t, SQChar f, Uint32 w, Uint32 o)
|
|
|
|
{
|
|
|
|
// Allocate a buffer with the requested width
|
|
|
|
Buffer b(w * sizeof(SQChar));
|
|
|
|
Uint32 n = !t ? 0 : strlen(t);
|
|
|
|
// Populate the entire buffer with the fill character
|
|
|
|
memset(b.Data(), f, w * sizeof(SQChar));
|
|
|
|
// Is the specified width valid?
|
|
|
|
if (w >= b.Size< SQChar >())
|
|
|
|
{
|
|
|
|
SqThrow("Invalid width specified: %d > %d", w, b.Size< SQChar >());
|
|
|
|
w = 0;
|
|
|
|
}
|
|
|
|
// Is the specified string valid?
|
|
|
|
else if (n == 0)
|
|
|
|
{
|
|
|
|
SqThrow("Invalid string length: %d < 0", n);
|
|
|
|
}
|
|
|
|
// Is the specified string within width range?
|
|
|
|
else if ((o+n) > w)
|
|
|
|
{
|
|
|
|
SqThrow("String is out of bounds: (%d+%d) > %d", o, n, w);
|
|
|
|
}
|
|
|
|
// Insert the specified string
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strncpy(b.Get< SQChar >() + o, t, n);
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(w) = 0;
|
|
|
|
// Return the resulted string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
CSStr RightStr(CSStr t, SQChar f, Uint32 w)
|
|
|
|
{
|
|
|
|
// Allocate a buffer with the requested width
|
|
|
|
Buffer b(w * sizeof(SQChar));
|
|
|
|
Uint32 n = !t ? 0 : strlen(t);
|
|
|
|
// Populate the entire buffer with the fill character
|
|
|
|
memset(b.Data(), f, w * sizeof(SQChar));
|
|
|
|
// Is the specified width valid?
|
|
|
|
if (w >= b.Size< SQChar >())
|
|
|
|
{
|
|
|
|
SqThrow("Invalid width specified: %d > %d", w, b.Size< SQChar >());
|
|
|
|
w = 0;
|
|
|
|
}
|
|
|
|
// Is the specified string valid?
|
|
|
|
else if (n == 0)
|
|
|
|
{
|
|
|
|
SqThrow("Invalid string length: %d < 0", n);
|
|
|
|
}
|
|
|
|
// Is the specified string within width range?
|
|
|
|
else if (n > w)
|
|
|
|
{
|
|
|
|
SqThrow("String is out of bounds: %d > %d", n, w);
|
|
|
|
}
|
|
|
|
// Insert the specified string
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strncpy(b.Get< SQChar >() + (w-n), t, n);
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(w) = 0;
|
|
|
|
// Return the resulted string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
|
|
|
CSStr RightStr(CSStr t, SQChar f, Uint32 w, Uint32 o)
|
|
|
|
{
|
|
|
|
// Allocate a buffer with the requested width
|
|
|
|
Buffer b(w * sizeof(SQChar));
|
|
|
|
Uint32 n = !t ? 0 : strlen(t);
|
|
|
|
// Populate the entire buffer with the fill character
|
|
|
|
memset(b.Data(), f, w * sizeof(SQChar));
|
|
|
|
// Is the specified width valid?
|
|
|
|
if (w >= b.Size< SQChar >())
|
|
|
|
{
|
|
|
|
SqThrow("Invalid width specified: %d > %d", w, b.Size< SQChar >());
|
|
|
|
w = 0;
|
|
|
|
}
|
|
|
|
// Is the specified string valid?
|
|
|
|
else if (n == 0)
|
|
|
|
{
|
|
|
|
SqThrow("Invalid string length: %d < 0", n);
|
|
|
|
}
|
|
|
|
// Is the specified string within width range?
|
|
|
|
else if ((n+o) > w)
|
|
|
|
{
|
|
|
|
SqThrow("String is out of bounds: (%d+%d) > %d", n, o, w);
|
|
|
|
}
|
|
|
|
// Insert the specified string
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strncpy(b.Get< SQChar >() + ((w-n)-o), t, n);
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(w) = 0;
|
|
|
|
// Return the resulted string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
CSStr CenterStr(CSStr t, SQChar f, Uint32 w)
|
2015-09-30 02:56:11 +02:00
|
|
|
{
|
2016-02-20 23:25:00 +01:00
|
|
|
// Allocate a buffer with the requested width
|
|
|
|
Buffer b(w * sizeof(SQChar));
|
|
|
|
Uint32 n = !t ? 0 : strlen(t);
|
|
|
|
// Populate the entire buffer with the fill character
|
|
|
|
memset(b.Data(), f, w * sizeof(SQChar));
|
|
|
|
// Is the specified width valid?
|
|
|
|
if (w >= b.Size< SQChar >())
|
|
|
|
{
|
|
|
|
SqThrow("Invalid width specified: %d > %d", w, b.Size< SQChar >());
|
|
|
|
w = 0;
|
|
|
|
}
|
|
|
|
// Is the specified string valid?
|
|
|
|
else if (n == 0)
|
|
|
|
{
|
|
|
|
SqThrow("Invalid string length: %d < 0", n);
|
|
|
|
}
|
|
|
|
// Is the specified string within width range?
|
|
|
|
else if (n > w)
|
|
|
|
{
|
|
|
|
SqThrow("String is out of bounds: %d > %d", n, w);
|
|
|
|
}
|
|
|
|
// Insert the specified string
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strncpy(b.Get< SQChar >() + (w/2 - n/2), t, n);
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(w) = 0;
|
|
|
|
// Return the resulted string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
CSStr StrJustAlphaNum(CSStr str)
|
|
|
|
{
|
|
|
|
Uint32 size = 0;
|
|
|
|
// See if we actually have something to search for
|
|
|
|
if(!str || (size = strlen(str)) <= 0)
|
|
|
|
{
|
|
|
|
return _SC("");
|
|
|
|
}
|
|
|
|
// Obtain a temporary buffer
|
|
|
|
Buffer b(size);
|
|
|
|
// Resulted string size
|
|
|
|
Uint32 n = 0;
|
|
|
|
// Currently processed character
|
|
|
|
SQChar c = 0;
|
|
|
|
// Process characters
|
|
|
|
while ((c = *(str++)) != 0)
|
|
|
|
{
|
|
|
|
// Is this an alpha-numeric character?
|
|
|
|
if (isalnum(c) != 0)
|
|
|
|
{
|
|
|
|
// Save it and move to the next one
|
|
|
|
b.At< SQChar >(n++) = c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(n) = 0;
|
|
|
|
// Return the string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
CSStr StrToLowercase(CSStr str)
|
|
|
|
{
|
|
|
|
Uint32 size = 0;
|
|
|
|
// See if we actually have something to search for
|
|
|
|
if(!str || (size = strlen(str)) <= 0)
|
|
|
|
{
|
|
|
|
return _SC("");
|
|
|
|
}
|
|
|
|
// Obtain a temporary buffer
|
|
|
|
Buffer b(size);
|
|
|
|
// Resulted string size
|
|
|
|
Uint32 n = 0;
|
|
|
|
// Currently processed character
|
|
|
|
SQChar c = 0;
|
|
|
|
// Process characters
|
|
|
|
while ((c = *(str++)) != 0)
|
|
|
|
{
|
|
|
|
// Convert it and move to the next one
|
|
|
|
b.At< SQChar >(n++) = tolower(c);
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(n) = 0;
|
|
|
|
// Return the string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
2016-02-21 09:30:47 +01:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
CSStr StrToUppercase(CSStr str)
|
|
|
|
{
|
|
|
|
Uint32 size = 0;
|
|
|
|
// See if we actually have something to search for
|
|
|
|
if(!str || (size = strlen(str)) <= 0)
|
|
|
|
{
|
|
|
|
return _SC("");
|
|
|
|
}
|
|
|
|
// Obtain a temporary buffer
|
|
|
|
Buffer b(size);
|
|
|
|
// Resulted string size
|
|
|
|
Uint32 n = 0;
|
|
|
|
// Currently processed character
|
|
|
|
SQChar c = 0;
|
|
|
|
// Process characters
|
|
|
|
while ((c = *(str++)) != 0)
|
|
|
|
{
|
|
|
|
// Convert it and move to the next one
|
|
|
|
b.At< SQChar >(n++) = toupper(c);
|
|
|
|
}
|
|
|
|
// End the resulted string
|
|
|
|
b.At< SQChar >(n) = 0;
|
|
|
|
// Return the string
|
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
2016-02-20 23:25:00 +01:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
static CSStr FromArray(Array & arr)
|
|
|
|
{
|
2016-02-21 09:30:47 +01:00
|
|
|
// Determine array size
|
|
|
|
const Int32 length = (Int32)arr.Length();
|
|
|
|
// Obtain a temporary buffer
|
|
|
|
Buffer b(length * sizeof(Int32));
|
|
|
|
// Get array elements as integers
|
|
|
|
arr.GetArray< Int32 >(b.Get< Int32 >(), length);
|
|
|
|
// Overwrite integers with characters
|
|
|
|
for (Int32 n = 0; n < length; ++n)
|
|
|
|
{
|
|
|
|
b.At< SQChar >(n) = (SQChar)b.At< Int32 >(n);
|
|
|
|
}
|
|
|
|
// Terminate the resulted string
|
|
|
|
b.At< SQChar >(length) = 0;
|
|
|
|
// Return the string
|
2016-02-20 23:25:00 +01:00
|
|
|
return b.Get< SQChar >();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
static SQInteger StdPrintF(HSQUIRRELVM vm)
|
|
|
|
{
|
|
|
|
CStr msg = NULL;
|
|
|
|
SQInteger length = 0;
|
|
|
|
if(SQ_FAILED(sqstd_format(vm, 2, &length, &msg)))
|
|
|
|
return -1;
|
|
|
|
LogUsr("%s", msg);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ================================================================================================
|
|
|
|
void Register_String(HSQUIRRELVM vm)
|
|
|
|
{
|
|
|
|
Table strns(vm);
|
|
|
|
|
|
|
|
strns.Func(_SC("FromArray"), &FromArray)
|
|
|
|
.Overload< CSStr (*)(CSStr, SQChar, Uint32) >(_SC("Left"), &LeftStr)
|
|
|
|
.Overload< CSStr (*)(CSStr, SQChar, Uint32, Uint32) >(_SC("Left"), &LeftStr)
|
|
|
|
.Overload< CSStr (*)(CSStr, SQChar, Uint32) >(_SC("Right"), &RightStr)
|
|
|
|
.Overload< CSStr (*)(CSStr, SQChar, Uint32, Uint32) >(_SC("Right"), &RightStr)
|
2016-02-21 09:30:47 +01:00
|
|
|
.Func(_SC("Center"), &CenterStr)
|
|
|
|
.Func(_SC("JustAlphaNum"), &StrJustAlphaNum)
|
|
|
|
.Func(_SC("Lowercase"), &StrToLowercase)
|
|
|
|
.Func(_SC("Uppercase"), &StrToUppercase);
|
2016-02-20 23:25:00 +01:00
|
|
|
|
|
|
|
RootTable(vm).Bind(_SC("SqStr"), strns);
|
|
|
|
RootTable(vm).SquirrelFunc(_SC("printf"), &StdPrintF);
|
2015-09-30 02:56:11 +02:00
|
|
|
}
|
|
|
|
|
2015-11-01 04:36:03 +01:00
|
|
|
} // Namespace:: SqMod
|