mirror of
				https://github.com/VCMP-SqMod/SqMod.git
				synced 2025-11-04 08:17:19 +01:00 
			
		
		
		
	Implemented a helper class to retrieve a string value from the stack as a string or generate a formatted string if necessary.
This commit is contained in:
		@@ -24,6 +24,9 @@
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
#include <sqstdstring.h>
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
namespace SqMod {
 | 
			
		||||
 | 
			
		||||
@@ -37,7 +40,7 @@ PluginCallbacks*    _Clbk = NULL;
 | 
			
		||||
PluginInfo*         _Info = NULL;
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------------------------
 | 
			
		||||
 * Common buffer to reduce memory allocations. To be immediately copied uppon return!
 | 
			
		||||
 * Common buffer to reduce memory allocations. To be immediately copied upon return!
 | 
			
		||||
*/
 | 
			
		||||
static SQChar g_Buffer[4096];
 | 
			
		||||
 | 
			
		||||
@@ -93,6 +96,96 @@ Object BufferToStrObj(const Buffer & b, Uint32 size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --------------------------------------------------------------------------------------------
 | 
			
		||||
StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt)
 | 
			
		||||
    : mPtr(nullptr)
 | 
			
		||||
    , mLen(-1)
 | 
			
		||||
    , mRes(SQ_OK)
 | 
			
		||||
    , mObj()
 | 
			
		||||
    , mVM(vm)
 | 
			
