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

Separate the IO library into smaller sub components.

Merge the INI module with the main plugin IO library.
This commit is contained in:
Sandu Liviu Catalin 2016-05-24 18:37:34 +03:00
parent d7c4d389eb
commit 76621cf946
18 changed files with 1530 additions and 2480 deletions

View File

@ -1,423 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Mod INI" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Win32 Debug Dynamic">
<Option output="../bin/win32-d/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win32-d/" />
<Option object_output="../obj/mingw32-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m32" />
<Add option="-g" />
<Add option="-D_DEBUG" />
<Add directory="../config/mingw32" />
</Compiler>
<Linker>
<Add option="-m32" />
<Add directory="../lib/mingw32-d" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Win32 Release Dynamic">
<Option output="../bin/win32/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win32/" />
<Option object_output="../obj/mingw32/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-m32" />
<Add option="-DNDEBUG" />
<Add directory="../config/mingw32" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m32" />
<Add directory="../lib/mingw32" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Win64 Debug Dynamic">
<Option output="../bin/win64-d/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win64-d/" />
<Option object_output="../obj/mingw64-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m64" />
<Add option="-g" />
<Add option="-D_DEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/mingw64" />
</Compiler>
<Linker>
<Add option="-m64" />
<Add directory="../lib/mingw64-d" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Win64 Release Dynamic">
<Option output="../bin/win64/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win64/" />
<Option object_output="../obj/mingw64/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-m64" />
<Add option="-DNDEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/mingw64" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m64" />
<Add directory="../lib/mingw64" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux32 Debug Dynamic">
<Option output="../bin/linux32-d/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux32-d/" />
<Option object_output="../obj/gcc32-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m32" />
<Add option="-g" />
<Add option="-fPIC" />
<Add option="-D_DEBUG" />
<Add directory="../config/gcc32" />
</Compiler>
<Linker>
<Add option="-m32" />
<Add directory="../lib/gcc32-d" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux32 Release Dynamic">
<Option output="../bin/linux32/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux32/" />
<Option object_output="../obj/gcc32/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-m32" />
<Add option="-fPIC" />
<Add option="-DNDEBUG" />
<Add directory="../config/gcc32" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m32" />
<Add directory="../lib/gcc32" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux64 Debug Dynamic">
<Option output="../bin/linux64-d/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux64-d/" />
<Option object_output="../obj/gcc64-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m64" />
<Add option="-g" />
<Add option="-fPIC" />
<Add option="-D_DEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/gcc64" />
</Compiler>
<Linker>
<Add option="-m64" />
<Add directory="../lib/gcc64-d" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux64 Release Dynamic">
<Option output="../bin/linux64/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux64/" />
<Option object_output="../obj/gcc64/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-m64" />
<Add option="-fPIC" />
<Add option="-DNDEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/gcc64" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m64" />
<Add directory="../lib/gcc64" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
<Target title="Win32 Debug Standalone">
<Option output="../bin/win32-d/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win32-d/" />
<Option object_output="../obj/mingw32-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m32" />
<Add option="-g" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-D_DEBUG" />
<Add directory="../config/mingw32" />
</Compiler>
<Linker>
<Add option="-m32" />
<Add option="-static" />
<Add directory="../lib/mingw32-d" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Win32 Release Standalone">
<Option output="../bin/win32/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win32/" />
<Option object_output="../obj/mingw32/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-m32" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-DNDEBUG" />
<Add directory="../config/mingw32" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m32" />
<Add option="-static" />
<Add directory="../lib/mingw32" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Win64 Debug Standalone">
<Option output="../bin/win64-d/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win64-d/" />
<Option object_output="../obj/mingw64-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m64" />
<Add option="-g" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-D_DEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/mingw64" />
</Compiler>
<Linker>
<Add option="-m64" />
<Add option="-static" />
<Add directory="../lib/mingw64-d" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Win64 Release Standalone">
<Option output="../bin/win64/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/win64/" />
<Option object_output="../obj/mingw64/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-m64" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-DNDEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/mingw64" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m64" />
<Add option="-static" />
<Add directory="../lib/mingw64" />
</Linker>
<ExtraCommands>
<Add after='cmd /c copy /Y &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux32 Debug Standalone">
<Option output="../bin/linux32-d/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux32-d/" />
<Option object_output="../obj/gcc32-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m32" />
<Add option="-g" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-fPIC" />
<Add option="-D_DEBUG" />
<Add directory="../config/gcc32" />
</Compiler>
<Linker>
<Add option="-m32" />
<Add option="-Bstatic" />
<Add directory="../lib/gcc32-d" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux32 Release Standalone">
<Option output="../bin/linux32/mod_ini32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux32/" />
<Option object_output="../obj/gcc32/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-m32" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-fPIC" />
<Add option="-DNDEBUG" />
<Add directory="../config/gcc32" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m32" />
<Add option="-Bstatic" />
<Add directory="../lib/gcc32" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux64 Debug Standalone">
<Option output="../bin/linux64-d/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux64-d/" />
<Option object_output="../obj/gcc64-d/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-m64" />
<Add option="-g" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-fPIC" />
<Add option="-D_DEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/gcc64" />
</Compiler>
<Linker>
<Add option="-m64" />
<Add option="-Bstatic" />
<Add directory="../lib/gcc64-d" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
<Target title="Linux64 Release Standalone">
<Option output="../bin/linux64/mod_ini64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
<Option working_dir="../bin/linux64/" />
<Option object_output="../obj/gcc64/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O3" />
<Add option="-Weffc++" />
<Add option="-m64" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++" />
<Add option="-enable-static" />
<Add option="-fPIC" />
<Add option="-DNDEBUG" />
<Add option="-D_SQ64" />
<Add directory="../config/gcc64" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-m64" />
<Add option="-Bstatic" />
<Add directory="../lib/gcc64" />
</Linker>
<ExtraCommands>
<Add after='/bin/cp -rf &quot;$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)&quot; &quot;$(PROJECT_DIR)../bin/plugins/$(TARGET_OUTPUT_BASENAME).so&quot;' />
</ExtraCommands>
</Target>
</Build>
<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" />
<Add directory="../config/common" />
</Compiler>
<Unit filename="../external/Common/ConvertUTF.cpp" />
<Unit filename="../modules/ini/Common.cpp" />
<Unit filename="../modules/ini/Common.hpp" />
<Unit filename="../modules/ini/Document.cpp" />
<Unit filename="../modules/ini/Document.hpp" />
<Unit filename="../modules/ini/Entries.cpp" />
<Unit filename="../modules/ini/Entries.hpp" />
<Unit filename="../modules/ini/Module.cpp" />
<Unit filename="../modules/ini/Module.hpp" />
<Unit filename="../shared/SqMod.cpp" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -484,10 +484,14 @@
<Unit filename="../source/Library/Crypt/AES.hpp" />
<Unit filename="../source/Library/Crypt/Hash.cpp" />
<Unit filename="../source/Library/Crypt/Hash.hpp" />
<Unit filename="../source/Library/FileIO.cpp" />
<Unit filename="../source/Library/FileIO.hpp" />
<Unit filename="../source/Library/Format.cpp" />
<Unit filename="../source/Library/Format.hpp" />
<Unit filename="../source/Library/IO.cpp" />
<Unit filename="../source/Library/IO.hpp" />
<Unit filename="../source/Library/IO/File.cpp" />
<Unit filename="../source/Library/IO/File.hpp" />
<Unit filename="../source/Library/IO/INI.cpp" />
<Unit filename="../source/Library/IO/INI.hpp" />
<Unit filename="../source/Library/Math.cpp" />
<Unit filename="../source/Library/Math.hpp" />
<Unit filename="../source/Library/Numeric.cpp" />

View File

@ -4,7 +4,6 @@
<Project filename="Module.cbp" />
<Project filename="Sandbox.cbp" />
<Project filename="Squirrel.cbp" />
<Project filename="ModINI.cbp" />
<Project filename="ModIRC.cbp" />
<Project filename="ModXML.cbp" />
<Project filename="ModJSON.cbp" />

View File

