mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-07-30 20:51:48 +02:00
Untested update to the new plugin API.
Various other changes to the plugin as well.
This commit is contained in:
@@ -7,231 +7,17 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#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("SqAES256");
|
||||
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 std::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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool AES256::Init(CSStr key)
|
||||
{
|
||||
// Clear current key, if any
|
||||
aes256_done(&m_Context);
|
||||
// Is the specified key empty?
|
||||
if (!key || *key == '\0')
|
||||
{
|
||||
return false; // Leave the context with an empty key
|
||||
}
|
||||
// Obtain the specified key size
|
||||
const Uint32 size = (std::strlen(key) * sizeof(SQChar));
|
||||
// See if the key size is accepted
|
||||
if (size > sizeof(m_Buffer))
|
||||
{
|
||||
STHROWF("The specified key is out of bounds: %u > %u", size, sizeof(m_Buffer));
|
||||
}
|
||||
// Initialize the key buffer to 0
|
||||
std::memset(m_Buffer, 0, sizeof(m_Buffer));
|
||||
// Copy the key into the key buffer
|
||||
std::memcpy(m_Buffer, key, size);
|
||||
// Initialize the context with the specified key
|
||||
aes256_init(&m_Context, m_Buffer);
|
||||
// This context was successfully initialized
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Forward the call to the actual implementation and store the string
|
||||
String str(BaseHash< T >::Algo(val.mPtr));
|
||||
// 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)
|
||||
);
|
||||
}
|
||||
extern void Register_Hash(HSQUIRRELVM vm);
|
||||
extern void Register_AES(HSQUIRRELVM vm);
|
||||
|
||||
// ================================================================================================
|
||||
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
|
||||
|
@@ -4,196 +4,10 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#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.
|
||||
*/
|
||||
bool 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
|
||||
|
||||
|
160
source/Library/Crypt/AES.cpp
Normal file
160
source/Library/Crypt/AES.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Crypt/AES.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Stack.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger AES256::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqAES256");
|
||||
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 std::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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool AES256::Init(CSStr key)
|
||||
{
|
||||
// Clear current key, if any
|
||||
aes256_done(&m_Context);
|
||||
// Is the specified key empty?
|
||||
if (!key || *key == '\0')
|
||||
{
|
||||
return false; // Leave the context with an empty key
|
||||
}
|
||||
// Obtain the specified key size
|
||||
const Uint32 size = (std::strlen(key) * sizeof(SQChar));
|
||||
// See if the key size is accepted
|
||||
if (size > sizeof(m_Buffer))
|
||||
{
|
||||
STHROWF("The specified key is out of bounds: %u > %u", size, sizeof(m_Buffer));
|
||||
}
|
||||
// Initialize the key buffer to 0
|
||||
std::memset(m_Buffer, 0, sizeof(m_Buffer));
|
||||
// Copy the key into the key buffer
|
||||
std::memcpy(m_Buffer, key, size);
|
||||
// Initialize the context with the specified key
|
||||
aes256_init(&m_Context, m_Buffer);
|
||||
// This context was successfully initialized
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_AES(HSQUIRRELVM vm)
|
||||
{
|
||||
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
|
110
source/Library/Crypt/AES.hpp
Normal file
110
source/Library/Crypt/AES.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef _LIBRARY_CRYPT_AES_HPP_
|
||||
#define _LIBRARY_CRYPT_AES_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <aes256.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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.
|
||||
*/
|
||||
bool 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_AES_HPP_
|
94
source/Library/Crypt/Hash.cpp
Normal file
94
source/Library/Crypt/Hash.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Crypt/Hash.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Stack.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <crc32.h>
|
||||
#include <keccak.h>
|
||||
#include <md5.h>
|
||||
#include <sha1.h>
|
||||
#include <sha256.h>
|
||||
#include <sha3.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Forward the call to the actual implementation and store the string
|
||||
String str(BaseHash< T >::Algo(val.mPtr));
|
||||
// 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_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
|
102
source/Library/Crypt/Hash.hpp
Normal file
102
source/Library/Crypt/Hash.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#ifndef _LIBRARY_CRYPT_HASH_HPP_
|
||||
#define _LIBRARY_CRYPT_HASH_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CRYPT_HASH_HPP_
|
109
source/Library/System.cpp
Normal file
109
source/Library/System.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/System.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Stack.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_SysEnv(HSQUIRRELVM vm);
|
||||
extern void Register_SysPath(HSQUIRRELVM vm);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger SqSysExec(HSQUIRRELVM vm)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.mRes))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Allocate a temp buffer to retrieve chunks from output
|
||||
char buffer[128];
|
||||
// Allocate a buffer which will contain the final output
|
||||
Buffer b(128);
|
||||
// Attempt to open the specified process
|
||||
FILE * pipe = popen(val.mPtr, "r");
|
||||
// The process return status
|
||||
Int32 status = -1;
|
||||
// Did we fail to open the process?
|
||||
if (!pipe)
|
||||
{
|
||||
return sq_throwerror(vm, ToStrF("Unable to open process [%s]", val.mPtr));
|
||||
}
|
||||
// Attempt to read process output
|
||||
try
|
||||
{
|
||||
while (!std::feof(pipe))
|
||||
{
|
||||
if (std::fgets(buffer, 128, pipe) != NULL)
|
||||
{
|
||||
b.AppendS(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Close the process
|
||||
status = pclose(pipe);
|
||||
// Now throw the error
|
||||
return sq_throwerror(vm, ToStrF("Unable read process output [%d]", status));
|
||||
}
|
||||
// Close the process and obtain the exit status
|
||||
status = pclose(pipe);
|
||||
// Remember the top of the stack
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Create a new table on the stack
|
||||
sq_newtable(vm);
|
||||
// Push the element name
|
||||
sq_pushstring(vm, _SC("Status"), -1);
|
||||
// Push the element value
|
||||
sq_pushinteger(vm, status);
|
||||
// Create the element in the table
|
||||
SQRESULT res = sq_rawset(vm, -3);
|
||||
// Check the result
|
||||
if (SQ_FAILED(res))
|
||||
{
|
||||
// Clean the stack
|
||||
sq_settop(vm, top);
|
||||
// Return the error
|
||||
return res;
|
||||
}
|
||||
// Push the element name
|
||||
sq_pushstring(vm, _SC("Output"), -1);
|
||||
// Push the element value
|
||||
sq_pushstring(vm, b.Get< SQChar >(), b.Position());
|
||||
// Create the element in the table
|
||||
res = sq_rawset(vm, -3);
|
||||
// Check the result
|
||||
if (SQ_FAILED(res))
|
||||
{
|
||||
// Clean the stack
|
||||
sq_settop(vm, top);
|
||||
// Return the error
|
||||
return res;
|
||||
}
|
||||
// Specify that we want to return the table we created
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_System(HSQUIRRELVM vm)
|
||||
{
|
||||
Register_SysEnv(vm);
|
||||
Register_SysPath(vm);
|
||||
|
||||
RootTable(vm).SquirrelFunc(_SC("SysExec"), &SqSysExec);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
14
source/Library/System.hpp
Normal file
14
source/Library/System.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LIBRARY_SYSTEM_HPP_
|
||||
#define _LIBRARY_SYSTEM_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_SYSTEM_HPP_
|
@@ -1,5 +1,5 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/SysEnv.hpp"
|
||||
#include "Library/System/Environment.hpp"
|
||||
#include "Base/Stack.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
@@ -1,6 +1,6 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/SysPath.hpp"
|
||||
#include "Library/SysEnv.hpp"
|
||||
#include "Library/System/Path.hpp"
|
||||
#include "Library/System/Environment.hpp"
|
||||
#include "Base/Stack.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
@@ -0,0 +1,16 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Utils.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_Buffer(HSQUIRRELVM vm);
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Utils(HSQUIRRELVM vm)
|
||||
{
|
||||
Register_Buffer(vm);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@@ -7,34 +7,7 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
class Blob
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Blob(const Blob &);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Blob & operator = (const Blob &);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Blob();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
~Blob();
|
||||
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
|
63
source/Library/Utils/BufferInterpreter.cpp
Normal file
63
source/Library/Utils/BufferInterpreter.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Utils/BufferInterpreter.hpp"
|
||||
#include "Library/Utils/BufferWrapper.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const SharedPtr< Buffer > & GetBufferBufferRef(const BufferWrapper & buffer)
|
||||
{
|
||||
return buffer.GetRef();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < typename T > static void RegisterInterpreter(Table & bns, CSStr cname, CSStr bname)
|
||||
{
|
||||
typedef BufferInterpreter< T > Interpreter;
|
||||
|
||||
bns.Bind(bname,
|
||||
Class< Interpreter >(bns.GetVM(), cname)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
// Properties
|
||||
.Prop(_SC("Front"), &Interpreter::GetFront, &Interpreter::SetFront)
|
||||
.Prop(_SC("Next"), &Interpreter::GetNext, &Interpreter::SetNext)
|
||||
.Prop(_SC("Back"), &Interpreter::GetBack, &Interpreter::SetBack)
|
||||
.Prop(_SC("Prev"), &Interpreter::GetPrev, &Interpreter::SetPrev)
|
||||
.Prop(_SC("Cursor"), &Interpreter::GetCursor, &Interpreter::SetCursor)
|
||||
.Prop(_SC("Before"), &Interpreter::GetBefore, &Interpreter::SetBefore)
|
||||
.Prop(_SC("After"), &Interpreter::GetAfter, &Interpreter::SetAfter)
|
||||
.Prop(_SC("Max"), &Interpreter::GetMax)
|
||||
.Prop(_SC("Size"), &Interpreter::GetSize)
|
||||
.Prop(_SC("Capacity"), &Interpreter::GetCapacity)
|
||||
.Prop(_SC("Position"), &Interpreter::GetPosition)
|
||||
.Prop(_SC("Remaining"), &Interpreter::GetRemaining)
|
||||
// Member Methods
|
||||
.Func(_SC("Use"), &Interpreter::UseBuffer)
|
||||
.Func(_SC("Get"), &Interpreter::Get)
|
||||
.Func(_SC("Set"), &Interpreter::Set)
|
||||
.Func(_SC("Advance"), &Interpreter::Advance)
|
||||
.Func(_SC("Retreat"), &Interpreter::Retreat)
|
||||
.Func(_SC("Push"), &Interpreter::Push)
|
||||
.Func(_SC("Grow"), &Interpreter::Grow)
|
||||
.Func(_SC("Adjust"), &Interpreter::Adjust)
|
||||
);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_BufferInterpreter(Table & bns)
|
||||
{
|
||||
RegisterInterpreter< Int8 >(bns, _SC("SqBufferInterpreterS8"), _SC("S8Interpreter"));
|
||||
RegisterInterpreter< Uint8 >(bns, _SC("SqBufferInterpreterU8"), _SC("U8Interpreter"));
|
||||
RegisterInterpreter< Int16 >(bns, _SC("SqBufferInterpreterS16"), _SC("S16Interpreter"));
|
||||
RegisterInterpreter< Uint16 >(bns, _SC("SqBufferInterpreterU16"), _SC("U16Interpreter"));
|
||||
RegisterInterpreter< Int32 >(bns, _SC("SqBufferInterpreterS32"), _SC("S32Interpreter"));
|
||||
RegisterInterpreter< Uint32 >(bns, _SC("SqBufferInterpreterU32"), _SC("U32Interpreter"));
|
||||
RegisterInterpreter< Int64 >(bns, _SC("SqBufferInterpreterS64"), _SC("S64Interpreter"));
|
||||
RegisterInterpreter< Uint64 >(bns, _SC("SqBufferInterpreterU64"), _SC("U64Interpreter"));
|
||||
RegisterInterpreter< Float32 >(bns, _SC("SqBufferInterpreterF32"), _SC("F32Interpreter"));
|
||||
RegisterInterpreter< Float64 >(bns, _SC("SqBufferInterpreterF64"), _SC("F64Interpreter"));
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
542
source/Library/Utils/BufferInterpreter.hpp
Normal file
542
source/Library/Utils/BufferInterpreter.hpp
Normal file
@@ -0,0 +1,542 @@
|
||||
#ifndef _LIBRARY_UTILS_BUFFERINTERPRETER_HPP_
|
||||
#define _LIBRARY_UTILS_BUFFERINTERPRETER_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BufferWrapper;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Used internally to obtain a reference to the memory buffer without including the wrapper header.
|
||||
*/
|
||||
const SharedPtr< Buffer > & GetBufferBufferRef(const BufferWrapper & buffer);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Utility class used to interpret a memory buffer in different ways.
|
||||
*/
|
||||
template < typename T > class BufferInterpreter
|
||||
{
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef SharedPtr< Buffer > SRef; // Strong reference type to the interpreted memory buffer.
|
||||
typedef WeakPtr< Buffer > WRef; // Weak reference type to the interpreted memory buffer.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
WRef m_Buffer; // The interpreted memory buffer.
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef T Value; // The type of value used to represent a byte.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value & Reference; // A reference to the stored value type.
|
||||
typedef const Value & ConstRef; // A const reference to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value * Pointer; // A pointer to the stored value type.
|
||||
typedef const Value * ConstPtr; // A const pointer to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::SzType SzType; // The type used to represent size in general.
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to obtain a strong reference to the memory buffer at all costs.
|
||||
*/
|
||||
SRef Validate() const
|
||||
{
|
||||
// Did the buffer that we reference expired?
|
||||
if (m_Buffer.Expired())
|
||||
{
|
||||
STHROWF("Invalid memory buffer reference");
|
||||
}
|
||||
// Obtain a strong reference to it
|
||||
return m_Buffer.Lock();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to obtain a strong reference to a valid memory buffer at all costs.
|
||||
*/
|
||||
SRef ValidateDeeper() const
|
||||
{
|
||||
// Did the buffer that we reference expired?
|
||||
if (m_Buffer.Expired())
|
||||
{
|
||||
STHROWF("Invalid memory buffer reference");
|
||||
}
|
||||
// Obtain a strong reference to it
|
||||
SRef ref = m_Buffer.Lock();
|
||||
// Validate the buffer itself
|
||||
if (!(*ref))
|
||||
{
|
||||
STHROWF("Invalid memory buffer");
|
||||
}
|
||||
// Return the reference
|
||||
return ref;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor. (null)
|
||||
*/
|
||||
BufferInterpreter()
|
||||
: m_Buffer()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
BufferInterpreter(const WRef & ref)
|
||||
: m_Buffer(ref)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
BufferInterpreter(const SRef & ref)
|
||||
: m_Buffer(ref)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
BufferInterpreter(const BufferInterpreter & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
BufferInterpreter(BufferInterpreter && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~BufferInterpreter() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
BufferInterpreter & operator = (const BufferInterpreter & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
BufferInterpreter & operator = (BufferInterpreter && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a reference to the managed memory buffer.
|
||||
*/
|
||||
const WRef & GetRef() const
|
||||
{
|
||||
return m_Buffer;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assign a different memory buffer to interpret from.
|
||||
*/
|
||||
void UseBuffer(const BufferWrapper & buffer)
|
||||
{
|
||||
m_Buffer = GetBufferBufferRef(buffer);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a certain element type at the specified position.
|
||||
*/
|
||||
T Get(SzType n) const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (n >= b->Size< T >())
|
||||
{
|
||||
STHROWF("Index (%u) is out of bounds (%u)", n, b->Size< T >());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->At< T >(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify a certain element type at the specified position.
|
||||
*/
|
||||
void Set(SzType n, T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (n >= b->Size< T >())
|
||||
{
|
||||
STHROWF("Index (%u) is out of bounds (%u)", n, b->Size< T >());
|
||||
}
|
||||
// Return the requested element
|
||||
b->At< T >(n) = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the front of the buffer.
|
||||
*/
|
||||
T GetFront() const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < sizeof(T))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->Front< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the front of the buffer.
|
||||
*/
|
||||
void SetFront(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < sizeof(T))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
b->Front< T >() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element after the first element in the buffer.
|
||||
*/
|
||||
T GetNext() const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < (sizeof(T) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->Next< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element after the first element in the buffer.
|
||||
*/
|
||||
void SetNext(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < (sizeof(T) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
b->Next< T >() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the back of the buffer.
|
||||
*/
|
||||
T GetBack() const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < sizeof(T))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->Back< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the back of the buffer.
|
||||
*/
|
||||
void SetBack(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < sizeof(T))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
b->Back< T >() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element before the last element in the buffer.
|
||||
*/
|
||||
T GetPrev() const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < (sizeof(T) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->Prev< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element before the last element in the buffer.
|
||||
*/
|
||||
void SetPrev(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < (sizeof(T) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
b->Prev< T >() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to the specified number of elements ahead.
|
||||
*/
|
||||
void Advance(SzType n)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Perform the requested operation
|
||||
b->Advance< T >(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to the specified number of elements behind.
|
||||
*/
|
||||
void Retreat(SzType n)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Perform the requested operation
|
||||
b->Retreat< T >(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to a fixed position within the buffer.
|
||||
*/
|
||||
void Move(SzType n)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Perform the requested operation
|
||||
b->Move< T >(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Append a value to the current cursor location and advance the cursor.
|
||||
*/
|
||||
void Push(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Perform the requested operation
|
||||
b->Push< T >(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the cursor position.
|
||||
*/
|
||||
T GetCursor() const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Position< T >() >= b->Size< T >())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), b->Position(), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->Cursor< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the cursor position.
|
||||
*/
|
||||
void SetCursor(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Position< T >() >= b->Size< T >())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), b->Position(), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
b->Cursor< T >() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element before the cursor position.
|
||||
*/
|
||||
T GetBefore() const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Position() < sizeof(T))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->Before< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element before the cursor position.
|
||||
*/
|
||||
void SetBefore(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Position() < sizeof(T))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(T), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
b->Before< T >() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element after the cursor position.
|
||||
*/
|
||||
T GetAfter() const
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < sizeof(T) || (b->Position() + sizeof(T)) > (b->Capacity() - sizeof(T)))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), b->Position(), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return b->After< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element after the cursor position.
|
||||
*/
|
||||
void SetAfter(T v)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Are we out of the memory buffer range?
|
||||
if (b->Capacity() < sizeof(T) || (b->Position() + sizeof(T)) > (b->Capacity() - sizeof(T)))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(T), b->Position(), b->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
b->After< T >() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve maximum elements it can hold for a certain type.
|
||||
*/
|
||||
SzType GetMax() const
|
||||
{
|
||||
return Buffer::Max< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current buffer capacity in element count.
|
||||
*/
|
||||
SzType GetSize() const
|
||||
{
|
||||
return Validate()->template Size< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current buffer capacity in byte count.
|
||||
*/
|
||||
SzType GetCapacity() const
|
||||
{
|
||||
return Validate()->Capacity();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current position of the cursor in the buffer.
|
||||
*/
|
||||
SzType GetPosition() const
|
||||
{
|
||||
return Validate()->template Position< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the amount of unused buffer after the edit cursor.
|
||||
*/
|
||||
SzType GetRemaining() const
|
||||
{
|
||||
return Validate()->template Remaining< T >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grow the size of the internal buffer by the specified amount of bytes.
|
||||
*/
|
||||
void Grow(SzType n)
|
||||
{
|
||||
return Validate()->Grow(n * sizeof(T));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes sure there is enough capacity to hold the specified element count.
|
||||
*/
|
||||
void Adjust(SzType n)
|
||||
{
|
||||
// Acquire a reference to the memory buffer
|
||||
SRef b(Validate());
|
||||
// Attempt to perform the requested operation
|
||||
try
|
||||
{
|
||||
Buffer bkp(b->Adjust(n * sizeof(T)));
|
||||
// Copy the data into the new buffer
|
||||
b->Write(0, bkp.Data(), bkp.Capacity());
|
||||
b->Move(bkp.Position());
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
STHROWF("%s", e.what()); // Re-package
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_UTILS_BUFFERINTERPRETER_HPP_
|
357
source/Library/Utils/BufferWrapper.cpp
Normal file
357
source/Library/Utils/BufferWrapper.cpp
Normal file
@@ -0,0 +1,357 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Utils/BufferWrapper.hpp"
|
||||
#include "Library/Utils/BufferInterpreter.hpp"
|
||||
#include "Base/Stack.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_BufferInterpreter(Table & bns);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object BufferWrapper::Create(SzType n)
|
||||
{
|
||||
// Attempt to create the requested buffer
|
||||
try
|
||||
{
|
||||
return MakeObject(BufferWrapper(SRef(new Buffer(n))));
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
throw e; // Re-throw
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
STHROWF("%s", e.what()); // Re-package
|
||||
}
|
||||
// Shouldn't really reach this point
|
||||
return NullObject();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BufferWrapper::WriteByte(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Uint8 >(ConvTo< Uint8 >::From(val));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BufferWrapper::WriteShort(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Int16 >(ConvTo< Int16 >::From(val));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BufferWrapper::WriteInt(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Int32 >(ConvTo< Int32 >::From(val));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BufferWrapper::WriteFloat(SQFloat val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Float32 >(ConvTo< Float32 >::From(val));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BufferWrapper::WriteString(CSStr val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Is the given string value even valid?
|
||||
if (!val)
|
||||
{
|
||||
STHROWF("Invalid string argument: null");
|
||||
}
|
||||
// Calculate the string length
|
||||
Uint16 length = ConvTo< Uint16 >::From(std::strlen(val));
|
||||
// Change the size endianness to big endian
|
||||
Uint16 size = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8);
|
||||
// Write the size and then the string contents
|
||||
m_Buffer->Push< Uint16 >(size);
|
||||
m_Buffer->AppendS(val, length);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BufferWrapper::WriteRawString(CSStr val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Is the given string value even valid?
|
||||
if (!val)
|
||||
{
|
||||
STHROWF("Invalid string argument: null");
|
||||
}
|
||||
// Calculate the string length
|
||||
Uint16 length = ConvTo< Uint16 >::From(std::strlen(val));
|
||||
// Write the the string contents
|
||||
m_Buffer->AppendS(val, length);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger BufferWrapper::ReadByte()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position< Int8 >() >= m_Buffer->Size< Int8 >())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Int8), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Read one element from the buffer
|
||||
const Int8 value = m_Buffer->Cursor< Int8 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Int8 >(1);
|
||||
// Return the requested information
|
||||
return value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger BufferWrapper::ReadShort()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position< Int16 >() >= m_Buffer->Size< Int16 >())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Int16), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Read one element from the buffer
|
||||
const Int16 value = m_Buffer->Cursor< Int16 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Int16 >(1);
|
||||
// Return the requested information
|
||||
return value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger BufferWrapper::ReadInt()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position< Int32 >() >= m_Buffer->Size< Int32 >())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Int32), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Read one element from the buffer
|
||||
const Int32 value = m_Buffer->Cursor< Int32 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Int32 >(1);
|
||||
// Return the requested information
|
||||
return value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQFloat BufferWrapper::ReadFloat()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position< Float32 >() >= m_Buffer->Size< Float32 >())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Float32), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Read one element from the buffer
|
||||
const Float32 value = m_Buffer->Cursor< Float32 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Float32 >(1);
|
||||
// Return the requested information
|
||||
return value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object BufferWrapper::ReadString()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position< Int16 >() >= m_Buffer->Size< Int16 >())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Int16), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Read one element from the buffer
|
||||
Int16 length = m_Buffer->Cursor< Int16 >();
|
||||
// Convert the length to little endian
|
||||
length = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8);
|
||||
// Validate the obtained length
|
||||
if ((m_Buffer->Position() + sizeof(Int16) + length) >= m_Buffer->Size())
|
||||
{
|
||||
STHROWF("String size (%u starting at %u) is out of bounds (%u)",
|
||||
length, m_Buffer->Position() + sizeof(Int16), m_Buffer->Capacity());
|
||||
}
|
||||
// Advance the buffer to the actual string
|
||||
m_Buffer->Advance< Int16 >(1);
|
||||
// Remember the current stack size
|
||||
const StackGuard sg;
|
||||
// Attempt to create the string as an object
|
||||
sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), length);
|
||||
// Advance the cursor after the string
|
||||
m_Buffer->Advance(length);
|
||||
// Return the resulted object
|
||||
return Var< Object >(DefaultVM::Get(), -1).value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object BufferWrapper::ReadRawString(Uint32 len)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Validate the obtained length
|
||||
if ((m_Buffer->Position() + len) >= m_Buffer->Size())
|
||||
{
|
||||
STHROWF("String size (%u starting at %u) is out of bounds (%u)",
|
||||
len, m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Remember the current stack size
|
||||
const StackGuard sg;
|
||||
// Attempt to create the string as an object
|
||||
sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), len);
|
||||
// Advance the cursor after the string
|
||||
m_Buffer->Advance(len);
|
||||
// Return the resulted object
|
||||
return Var< Object >(DefaultVM::Get(), -1).value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Int8 > BufferWrapper::GetInt8Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Int8 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Uint8 > BufferWrapper::GetUint8Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Uint8 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Int16 > BufferWrapper::GetInt16Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Int16 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Uint16 > BufferWrapper::GetUint16Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Uint16 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Int32 > BufferWrapper::GetInt32Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Int32 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Uint32 > BufferWrapper::GetUint32Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Uint32 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Int64 > BufferWrapper::GetInt64Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Int64 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Uint64 > BufferWrapper::GetUint64Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Uint64 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Float32 > BufferWrapper::GetFloat32Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Float32 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BufferInterpreter< Float64 > BufferWrapper::GetFloat64Interpreter() const
|
||||
{
|
||||
return BufferInterpreter< Float64 >(m_Buffer);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Buffer(HSQUIRRELVM vm)
|
||||
{
|
||||
Table bns(vm);
|
||||
|
||||
bns.Bind(_SC("Wrapper"),
|
||||
Class< BufferWrapper >(vm, _SC("SqBufferWrapper"))
|
||||
// Constructors
|
||||
.Ctor()
|
||||
// Properties
|
||||
.Prop(_SC("Front"), &BufferWrapper::GetFront, &BufferWrapper::SetFront)
|
||||
.Prop(_SC("Next"), &BufferWrapper::GetNext, &BufferWrapper::SetNext)
|
||||
.Prop(_SC("Back"), &BufferWrapper::GetBack, &BufferWrapper::SetBack)
|
||||
.Prop(_SC("Prev"), &BufferWrapper::GetPrev, &BufferWrapper::SetPrev)
|
||||
.Prop(_SC("Cursor"), &BufferWrapper::GetCursor, &BufferWrapper::SetCursor)
|
||||
.Prop(_SC("Before"), &BufferWrapper::GetBefore, &BufferWrapper::SetBefore)
|
||||
.Prop(_SC("After"), &BufferWrapper::GetAfter, &BufferWrapper::SetAfter)
|
||||
.Prop(_SC("Max"), &BufferWrapper::GetMax)
|
||||
.Prop(_SC("Size"), &BufferWrapper::GetSize)
|
||||
.Prop(_SC("Capacity"), &BufferWrapper::GetCapacity)
|
||||
.Prop(_SC("Position"), &BufferWrapper::GetPosition)
|
||||
.Prop(_SC("Remaining"), &BufferWrapper::GetRemaining)
|
||||
.Prop(_SC("Int8"), &BufferWrapper::GetInt8Interpreter)
|
||||
.Prop(_SC("Uint8"), &BufferWrapper::GetUint8Interpreter)
|
||||
.Prop(_SC("Int16"), &BufferWrapper::GetInt16Interpreter)
|
||||
.Prop(_SC("Uint16"), &BufferWrapper::GetUint16Interpreter)
|
||||
.Prop(_SC("Int32"), &BufferWrapper::GetInt32Interpreter)
|
||||
.Prop(_SC("Uint32"), &BufferWrapper::GetUint32Interpreter)
|
||||
.Prop(_SC("Int64"), &BufferWrapper::GetInt64Interpreter)
|
||||
.Prop(_SC("Uint64"), &BufferWrapper::GetUint64Interpreter)
|
||||
.Prop(_SC("Float32"), &BufferWrapper::GetFloat32Interpreter)
|
||||
.Prop(_SC("Float64"), &BufferWrapper::GetFloat64Interpreter)
|
||||
// Member Methods
|
||||
.Func(_SC("Get"), &BufferWrapper::Get)
|
||||
.Func(_SC("Set"), &BufferWrapper::Set)
|
||||
.Func(_SC("Advance"), &BufferWrapper::Advance)
|
||||
.Func(_SC("Retreat"), &BufferWrapper::Retreat)
|
||||
.Func(_SC("Push"), &BufferWrapper::Push)
|
||||
.Func(_SC("Grow"), &BufferWrapper::Grow)
|
||||
.Func(_SC("Adjust"), &BufferWrapper::Adjust)
|
||||
.Func(_SC("WriteByte"), &BufferWrapper::WriteByte)
|
||||
.Func(_SC("WriteShort"), &BufferWrapper::WriteShort)
|
||||
.Func(_SC("WriteInt"), &BufferWrapper::WriteInt)
|
||||
.Func(_SC("WriteFloat"), &BufferWrapper::WriteFloat)
|
||||
.Func(_SC("WriteString"), &BufferWrapper::WriteString)
|
||||
.Func(_SC("WriteRawString"), &BufferWrapper::WriteRawString)
|
||||
.Func(_SC("ReadByte"), &BufferWrapper::ReadByte)
|
||||
.Func(_SC("ReadShort"), &BufferWrapper::ReadShort)
|
||||
.Func(_SC("ReadInt"), &BufferWrapper::ReadInt)
|
||||
.Func(_SC("ReadFloat"), &BufferWrapper::ReadFloat)
|
||||
.Func(_SC("ReadString"), &BufferWrapper::ReadString)
|
||||
.Func(_SC("ReadRawString"), &BufferWrapper::ReadRawString)
|
||||
);
|
||||
|
||||
Register_BufferInterpreter(bns);
|
||||
|
||||
bns.Func(_SC("Create"), &BufferWrapper::Create);
|
||||
|
||||
RootTable(vm).Bind(_SC("SqBuffer"), bns);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
644
source/Library/Utils/BufferWrapper.hpp
Normal file
644
source/Library/Utils/BufferWrapper.hpp
Normal file
@@ -0,0 +1,644 @@
|
||||
#ifndef _LIBRARY_UTILS_BUFFERWRAPPER_HPP_
|
||||
#define _LIBRARY_UTILS_BUFFERWRAPPER_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < typename T > class BufferInterpreter;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Squirrel wrapper for the shared buffer class.
|
||||
*/
|
||||
class BufferWrapper
|
||||
{
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef SharedPtr< Buffer > SRef; // Strong reference type to the managed memory buffer.
|
||||
typedef WeakPtr< Buffer > WRef; // Weak reference type to the managed memory buffer.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SRef m_Buffer; // The managed memory buffer.
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::Value Value; // The type of value used to represent a byte.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value & Reference; // A reference to the stored value type.
|
||||
typedef const Value & ConstRef; // A const reference to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value * Pointer; // A pointer to the stored value type.
|
||||
typedef const Value * ConstPtr; // A const pointer to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::SzType SzType; // The type used to represent size in general.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create a memory buffer with the requested size.
|
||||
*/
|
||||
static Object Create(SzType n);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
BufferWrapper(const SRef & ref)
|
||||
: m_Buffer(ref)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Buffer constructor.
|
||||
*/
|
||||
BufferWrapper(Buffer && b)
|
||||
: m_Buffer(new Buffer(std::move(b)))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
BufferWrapper(const BufferWrapper & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
BufferWrapper(BufferWrapper && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~BufferWrapper() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
BufferWrapper & operator = (const BufferWrapper & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
BufferWrapper & operator = (BufferWrapper && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a reference to the managed memory buffer.
|
||||
*/
|
||||
const SRef & GetRef() const
|
||||
{
|
||||
return m_Buffer;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the managed memory buffer reference.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
// Do we even point to a valid buffer?
|
||||
if (!m_Buffer)
|
||||
{
|
||||
STHROWF("Invalid memory buffer reference");
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the managed memory buffer reference and the buffer itself.
|
||||
*/
|
||||
void ValidateDeeper() const
|
||||
{
|
||||
// Do we even point to a valid buffer?
|
||||
if (!m_Buffer)
|
||||
{
|
||||
STHROWF("Invalid memory buffer reference");
|
||||
}
|
||||
// Validate the buffer itself
|
||||
else if (!(*m_Buffer))
|
||||
{
|
||||
STHROWF("Invalid memory buffer");
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a certain element type at the specified position.
|
||||
*/
|
||||
Value Get(SzType n) const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (n >= m_Buffer->Size())
|
||||
{
|
||||
STHROWF("Index (%u) is out of bounds (%u)", n, m_Buffer->Size());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->At(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify a certain element type at the specified position.
|
||||
*/
|
||||
void Set(SzType n, Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (n >= m_Buffer->Size())
|
||||
{
|
||||
STHROWF("Index (%u) is out of bounds (%u)", n, m_Buffer->Size());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->At(n) = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the front of the buffer.
|
||||
*/
|
||||
Value GetFront() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < sizeof(Value))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->Front();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the front of the buffer.
|
||||
*/
|
||||
void SetFront(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < sizeof(Value))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->Front() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element after the first element in the buffer.
|
||||
*/
|
||||
Value GetNext() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < (sizeof(Value) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->Next();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element after the first element in the buffer.
|
||||
*/
|
||||
void SetNext(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < (sizeof(Value) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->Next() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the back of the buffer.
|
||||
*/
|
||||
Value GetBack() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < sizeof(Value))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->Back();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the back of the buffer.
|
||||
*/
|
||||
void SetBack(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < sizeof(Value))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->Back() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element before the last element in the buffer.
|
||||
*/
|
||||
Value GetPrev() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < (sizeof(Value) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->Prev();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element before the last element in the buffer.
|
||||
*/
|
||||
void SetPrev(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < (sizeof(Value) * 2))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->Prev() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to the specified number of elements ahead.
|
||||
*/
|
||||
void Advance(SzType n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Advance(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to the specified number of elements behind.
|
||||
*/
|
||||
void Retreat(SzType n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Retreat(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to a fixed position within the buffer.
|
||||
*/
|
||||
void Move(SzType n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Move(n);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Append a value to the current cursor location and advance the cursor.
|
||||
*/
|
||||
void Push(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the cursor position.
|
||||
*/
|
||||
Value GetCursor() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position() >= m_Buffer->Size())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->Cursor();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the cursor position.
|
||||
*/
|
||||
void SetCursor(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position() >= m_Buffer->Size())
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->Cursor() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element before the cursor position.
|
||||
*/
|
||||
Value GetBefore() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position() < sizeof(Value))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->Before();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element before the cursor position.
|
||||
*/
|
||||
void SetBefore(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Position() < sizeof(Value))
|
||||
{
|
||||
STHROWF("Value size (%u starting at 0) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->Before() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element after the cursor position.
|
||||
*/
|
||||
Value GetAfter() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < sizeof(Value) ||
|
||||
(m_Buffer->Position() + sizeof(Value)) > (m_Buffer->Capacity() - sizeof(Value)))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
return m_Buffer->After();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element after the cursor position.
|
||||
*/
|
||||
void SetAfter(Value v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Are we out of the memory buffer range?
|
||||
if (m_Buffer->Capacity() < sizeof(Value) ||
|
||||
(m_Buffer->Position() + sizeof(Value)) > (m_Buffer->Capacity() - sizeof(Value)))
|
||||
{
|
||||
STHROWF("Value size (%u starting at %u) is out of bounds (%u)",
|
||||
sizeof(Value), m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Return the requested element
|
||||
m_Buffer->After() = v;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve maximum elements it can hold for a certain type.
|
||||
*/
|
||||
SzType GetMax() const
|
||||
{
|
||||
return Buffer::Max();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current buffer capacity in element count.
|
||||
*/
|
||||
SzType GetSize() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->Size();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current buffer capacity in byte count.
|
||||
*/
|
||||
SzType GetCapacity() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->Capacity();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current position of the cursor in the buffer.
|
||||
*/
|
||||
SzType GetPosition() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->Position();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the amount of unused buffer after the edit cursor.
|
||||
*/
|
||||
SzType GetRemaining() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->Remaining();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grow the size of the internal buffer by the specified amount of bytes.
|
||||
*/
|
||||
void Grow(SzType n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return m_Buffer->Grow(n * sizeof(Value));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes sure there is enough capacity to hold the specified element count.
|
||||
*/
|
||||
void Adjust(SzType n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Attempt to perform the requested operation
|
||||
try
|
||||
{
|
||||
Buffer bkp(m_Buffer->Adjust(n * sizeof(Value)));
|
||||
// Copy the data into the new buffer
|
||||
m_Buffer->Write(0, bkp.Data(), bkp.Capacity());
|
||||
m_Buffer->Move(bkp.Position());
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
STHROWF("%s", e.what()); // Re-package
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a 8 bit byte to the stream buffer.
|
||||
*/
|
||||
void WriteByte(SQInteger val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a 16 bit short to the stream buffer.
|
||||
*/
|
||||
void WriteShort(SQInteger val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a 32 bit integer to the stream buffer.
|
||||
*/
|
||||
void WriteInt(SQInteger val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a 32 bit float to the stream buffer.
|
||||
*/
|
||||
void WriteFloat(SQFloat val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a string to the stream buffer.
|
||||
*/
|
||||
void WriteString(CSStr val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a raw string to the stream buffer.
|
||||
*/
|
||||
void WriteRawString(CSStr val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a 8 bit byte to the stream buffer.
|
||||
*/
|
||||
SQInteger ReadByte();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a 16 bit short to the stream buffer.
|
||||
*/
|
||||
SQInteger ReadShort();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a 32 bit integer to the stream buffer.
|
||||
*/
|
||||
SQInteger ReadInt();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a 32 bit float to the stream buffer.
|
||||
*/
|
||||
SQFloat ReadFloat();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a string to the stream buffer.
|
||||
*/
|
||||
Object ReadString();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a raw string to the stream buffer.
|
||||
*/
|
||||
Object ReadRawString(Uint32 len);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 8 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Int8 > GetInt8Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 8 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Uint8 > GetUint8Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 16 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Int16 > GetInt16Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 16 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Uint16 > GetUint16Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 32 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Int32 > GetInt32Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 32 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Uint32 > GetUint32Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a signed 64 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Int64 > GetInt64Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve an unsigned 64 bit interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Uint64 > GetUint64Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a 32 bit floating point interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Float32 > GetFloat32Interpreter() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a 64 bit floating point interpreter to this buffer.
|
||||
*/
|
||||
BufferInterpreter< Float64 > GetFloat64Interpreter() const;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_UTILS_BUFFERWRAPPER_HPP_
|
Reference in New Issue
Block a user