		||||
{
 | 
			
		||||
    const Int32 top = sq_gettop(vm);
 | 
			
		||||
    // Reset the converted value object
 | 
			
		||||
    sq_resetobject(&mObj);
 | 
			
		||||
    // Was the string or value specified?
 | 
			
		||||
    if (top <= (idx - 1))
 | 
			
		||||
    {
 | 
			
		||||
        mRes = sq_throwerror(vm, "Missing string or value");
 | 
			
		||||
    }
 | 
			
		||||
    // Do we have enough values to call the format function and are we allowed to?
 | 
			
		||||
    else if (top > idx && fmt)
 | 
			
		||||
    {
 | 
			
		||||
        // Pointer to the generated string
 | 
			
		||||
        SStr str = nullptr;
 | 
			
		||||
        // Attempt to generate the specified string format
 | 
			
		||||
        mRes = sqstd_format(vm, idx, &mLen, &str);
 | 
			
		||||
        // Did the format succeeded but ended up with a null string pointer?
 | 
			
		||||
        if (SQ_SUCCEEDED(mRes) && !str)
 | 
			
		||||
        {
 | 
			
		||||
            mRes = sq_throwerror(vm, "Unable to generate the string");
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mPtr = const_cast< CSStr >(str);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // Is the value on the stack an actual string?
 | 
			
		||||
    else if (sq_gettype(vm, idx) == OT_STRING)
 | 
			
		||||
    {
 | 
			
		||||
        // Obtain a reference to the string object
 | 
			
		||||
        mRes = sq_getstackobj(vm, idx, &mObj);
 | 
			
		||||
        // Could we retrieve the object from the stack?
 | 
			
		||||
        if (SQ_SUCCEEDED(mRes))
 | 
			
		||||
        {
 | 
			
		||||
            // Keep a strong reference to the object
 | 
			
		||||
            sq_addref(vm, &mObj);
 | 
			
		||||
            // Attempt to retrieve the string value from the stack
 | 
			
		||||
            mRes = sq_getstring(vm, idx, &mPtr);
 | 
			
		||||
        }
 | 
			
		||||
        // Did the retrieval succeeded but ended up with a null string pointer?
 | 
			
		||||
        if (SQ_SUCCEEDED(mRes) && !mPtr)
 | 
			
		||||
        {
 | 
			
		||||
            mRes = sq_throwerror(vm, "Unable to retrieve the string");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // We have to try and convert it to string
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Attempt to convert the value from the stack to a string
 | 
			
		||||
        mRes = sq_tostring(vm, idx);
 | 
			
		||||
        // Could we convert the specified value to string?
 | 
			
		||||
        if (SQ_SUCCEEDED(mRes))
 | 
			
		||||
        {
 | 
			
		||||
            // Obtain a reference to the resulted object
 | 
			
		||||
            mRes = sq_getstackobj(vm, -1, &mObj);
 | 
			
		||||
            // Could we retrieve the object from the stack?
 | 
			
		||||
            if (SQ_SUCCEEDED(mRes))
 | 
			
		||||
            {
 | 
			
		||||
                // Keep a strong reference to the object
 | 
			
		||||
                sq_addref(vm, &mObj);
 | 
			
		||||
                // Attempt to obtain the string pointer
 | 
			
		||||
                mRes = sq_getstring(vm, -1, &mPtr);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Pop a value from the stack regardless of the result
 | 
			
		||||
        sq_pop(vm, 1);
 | 
			
		||||
        // Did the retrieval succeeded but ended up with a null string pointer?
 | 
			
		||||
        if (SQ_SUCCEEDED(mRes) && !mPtr)
 | 
			
		||||
        {
 | 
			
		||||
            mRes = sq_throwerror(vm, "Unable to retrieve the value");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
StackStrF::~StackStrF()
 | 
			
		||||
{
 | 
			
		||||
    if (mVM && !sq_isnull(mObj))
 | 
			
		||||
    {
 | 
			
		||||
        sq_release(mVM, &mObj);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
bool SToB(CSStr str)
 | 
			
		||||
{
 | 
			
		||||
    return (strcmp(str, "true") == 0 || strcmp(str, "yes") == 0 ||
 | 
			
		||||
 
 | 
			
		||||
@@ -82,6 +82,49 @@ private:
 | 
			
		||||
    HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------------------------
 | 
			
		||||
 * Helper structure for retrieving a value from the stack as a string or a formatted string.
 | 
			
		||||
*/
 | 
			
		||||
struct StackStrF
 | 
			
		||||
{
 | 
			
		||||
    // --------------------------------------------------------------------------------------------
 | 
			
		||||
    CSStr       mPtr; // Pointer to the C string that was retrieved.
 | 
			
		||||
    SQInteger   mLen; // The string length if it could be retrieved.
 | 
			
		||||
    SQRESULT    mRes; // The result of the retrieval attempts.
 | 
			
		||||
    HSQOBJECT   mObj; // Strong reference to the string object.
 | 
			
		||||
    HSQUIRRELVM mVM; // The associated virtual machine.
 | 
			
		||||
 | 
			
		||||
    /* --------------------------------------------------------------------------------------------
 | 
			
		||||
     * Base constructor.
 | 
			
		||||
    */
 | 
			
		||||
    StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true);
 | 
			
		||||
 | 
			
		||||
    /* --------------------------------------------------------------------------------------------
 | 
			
		||||
     * Copy constructor. (disabled)
 | 
			
		||||
    */
 | 
			
		||||
    StackStrF(const StackStrF & o) = delete;
 | 
			
		||||
 | 
			
		||||
    /* --------------------------------------------------------------------------------------------
 | 
			
		||||
     * Copy constructor. (disabled)
 | 
			
		||||
    */
 | 
			
		||||
    StackStrF(StackStrF && o) = delete;
 | 
			
		||||
 | 
			
		||||
    /* --------------------------------------------------------------------------------------------
 | 
			
		||||
     * Destructor.
 | 
			
		||||
    */
 | 
			
		||||
    ~StackStrF();
 | 
			
		||||
 | 
			
		||||
    /* --------------------------------------------------------------------------------------------
 | 
			
		||||
     * Copy constructor. (disabled)
 | 
			
		||||
    */
 | 
			
		||||
    StackStrF & operator = (const StackStrF & o) = delete;
 | 
			
		||||
 | 
			
		||||
    /* --------------------------------------------------------------------------------------------
 | 
			
		||||
     * Copy constructor. (disabled)
 | 
			
		||||
    */
 | 
			
		||||
    StackStrF & operator = (StackStrF && o) = delete;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------------------------
 | 
			
		||||
 * Perform an equality comparison between two values taking into account floating point issues.
 | 
			
		||||
*/
 | 
			
		||||
@@ -241,14 +284,12 @@ Object BufferToStrObj(const Buffer & b, Uint32 size);
 | 
			
		||||
*/
 | 
			
		||||
template < typename T > Object MakeObject(const T & v)
 | 
			
		||||
{
 | 
			
		||||
    // Remember the current stack size
 | 
			
		||||
    const StackGuard sg;
 | 
			
		||||
    // Transform the specified value into a script object
 | 
			
		||||
    PushVar< T >(DefaultVM::Get(), v);
 | 
			
		||||
    // Get the object from the stack to obtain a strong reference to it
 | 
			
		||||
    Var< Object > var(DefaultVM::Get(), -1);
 | 
			
		||||
    // Now it's safe to pop the object from the stack
 | 
			
		||||
    sq_pop(DefaultVM::Get(), 1);
 | 
			
		||||
    // Return the resulted script object
 | 
			
		||||
    return var.value;
 | 
			
		||||
    // Get the object from the stack and return it
 | 
			
		||||
    return Var< Object >(DefaultVM::Get(), -1).value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------------------------
 | 
			
		||||
@@ -256,14 +297,12 @@ template < typename T > Object MakeObject(const T & v)
 | 
			
		||||
*/
 | 
			
		||||
template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v)
 | 
			
		||||
{
 | 
			
		||||
    // Remember the current stack size
 | 
			
		||||
    const StackGuard sg;
 | 
			
		||||
    // Transform the specified value into a script object
 | 
			
		||||
    PushVar< T >(vm, v);
 | 
			
		||||
    // Get the object from the stack to obtain a strong reference to it
 | 
			
		||||
    Var< Object > var(vm, -1);
 | 
			
		||||
    // Now it's safe to pop the object from the stack
 | 
			
		||||
    sq_pop(vm, 1);
 | 
			
		||||
    // Return the resulted script object
 | 
			
		||||
    return var.value;
 | 
			
		||||
    // Get the object from the stack and return it
 | 
			
		||||
    return Var< Object >(vm, -1).value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user