@ -1,126 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstring>
#include <cstdarg>
// ------------------------------------------------------------------------------------------------
#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 (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
{
std::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 (std::vsnprintf(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()
: m_VM(_SqVM), m_Top(sq_gettop(m_VM))
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
StackGuard::StackGuard(HSQUIRRELVM vm)
: m_VM(vm), m_Top(sq_gettop(vm))
{
/* ... */
}
// ------------------------------------------------------------------------------------------------
StackGuard::~StackGuard()
{
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
}
// ------------------------------------------------------------------------------------------------
void DocumentRef::Validate() const
{
// Is the document handle valid?
if (!m_Ptr)
{
STHROWF("Invalid INI document reference");
}
}
// ------------------------------------------------------------------------------------------------
SQInteger IniResult::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqIniResult");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
void IniResult::Check() const
{
// Identify the error type
switch (m_Result)
{
case SI_FAIL:
STHROWF("Unable to %s. Probably invalid", m_Action.c_str());
break;
case SI_NOMEM:
STHROWF("Unable to %s. Ran out of memory", m_Action.c_str());
break;
case SI_FILE:
STHROWF("Unable to %s. %s", strerror(errno));
break;
case SI_OK:
case SI_UPDATED:
case SI_INSERTED:
break; /* These are not error messahes. */
default:
STHROWF("Unable to %s for some unforeseen reason", m_Action.c_str());
}
}
} // Namespace:: SqMod

View File

@ -1,493 +0,0 @@
#ifndef _SQINI_COMMON_HPP_
#define _SQINI_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "ModBase.hpp"
// ------------------------------------------------------------------------------------------------
#include <assert.h>
// ------------------------------------------------------------------------------------------------
#include <SimpleIni.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQINI_NAME "Squirrel INI Module"
#define SQINI_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQINI_COPYRIGHT "Copyright (C) 2016 Sandu Liviu Catalin"
#define SQINI_HOST_NAME "SqModINIHost"
#define SQINI_VERSION 001
#define SQINI_VERSION_STR "0.0.1"
#define SQINI_VERSION_MAJOR 0
#define SQINI_VERSION_MINOR 0
#define SQINI_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
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
{
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
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:
// --------------------------------------------------------------------------------------------
HSQUIRRELVM m_VM; // The VM where the stack should be restored.
Int32 m_Top; // The top of the stack when this instance was created.
};
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted INI document instance.
*/
class DocumentRef
{
// --------------------------------------------------------------------------------------------
friend class Document;
public:
// --------------------------------------------------------------------------------------------
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& Reference; // Reference to the managed type.
typedef const Type& ConstRef; // Constant reference to the managed type.
// --------------------------------------------------------------------------------------------
typedef unsigned int Counter; // Reference counter type.
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
void Validate() const;
private:
// --------------------------------------------------------------------------------------------
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.
*/
void Grab()
{
if (m_Ptr)
{
++(*m_Ref);
}
}
/* --------------------------------------------------------------------------------------------
* Drop a strong reference to a document instance.
*/
void Drop()
{
if (m_Ptr && --(*m_Ref) == 0)
{
delete m_Ptr;
delete m_Ref;
m_Ptr = NULL;
m_Ref = NULL;
}
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
DocumentRef(bool utf8, bool multikey, bool multiline)
: m_Ptr(new Type(utf8, multikey, multiline)), m_Ref(new Counter(1))
{
/* ... */
}
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
DocumentRef()
: m_Ptr(NULL), m_Ref(NULL)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
DocumentRef(const DocumentRef & o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
{
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.
*/
~DocumentRef()
{
Drop();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
DocumentRef & operator = (const DocumentRef & o)
{
if (m_Ptr != o.m_Ptr)
{
Drop();
m_Ptr = o.m_Ptr;
m_Ref = o.m_Ref;
Grab();
}
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.
*/
bool operator == (const DocumentRef & o) const
{
return (m_Ptr == o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two document instances.
*/
bool operator != (const DocumentRef & o) const
{
return (m_Ptr != o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator Pointer ()
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator ConstPtr () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator Reference ()
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator ConstRef () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Member operator for dereferencing the managed pointer.
*/
Pointer operator -> () const
{
assert(m_Ptr);
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Reference operator * () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of active references to the managed instance.
*/
Counter Count() const
{
return (m_Ptr && m_Ref) ? (*m_Ref) : 0;
}
};
/* ------------------------------------------------------------------------------------------------
* Allows the user to inspect the result of certain operations and act accordingly.
*/
class IniResult
{
private:
// --------------------------------------------------------------------------------------------
String m_Action; /* The action that was performed. */
SQInteger m_Result; /* The internal result code. */
public:
/* --------------------------------------------------------------------------------------------
* Construct with no specific action or result.
*/
IniResult()
: m_Action("unknown action"), m_Result(SI_OK)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with no specific result.
*/
explicit IniResult(CSStr action)
: m_Action(!action ? _SC("") : action), m_Result(SI_OK)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with no specific action.
*/
explicit IniResult(SQInteger result)
: m_Action("unknown action"), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with specific action and result.
*/
IniResult(CSStr action, SQInteger result)
: m_Action(!action ? _SC("") : action), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
IniResult(const IniResult & o)
: m_Action(o.m_Action), m_Result(o.m_Result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~IniResult()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
IniResult & operator = (const IniResult & o)
{
m_Action = o.m_Action;
m_Result = o.m_Result;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two results.
*/
bool operator == (const IniResult & o) const
{
return (m_Result == o.m_Result);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two results.
*/
bool operator != (const IniResult & o) const
{
return (m_Result != o.m_Result);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return (m_Result >= 0);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const IniResult & o) const
{
if (m_Result == o.m_Result)
{
return 0;
}
else if (m_Result > o.m_Result)
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Action.c_str();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI result.
*/
bool IsValid() const
{
return (m_Result >= 0);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated action.
*/
CSStr GetAction() const
{
return m_Action.c_str();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the resulted code.
*/
SQInteger GetResult() const
{
return m_Result;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the resulted code.
*/
void Check() const;
};
} // Namespace:: SqMod
#endif // _SQINI_COMMON_HPP_

View File

@ -1,232 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Document.hpp"
#include "Entries.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <errno.h>
// --------------------------------------------------------------------------------------------
#include <sqrat.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Document::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqIniDocument");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Int32 Document::Cmp(const Document & o) const
{
if (m_Doc == o.m_Doc)
{
return 0;
}
else if (m_Doc.m_Ptr > o.m_Doc.m_Ptr)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadFile(CSStr filepath)
{
// Validate the handle
m_Doc.Validate();
// Attempt to load the file from disk and return the result
return IniResult("load INI file", m_Doc->LoadFile(filepath));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadData(CSStr source, Int32 size)
{
// Validate the handle
m_Doc.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));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SaveFile(CSStr filepath, bool signature)
{
// Validate the handle
m_Doc.Validate();
// Attempt to save the file to disk and return the result
return IniResult("save INI file", m_Doc->SaveFile(filepath, signature));
}
// ------------------------------------------------------------------------------------------------
Object Document::SaveData(bool signature)
{
// Validate the handle
m_Doc.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)
{
STHROWF("Unable to save INI document");
}
// Obtain the initial stack size
const StackGuard sg(_SqVM);
// Transform it into a script object
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
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllSections(entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllKeys(CSStr section) const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllKeys(section, entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllValues(CSStr section, CSStr key) const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllValues(section, key, entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Int32 Document::GetSectionSize(CSStr section) const
{
// Validate the handle
m_Doc.Validate();
// Return the requested information
return m_Doc->GetSectionSize(section);
}
// ------------------------------------------------------------------------------------------------
bool Document::HasMultipleKeys(CSStr section, CSStr key) const
{
// Validate the handle
m_Doc.Validate();
// Where to retrive whether the key has multiple instances
bool multiple = false;
// Attempt to query the information
if (m_Doc->GetValue(section, key, nullptr, &multiple) == nullptr)
{
return true; // Doesn't exist
}
// Return the result
return multiple;
}
// ------------------------------------------------------------------------------------------------
CCStr Document::GetValue(CSStr section, CSStr key, CSStr def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return m_Doc->GetValue(section, key, def, nullptr);
}
// ------------------------------------------------------------------------------------------------
SQInteger Document::GetInteger(CSStr section, CSStr key, SQInteger def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return static_cast< SQInteger >(m_Doc->GetLongValue(section, key, def, nullptr));
}
// ------------------------------------------------------------------------------------------------
SQFloat Document::GetFloat(CSStr section, CSStr key, SQFloat def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return static_cast< SQFloat >(m_Doc->GetDoubleValue(section, key, def, nullptr));
}
// ------------------------------------------------------------------------------------------------
bool Document::GetBoolean(CSStr section, CSStr key, bool def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return m_Doc->GetBoolValue(section, key, def, nullptr);
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI value", m_Doc->SetValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment)
{
// Validate the handle
m_Doc.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));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI float", m_Doc->SetDoubleValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information
return IniResult("set INI boolean", m_Doc->SetBoolValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
bool Document::DeleteValue(CSStr section, CSStr key, CSStr value, bool empty)
{
// Validate the handle
m_Doc.Validate();
// Attempt to remove the specified value and return the result
return m_Doc->DeleteValue(section, key, value, empty);
}
} // Namespace:: SqMod

View File

@ -1,400 +0,0 @@
#ifndef _SQINI_DOCUMENT_HPP_
#define _SQINI_DOCUMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can read/write and alter the contents of INI files.
*/
class Document
{
protected:
// --------------------------------------------------------------------------------------------
typedef DocumentRef::Type::TNamesDepend Container;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Document(const Document & o);
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Document & operator = (const Document & o);
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; /* The main INI document instance. */
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Document()
: m_Doc(false, false, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8)
: m_Doc(utf8, false, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8, bool multikey)
: m_Doc(utf8, multikey, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8, bool multikey, bool multiline)
: m_Doc(utf8, multikey, multiline)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Document()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Document & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether any data has been loaded into this document.
*/
bool IsEmpty() const
{
return m_Doc->IsEmpty();
}
/* --------------------------------------------------------------------------------------------
* Deallocate all memory stored by this document.
*/
void Reset() const
{
m_Doc->Reset();
}
/* --------------------------------------------------------------------------------------------
* See whether the INI data is treated as unicode.
*/
bool GetUnicode() const
{
return m_Doc->IsUnicode();
}
/* --------------------------------------------------------------------------------------------
* Set whether the INI data should be treated as unicode.
*/
void SetUnicode(bool toggle)
{
m_Doc->SetUnicode(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether multiple identical keys be permitted in the file.
*/
bool GetMultiKey() const
{
return m_Doc->IsMultiKey();
}
/* --------------------------------------------------------------------------------------------
* Set whether multiple identical keys be permitted in the file.
*/
void SetMultiKey(bool toggle)
{
m_Doc->SetMultiKey(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether data values are permitted to span multiple lines in the file.
*/
bool GetMultiLine() const
{
return m_Doc->IsMultiLine();
}
/* --------------------------------------------------------------------------------------------
* Set whether data values are permitted to span multiple lines in the file.
*/
void SetMultiLine(bool toggle)
{
m_Doc->SetMultiLine(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether spaces are added around the equals sign when writing key/value pairs out.
*/
bool GetSpaces() const
{
return m_Doc->UsingSpaces();
}
/* --------------------------------------------------------------------------------------------
* Set whether spaces are added around the equals sign when writing key/value pairs out.
*/
void SetSpaces(bool toggle)
{
m_Doc->SetSpaces(toggle);
}
/* --------------------------------------------------------------------------------------------
* Load an INI file from disk into memory.
*/
IniResult LoadFile(CSStr filepath);
/* --------------------------------------------------------------------------------------------
* Load INI file data direct from a string. (LoadString collides with the windows api)
*/
IniResult LoadData(CSStr source)
{
return LoadData(source, -1);
}
/* --------------------------------------------------------------------------------------------
* Load INI file data direct from a string. (LoadString collides with the windows api)
*/
IniResult LoadData(CSStr source, Int32 size);
/* --------------------------------------------------------------------------------------------
* Save an INI file from memory to disk.
*/
IniResult SaveFile(CSStr filepath)
{
return SaveFile(filepath, true);
}
/* --------------------------------------------------------------------------------------------
* Save an INI file from memory to disk.
*/
IniResult SaveFile(CSStr filepath, bool signature);
/* --------------------------------------------------------------------------------------------
* Save the INI data to a string.
*/
Object SaveData(bool signature);
/* --------------------------------------------------------------------------------------------
* Retrieve all section names.
*/
Entries GetAllSections() const;
/* --------------------------------------------------------------------------------------------
* Retrieve all unique key names in a section.
*/
Entries GetAllKeys(CSStr section) const;
/* --------------------------------------------------------------------------------------------
* Retrieve all values for a specific key.
*/
Entries GetAllValues(CSStr section, CSStr key) const;
/* --------------------------------------------------------------------------------------------
* Query the number of keys in a specific section.
*/
Int32 GetSectionSize(CSStr section) const;
/* --------------------------------------------------------------------------------------------
* See whether a certain key has multiple instances.
*/
bool HasMultipleKeys(CSStr section, CSStr key) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value for a specific key.
*/
CCStr GetValue(CSStr section, CSStr key, CSStr def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a numeric value for a specific key.
*/
SQInteger GetInteger(CSStr section, CSStr key, SQInteger def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a numeric value for a specific key.
*/
SQFloat GetFloat(CSStr section, CSStr key, SQFloat def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a boolean value for a specific key.
*/
bool GetBoolean(CSStr section, CSStr key, bool def) const;
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value)
{
return SetValue(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force)
{
return SetValue(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value)
{
return SetInteger(section, key, value, false, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex)
{
return SetInteger(section, key, value, hex, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force)
{
return SetInteger(section, key, value, hex, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value)
{
return SetFloat(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force)
{
return SetFloat(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value)
{
return SetBoolean(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force)
{
return SetBoolean(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a boolean value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section)
{
return DeleteValue(section, nullptr, nullptr, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key)
{
return DeleteValue(section, key, nullptr, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key, CSStr value)
{
return DeleteValue(section, key, value, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key, CSStr value, bool empty);
};
} // Namespace:: SqMod
#endif // _SQINI_DOCUMENT_HPP_

View File

@ -1,119 +0,0 @@
// ------------------------------------------------------------------------------------------------
#include "Entries.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Entries::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqIniEntries");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Int32 Entries::Cmp(const Entries & o) const
{
if (m_Elem == o.m_Elem)
{
return 0;
}
else if (m_List.size() > o.m_List.size())
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Next()
{
// Are there any other elements ahead?
if (!m_List.empty() && m_Elem != m_List.end())
{
++m_Elem; // Go ahead one element
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Prev()
{
// Are there any other elements behind?
if (!m_List.empty() && m_Elem != m_List.begin())
{
--m_Elem; // Go back one element
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Advance(Int32 n)
{
// Are there any other elements ahead?
if (m_List.empty() || m_Elem == m_List.end())
{
return;
}
// Jump as many elements as possible within the specified distance
while ((--n >= 0) && m_Elem != m_List.end())
{
++m_Elem;
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Retreat(Int32 n)
{
// Are there any other elements behind?
if (m_List.empty() || m_Elem == m_List.begin())
{
return;
}
// Jump as many elements as possible within the specified distance
while ((--n >= 0) && m_Elem != m_List.begin())
{
--m_Elem;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Entries::GetItem() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
{
STHROWF("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())
{
STHROWF("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())
{
STHROWF("Invalid INI entry [order]");
}
// Return the requested information
return m_Elem->nOrder;
}
} // Namespace:: SqMod

View File

@ -1,218 +0,0 @@
#ifndef _SQINI_ENTRIES_HPP_
#define _SQINI_ENTRIES_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can access and iterate a series of entries in the INI document.
*/
class Entries
{
// --------------------------------------------------------------------------------------------
friend class Document;
protected:
// --------------------------------------------------------------------------------------------
typedef DocumentRef::Type::TNamesDepend Container;
// --------------------------------------------------------------------------------------------
typedef Container::iterator Iterator;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Entries(const DocumentRef & ini, Container & list)
: m_Doc(ini), m_List(), m_Elem()
{
m_List.swap(list);
Reset();
}
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The document that contains the elements.
Container m_List; // The list of elements to iterate.
Iterator m_Elem; // The currently processed element.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
Entries()
: m_Doc(), m_List(), m_Elem(m_List.end())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Entries(const Entries & o)
: m_Doc(o.m_Doc), m_List(o.m_List), m_Elem()
{
Reset();
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Entries()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Entries & operator = (const Entries & o)
{
m_Doc = o.m_Doc;
m_List = o.m_List;
Reset();
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Entries & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return GetItem();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Return whether the current element is valid and can be accessed.
*/
bool IsValid() const
{
return !(m_List.empty() || m_Elem == m_List.end());
}
/* --------------------------------------------------------------------------------------------
* Return whether the entry list is empty.
*/
bool IsEmpty() const
{
return m_List.empty();
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* Return the total entries in the list.
*/
Int32 GetSize() const
{
return static_cast< Int32 >(m_List.size());
}
/* --------------------------------------------------------------------------------------------
* Reset the internal iterator to the first element.
*/
void Reset()
{
if (m_List.empty())
{
m_Elem = m_List.end();
}
else
{
m_Elem = m_List.begin();
}
}
/* --------------------------------------------------------------------------------------------
* Go to the next element.
*/
void Next();
/* --------------------------------------------------------------------------------------------
* Go to the previous element.
*/
void Prev();
/* --------------------------------------------------------------------------------------------
* Advance a certain number of elements.
*/
void Advance(Int32 n);
/* --------------------------------------------------------------------------------------------
* Retreat a certain number of elements.
*/
void Retreat(Int32 n);
/* --------------------------------------------------------------------------------------------
* Sort the entries using the default options.
*/
void Sort()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Sort the entries by name of key only.
*/
void SortByKeyOrder()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Sort the entries by their load order and then name of key.
*/
void SortByLoadOrder()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::LoadOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Retrieve the string value of the current element item.
*/
CSStr GetItem() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the string value of the current element comment.
*/
CSStr GetComment() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the order of the current element.
*/
Int32 GetOrder() const;
};
} // Namespace:: SqMod
#endif // _SQINI_ENTRIES_HPP_

View File

@ -1,425 +0,0 @@
// --------------------------------------------------------------------------------------------
#include "Module.hpp"
#include "Common.hpp"
#include "Entries.hpp"
#include "Document.hpp"
// --------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
// --------------------------------------------------------------------------------------------
#include <sqrat.h>
// --------------------------------------------------------------------------------------------
#if defined(WIN32) || defined(_WIN32)
#include <Windows.h>
#endif
namespace SqMod {
// --------------------------------------------------------------------------------------------
PluginFuncs* _Func = nullptr;
PluginCallbacks* _Clbk = nullptr;
PluginInfo* _Info = nullptr;
// --------------------------------------------------------------------------------------------
HSQAPI _SqAPI = nullptr;
HSQEXPORTS _SqMod = nullptr;
HSQUIRRELVM _SqVM = nullptr;
/* ------------------------------------------------------------------------------------------------
* Bind speciffic functions to certain server events.
*/
void BindCallbacks();
/* ------------------------------------------------------------------------------------------------
* Undo changes made with BindCallbacks().
*/
void UnbindCallbacks();
/* --------------------------------------------------------------------------------------------
* Register the module API under the specified virtual machine.
*/
void RegisterAPI(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Initialize the plugin by obtaining the API provided by the host plugin.
*/
void OnSquirrelInitialize()
{
// Attempt to import the plugin API exported by the host plugin
_SqMod = sq_api_import(_Func);
// Did we failed to obtain the plugin exports?
if(!_SqMod)
{
OutputError("Failed to attach [%s] on host plugin.", SQINI_NAME);
}
else
{
// Obtain the Squirrel API
_SqAPI = _SqMod->GetSquirrelAPI();
// Expand the Squirrel API into global functions
sq_api_expand(_SqAPI);
}
}
/* --------------------------------------------------------------------------------------------
* Load the module on the virtual machine provided by the host module.
*/
void OnSquirrelLoad()
{
// Make sure that we have a valid plugin API
if (!_SqMod)
{
return; // Unable to proceed!
}
// Obtain the Squirrel API and VM
_SqVM = _SqMod->GetSquirrelVM();
// Make sure that a valid virtual machine exists
if (!_SqVM)
{
return; // Unable to proceed!
}
// Set this as the default database
DefaultVM::Set(_SqVM);
// Register the module API
RegisterAPI(_SqVM);
// Notify about the current status
OutputMessage("Registered: %s", SQINI_NAME);
}
/* --------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQINI_NAME);
// Release the current virtual machine, if any
DefaultVM::Set(nullptr);
}
/* --------------------------------------------------------------------------------------------
* Validate the module API to make sure we don't run into issues.
*/
bool CheckAPIVer(CCStr ver)
{
// Obtain the numeric representation of the API version
long vernum = std::strtol(ver, nullptr, 10);
// Check against version mismatch
if (vernum == SQMOD_API_VER)
{
return true;
}
// Log the incident
OutputError("API version mismatch on %s", SQINI_NAME);
OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER);
// Invoker should not attempt to communicate through the module API
return false;
}
/* --------------------------------------------------------------------------------------------
* React to command sent by other plugins.
*/
static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message)
{
switch(command_identifier)
{
case SQMOD_INITIALIZE_CMD:
if (CheckAPIVer(message))
{
OnSquirrelInitialize();
}
break;
case SQMOD_LOAD_CMD:
OnSquirrelLoad();
break;
case SQMOD_TERMINATE_CMD:
OnSquirrelTerminate();
break;
default: break;
}
return 1;
}
/* --------------------------------------------------------------------------------------------
* The server was initialized and this plugin was loaded successfully.
*/
static uint8_t OnServerInitialise()
{
return 1;
}
static void OnServerShutdown(void)
{
// The server may still send callbacks
UnbindCallbacks();
}
// ------------------------------------------------------------------------------------------------
void BindCallbacks()
{
_Clbk->OnServerInitialise = OnServerInitialise;
_Clbk->OnServerShutdown = OnServerShutdown;
_Clbk->OnPluginCommand = OnPluginCommand;
}
// ------------------------------------------------------------------------------------------------
void UnbindCallbacks()
{
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnPluginCommand = nullptr;
}
// --------------------------------------------------------------------------------------------
void RegisterAPI(HSQUIRRELVM vm)
{
Table inins(vm);
inins.Bind(_SC("Result"), Class< IniResult >(vm, _SC("SqIniResult"))
// Constructors
.Ctor()
.Ctor< CSStr, SQInteger >()
.Ctor< const IniResult & >()
// Core Metamethods
.Func(_SC("_cmp"), &IniResult::Cmp)
.SquirrelFunc(_SC("_typename"), &IniResult::Typename)
.Func(_SC("_tostring"), &IniResult::ToString)
// Properties
.Prop(_SC("Valid"), &IniResult::IsValid)
.Prop(_SC("Action"), &IniResult::GetAction)
.Prop(_SC("Result"), &IniResult::GetResult)
// Member Methods
.Func(_SC("Check"), &IniResult::Check)
);
inins.Bind(_SC("Entries"), Class< Entries >(vm, _SC("SqIniEntries"))
// Constructors
.Ctor()
.Ctor< const Entries & >()
// Core Metamethods
.Func(_SC("_cmp"), &Entries::Cmp)
.SquirrelFunc(_SC("_typename"), &Entries::Typename)
.Func(_SC("_tostring"), &Entries::ToString)
// Properties
.Prop(_SC("Valid"), &Entries::IsValid)
.Prop(_SC("Empty"), &Entries::IsEmpty)
.Prop(_SC("References"), &Entries::GetRefCount)
.Prop(_SC("Size"), &Entries::GetSize)
.Prop(_SC("Item"), &Entries::GetItem)
.Prop(_SC("Comment"), &Entries::GetComment)
.Prop(_SC("Order"), &Entries::GetOrder)
// Member Methods
.Func(_SC("Reset"), &Entries::Reset)
.Func(_SC("Next"), &Entries::Next)
.Func(_SC("Prev"), &Entries::Prev)
.Func(_SC("Advance"), &Entries::Advance)
.Func(_SC("Retreat"), &Entries::Retreat)
.Func(_SC("Sort"), &Entries::Sort)
.Func(_SC("SortByKeyOrder"), &Entries::SortByKeyOrder)
.Func(_SC("SortByLoadOrder"), &Entries::SortByLoadOrder)
);
inins.Bind(_SC("Document"), Class< Document, NoCopy< Document > >(vm, _SC("SqIniDocument"))
// Constructors
.Ctor()
.Ctor< bool >()
.Ctor< bool, bool >()
.Ctor< bool, bool, bool >()
// Core Metamethods
.Func(_SC("_cmp"), &Document::Cmp)
.SquirrelFunc(_SC("_typename"), &Document::Typename)
.Func(_SC("_tostring"), &Document::ToString)
// Properties
.Prop(_SC("Valid"), &Document::IsValid)
.Prop(_SC("Empty"), &Document::IsEmpty)
.Prop(_SC("References"), &Document::GetRefCount)
.Prop(_SC("Unicode"), &Document::GetUnicode, &Document::SetUnicode)
.Prop(_SC("MultiKey"), &Document::GetMultiKey, &Document::SetMultiKey)
.Prop(_SC("MultiLine"), &Document::GetMultiLine, &Document::SetMultiLine)
.Prop(_SC("Spaces"), &Document::GetSpaces, &Document::SetSpaces)
// Member Methods
.Func(_SC("Reset"), &Document::Reset)
.Func(_SC("LoadFile"), &Document::LoadFile)
.Overload< IniResult (Document::*)(CSStr) >(_SC("LoadString"), &Document::LoadData)
.Overload< IniResult (Document::*)(CSStr, Int32) >(_SC("LoadString"), &Document::LoadData)
.Overload< IniResult (Document::*)(CSStr) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< IniResult (Document::*)(CSStr, bool) >(_SC("SaveFile"), &Document::SaveFile)
.Func(_SC("SaveData"), &Document::SaveData)
.Func(_SC("GetSections"), &Document::GetAllSections)
.Func(_SC("GetKeys"), &Document::GetAllKeys)
.Func(_SC("GetValues"), &Document::GetAllValues)
.Func(_SC("GetSectionSize"), &Document::GetSectionSize)
.Func(_SC("HasMultipleKeys"), &Document::HasMultipleKeys)
.Func(_SC("GetValue"), &Document::GetValue)
.Func(_SC("GetInteger"), &Document::GetInteger)
.Func(_SC("GetFloat"), &Document::GetFloat)
.Func(_SC("GetBoolean"), &Document::GetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool, CSStr) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool, CSStr) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool, CSStr) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool, CSStr) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< bool (Document::*)(CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("DeleteValue"), &Document::DeleteValue)
);
RootTable(vm).Bind(_SC("SqIni"), inins);
ConstTable(vm).Enum(_SC("SqIniError"), Enumeration(vm)
.Const(_SC("Ok"), Int32(SI_OK))
.Const(_SC("Updated"), Int32(SI_UPDATED))
.Const(_SC("Inserted"), Int32(SI_INSERTED))
.Const(_SC("Fail"), Int32(SI_FAIL))
.Const(_SC("NoMem"), Int32(SI_NOMEM))
.Const(_SC("File"), Int32(SI_FILE))
);
}
// --------------------------------------------------------------------------------------------
void OutputMessageImpl(const char * msg, va_list args)
{
#if defined(WIN32) || defined(_WIN32)
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csb_before;
GetConsoleScreenBufferInfo( hstdout, &csb_before);
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
std::printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
std::vprintf(msg, args);
std::puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27);
std::vprintf(msg, args);
std::puts("");
#endif
}
// --------------------------------------------------------------------------------------------
void OutputErrorImpl(const char * msg, va_list args)
{
#if defined(WIN32) || defined(_WIN32)
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csb_before;
GetConsoleScreenBufferInfo( hstdout, &csb_before);
SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY);
std::printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
std::vprintf(msg, args);
std::puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27);
std::vprintf(msg, args);
std::puts("");
#endif
}
// --------------------------------------------------------------------------------------------
void OutputDebug(const char * msg, ...)
{
#ifdef _DEBUG
// Initialize the arguments list
va_list args;
va_start(args, msg);
// Call the output function
OutputMessageImpl(msg, args);
// Finalize the arguments list
va_end(args);
#else
SQMOD_UNUSED_VAR(msg);
#endif
}
// --------------------------------------------------------------------------------------------
void OutputMessage(const char * msg, ...)
{
// Initialize the arguments list
va_list args;
va_start(args, msg);
// Call the output function
OutputMessageImpl(msg, args);
// Finalize the arguments list
va_end(args);
}
// --------------------------------------------------------------------------------------------
void OutputError(const char * msg, ...)
{
// Initialize the arguments list
va_list args;
va_start(args, msg);
// Call the output function
OutputErrorImpl(msg, args);
// Finalize the arguments list
va_end(args);
}
} // Namespace:: SqMod
// --------------------------------------------------------------------------------------------
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallbacks* callbacks, PluginInfo* info)
{
using namespace SqMod;
// Output plugin header
puts("");
OutputMessage("--------------------------------------------------------------------");
OutputMessage("Plugin: %s", SQINI_NAME);
OutputMessage("Author: %s", SQINI_AUTHOR);
OutputMessage("Legal: %s", SQINI_COPYRIGHT);
OutputMessage("--------------------------------------------------------------------");
puts("");
// Attempt to find the host plugin ID
int host_plugin_id = functions->FindPlugin((char *)(SQMOD_HOST_NAME));
// See if our plugin was loaded after the host plugin
if (host_plugin_id < 0)
{
OutputError("%s could find the host plugin", SQINI_NAME);
// Don't load!
return SQMOD_FAILURE;
}
// Should never reach this point but just in case
else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId)
{
OutputError("%s loaded after the host plugin", SQINI_NAME);
// Don't load!
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plugin version
_Info->pluginVersion = SQINI_VERSION;
_Info->apiMajorVersion = PLUGIN_API_MAJOR;
_Info->apiMinorVersion = PLUGIN_API_MINOR;
// Assign the plugin name
std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQINI_HOST_NAME);
// Bind callbacks
BindCallbacks();
// Notify that the plugin was successfully loaded
OutputMessage("Successfully loaded %s", SQINI_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

View File

@ -1,41 +0,0 @@
#ifndef _SQINI_MODULE_HPP_
#define _SQINI_MODULE_HPP_
// ------------------------------------------------------------------------------------------------
#include "SqMod.h"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Proxies to comunicate with the server.
*/
extern PluginFuncs* _Func;
extern PluginCallbacks* _Clbk;
extern PluginInfo* _Info;
/* ------------------------------------------------------------------------------------------------
* Proxies to comunicate with the Squirrel plugin.
*/
extern HSQAPI _SqAPI;
extern HSQEXPORTS _SqMod;
extern HSQUIRRELVM _SqVM;
/* ------------------------------------------------------------------------------------------------
* Output a message only if the _DEBUG was defined.
*/
void OutputDebug(const char * msg, ...);
/* ------------------------------------------------------------------------------------------------
* Output a formatted user message to the console.
*/
void OutputMessage(const char * msg, ...);
/* ------------------------------------------------------------------------------------------------
* Output a formatted error message to the console.
*/
void OutputError(const char * msg, ...);
} // Namespace:: SqMod
#endif // _SQINI_MODULE_HPP_

16
source/Library/IO.cpp Normal file
View File

@ -0,0 +1,16 @@
// ------------------------------------------------------------------------------------------------
#include "Library/IO.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
extern void Register_INI(HSQUIRRELVM vm);
// ================================================================================================
void Register_IO(HSQUIRRELVM vm)
{
Register_INI(vm);
}
} // Namespace:: SqMod

14
source/Library/IO.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef _LIBRARY_IO_HPP_
#define _LIBRARY_IO_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod
#endif // _LIBRARY_IO_HPP_

496
source/Library/IO/INI.cpp Normal file
View File

@ -0,0 +1,496 @@
// ------------------------------------------------------------------------------------------------
#include "Library/IO/INI.hpp"
#include "Base/Stack.hpp"
// ------------------------------------------------------------------------------------------------
#include <cerrno>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger IniResult::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqIniResult");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
void IniResult::Check() const
{
// Identify the error type
switch (m_Result)
{
case SI_FAIL:
STHROWF("Unable to %s. Probably invalid", m_Action.c_str());
break;
case SI_NOMEM:
STHROWF("Unable to %s. Ran out of memory", m_Action.c_str());
break;
case SI_FILE:
STHROWF("Unable to %s. %s", strerror(errno));
break;
case SI_OK:
case SI_UPDATED:
case SI_INSERTED:
break; /* These are not error messahes. */
default:
STHROWF("Unable to %s for some unforeseen reason", m_Action.c_str());
}
}
// ------------------------------------------------------------------------------------------------
void DocumentRef::Validate() const
{
// Is the document handle valid?
if (!m_Ptr)
{
STHROWF("Invalid INI document reference");
}
}
// ------------------------------------------------------------------------------------------------
SQInteger Entries::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqIniEntries");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Int32 Entries::Cmp(const Entries & o) const
{
if (m_Elem == o.m_Elem)
{
return 0;
}
else if (m_List.size() > o.m_List.size())
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Next()
{
// Are there any other elements ahead?
if (!m_List.empty() && m_Elem != m_List.end())
{
++m_Elem; // Go ahead one element
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Prev()
{
// Are there any other elements behind?
if (!m_List.empty() && m_Elem != m_List.begin())
{
--m_Elem; // Go back one element
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Advance(Int32 n)
{
// Are there any other elements ahead?
if (m_List.empty() || m_Elem == m_List.end())
{
return;
}
// Jump as many elements as possible within the specified distance
while ((--n >= 0) && m_Elem != m_List.end())
{
++m_Elem;
}
}
// ------------------------------------------------------------------------------------------------
void Entries::Retreat(Int32 n)
{
// Are there any other elements behind?
if (m_List.empty() || m_Elem == m_List.begin())
{
return;
}
// Jump as many elements as possible within the specified distance
while ((--n >= 0) && m_Elem != m_List.begin())
{
--m_Elem;
}
}
// ------------------------------------------------------------------------------------------------
CSStr Entries::GetItem() const
{
// is the current element valid?
if (m_List.empty() || m_Elem == m_List.end())
{
STHROWF("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())
{
STHROWF("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())
{
STHROWF("Invalid INI entry [order]");
}
// Return the requested information
return m_Elem->nOrder;
}
// ------------------------------------------------------------------------------------------------
SQInteger Document::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqIniDocument");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
Int32 Document::Cmp(const Document & o) const
{
if (m_Doc == o.m_Doc)
{
return 0;
}
else if (m_Doc.m_Ptr > o.m_Doc.m_Ptr)
{
return 1;
}
else
{
return -1;
}
}
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadFile(CSStr filepath)
{
// Validate the handle
m_Doc.Validate();
// Attempt to load the file from disk and return the result
return IniResult("load INI file", m_Doc->LoadFile(filepath));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadData(CSStr source, Int32 size)
{
// Validate the handle
m_Doc.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));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SaveFile(CSStr filepath, bool signature)
{
// Validate the handle
m_Doc.Validate();
// Attempt to save the file to disk and return the result
return IniResult("save INI file", m_Doc->SaveFile(filepath, signature));
}
// ------------------------------------------------------------------------------------------------
Object Document::SaveData(bool signature)
{
// Validate the handle
m_Doc.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)
{
STHROWF("Unable to save INI document");
}
// Obtain the initial stack size
const StackGuard sg(DefaultVM::Get());
// Transform it into a script object
sq_pushstring(DefaultVM::Get(), source.c_str(), source.size());
// Get the object from the stack and return it
return Var< Object >(DefaultVM::Get(), -1).value;
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllSections() const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllSections(entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllKeys(CSStr section) const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllKeys(section, entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllValues(CSStr section, CSStr key) const
{
// Validate the handle
m_Doc.Validate();
// Prepare a container to receive the entries
static Container entries;
// Obtain all sections from the INI document
m_Doc->GetAllValues(section, key, entries);
// Return the entries and take over content
return Entries(m_Doc, entries);
}
// ------------------------------------------------------------------------------------------------
Int32 Document::GetSectionSize(CSStr section) const
{
// Validate the handle
m_Doc.Validate();
// Return the requested information
return m_Doc->GetSectionSize(section);
}
// ------------------------------------------------------------------------------------------------
bool Document::HasMultipleKeys(CSStr section, CSStr key) const
{
// Validate the handle
m_Doc.Validate();
// Where to retrive whether the key has multiple instances
bool multiple = false;
// Attempt to query the information
if (m_Doc->GetValue(section, key, nullptr, &multiple) == nullptr)
{
return true; // Doesn't exist
}
// Return the result
return multiple;
}
// ------------------------------------------------------------------------------------------------
CCStr Document::GetValue(CSStr section, CSStr key, CSStr def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return m_Doc->GetValue(section, key, def, nullptr);
}
// ------------------------------------------------------------------------------------------------
SQInteger Document::GetInteger(CSStr section, CSStr key, SQInteger def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return static_cast< SQInteger >(m_Doc->GetLongValue(section, key, def, nullptr));
}
// ------------------------------------------------------------------------------------------------
SQFloat Document::GetFloat(CSStr section, CSStr key, SQFloat def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return static_cast< SQFloat >(m_Doc->GetDoubleValue(section, key, def, nullptr));
}
// ------------------------------------------------------------------------------------------------
bool Document::GetBoolean(CSStr section, CSStr key, bool def) const
{
// Validate the handle
m_Doc.Validate();
// Attempt to query the information and return it
return m_Doc->GetBoolValue(section, key, def, nullptr);
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI value", m_Doc->SetValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment)
{
// Validate the handle
m_Doc.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));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information and return the result
return IniResult("set INI float", m_Doc->SetDoubleValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment)
{
// Validate the handle
m_Doc.Validate();
// Attempt to apply the specified information
return IniResult("set INI boolean", m_Doc->SetBoolValue(section, key, value, comment, force));
}
// ------------------------------------------------------------------------------------------------
bool Document::DeleteValue(CSStr section, CSStr key, CSStr value, bool empty)
{
// Validate the handle
m_Doc.Validate();
// Attempt to remove the specified value and return the result
return m_Doc->DeleteValue(section, key, value, empty);
}
// ================================================================================================
void Register_INI(HSQUIRRELVM vm)
{
Table inins(vm);
inins.Bind(_SC("Result"), Class< IniResult >(vm, _SC("SqIniResult"))
// Constructors
.Ctor()
.Ctor< CSStr, SQInteger >()
.Ctor< const IniResult & >()
// Core Metamethods
.Func(_SC("_cmp"), &IniResult::Cmp)
.SquirrelFunc(_SC("_typename"), &IniResult::Typename)
.Func(_SC("_tostring"), &IniResult::ToString)
// Properties
.Prop(_SC("Valid"), &IniResult::IsValid)
.Prop(_SC("Action"), &IniResult::GetAction)
.Prop(_SC("Result"), &IniResult::GetResult)
// Member Methods
.Func(_SC("Check"), &IniResult::Check)
);
inins.Bind(_SC("Entries"), Class< Entries >(vm, _SC("SqIniEntries"))
// Constructors
.Ctor()
.Ctor< const Entries & >()
// Core Metamethods
.Func(_SC("_cmp"), &Entries::Cmp)
.SquirrelFunc(_SC("_typename"), &Entries::Typename)
.Func(_SC("_tostring"), &Entries::ToString)
// Properties
.Prop(_SC("Valid"), &Entries::IsValid)
.Prop(_SC("Empty"), &Entries::IsEmpty)
.Prop(_SC("References"), &Entries::GetRefCount)
.Prop(_SC("Size"), &Entries::GetSize)
.Prop(_SC("Item"), &Entries::GetItem)
.Prop(_SC("Comment"), &Entries::GetComment)
.Prop(_SC("Order"), &Entries::GetOrder)
// Member Methods
.Func(_SC("Reset"), &Entries::Reset)
.Func(_SC("Next"), &Entries::Next)
.Func(_SC("Prev"), &Entries::Prev)
.Func(_SC("Advance"), &Entries::Advance)
.Func(_SC("Retreat"), &Entries::Retreat)
.Func(_SC("Sort"), &Entries::Sort)
.Func(_SC("SortByKeyOrder"), &Entries::SortByKeyOrder)
.Func(_SC("SortByLoadOrder"), &Entries::SortByLoadOrder)
);
inins.Bind(_SC("Document"), Class< Document, NoCopy< Document > >(vm, _SC("SqIniDocument"))
// Constructors
.Ctor()
.Ctor< bool >()
.Ctor< bool, bool >()
.Ctor< bool, bool, bool >()
// Core Metamethods
.Func(_SC("_cmp"), &Document::Cmp)
.SquirrelFunc(_SC("_typename"), &Document::Typename)
.Func(_SC("_tostring"), &Document::ToString)
// Properties
.Prop(_SC("Valid"), &Document::IsValid)
.Prop(_SC("Empty"), &Document::IsEmpty)
.Prop(_SC("References"), &Document::GetRefCount)
.Prop(_SC("Unicode"), &Document::GetUnicode, &Document::SetUnicode)
.Prop(_SC("MultiKey"), &Document::GetMultiKey, &Document::SetMultiKey)
.Prop(_SC("MultiLine"), &Document::GetMultiLine, &Document::SetMultiLine)
.Prop(_SC("Spaces"), &Document::GetSpaces, &Document::SetSpaces)
// Member Methods
.Func(_SC("Reset"), &Document::Reset)
.Func(_SC("LoadFile"), &Document::LoadFile)
.Overload< IniResult (Document::*)(CSStr) >(_SC("LoadString"), &Document::LoadData)
.Overload< IniResult (Document::*)(CSStr, Int32) >(_SC("LoadString"), &Document::LoadData)
.Overload< IniResult (Document::*)(CSStr) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< IniResult (Document::*)(CSStr, bool) >(_SC("SaveFile"), &Document::SaveFile)
.Func(_SC("SaveData"), &Document::SaveData)
.Func(_SC("GetSections"), &Document::GetAllSections)
.Func(_SC("GetKeys"), &Document::GetAllKeys)
.Func(_SC("GetValues"), &Document::GetAllValues)
.Func(_SC("GetSectionSize"), &Document::GetSectionSize)
.Func(_SC("HasMultipleKeys"), &Document::HasMultipleKeys)
.Func(_SC("GetValue"), &Document::GetValue)
.Func(_SC("GetInteger"), &Document::GetInteger)
.Func(_SC("GetFloat"), &Document::GetFloat)
.Func(_SC("GetBoolean"), &Document::GetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool, CSStr) >(_SC("SetValue"), &Document::SetValue)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool, CSStr) >(_SC("SetInteger"), &Document::SetInteger)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool, CSStr) >(_SC("SetFloat"), &Document::SetFloat)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool, CSStr) >(_SC("SetBoolean"), &Document::SetBoolean)
.Overload< bool (Document::*)(CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
.Overload< bool (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("DeleteValue"), &Document::DeleteValue)
);
RootTable(vm).Bind(_SC("SqIni"), inins);
ConstTable(vm).Enum(_SC("SqIniError"), Enumeration(vm)
.Const(_SC("Ok"), Int32(SI_OK))
.Const(_SC("Updated"), Int32(SI_UPDATED))
.Const(_SC("Inserted"), Int32(SI_INSERTED))
.Const(_SC("Fail"), Int32(SI_FAIL))
.Const(_SC("NoMem"), Int32(SI_NOMEM))
.Const(_SC("File"), Int32(SI_FILE))
);
}
} // Namespace:: SqMod

996
source/Library/IO/INI.hpp Normal file
View File

@ -0,0 +1,996 @@
#ifndef _LIBRARY_IO_INI_HPP_
#define _LIBRARY_IO_INI_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#include <SimpleIni.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Allows the user to inspect the result of certain operations and act accordingly.
*/
class IniResult
{
private:
// --------------------------------------------------------------------------------------------
String m_Action; // The action that was performed.
SQInteger m_Result; // The internal result code.
public:
/* --------------------------------------------------------------------------------------------
* Construct with no specific action or result.
*/
IniResult()
: m_Action("unknown action"), m_Result(SI_OK)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with no specific result.
*/
explicit IniResult(CSStr action)
: m_Action(!action ? _SC("") : action), m_Result(SI_OK)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with no specific action.
*/
explicit IniResult(SQInteger result)
: m_Action("unknown action"), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Construct with specific action and result.
*/
IniResult(CSStr action, SQInteger result)
: m_Action(!action ? _SC("") : action), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
IniResult(const IniResult & o)
: m_Action(o.m_Action), m_Result(o.m_Result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~IniResult()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
IniResult & operator = (const IniResult & o)
{
m_Action = o.m_Action;
m_Result = o.m_Result;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Perform an equality comparison between two results.
*/
bool operator == (const IniResult & o) const
{
return (m_Result == o.m_Result);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two results.
*/
bool operator != (const IniResult & o) const
{
return (m_Result != o.m_Result);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return (m_Result >= 0);
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const IniResult & o) const
{
if (m_Result == o.m_Result)
{
return 0;
}
else if (m_Result > o.m_Result)
{
return 1;
}
else
{
return -1;
}
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Action.c_str();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI result.
*/
bool IsValid() const
{
return (m_Result >= 0);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the associated action.
*/
CSStr GetAction() const
{
return m_Action.c_str();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the resulted code.
*/
SQInteger GetResult() const
{
return m_Result;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the resulted code.
*/
void Check() const;
};
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted INI document instance.
*/
class DocumentRef
{
// --------------------------------------------------------------------------------------------
friend class Document;
public:
// --------------------------------------------------------------------------------------------
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& Reference; // Reference to the managed type.
typedef const Type& ConstRef; // Constant reference to the managed type.
// --------------------------------------------------------------------------------------------
typedef unsigned int Counter; // Reference counter type.
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
void Validate() const;
private:
// --------------------------------------------------------------------------------------------
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.
*/
void Grab()
{
if (m_Ptr)
{
++(*m_Ref);
}
}
/* --------------------------------------------------------------------------------------------
* Drop a strong reference to a document instance.
*/
void Drop()
{
if (m_Ptr && --(*m_Ref) == 0)
{
delete m_Ptr;
delete m_Ref;
m_Ptr = NULL;
m_Ref = NULL;
}
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
DocumentRef(bool utf8, bool multikey, bool multiline)
: m_Ptr(new Type(utf8, multikey, multiline)), m_Ref(new Counter(1))
{
/* ... */
}
public:
/* --------------------------------------------------------------------------------------------
* Default constructor (null).
*/
DocumentRef()
: m_Ptr(NULL), m_Ref(NULL)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
DocumentRef(const DocumentRef & o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
{
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.
*/
~DocumentRef()
{
Drop();
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
DocumentRef & operator = (const DocumentRef & o)
{
if (m_Ptr != o.m_Ptr)
{
Drop();
m_Ptr = o.m_Ptr;
m_Ref = o.m_Ref;
Grab();
}
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.
*/
bool operator == (const DocumentRef & o) const
{
return (m_Ptr == o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Perform an inequality comparison between two document instances.
*/
bool operator != (const DocumentRef & o) const
{
return (m_Ptr != o.m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean for use in boolean operations.
*/
operator bool () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator Pointer ()
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance pointer.
*/
operator ConstPtr () const
{
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator Reference ()
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to the managed instance reference.
*/
operator ConstRef () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Member operator for dereferencing the managed pointer.
*/
Pointer operator -> () const
{
assert(m_Ptr);
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Reference operator * () const
{
assert(m_Ptr);
return *m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of active references to the managed instance.
*/
Counter Count() const
{
return (m_Ptr && m_Ref) ? (*m_Ref) : 0;
}
};
/* ------------------------------------------------------------------------------------------------
* Class that can access and iterate a series of entries in the INI document.
*/
class Entries
{
// --------------------------------------------------------------------------------------------
friend class Document;
protected:
// --------------------------------------------------------------------------------------------
typedef DocumentRef::Type::TNamesDepend Container;
// --------------------------------------------------------------------------------------------
typedef Container::iterator Iterator;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Entries(const DocumentRef & ini, Container & list)
: m_Doc(ini), m_List(), m_Elem()
{
m_List.swap(list);
Reset();
}
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The document that contains the elements.
Container m_List; // The list of elements to iterate.
Iterator m_Elem; // The currently processed element.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor. (null)
*/
Entries()
: m_Doc(), m_List(), m_Elem(m_List.end())
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
Entries(const Entries & o)
: m_Doc(o.m_Doc), m_List(o.m_List), m_Elem()
{
Reset();
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Entries()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
Entries & operator = (const Entries & o)
{
m_Doc = o.m_Doc;
m_List = o.m_List;
Reset();
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Entries & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return GetItem();
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Return whether the current element is valid and can be accessed.
*/
bool IsValid() const
{
return !(m_List.empty() || m_Elem == m_List.end());
}
/* --------------------------------------------------------------------------------------------
* Return whether the entry list is empty.
*/
bool IsEmpty() const
{
return m_List.empty();
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* Return the total entries in the list.
*/
Int32 GetSize() const
{
return static_cast< Int32 >(m_List.size());
}
/* --------------------------------------------------------------------------------------------
* Reset the internal iterator to the first element.
*/
void Reset()
{
if (m_List.empty())
{
m_Elem = m_List.end();
}
else
{
m_Elem = m_List.begin();
}
}
/* --------------------------------------------------------------------------------------------
* Go to the next element.
*/
void Next();
/* --------------------------------------------------------------------------------------------
* Go to the previous element.
*/
void Prev();
/* --------------------------------------------------------------------------------------------
* Advance a certain number of elements.
*/
void Advance(Int32 n);
/* --------------------------------------------------------------------------------------------
* Retreat a certain number of elements.
*/
void Retreat(Int32 n);
/* --------------------------------------------------------------------------------------------
* Sort the entries using the default options.
*/
void Sort()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Sort the entries by name of key only.
*/
void SortByKeyOrder()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Sort the entries by their load order and then name of key.
*/
void SortByLoadOrder()
{
if (!m_List.empty())
{
m_List.sort(DocumentRef::Type::Entry::LoadOrder());
}
}
/* --------------------------------------------------------------------------------------------
* Retrieve the string value of the current element item.
*/
CSStr GetItem() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the string value of the current element comment.
*/
CSStr GetComment() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the order of the current element.
*/
Int32 GetOrder() const;
};
/* ------------------------------------------------------------------------------------------------
* Class that can read/write and alter the contents of INI files.
*/
class Document
{
protected:
// --------------------------------------------------------------------------------------------
typedef DocumentRef::Type::TNamesDepend Container;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Document(const Document & o);
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Document & operator = (const Document & o);
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; // The main INI document instance.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Document()
: m_Doc(false, false, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8)
: m_Doc(utf8, false, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8, bool multikey)
: m_Doc(utf8, multikey, true)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Document(bool utf8, bool multikey, bool multiline)
: m_Doc(utf8, multikey, multiline)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Document()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Document & o) const;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return _SC("");
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to retrieve the name from instances of this type.
*/
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* See whether any data has been loaded into this document.
*/
bool IsEmpty() const
{
return m_Doc->IsEmpty();
}
/* --------------------------------------------------------------------------------------------
* Deallocate all memory stored by this document.
*/
void Reset() const
{
m_Doc->Reset();
}
/* --------------------------------------------------------------------------------------------
* See whether the INI data is treated as unicode.
*/
bool GetUnicode() const
{
return m_Doc->IsUnicode();
}
/* --------------------------------------------------------------------------------------------
* Set whether the INI data should be treated as unicode.
*/
void SetUnicode(bool toggle)
{
m_Doc->SetUnicode(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether multiple identical keys be permitted in the file.
*/
bool GetMultiKey() const
{
return m_Doc->IsMultiKey();
}
/* --------------------------------------------------------------------------------------------
* Set whether multiple identical keys be permitted in the file.
*/
void SetMultiKey(bool toggle)
{
m_Doc->SetMultiKey(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether data values are permitted to span multiple lines in the file.
*/
bool GetMultiLine() const
{
return m_Doc->IsMultiLine();
}
/* --------------------------------------------------------------------------------------------
* Set whether data values are permitted to span multiple lines in the file.
*/
void SetMultiLine(bool toggle)
{
m_Doc->SetMultiLine(toggle);
}
/* --------------------------------------------------------------------------------------------
* See whether spaces are added around the equals sign when writing key/value pairs out.
*/
bool GetSpaces() const
{
return m_Doc->UsingSpaces();
}
/* --------------------------------------------------------------------------------------------
* Set whether spaces are added around the equals sign when writing key/value pairs out.
*/
void SetSpaces(bool toggle)
{
m_Doc->SetSpaces(toggle);
}
/* --------------------------------------------------------------------------------------------
* Load an INI file from disk into memory.
*/
IniResult LoadFile(CSStr filepath);
/* --------------------------------------------------------------------------------------------
* Load INI file data direct from a string. (LoadString collides with the windows api)
*/
IniResult LoadData(CSStr source)
{
return LoadData(source, -1);
}
/* --------------------------------------------------------------------------------------------
* Load INI file data direct from a string. (LoadString collides with the windows api)
*/
IniResult LoadData(CSStr source, Int32 size);
/* --------------------------------------------------------------------------------------------
* Save an INI file from memory to disk.
*/
IniResult SaveFile(CSStr filepath)
{
return SaveFile(filepath, true);
}
/* --------------------------------------------------------------------------------------------
* Save an INI file from memory to disk.
*/
IniResult SaveFile(CSStr filepath, bool signature);
/* --------------------------------------------------------------------------------------------
* Save the INI data to a string.
*/
Object SaveData(bool signature);
/* --------------------------------------------------------------------------------------------
* Retrieve all section names.
*/
Entries GetAllSections() const;
/* --------------------------------------------------------------------------------------------
* Retrieve all unique key names in a section.
*/
Entries GetAllKeys(CSStr section) const;
/* --------------------------------------------------------------------------------------------
* Retrieve all values for a specific key.
*/
Entries GetAllValues(CSStr section, CSStr key) const;
/* --------------------------------------------------------------------------------------------
* Query the number of keys in a specific section.
*/
Int32 GetSectionSize(CSStr section) const;
/* --------------------------------------------------------------------------------------------
* See whether a certain key has multiple instances.
*/
bool HasMultipleKeys(CSStr section, CSStr key) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value for a specific key.
*/
CCStr GetValue(CSStr section, CSStr key, CSStr def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a numeric value for a specific key.
*/
SQInteger GetInteger(CSStr section, CSStr key, SQInteger def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a numeric value for a specific key.
*/
SQFloat GetFloat(CSStr section, CSStr key, SQFloat def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve a boolean value for a specific key.
*/
bool GetBoolean(CSStr section, CSStr key, bool def) const;
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value)
{
return SetValue(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force)
{
return SetValue(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value)
{
return SetInteger(section, key, value, false, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex)
{
return SetInteger(section, key, value, hex, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force)
{
return SetInteger(section, key, value, hex, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value)
{
return SetFloat(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force)
{
return SetFloat(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value)
{
return SetBoolean(section, key, value, false, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force)
{
return SetBoolean(section, key, value, force, nullptr);
}
/* --------------------------------------------------------------------------------------------
* Add or update a boolean value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment);
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section)
{
return DeleteValue(section, nullptr, nullptr, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key)
{
return DeleteValue(section, key, nullptr, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key, CSStr value)
{
return DeleteValue(section, key, value, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key, CSStr value, bool empty);
};
} // Namespace:: SqMod
#endif // _LIBRARY_IO_INI_HPP_

View File

@ -36,6 +36,7 @@ extern void Register_Entity(HSQUIRRELVM vm);
// ------------------------------------------------------------------------------------------------
extern void Register_Chrono(HSQUIRRELVM vm);
extern void Register_Crypt(HSQUIRRELVM vm);
extern void Register_IO(HSQUIRRELVM vm);
extern void Register_Numeric(HSQUIRRELVM vm);
extern void Register_Math(HSQUIRRELVM vm);
extern void Register_Random(HSQUIRRELVM vm);
@ -77,6 +78,7 @@ bool RegisterAPI(HSQUIRRELVM vm)
Register_Chrono(vm);
Register_Crypt(vm);
Register_IO(vm);
Register_Random(vm);
Register_Numeric(vm);
Register_Math(vm);