mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-09 01:07:16 +01:00
357 lines
14 KiB
C++
357 lines
14 KiB
C++
// ------------------------------------------------------------------------------------------------
|
|
#include "Library/Utils/BufferWrapper.hpp"
|
|
#include "Library/Utils/BufferInterpreter.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
|