mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-06-15 22:57:12 +02:00
Migrated the host module to C++ exceptions as well.
Also enabled the latest C++ revision in the project. Replaced the Random library with the one provided by C++11. Implemented a simple AES256 encryption class. Various other fixes and improvements.
This commit is contained in:
239
source/Library/Crypt.cpp
Normal file
239
source/Library/Crypt.cpp
Normal file
@ -0,0 +1,239 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Crypt.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <sqstdstring.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <crc32.h>
|
||||
#include <keccak.h>
|
||||
#include <md5.h>
|
||||
#include <sha1.h>
|
||||
#include <sha256.h>
|
||||
#include <sha3.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger AES256::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqAES");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AES256::AES256()
|
||||
: m_Context(), m_Buffer()
|
||||
{
|
||||
aes256_done(&m_Context);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AES256::AES256(CSStr key)
|
||||
: m_Context(), m_Buffer()
|
||||
{
|
||||
Init(key);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 AES256::Cmp(const AES256 & o) const
|
||||
{
|
||||
return memcmp(m_Buffer, o.m_Buffer, sizeof(m_Buffer));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr AES256::ToString() const
|
||||
{
|
||||
return ToStrF("%s", m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr AES256::GetKey() const
|
||||
{
|
||||
return reinterpret_cast< CSStr >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void AES256::Init(CSStr key)
|
||||
{
|
||||
// Clear current key, if any
|
||||
aes256_done(&m_Context);
|
||||
// Is the specified key empty?
|
||||
if (!key || *key == 0)
|
||||
return; // Leave the context with an empty key
|
||||
// Obtain the specified key size
|
||||
const Uint32 size = (strlen(key) * sizeof(SQChar));
|
||||
// See if the key size is accepted
|
||||
if (size > sizeof(m_Buffer))
|
||||
SqThrowF("The specified key is out of bounds: %u > %u", size, sizeof(m_Buffer));
|
||||
// Initialize the key buffer to 0
|
||||
memset(m_Buffer, 0, sizeof(m_Buffer));
|
||||
// Copy the key into the key buffer
|
||||
memcpy(m_Buffer, key, size);
|
||||
// Initialize the context with the specified key
|
||||
aes256_init(&m_Context, m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void AES256::Done()
|
||||
{
|
||||
aes256_done(&m_Context);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
String AES256::Encrypt(CSStr data)
|
||||
{
|
||||
// Is there any data to encrypt?
|
||||
if (!data || *data == 0)
|
||||
return String();
|
||||
// Copy the data into an editable string
|
||||
String str(data);
|
||||
// Make sure that we have a size with a multiple of 16
|
||||
if ((str.size() % 16) != 0)
|
||||
str.resize(str.size() - (str.size() % 16) + 16);
|
||||
// Encrypt in chunks of 16 characters
|
||||
for (Uint32 n = 0; n < str.size(); n += 16)
|
||||
aes256_encrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n]));
|
||||
// Return ownership of the encrypted string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
String AES256::Decrypt(CSStr data)
|
||||
{
|
||||
// Is there any data to decrypt?
|
||||
if (!data || *data == 0)
|
||||
return String();
|
||||
// Copy the data into an editable string
|
||||
String str(data);
|
||||
// Make sure that we have a size with a multiple of 16
|
||||
if ((str.size() % 16) != 0)
|
||||
str.resize(str.size() - (str.size() % 16) + 16);
|
||||
// Decrypt inc chunks of 16 characters
|
||||
for (Uint32 n = 0; n < str.size(); n += 16)
|
||||
aes256_decrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n]));
|
||||
// Remove null characters in case the string was not a multiple of 16 when encrypted
|
||||
while (!str.empty() && str.back() == 0)
|
||||
str.pop_back();
|
||||
// Return ownership of the encrypted string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Utility to avoid creating encoder instances for each call.
|
||||
*/
|
||||
template < class T > struct BaseHash
|
||||
{
|
||||
static T Algo;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < class T > T BaseHash< T >::Algo;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Hash the specified value or the result of a formatted string.
|
||||
*/
|
||||
template < class T > static SQInteger HashF(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Was the hash value specified?
|
||||
if (top <= 1)
|
||||
return sq_throwerror(vm, "Missing hash value");
|
||||
// Do we have enough values to call the format function?
|
||||
else if (top > 2)
|
||||
{
|
||||
SStr val = NULL;
|
||||
SQInteger len = 0;
|
||||
// Attempt to generate the specified string format
|
||||
SQRESULT ret = sqstd_format(vm, 2, &len, &val);
|
||||
// Did the format failed?
|
||||
if (SQ_FAILED(ret))
|
||||
return ret; // Propagate the exception
|
||||
// Hash the resulted string
|
||||
String str(BaseHash< T >::Algo(val));
|
||||
// Push the string on the stack
|
||||
sq_pushstring(vm, str.data(), str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
Var< CSStr > val(vm, 2);
|
||||
// See if the obtained value is a valid string
|
||||
if (!val.value)
|
||||
return sq_throwerror(vm, "Unable to retrieve the value");
|
||||
// Hash the resulted string
|
||||
String str(BaseHash< T >::Algo(val.value));
|
||||
// Push the string on the stack
|
||||
sq_pushstring(vm, str.data(), str.size());
|
||||
}
|
||||
// At this point we have a valid string on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
template < class T > static void RegisterWrapper(Table & hashns, CCStr cname)
|
||||
{
|
||||
typedef HashWrapper< T > Hash;
|
||||
hashns.Bind(cname, Class< Hash >(hashns.GetVM(), cname)
|
||||
/* Constructors */
|
||||
.Ctor()
|
||||
/* Metamethods */
|
||||
.Func(_SC("_tostring"), &Hash::ToString)
|
||||
/* Properties */
|
||||
.Prop(_SC("Hash"), &Hash::GetHash)
|
||||
/* Functions */
|
||||
.Func(_SC("Reset"), &Hash::Reset)
|
||||
.Func(_SC("Compute"), &Hash::Compute)
|
||||
.Func(_SC("GetHash"), &Hash::GetHash)
|
||||
.Func(_SC("Add"), &Hash::AddStr)
|
||||
.Func(_SC("AddStr"), &Hash::AddStr)
|
||||
);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Crypt(HSQUIRRELVM vm)
|
||||
{
|
||||
Table hashns(vm);
|
||||
|
||||
RegisterWrapper< CRC32 >(hashns, _SC("CRC32"));
|
||||
RegisterWrapper< Keccak >(hashns, _SC("Keccak"));
|
||||
RegisterWrapper< MD5 >(hashns, _SC("MD5"));
|
||||
RegisterWrapper< SHA1 >(hashns, _SC("SHA1"));
|
||||
RegisterWrapper< SHA256 >(hashns, _SC("SHA256"));
|
||||
RegisterWrapper< SHA3 >(hashns, _SC("SHA3"));
|
||||
|
||||
hashns.SquirrelFunc(_SC("GetCRC32"), &HashF< CRC32 >);
|
||||
hashns.SquirrelFunc(_SC("GetKeccak"), &HashF< Keccak >);
|
||||
hashns.SquirrelFunc(_SC("GetMD5"), &HashF< MD5 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA1"), &HashF< SHA1 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA256"), &HashF< SHA256 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA3"), &HashF< SHA3 >);
|
||||
|
||||
RootTable(vm).Bind(_SC("SqHash"), hashns);
|
||||
|
||||
RootTable(vm).Bind("SqAES256", Class< AES256 >(vm, "SqAES256")
|
||||
/* Constructors */
|
||||
.Ctor()
|
||||
.Ctor< CSStr >()
|
||||
/* Metamethods */
|
||||
.Func(_SC("_cmp"), &AES256::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &AES256::Typename)
|
||||
.Func(_SC("_tostring"), &AES256::ToString)
|
||||
/* Properties */
|
||||
.Prop(_SC("Key"), &AES256::GetKey)
|
||||
/* Functions */
|
||||
.Func(_SC("Init"), &AES256::Init)
|
||||
.Func(_SC("Done"), &AES256::Done)
|
||||
.Func(_SC("Encrypt"), &AES256::Encrypt)
|
||||
.Func(_SC("Decrypt"), &AES256::Decrypt)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
200
source/Library/Crypt.hpp
Normal file
200
source/Library/Crypt.hpp
Normal file
@ -0,0 +1,200 @@
|
||||
#ifndef _LIBRARY_CRYPT_HPP_
|
||||
#define _LIBRARY_CRYPT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <aes256.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Simple class to maintain the state of an encoder.
|
||||
*/
|
||||
template < class T > class HashWrapper
|
||||
{
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
HashWrapper()
|
||||
: m_Encoder()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy operator.
|
||||
*/
|
||||
HashWrapper(const HashWrapper & o)
|
||||
: m_Encoder(o.m_Encoder)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~HashWrapper()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
HashWrapper & operator = (const HashWrapper & o)
|
||||
{
|
||||
m_Encoder = o.m_Encoder;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
String ToString()
|
||||
{
|
||||
return m_Encoder.getHash();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reset the encoder state.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
m_Encoder.reset();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Compute the hash of the specified string.
|
||||
*/
|
||||
String Compute(const String & str)
|
||||
{
|
||||
return m_Encoder(str);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the hash value of the data hashed so far.
|
||||
*/
|
||||
String GetHash()
|
||||
{
|
||||
return m_Encoder.getHash();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add a string value to be hashed.
|
||||
*/
|
||||
void AddStr(const String & str)
|
||||
{
|
||||
m_Encoder.add(str.data(), str.length() * sizeof(String::value_type));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The managed encoder state.
|
||||
*/
|
||||
T m_Encoder;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Simple wrapper around a the AES encryption context.
|
||||
*/
|
||||
class AES256
|
||||
{
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
AES256();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct with an explicit key.
|
||||
*/
|
||||
AES256(CSStr key);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
AES256(const AES256 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
AES256(AES256 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~AES256() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
AES256 & operator = (const AES256 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
AES256 & operator = (AES256 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const AES256 & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated key.
|
||||
*/
|
||||
CSStr GetKey() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Initialize the context key.
|
||||
*/
|
||||
void Init(CSStr key);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reset the associated context.
|
||||
*/
|
||||
void Done();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Encrypt the specified string.
|
||||
*/
|
||||
String Encrypt(CSStr data);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Decrypt the specified string.
|
||||
*/
|
||||
String Decrypt(CSStr data);
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The managed encryption context.
|
||||
*/
|
||||
aes256_context m_Context;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The key used to encrypt data.
|
||||
*/
|
||||
Uint8 m_Buffer[32]{0};
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CRYPT_HPP_
|
@ -1,103 +0,0 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Hashing.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <sqstdstring.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <crc32.h>
|
||||
#include <keccak.h>
|
||||
#include <md5.h>
|
||||
#include <sha1.h>
|
||||
#include <sha256.h>
|
||||
#include <sha3.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
template < class T > struct BaseHash
|
||||
{
|
||||
static T Algo;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < class T > T BaseHash< T >::Algo;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < class T > static SQInteger HashF(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
Object ret;
|
||||
if (top <= 1)
|
||||
SqThrow("Missing the hash string");
|
||||
else if (top == 2 && ((sq_gettype(vm, -1) == OT_STRING) || !SQ_FAILED(sq_tostring(vm, -1))))
|
||||
{
|
||||
CCStr str = 0;
|
||||
if (SQ_FAILED(sq_getstring(vm, -1, &str)))
|
||||
SqThrow("Unable to retrieve the string");
|
||||
else
|
||||
ret = MakeObject(vm, BaseHash< T >::Algo(str));
|
||||
sq_settop(vm, top);
|
||||
}
|
||||
else if (top > 2)
|
||||
{
|
||||
CStr str = NULL;
|
||||
SQInteger len = 0;
|
||||
if (SQ_FAILED(sqstd_format(vm, 2, &len, &str)))
|
||||
SqThrow("Unable to generate the string [%s]", Error::Message(vm).c_str());
|
||||
else
|
||||
ret = MakeObject(vm, BaseHash< T >::Algo(str));
|
||||
}
|
||||
else
|
||||
SqThrow("Unable to extract the hash string");
|
||||
Var< Object >::push(vm, ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
template < class T > static void RegisterWrapper(Table & hashns, CCStr cname)
|
||||
{
|
||||
typedef HashWrapper< T > Hash;
|
||||
hashns.Bind(cname, Class< Hash >(hashns.GetVM(), cname)
|
||||
/* Constructors */
|
||||
.Ctor()
|
||||
/* Metamethods */
|
||||
.Func(_SC("_tostring"), &Hash::ToString)
|
||||
/* Properties */
|
||||
.Prop(_SC("Hash"), &Hash::GetHash)
|
||||
/* Functions */
|
||||
.Func(_SC("Reset"), &Hash::Reset)
|
||||
.Func(_SC("Compute"), &Hash::Compute)
|
||||
.Func(_SC("GetHash"), &Hash::GetHash)
|
||||
.Func(_SC("Add"), &Hash::AddStr)
|
||||
.Func(_SC("AddStr"), &Hash::AddStr)
|
||||
);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Hash(HSQUIRRELVM vm)
|
||||
{
|
||||
Table hashns(vm);
|
||||
|
||||
RegisterWrapper< CRC32 >(hashns, _SC("CRC32"));
|
||||
RegisterWrapper< Keccak >(hashns, _SC("Keccak"));
|
||||
RegisterWrapper< MD5 >(hashns, _SC("MD5"));
|
||||
RegisterWrapper< SHA1 >(hashns, _SC("SHA1"));
|
||||
RegisterWrapper< SHA256 >(hashns, _SC("SHA256"));
|
||||
RegisterWrapper< SHA3 >(hashns, _SC("SHA3"));
|
||||
|
||||
hashns.SquirrelFunc(_SC("GetCRC32"), &HashF< CRC32 >);
|
||||
hashns.SquirrelFunc(_SC("GetKeccak"), &HashF< Keccak >);
|
||||
hashns.SquirrelFunc(_SC("GetMD5"), &HashF< MD5 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA1"), &HashF< SHA1 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA256"), &HashF< SHA256 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA3"), &HashF< SHA3 >);
|
||||
|
||||
RootTable(vm).Bind(_SC("SqHash"), hashns);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
@ -1,58 +0,0 @@
|
||||
#ifndef _LIBRARY_HASHING_HPP_
|
||||
#define _LIBRARY_HASHING_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < class T > class HashWrapper
|
||||
{
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
HashWrapper()
|
||||
: m_Encoder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
HashWrapper(const HashWrapper & o)
|
||||
: m_Encoder(o.m_Encoder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
~HashWrapper()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
HashWrapper & operator = (const HashWrapper & o)
|
||||
{
|
||||
m_Encoder = o.m_Encoder;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String ToString() { return m_Encoder.getHash(); }
|
||||
void Reset() { m_Encoder.reset(); }
|
||||
String Compute(const String & str) { return m_Encoder(str); }
|
||||
String GetHash() { return m_Encoder.getHash(); }
|
||||
void AddStr(const String & str)
|
||||
{ m_Encoder.add(str.data(), str.length() * sizeof(String::value_type)); }
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
T m_Encoder;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_HASHING_HPP_
|
@ -4,11 +4,12 @@
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <RandomLib/Random.hpp>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef SQMOD_OS_WINDOWS
|
||||
#include <process.h>
|
||||
#else
|
||||
@ -17,10 +18,45 @@
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
RandomLib::Random g_RGen;
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
static std::unique_ptr< std::mt19937 > RG32_MT19937 =
|
||||
std::unique_ptr< std::mt19937 >(new std::mt19937(GenerateSeed()));
|
||||
|
||||
static std::unique_ptr< std::mt19937_64 > RG64_MT19937 =
|
||||
std::unique_ptr< std::mt19937_64 >(new std::mt19937_64(GenerateSeed()));
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static std::uniform_int_distribution< Int8 > Int8_Dist(std::numeric_limits< Int8 >::min(),
|
||||
std::numeric_limits< Int8 >::max());
|
||||
static std::uniform_int_distribution< Uint8 > Uint8_Dist(std::numeric_limits< Uint8 >::min(),
|
||||
std::numeric_limits< Uint8 >::max());
|
||||
|
||||
static std::uniform_int_distribution< Int16 > Int16_Dist(std::numeric_limits< Int16 >::min(),
|
||||
std::numeric_limits< Int16 >::max());
|
||||
static std::uniform_int_distribution< Uint16 > Uint16_Dist(std::numeric_limits< Uint16 >::min(),
|
||||
std::numeric_limits< Uint16 >::max());
|
||||
|
||||
static std::uniform_int_distribution< Int32 > Int32_Dist(std::numeric_limits< Int32 >::min(),
|
||||
std::numeric_limits< Int32 >::max());
|
||||
static std::uniform_int_distribution< Uint32 > Uint32_Dist(std::numeric_limits< Uint32 >::min(),
|
||||
std::numeric_limits< Uint32 >::max());
|
||||
|
||||
static std::uniform_int_distribution< Int64 > Int64_Dist(std::numeric_limits< Int64 >::min(),
|
||||
std::numeric_limits< Int64 >::max());
|
||||
static std::uniform_int_distribution< Uint64 > Uint64_Dist(std::numeric_limits< Uint64 >::min(),
|
||||
std::numeric_limits< Uint64 >::max());
|
||||
|
||||
static std::uniform_real_distribution<Float32> Float32_Dist(std::numeric_limits< Float32 >::min(),
|
||||
std::numeric_limits< Float32 >::max());
|
||||
static std::uniform_real_distribution<Float64> Float64_Dist(std::numeric_limits< Float64 >::min(),
|
||||
std::numeric_limits< Float64 >::max());
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static std::uniform_int_distribution< String::value_type >
|
||||
String_Dist(std::numeric_limits< String::value_type >::min(),
|
||||
std::numeric_limits< String::value_type >::max());
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SizeT GenerateSeed()
|
||||
@ -49,309 +85,296 @@ SizeT GenerateSeed()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReseedRandom()
|
||||
{
|
||||
g_RGen.Reseed();
|
||||
RG32_MT19937.reset(new std::mt19937(GenerateSeed()));
|
||||
RG64_MT19937.reset(new std::mt19937_64(GenerateSeed()));
|
||||
}
|
||||
|
||||
void ReseedRandom(Uint32 n)
|
||||
{
|
||||
g_RGen.Reseed(n);
|
||||
RG32_MT19937.reset(new std::mt19937(n));
|
||||
RG64_MT19937.reset(new std::mt19937_64(n));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReseedRandom32()
|
||||
{
|
||||
RG32_MT19937.reset(new std::mt19937(GenerateSeed()));
|
||||
}
|
||||
|
||||
void ReseedRandom32(Uint32 n)
|
||||
{
|
||||
RG32_MT19937.reset(new std::mt19937(n));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReseedRandom64()
|
||||
{
|
||||
RG64_MT19937.reset(new std::mt19937_64(GenerateSeed()));
|
||||
}
|
||||
|
||||
void ReseedRandom64(Uint32 n)
|
||||
{
|
||||
RG64_MT19937.reset(new std::mt19937_64(n));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int8 GetRandomInt8()
|
||||
{
|
||||
return g_RGen.Integer< Int8 >();
|
||||
return Int8_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int8 GetRandomInt8(Int8 n)
|
||||
{
|
||||
return g_RGen.Integer< Int8 >(n);
|
||||
return std::uniform_int_distribution< Int8 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int8 GetRandomInt8(Int8 m, Int8 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Int8 >(m, n);
|
||||
return std::uniform_int_distribution< Int8 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint8 GetRandomUint8()
|
||||
{
|
||||
return g_RGen.Integer< Uint8 >();
|
||||
return Uint8_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint8 GetRandomUint8(Uint8 n)
|
||||
{
|
||||
return g_RGen.Integer< Uint8 >(n);
|
||||
return std::uniform_int_distribution< Uint8 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint8 GetRandomUint8(Uint8 m, Uint8 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Uint8 >(m, n);
|
||||
return std::uniform_int_distribution< Uint8 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int16 GetRandomInt16()
|
||||
{
|
||||
return g_RGen.Integer< Int16 >();
|
||||
return Int16_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int16 GetRandomInt16(Int16 n)
|
||||
{
|
||||
return g_RGen.Integer< Int16 >(n);
|
||||
return std::uniform_int_distribution< Int16 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int16 GetRandomInt16(Int16 m, Int16 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Int16 >(m, n);
|
||||
return std::uniform_int_distribution< Int16 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint16 GetRandomUint16()
|
||||
{
|
||||
return g_RGen.Integer< Uint16 >();
|
||||
return Uint16_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint16 GetRandomUint16(Uint16 n)
|
||||
{
|
||||
return g_RGen.Integer< Uint16 >(n);
|
||||
return std::uniform_int_distribution< Uint16 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint16 GetRandomUint16(Uint16 m, Uint16 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Uint16 >(m, n);
|
||||
return std::uniform_int_distribution< Uint16 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 GetRandomInt32()
|
||||
{
|
||||
return g_RGen.Integer< Int32 >();
|
||||
return Int32_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int32 GetRandomInt32(Int32 n)
|
||||
{
|
||||
return g_RGen.Integer< Int32 >(n);
|
||||
return std::uniform_int_distribution< Int32 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int32 GetRandomInt32(Int32 m, Int32 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Int32 >(m, n);
|
||||
return std::uniform_int_distribution< Int32 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 GetRandomUint32()
|
||||
{
|
||||
return g_RGen.Integer< Uint32 >();
|
||||
return Int32_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint32 GetRandomUint32(Uint32 n)
|
||||
{
|
||||
return g_RGen.Integer< Uint32 >(n);
|
||||
return std::uniform_int_distribution< Int32 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint32 GetRandomUint32(Uint32 m, Uint32 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Uint32 >(m, n);
|
||||
return std::uniform_int_distribution< Int32 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 GetRandomInt64()
|
||||
{
|
||||
return g_RGen.Integer< Int64 >();
|
||||
return Int64_Dist(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Int64 GetRandomInt64(Int64 n)
|
||||
{
|
||||
return g_RGen.Integer< Int64 >(n);
|
||||
return std::uniform_int_distribution< Int64 >(0, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Int64 GetRandomInt64(Int64 m, Int64 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Int64 >(m, n);
|
||||
return std::uniform_int_distribution< Int64 >(m, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint64 GetRandomUint64()
|
||||
{
|
||||
return g_RGen.Integer< Uint64 >();
|
||||
return Uint64_Dist(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Uint64 GetRandomUint64(Uint64 n)
|
||||
{
|
||||
return g_RGen.Integer< Uint64 >(n);
|
||||
return std::uniform_int_distribution< Uint64 >(0, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Uint64 GetRandomUint64(Uint64 m, Uint64 n)
|
||||
{
|
||||
return g_RGen.IntegerC< Uint64 >(m, n);
|
||||
return std::uniform_int_distribution< Uint64 >(m, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 GetRandomFloat32()
|
||||
{
|
||||
static const Float32 m = NumLimit<Int32>::Min, n = NumLimit<Int32>::Max;
|
||||
return (n - m) * (Float32(g_RGen.IntegerC< Int16 >(0, NumLimit< Int16 >::Max)) / Float32(RAND_MAX)) + m;
|
||||
return Float32_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Float32 GetRandomFloat32(Float32 n)
|
||||
{
|
||||
return Float32(g_RGen.IntegerC< Int16 >(0, NumLimit< Int16 >::Max)) / Float32(RAND_MAX/n);
|
||||
return std::uniform_real_distribution< Float32 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Float32 GetRandomFloat32(Float32 m, Float32 n)
|
||||
{
|
||||
return (n - m) * (Float32(g_RGen.IntegerC< Int16 >(0, NumLimit< Int16 >::Max)) / Float32(RAND_MAX)) + m;
|
||||
return std::uniform_real_distribution< Float32 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float64 GetRandomFloat64()
|
||||
{
|
||||
static const Float64 m = NumLimit<Int32>::Min, n = NumLimit<Int32>::Max;
|
||||
return (n - m) * (Float64(g_RGen.IntegerC< Int16 >(0, NumLimit< Int16 >::Max)) / Float64(RAND_MAX)) + m;
|
||||
return Float64_Dist(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Float64 GetRandomFloat64(Float64 n)
|
||||
{
|
||||
return Float64(g_RGen.IntegerC< Int16 >(0, NumLimit< Int16 >::Max)) / Float64(RAND_MAX/n);
|
||||
return std::uniform_real_distribution< Float64 >(0, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Float64 GetRandomFloat64(Float64 m, Float64 n)
|
||||
{
|
||||
return (n - m) * (Float64(g_RGen.IntegerC< Int16 >(0, NumLimit< Int16 >::Max)) / Float64(RAND_MAX)) + m;
|
||||
return std::uniform_real_distribution< Float64 >(m, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void GetRandomString(String & str, String::size_type len)
|
||||
{
|
||||
// Reserve the requested size + the null terminator
|
||||
str.reserve(len+1);
|
||||
// Resize to the requested size and fill with 0
|
||||
str.resize(len);
|
||||
for (String::iterator itr = str.begin(); itr != str.end(); ++itr)
|
||||
{
|
||||
*itr = g_RGen.Integer< String::value_type >();
|
||||
}
|
||||
// Generate the requested amount of characters
|
||||
for (auto & c : str)
|
||||
c = String_Dist(*RG32_MT19937);
|
||||
// Append the null terminator
|
||||
str.push_back(0);
|
||||
}
|
||||
|
||||
void GetRandomString(String & str, String::size_type len, String::value_type n)
|
||||
{
|
||||
// Reserve the requested size + the null terminator
|
||||
str.reserve(len+1);
|
||||
// Resize to the requested size and fill with 0
|
||||
str.resize(len);
|
||||
for (String::iterator itr = str.begin(); itr != str.end(); ++itr)
|
||||
{
|
||||
*itr = g_RGen.Integer< String::value_type >(n);
|
||||
}
|
||||
// Create the custom distribution
|
||||
std::uniform_int_distribution< String::value_type > dist(1, n);
|
||||
// Generate the requested amount of characters
|
||||
for (auto & c : str)
|
||||
c = dist(*RG32_MT19937);
|
||||
// Append the null terminator
|
||||
str.push_back(0);
|
||||
}
|
||||
|
||||
void GetRandomString(String & str, String::size_type len, String::value_type m, String::value_type n)
|
||||
{
|
||||
// Reserve the requested size + the null terminator
|
||||
str.reserve(len+1);
|
||||
// Resize to the requested size and fill with 0
|
||||
str.resize(len);
|
||||
for (String::iterator itr = str.begin(); itr != str.end(); ++itr)
|
||||
{
|
||||
*itr = g_RGen.IntegerC< String::value_type >(m, n);
|
||||
}
|
||||
// Create the custom distribution
|
||||
std::uniform_int_distribution< String::value_type > dist(m, n);
|
||||
// Generate the requested amount of characters
|
||||
for (auto & c : str)
|
||||
c = dist(*RG32_MT19937);
|
||||
// Append the null terminator
|
||||
str.push_back(0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool GetRandomBool()
|
||||
{
|
||||
return g_RGen.Boolean();
|
||||
return std::bernoulli_distribution()(*RG32_MT19937);
|
||||
}
|
||||
|
||||
bool GetRandomBool(SQFloat p)
|
||||
{
|
||||
return std::bernoulli_distribution(p)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < typename T > static T RandomValue()
|
||||
{
|
||||
return RandomVal< T >::Get();
|
||||
}
|
||||
|
||||
template < typename T > static T RandomValue(T n)
|
||||
{
|
||||
return RandomVal< T >::Get(n);
|
||||
}
|
||||
|
||||
template < typename T > static T RandomValue(T m, T n)
|
||||
{
|
||||
return RandomVal< T >::Get(m, n);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static CSStr RandomString(Int32 len)
|
||||
static String RandomString(Int32 len)
|
||||
{
|
||||
// Is there anything to generate?
|
||||
if (len <= 0)
|
||||
{
|
||||
return _SC("");
|
||||
}
|
||||
Buffer b(len+1);
|
||||
SStr s = b.Get< SQChar >();
|
||||
for (Int32 n = 0; n <= len; ++n, ++s)
|
||||
{
|
||||
*s = g_RGen.Integer< SQChar >();
|
||||
}
|
||||
b.At< SQChar >(len) = 0;
|
||||
return b.Get< SQChar >();
|
||||
// Prepare the string buffer
|
||||
String str;
|
||||
// Request the random fill
|
||||
GetRandomString(str, len);
|
||||
// Return ownership of the string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static CSStr RandomString(Int32 len, SQChar n)
|
||||
static String RandomString(Int32 len, SQChar n)
|
||||
{
|
||||
// Is there anything to generate?
|
||||
if (len <= 0)
|
||||
{
|
||||
return _SC("");
|
||||
}
|
||||
Buffer b(len+1);
|
||||
SStr s = b.Get< SQChar >();
|
||||
for (Int32 i = 0; i <= len; ++i, ++s)
|
||||
{
|
||||
*s = g_RGen.Integer< SQChar >(n);
|
||||
}
|
||||
b.At< SQChar >(len) = 0;
|
||||
return b.Get< SQChar >();
|
||||
// Prepare the string buffer
|
||||
String str;
|
||||
// Request the random fill
|
||||
GetRandomString(str, len, n);
|
||||
// Return ownership of the string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static CSStr RandomString(Int32 len, SQChar m, SQChar n)
|
||||
static String RandomString(Int32 len, SQChar m, SQChar n)
|
||||
{
|
||||
// Is there anything to generate?
|
||||
if (len <= 0)
|
||||
{
|
||||
return _SC("");
|
||||
}
|
||||
Buffer b(len+1);
|
||||
SStr s = b.Get< SQChar >();
|
||||
for (Int32 i = 0; i <= len; ++i, ++s)
|
||||
{
|
||||
*s = g_RGen.IntegerC< SQChar >(m, n);
|
||||
}
|
||||
b.At< SQChar >(len) = 0;
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static bool RandomProbI(SQInteger p)
|
||||
{
|
||||
return g_RGen.Prob(p);
|
||||
}
|
||||
|
||||
static bool RandomProbI(SQInteger m, SQInteger n)
|
||||
{
|
||||
return g_RGen.Prob(m, n);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static bool RandomProbF(SQFloat p)
|
||||
{
|
||||
return g_RGen.Prob(p);
|
||||
}
|
||||
|
||||
static bool RandomProbF(SQFloat m, SQFloat n)
|
||||
{
|
||||
return g_RGen.Prob(m, n);
|
||||
// Prepare the string buffer
|
||||
String str;
|
||||
// Request the random fill
|
||||
GetRandomString(str, len, m, n);
|
||||
// Return ownership of the string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -361,20 +384,36 @@ void Register_Random(HSQUIRRELVM vm)
|
||||
.Func(_SC("GenSeed"), &GenerateSeed)
|
||||
.Overload< void (*)(void) >(_SC("Reseed"), &ReseedRandom)
|
||||
.Overload< void (*)(Uint32) >(_SC("Reseed"), &ReseedRandom)
|
||||
.Overload< SQInteger (*)(void) >(_SC("Integer"), &RandomValue< SQInteger >)
|
||||
.Overload< SQInteger (*)(SQInteger) >(_SC("Integer"), &RandomValue< SQInteger >)
|
||||
.Overload< SQInteger (*)(SQInteger, SQInteger) >(_SC("Integer"), &RandomValue< SQInteger >)
|
||||
.Overload< SQFloat (*)(void) >(_SC("Float"), &RandomValue< SQFloat >)
|
||||
.Overload< SQFloat (*)(SQFloat) >(_SC("Float"), &RandomValue< SQFloat >)
|
||||
.Overload< SQFloat (*)(SQFloat, SQFloat) >(_SC("Float"), &RandomValue< SQFloat >)
|
||||
.Overload< CSStr (*)(Int32) >(_SC("String"), &RandomString)
|
||||
.Overload< CSStr (*)(Int32, SQChar) >(_SC("String"), &RandomString)
|
||||
.Overload< CSStr (*)(Int32, SQChar, SQChar) >(_SC("String"), &RandomString)
|
||||
.Func(_SC("Bool"), &GetRandomBool)
|
||||
.Overload< bool (*)(SQInteger) >(_SC("ProbI"), &RandomProbI)
|
||||
.Overload< bool (*)(SQInteger, SQInteger) >(_SC("ProbI"), &RandomProbI)
|
||||
.Overload< bool (*)(SQFloat) >(_SC("ProbF"), &RandomProbF)
|
||||
.Overload< bool (*)(SQFloat, SQFloat) >(_SC("ProbF"), &RandomProbF)
|
||||
.Overload< void (*)(void) >(_SC("Reseed32"), &ReseedRandom32)
|
||||
.Overload< void (*)(Uint32) >(_SC("Reseed32"), &ReseedRandom32)
|
||||
.Overload< void (*)(void) >(_SC("Reseed64"), &ReseedRandom64)
|
||||
.Overload< void (*)(Uint32) >(_SC("Reseed64"), &ReseedRandom64)
|
||||
|
||||
#ifdef _SQ64
|
||||
.Overload< SQInteger (*)(void) >(_SC("Integer"), &GetRandomInt64)
|
||||
.Overload< SQInteger (*)(SQInteger) >(_SC("Integer"), &GetRandomInt64)
|
||||
.Overload< SQInteger (*)(SQInteger, SQInteger) >(_SC("Integer"), &GetRandomInt64)
|
||||
#else
|
||||
.Overload< SQInteger (*)(void) >(_SC("Integer"), &GetRandomInt32)
|
||||
.Overload< SQInteger (*)(SQInteger) >(_SC("Integer"), &GetRandomInt32)
|
||||
.Overload< SQInteger (*)(SQInteger, SQInteger) >(_SC("Integer"), &GetRandomInt32)
|
||||
#endif // _SQ64
|
||||
|
||||
#ifdef SQUSEDOUBLE
|
||||
.Overload< SQFloat (*)(void) >(_SC("Float"), &GetRandomFloat64)
|
||||
.Overload< SQFloat (*)(SQFloat) >(_SC("Float"), &GetRandomFloat64)
|
||||
.Overload< SQFloat (*)(SQFloat, SQFloat) >(_SC("Float"), &GetRandomFloat64)
|
||||
#else
|
||||
.Overload< SQFloat (*)(void) >(_SC("Float"), &GetRandomFloat32)
|
||||
.Overload< SQFloat (*)(SQFloat) >(_SC("Float"), &GetRandomFloat32)
|
||||
.Overload< SQFloat (*)(SQFloat, SQFloat) >(_SC("Float"), &GetRandomFloat32)
|
||||
#endif // SQUSEDOUBLE
|
||||
|
||||
.Overload< String (*)(Int32) >(_SC("String"), &RandomString)
|
||||
.Overload< String (*)(Int32, SQChar) >(_SC("String"), &RandomString)
|
||||
.Overload< String (*)(Int32, SQChar, SQChar) >(_SC("String"), &RandomString)
|
||||
.Overload< bool (*)(void) >(_SC("Bool"), &GetRandomBool)
|
||||
.Overload< bool (*)(SQFloat) >(_SC("Bool"), &GetRandomBool)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,10 @@
|
||||
#include <sqstdstring.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <algorithm>
|
||||
@ -21,137 +21,117 @@ namespace SqMod {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
if (!w)
|
||||
return _SC("");
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w);
|
||||
// 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
|
||||
if (!t || *t == 0)
|
||||
// Insert only the fill character
|
||||
memset(b.Data(), f, w);
|
||||
else
|
||||
{
|
||||
// Calculate the string length
|
||||
const Uint32 n = strlen(t);
|
||||
// Insert only the fill character first
|
||||
memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
strncpy(b.Data(), t, n);
|
||||
}
|
||||
// End the resulted string
|
||||
b.At< SQChar >(w) = 0;
|
||||
b.At(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;
|
||||
}
|
||||
if (!w)
|
||||
return _SC("");
|
||||
// Is the specified offset within width range?
|
||||
else if (o > w)
|
||||
SqThrowF("Offset is out of bounds");
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w);
|
||||
// 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
|
||||
if (!t || *t == 0)
|
||||
// Insert only the fill character
|
||||
memset(b.Data(), f, w);
|
||||
else
|
||||
{
|
||||
strncpy(b.Get< SQChar >() + o, t, n);
|
||||
// Clculate the string length
|
||||
const Uint32 n = strlen(t);
|
||||
// Insert the fill character first
|
||||
memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
strncpy(b.Data() + o, t, w - n);
|
||||
}
|
||||
// End the resulted string
|
||||
b.At< SQChar >(w) = 0;
|
||||
b.At(w) = 0;
|
||||
// Return the resulted string
|
||||
return b.Get< SQChar >();
|
||||
return b.Get();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
if (!w)
|
||||
return _SC("");
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w);
|
||||
// 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
|
||||
if (!t || *t == 0)
|
||||
// Insert only the fill character
|
||||
memset(b.Data(), f, w);
|
||||
else
|
||||
{
|
||||
strncpy(b.Get< SQChar >() + (w-n), t, n);
|
||||
// Calculate the string length
|
||||
const Uint32 n = strlen(t);
|
||||
// Insert the fill character first
|
||||
memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
if (n >= w)
|
||||
strncpy(b.Data(), t, w);
|
||||
else
|
||||
strncpy(b.Data() + (w - n), t, n);
|
||||
}
|
||||
// End the resulted string
|
||||
b.At< SQChar >(w) = 0;
|
||||
b.At(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;
|
||||
}
|
||||
if (!w)
|
||||
return _SC("");
|
||||
// Is the specified offset within width range?
|
||||
else if (o > w)
|
||||
SqThrowF("Offset is out of bounds");
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w);
|
||||
// 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
|
||||
if (!t || *t == 0)
|
||||
// Insert only the fill character
|
||||
memset(b.Data(), f, w);
|
||||
else
|
||||
{
|
||||
strncpy(b.Get< SQChar >() + ((w-n)-o), t, n);
|
||||
// Calculate the string length
|
||||
const Uint32 n = strlen(t);
|
||||
// Insert the fill character first
|
||||
memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
if (n >= w || (n + o) >= w)
|
||||
strncpy(b.Data(), t, w - o);
|
||||
else
|
||||
strncpy(b.Data() + ((w - n) - o), t, n);
|
||||
}
|
||||
// End the resulted string
|
||||
b.At< SQChar >(w) = 0;
|
||||
b.At(w) = 0;
|
||||
// Return the resulted string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
@ -159,34 +139,26 @@ CSStr RightStr(CSStr t, SQChar f, Uint32 w, Uint32 o)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr CenterStr(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;
|
||||
}
|
||||
if (!w)
|
||||
return _SC("");
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w);
|
||||
// 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
|
||||
if (!t || *t == 0)
|
||||
// Insert only the fill character
|
||||
memset(b.Data(), f, w);
|
||||
else
|
||||
{
|
||||
strncpy(b.Get< SQChar >() + (w/2 - n/2), t, n);
|
||||
// Calculate the string length
|
||||
const Uint32 n = strlen(t);
|
||||
// Insert only the fill character first
|
||||
memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
strncpy(b.Data() + ((w/2) - (n/2)), t, n);
|
||||
}
|
||||
// End the resulted string
|
||||
b.At< SQChar >(w) = 0;
|
||||
b.At(w) = 0;
|
||||
// Return the resulted string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
@ -194,12 +166,11 @@ CSStr CenterStr(CSStr t, SQChar f, Uint32 w)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr StrJustAlphaNum(CSStr str)
|
||||
{
|
||||
Uint32 size = 0;
|
||||
// See if we actually have something to search for
|
||||
if(!str || (size = strlen(str)) <= 0)
|
||||
{
|
||||
if(!str || *str == 0)
|
||||
return _SC("");
|
||||
}
|
||||
// Calculate the string length
|
||||
Uint32 size = strlen(str);
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(size);
|
||||
// Resulted string size
|
||||
@ -211,13 +182,11 @@ CSStr StrJustAlphaNum(CSStr str)
|
||||
{
|
||||
// Is this an alpha-numeric character?
|
||||
if (isalnum(c) != 0)
|
||||
{
|
||||
// Save it and move to the next one
|
||||
b.At< SQChar >(n++) = c;
|
||||
}
|
||||
b.At(n++) = c;
|
||||
}
|
||||
// End the resulted string
|
||||
b.At< SQChar >(n) = 0;
|
||||
b.At(n) = 0;
|
||||
// Return the string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
@ -225,12 +194,11 @@ CSStr StrJustAlphaNum(CSStr str)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr StrToLowercase(CSStr str)
|
||||
{
|
||||
Uint32 size = 0;
|
||||
// See if we actually have something to search for
|
||||
if(!str || (size = strlen(str)) <= 0)
|
||||
{
|
||||
if(!str || *str == 0)
|
||||
return _SC("");
|
||||
}
|
||||
// Calculate the string length
|
||||
Uint32 size = strlen(str);
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(size);
|
||||
// Resulted string size
|
||||
@ -239,12 +207,10 @@ CSStr StrToLowercase(CSStr str)
|
||||
SQChar c = 0;
|
||||
// Process characters
|
||||
while ((c = *(str++)) != 0)
|
||||
{
|
||||
// Convert it and move to the next one
|
||||
b.At< SQChar >(n++) = tolower(c);
|
||||
}
|
||||
b.At(n++) = tolower(c);
|
||||
// End the resulted string
|
||||
b.At< SQChar >(n) = 0;
|
||||
b.At(n) = 0;
|
||||
// Return the string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
@ -252,12 +218,11 @@ CSStr StrToLowercase(CSStr str)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr StrToUppercase(CSStr str)
|
||||
{
|
||||
Uint32 size = 0;
|
||||
// See if we actually have something to search for
|
||||
if(!str || (size = strlen(str)) <= 0)
|
||||
{
|
||||
if(!str || *str == 0)
|
||||
return _SC("");
|
||||
}
|
||||
// Calculate the string length
|
||||
Uint32 size = strlen(str);
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(size);
|
||||
// Resulted string size
|
||||
@ -266,12 +231,10 @@ CSStr StrToUppercase(CSStr str)
|
||||
SQChar c = 0;
|
||||
// Process characters
|
||||
while ((c = *(str++)) != 0)
|
||||
{
|
||||
// Convert it and move to the next one
|
||||
b.At< SQChar >(n++) = toupper(c);
|
||||
}
|
||||
b.At(n++) = toupper(c);
|
||||
// End the resulted string
|
||||
b.At< SQChar >(n) = 0;
|
||||
b.At(n) = 0;
|
||||
// Return the string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
@ -280,18 +243,16 @@ CSStr StrToUppercase(CSStr str)
|
||||
static CSStr FromArray(Array & arr)
|
||||
{
|
||||
// Determine array size
|
||||
const Int32 length = (Int32)arr.Length();
|
||||
const Int32 length = static_cast< 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);
|
||||
}
|
||||
b.At(n) = static_cast< SQChar >(b.At< Int32 >(n));
|
||||
// Terminate the resulted string
|
||||
b.At< SQChar >(length) = 0;
|
||||
b.At(length) = 0;
|
||||
// Return the string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
@ -301,9 +262,14 @@ static SQInteger StdPrintF(HSQUIRRELVM vm)
|
||||
{
|
||||
CStr msg = NULL;
|
||||
SQInteger length = 0;
|
||||
if(SQ_FAILED(sqstd_format(vm, 2, &length, &msg)))
|
||||
return -1;
|
||||
// Attempt to run the specified format and save the result
|
||||
const SQRESULT res = sqstd_format(vm, 2, &length, &msg);
|
||||
// Validate the result for errors and propagate them to the VM
|
||||
if(SQ_FAILED(res))
|
||||
return res;
|
||||
// Send the resulted string to console as a user message
|
||||
LogUsr("%s", msg);
|
||||
// This function doesn't return anything
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user