1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +01:00

Migrated the INI module to C++ exceptions as well.

Also enabled the latest C++ revision in the project.
Various other fixes and improvements.
This commit is contained in:
Sandu Liviu Catalin 2016-02-28 16:16:08 +02:00
parent 331b03028c
commit 8333cc83ce
8 changed files with 268 additions and 108 deletions

View File

@ -370,7 +370,10 @@
<Compiler>
<Add option="-Wextra" />
<Add option="-Wall" />
<Add option="-std=c++14" />
<Add option="-DSQMOD_PLUGIN_API" />
<Add option="-DSCRAT_USE_EXCEPTIONS" />
<Add option="-DSCRAT_USE_CXX11_OPTIMIZATIONS" />
<Add directory="../modules/ini" />
<Add directory="../shared" />
<Add directory="../include" />

View File

@ -2,9 +2,81 @@
#include "Common.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <stdarg.h>
// ------------------------------------------------------------------------------------------------
#include <sqrat.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations.
// ------------------------------------------------------------------------------------------------
SStr GetTempBuff()
{
return g_Buffer;
}
// ------------------------------------------------------------------------------------------------
Uint32 GetTempBuffSize()
{
return sizeof(g_Buffer);
}
// ------------------------------------------------------------------------------------------------
void SqThrowF(CSStr str, ...)
{
// Initialize the argument list
va_list args;
va_start (args, str);
// Write the requested contents
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
strcpy(g_Buffer, "Unknown error has occurred");
// Release the argument list
va_end(args);
// Throw the exception with the resulted message
throw Sqrat::Exception(g_Buffer);
}
// ------------------------------------------------------------------------------------------------
CSStr FmtStr(CSStr str, ...)
{
// Initialize the argument list
va_list args;
va_start (args, str);
// Write the requested contents
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
g_Buffer[0] = 0; /* make sure the string is terminated */
// Release the argument list
va_end(args);
// Return the data from the buffer
return g_Buffer;
}
// ------------------------------------------------------------------------------------------------
StackGuard::StackGuard(HSQUIRRELVM vm)
: m_Top(sq_gettop(vm)), m_VM(vm)
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
StackGuard::~StackGuard()
{
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
}
// ------------------------------------------------------------------------------------------------
SQInteger IniResult::Typename(HSQUIRRELVM vm)
{
static SQChar name[] = _SC("SqIniResult");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
void IniResult::Check() const
{
@ -12,23 +84,20 @@ void IniResult::Check() const
switch (m_Result)
{
case SI_FAIL:
_SqMod->SqThrow("Unable to %s. Probably invalid", m_Action.c_str());
SqThrowF("Unable to %s. Probably invalid", m_Action.c_str());
break;
case SI_NOMEM:
_SqMod->SqThrow("Unable to %s. Ran out of memory", m_Action.c_str());
SqThrowF("Unable to %s. Ran out of memory", m_Action.c_str());
break;
case SI_FILE:
_SqMod->SqThrow("Unable to %s. %s", strerror(errno));
break;
case SI_BADREF:
_SqMod->SqThrow("Unable to %s. Invalid document reference", m_Action.c_str());
SqThrowF("Unable to %s. %s", strerror(errno));
break;
case SI_OK:
case SI_UPDATED:
case SI_INSERTED:
break; /* These are not error messahes. */
default:
_SqMod->SqThrow("Unable to %s for some unforeseen reason", m_Action.c_str());
SqThrowF("Unable to %s for some unforeseen reason", m_Action.c_str());
}
}

View File

@ -11,15 +11,13 @@
#include <SimpleIni.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
extern "C" {
struct SQVM;
typedef struct SQVM* HSQUIRRELVM;
} /*extern "C"*/
/* ------------------------------------------------------------------------------------------------
* Custom Error messages.
*/
enum SI_Custom_Error
{
SI_BADREF = -4
};
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
@ -40,6 +38,70 @@ enum SI_Custom_Error
class Entries;
class Document;
/* ------------------------------------------------------------------------------------------------
* Retrieve the temporary buffer.
*/
SStr GetTempBuff();
/* ------------------------------------------------------------------------------------------------
* Retrieve the size of the temporary buffer.
*/
Uint32 GetTempBuffSize();
/* ------------------------------------------------------------------------------------------------
* Throw a formatted exception.
*/
void SqThrowF(CSStr str, ...);
/* ------------------------------------------------------------------------------------------------
* Generate a formatted string.
*/
CSStr FmtStr(CSStr str, ...);
/* ------------------------------------------------------------------------------------------------
* Implements RAII to restore the VM stack to it's initial size on function exit.
*/
struct StackGuard
{
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
StackGuard(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~StackGuard();
private:
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
StackGuard(const StackGuard &);
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
StackGuard(StackGuard &&);
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
StackGuard & operator = (const StackGuard &);
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
StackGuard & operator = (StackGuard &&);
private:
// --------------------------------------------------------------------------------------------
Int32 m_Top; /* The top of the stack when this instance was created. */
HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */
};
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted INI document instance.
*/
@ -51,24 +113,24 @@ class DocumentRef
public:
// --------------------------------------------------------------------------------------------
typedef CSimpleIniA Type; /* The managed type. */
typedef CSimpleIniA Type; // The managed type.
// --------------------------------------------------------------------------------------------
typedef Type* Pointer; /* Pointer to the managed type. */
typedef const Type* ConstPtr; /* Constant pointer to the managed type. */
typedef Type* Pointer; // Pointer to the managed type.
typedef const Type* ConstPtr; // Constant pointer to the managed type.
// --------------------------------------------------------------------------------------------
typedef Type& Reference; /* Reference to the managed type. */
typedef const Type& ConstRef; /* Constant reference to the managed type. */
typedef Type& Reference; // Reference to the managed type.
typedef const Type& ConstRef; // Constant reference to the managed type.
// --------------------------------------------------------------------------------------------
typedef unsigned int Counter; /* Reference counter type. */
typedef unsigned int Counter; // Reference counter type.
private:
// --------------------------------------------------------------------------------------------
Pointer m_Ptr; /* The document reader, writer and manager instance. */
Counter* m_Ref; /* Reference count to the managed instance. */
Pointer m_Ptr; // The document reader, writer and manager instance.
Counter* m_Ref; // Reference count to the managed instance.
/* --------------------------------------------------------------------------------------------
* Grab a strong reference to a document instance.
@ -123,6 +185,17 @@ public:
Grab();
}
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
DocumentRef(DocumentRef && o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
{
o.m_Ptr = NULL;
o.m_Ref = NULL;
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
@ -146,6 +219,21 @@ public:
return *this;
}
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
DocumentRef & operator = (DocumentRef && o)
{
if (m_Ptr != o.m_Ptr)
{
m_Ptr = o.m_Ptr;
m_Ref = o.m_Ref;
o.m_Ptr = NULL;
o.m_Ref = NULL;
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two document instances.
*/
@ -209,7 +297,7 @@ public:
*/
Pointer operator -> () const
{
assert(m_Ptr != NULL);
assert(m_Ptr);
return m_Ptr;
}
@ -218,7 +306,7 @@ public:
*/
Reference operator * () const
{
assert(m_Ptr != NULL);
assert(m_Ptr);
return *m_Ptr;
}
@ -356,10 +444,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
CSStr Typename() const
{
return _SC("SqIniResult");
}
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI result.

View File

@ -13,13 +13,19 @@
namespace SqMod {
// ------------------------------------------------------------------------------------------------
bool Document::Validate() const
SQInteger Document::Typename(HSQUIRRELVM vm)
{
if (m_Doc)
return true;
// No document available
_SqMod->SqThrow("Invalid INI document reference");
return false;
static SQChar name[] = _SC("SqIniDocument");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
void Document::Validate() const
{
// Is the document handle valid?
if (!m_Doc)
SqThrowF("Invalid INI document reference");
}
// ------------------------------------------------------------------------------------------------
@ -36,8 +42,8 @@ Int32 Document::Cmp(const Document & o) const
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadFile(CSStr filepath)
{
if (!Validate())
return IniResult("load INI file", SI_BADREF); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to load the file from disk and return the result
return IniResult("load INI file", m_Doc->LoadFile(filepath));
}
@ -45,8 +51,8 @@ IniResult Document::LoadFile(CSStr filepath)
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadData(CSStr source, Int32 size)
{
if (!Validate())
return IniResult("load INI file", SI_BADREF); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to load the file from memory and return the result
return IniResult("load INI file", m_Doc->LoadData(source, size < 0 ? strlen(source) : size));
}
@ -54,8 +60,8 @@ IniResult Document::LoadData(CSStr source, Int32 size)
// ------------------------------------------------------------------------------------------------
IniResult Document::SaveFile(CSStr filepath, bool signature)
{
if (!Validate())
return IniResult("save INI file", SI_BADREF); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to save the file to disk and return the result
return IniResult("save INI file", m_Doc->SaveFile(filepath, signature));
}
@ -63,29 +69,26 @@ IniResult Document::SaveFile(CSStr filepath, bool signature)
// ------------------------------------------------------------------------------------------------
Object Document::SaveData(bool signature)
{
if (!Validate())
return Object(); /* Unable to proceed */
// Validate the handle
Validate();
// The string where the content will be saved
String source;
// Attempt to save the data to string
if (m_Doc->Save(source, signature) < 0)
return Object(); /* Unable to proceed */
SqThrowF("Unable to save INI document");
// Obtain the initial stack size
const StackGuard sg(_SqVM);
// Transform it into a script object
sq_pushstring(DefaultVM::Get(), source.c_str(), source.size());
// Get the object from the stack
Var< Object > var(DefaultVM::Get(), -1);
// Pop the created object from the stack
if (!var.value.IsNull())
sq_pop(DefaultVM::Get(), 1);
// Return the script object
return var.value;
sq_pushstring(_SqVM, source.c_str(), source.size());
// Get the object from the stack and return it
return Var< Object >(_SqVM, -1).value;
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllSections() const
{
if (!Validate())
return Entries(); /* Unable to proceed */
// Validate the handle
Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
@ -97,8 +100,8 @@ Entries Document::GetAllSections() const
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllKeys(CSStr section) const
{
if (!Validate())
return Entries(); /* Unable to proceed */
// Validate the handle
Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
@ -110,8 +113,8 @@ Entries Document::GetAllKeys(CSStr section) const
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllValues(CSStr section, CSStr key) const
{
if (!Validate())
return Entries(); /* Unable to proceed */
// Validate the handle
Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
@ -123,18 +126,17 @@ Entries Document::GetAllValues(CSStr section, CSStr key) const
// ------------------------------------------------------------------------------------------------
Int32 Document::GetSectionSize(CSStr section) const
{
if (Validate())
// Return the requested information
return m_Doc->GetSectionSize(section);
// Return invalid size
return -1;
// Validate the handle
Validate();
// Return the requested information
return m_Doc->GetSectionSize(section);
}
// ------------------------------------------------------------------------------------------------
bool Document::HasMultipleKeys(CSStr section, CSStr key) const
{
if (!Validate())
return false; /* Unable to proceed */
// Validate the handle
Validate();
// Where to retrive whether the key has multiple instances
bool multiple = false;
// Attempt to query the information
@ -146,8 +148,8 @@ bool Document::HasMultipleKeys(CSStr section, CSStr key) const
// ------------------------------------------------------------------------------------------------
CCStr Document::GetValue(CSStr section, CSStr key, CSStr def) const
{
if (!Validate())
return _SC(""); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to query the information and return it
return m_Doc->GetValue(section, key, def, NULL);
}
@ -155,8 +157,8 @@ CCStr Document::GetValue(CSStr section, CSStr key, CSStr def) const
// ------------------------------------------------------------------------------------------------
SQInteger Document::GetInteger(CSStr section, CSStr key, SQInteger def) const
{
if (!Validate())
return 0; /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to query the information and return it
return (SQInteger)m_Doc->GetLongValue(section, key, def, NULL);
}
@ -164,8 +166,8 @@ SQInteger Document::GetInteger(CSStr section, CSStr key, SQInteger def) const
// ------------------------------------------------------------------------------------------------
SQFloat Document::GetFloat(CSStr section, CSStr key, SQFloat def) const
{
if (!Validate())
return SQFloat(0.0); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to query the information and return it
return (SQFloat)m_Doc->GetDoubleValue(section, key, def, NULL);
}
@ -173,8 +175,8 @@ SQFloat Document::GetFloat(CSStr section, CSStr key, SQFloat def) const
// ------------------------------------------------------------------------------------------------
bool Document::GetBoolean(CSStr section, CSStr key, bool def) const
{
if (!Validate())
return false; /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to query the information and return it
return m_Doc->GetBoolValue(section, key, def, NULL);
}
@ -182,8 +184,8 @@ bool Document::GetBoolean(CSStr section, CSStr key, bool def) const
// ------------------------------------------------------------------------------------------------
IniResult Document::SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment)
{
if (!Validate())
return IniResult("set INI value", SI_BADREF); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI value", m_Doc->SetValue(section, key, value, comment, force));
}
@ -191,8 +193,8 @@ IniResult Document::SetValue(CSStr section, CSStr key, CSStr value, bool force,
// ------------------------------------------------------------------------------------------------
IniResult Document::SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment)
{
if (!Validate())
return IniResult("set INI integer", SI_BADREF); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI integer", m_Doc->SetLongValue(section, key, value, comment, hex, force));
}
@ -200,8 +202,8 @@ IniResult Document::SetInteger(CSStr section, CSStr key, SQInteger value, bool h
// ------------------------------------------------------------------------------------------------
IniResult Document::SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment)
{
if (!Validate())
return IniResult("set INI float", SI_BADREF); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI float", m_Doc->SetDoubleValue(section, key, value, comment, force));
}
@ -209,8 +211,8 @@ IniResult Document::SetFloat(CSStr section, CSStr key, SQFloat value, bool force
// ------------------------------------------------------------------------------------------------
IniResult Document::SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment)
{
if (!Validate())
return IniResult("set INI boolean", SI_BADREF); /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to apply the specified information
return IniResult("set INI boolean", m_Doc->SetBoolValue(section, key, value, comment, force));
}
@ -218,8 +220,8 @@ IniResult Document::SetBoolean(CSStr section, CSStr key, bool value, bool force,
// ------------------------------------------------------------------------------------------------
bool Document::DeleteValue(CSStr section, CSStr key, CSStr value, bool empty)
{
if (!Validate())
return false; /* Unable to proceed */
// Validate the handle
Validate();
// Attempt to remove the specified value and return the result
return m_Doc->DeleteValue(section, key, value, empty);
}

View File

@ -30,7 +30,7 @@ protected:
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
bool Validate() const;
void Validate() const;
private:
@ -99,10 +99,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
CSStr Typename() const
{
return _SC("SqIniDocument");
}
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI document.

View File

@ -5,6 +5,14 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Entries::Typename(HSQUIRRELVM vm)
{
static SQChar name[] = _SC("SqIniEntries");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Int32 Entries::Cmp(const Entries & o) const
{
@ -55,31 +63,31 @@ void Entries::Retreat(Int32 n)
// ------------------------------------------------------------------------------------------------
CSStr Entries::GetItem() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
_SqMod->SqThrow("Invalid INI entry [item]");
else
return m_Elem->pItem;
return _SC("");
SqThrowF("Invalid INI entry [item]");
// Return the requested information
return m_Elem->pItem;
}
// ------------------------------------------------------------------------------------------------
CSStr Entries::GetComment() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
_SqMod->SqThrow("Invalid INI entry [comment]");
else
return m_Elem->pComment;
return _SC("");
SqThrowF("Invalid INI entry [comment]");
// Return the requested information
return m_Elem->pComment;
}
// ------------------------------------------------------------------------------------------------
Int32 Entries::GetOrder() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
_SqMod->SqThrow("Invalid INI entry [order]");
else
return m_Elem->nOrder;
return -1;
SqThrowF("Invalid INI entry [order]");
// Return the requested information
return m_Elem->nOrder;
}
} // Namespace:: SqMod

View File

@ -95,10 +95,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
CSStr Typename() const
{
return _SC("SqIniEntries");
}
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Return whether the current element is valid and can be accessed.

View File

@ -175,8 +175,8 @@ void RegisterAPI(HSQUIRRELVM vm)
.Ctor< const IniResult & >()
/* Core Metamethods */
.Func(_SC("_cmp"), &IniResult::Cmp)
.SquirrelFunc(_SC("_typename"), &IniResult::Typename)
.Func(_SC("_tostring"), &IniResult::ToString)
.Func(_SC("_typename"), &IniResult::Typename)
/* Properties */
.Prop(_SC("Valid"), &IniResult::IsValid)
.Prop(_SC("Action"), &IniResult::GetAction)
@ -191,7 +191,7 @@ void RegisterAPI(HSQUIRRELVM vm)
.Ctor< const Entries & >()
/* Core Metamethods */
.Func(_SC("_cmp"), &Entries::Cmp)
.Func(_SC("_typename"), &Entries::Typename)
.SquirrelFunc(_SC("_typename"), &Entries::Typename)
.Func(_SC("_tostring"), &Entries::ToString)
/* Properties */
.Prop(_SC("Valid"), &Entries::IsValid)
@ -221,7 +221,7 @@ void RegisterAPI(HSQUIRRELVM vm)
.Ctor< bool, bool, bool >()
/* Core Metamethods */
.Func(_SC("_cmp"), &Document::Cmp)
.Func(_SC("_typename"), &Document::Typename)
.SquirrelFunc(_SC("_typename"), &Document::Typename)
.Func(_SC("_tostring"), &Document::ToString)
/* Properties */
.Prop(_SC("Valid"), &Document::IsValid)
@ -276,7 +276,6 @@ void RegisterAPI(HSQUIRRELVM vm)
.Const(_SC("Fail"), Int32(SI_FAIL))
.Const(_SC("NoMem"), Int32(SI_NOMEM))
.Const(_SC("File"), Int32(SI_FILE))
.Const(_SC("BadRef"), Int32(SI_BADREF))
);
}