1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-16 07:07:13 +02:00

Separated major non mandatory libraries into their onwn modules.

Consolidated and simplified the module API system.
Various other fixes and improvements.
This commit is contained in:
Sandu Liviu Catalin
2016-02-27 11:57:10 +02:00
parent fa12692490
commit f4a11ef825
82 changed files with 10509 additions and 7580 deletions

35
modules/ini/Common.cpp Normal file
View File

@ -0,0 +1,35 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
void IniResult::Check() const
{
// Identify the error type
switch (m_Result)
{
case SI_FAIL:
_SqMod->SqThrow("Unable to %s. Probably invalid", m_Action.c_str());
break;
case SI_NOMEM:
_SqMod->SqThrow("Unable to %s. Ran out of memory", m_Action.c_str());
break;
case SI_FILE:
_SqMod->SqThrow("Unable to %s. %s", strerror(errno));
break;
case SI_BADREF:
_SqMod->SqThrow("Unable to %s. Invalid document reference", m_Action.c_str());
break;
case SI_OK:
case SI_UPDATED:
case SI_INSERTED:
break; /* These are not error messahes. */
default:
_SqMod->SqThrow("Unable to %s for some unforeseen reason", m_Action.c_str());
}
}
} // Namespace:: SqMod

396
modules/ini/Common.hpp Normal file
View File

@ -0,0 +1,396 @@
#ifndef _SQINI_COMMON_HPP_
#define _SQINI_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "ModBase.hpp"
// ------------------------------------------------------------------------------------------------
#include <assert.h>
// ------------------------------------------------------------------------------------------------
#include <SimpleIni.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Custom Error messages.
*/
enum SI_Custom_Error
{
SI_BADREF = -4
};
/* ------------------------------------------------------------------------------------------------
* 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;
/* ------------------------------------------------------------------------------------------------
* 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. */
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();
}
/* --------------------------------------------------------------------------------------------
* 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;
}
/* --------------------------------------------------------------------------------------------
* 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 != NULL);
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Reference operator * () const
{
assert(m_Ptr != NULL);
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.
*/
CSStr Typename() const
{
return _SC("SqIniResult");
}
/* --------------------------------------------------------------------------------------------
* 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_

227
modules/ini/Document.cpp Normal file
View File

@ -0,0 +1,227 @@
// ------------------------------------------------------------------------------------------------
#include "Document.hpp"
#include "Entries.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <errno.h>
// --------------------------------------------------------------------------------------------
#include <sqrat.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
bool Document::Validate() const
{
if (m_Doc)
return true;
// No document available
_SqMod->SqThrow("Invalid INI document reference");
return false;
}
// ------------------------------------------------------------------------------------------------
Int32 Document::Cmp(const Document & o) const
{
if (m_Doc == o.m_Doc)
return 0;
else if (this > &o)
return 1;
else
return -1;
}
// ------------------------------------------------------------------------------------------------
IniResult Document::LoadFile(CSStr filepath)
{
if (!Validate())
return IniResult("load INI file", SI_BADREF); /* Unable to proceed */
// 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)
{
if (!Validate())
return IniResult("load INI file", SI_BADREF); /* Unable to proceed */
// 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)
{
if (!Validate())
return IniResult("save INI file", SI_BADREF); /* Unable to proceed */
// 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)
{
if (!Validate())
return Object(); /* Unable to proceed */
// The string where the content will be saved
String source;
// Attempt to save the data to string
if (m_Doc->Save(source, signature) < 0)
return Object(); /* Unable to proceed */
// Transform it into a script object
sq_pushstring(DefaultVM::Get(), source.c_str(), source.size());
// Get the object from the stack
Var< Object > var(DefaultVM::Get(), -1);
// Pop the created object from the stack
if (!var.value.IsNull())
sq_pop(DefaultVM::Get(), 1);
// Return the script object
return var.value;
}
// ------------------------------------------------------------------------------------------------
Entries Document::GetAllSections() const
{
if (!Validate())
return Entries(); /* Unable to proceed */
// 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
{
if (!Validate())
return Entries(); /* Unable to proceed */
// 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
{
if (!Validate())
return Entries(); /* Unable to proceed */
// 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
{
if (Validate())
// Return the requested information
return m_Doc->GetSectionSize(section);
// Return invalid size
return -1;
}
// ------------------------------------------------------------------------------------------------
bool Document::HasMultipleKeys(CSStr section, CSStr key) const
{
if (!Validate())
return false; /* Unable to proceed */
// Where to retrive whether the key has multiple instances
bool multiple = false;
// Attempt to query the information
if (m_Doc->GetValue(section, key, NULL, &multiple) == NULL)
return true; /* Doesn't exist */
return multiple;
}
// ------------------------------------------------------------------------------------------------
CCStr Document::GetValue(CSStr section, CSStr key, CSStr def) const
{
if (!Validate())
return _SC(""); /* Unable to proceed */
// Attempt to query the information and return it
return m_Doc->GetValue(section, key, def, NULL);
}
// ------------------------------------------------------------------------------------------------
SQInteger Document::GetInteger(CSStr section, CSStr key, SQInteger def) const
{
if (!Validate())
return 0; /* Unable to proceed */
// Attempt to query the information and return it
return (SQInteger)m_Doc->GetLongValue(section, key, def, NULL);
}
// ------------------------------------------------------------------------------------------------
SQFloat Document::GetFloat(CSStr section, CSStr key, SQFloat def) const
{
if (!Validate())
return SQFloat(0.0); /* Unable to proceed */
// Attempt to query the information and return it
return (SQFloat)m_Doc->GetDoubleValue(section, key, def, NULL);
}
// ------------------------------------------------------------------------------------------------
bool Document::GetBoolean(CSStr section, CSStr key, bool def) const
{
if (!Validate())
return false; /* Unable to proceed */
// Attempt to query the information and return it
return m_Doc->GetBoolValue(section, key, def, NULL);
}
// ------------------------------------------------------------------------------------------------
IniResult Document::SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment)
{
if (!Validate())
return IniResult("set INI value", SI_BADREF); /* Unable to proceed */
// 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)
{
if (!Validate())
return IniResult("set INI integer", SI_BADREF); /* Unable to proceed */
// 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)
{
if (!Validate())
return IniResult("set INI float", SI_BADREF); /* Unable to proceed */
// 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)
{
if (!Validate())
return IniResult("set INI boolean", SI_BADREF); /* Unable to proceed */
// 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)
{
if (!Validate())
return false; /* Unable to proceed */
// Attempt to remove the specified value and return the result
return m_Doc->DeleteValue(section, key, value, empty);
}
} // Namespace:: SqMod

408
modules/ini/Document.hpp Normal file
View File

@ -0,0 +1,408 @@
#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);
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
bool Validate() const;
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.
*/
CSStr Typename() const
{
return _SC("SqIniDocument");
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid INI document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* See whether any data has been loaded into this document.
*/
bool IsEmpty() const
{
return m_Doc->IsEmpty();
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* 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, NULL);
}
/* --------------------------------------------------------------------------------------------
* Add or update a section or value.
*/
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force)
{
return SetValue(section, key, value, force, NULL);
}
/* --------------------------------------------------------------------------------------------
* 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, NULL);
}
/* --------------------------------------------------------------------------------------------
* Add or update a numeric value.
*/
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex)
{
return SetInteger(section, key, value, hex, false, NULL);
}
/* --------------------------------------------------------------------------------------------
* 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, NULL);
}
/* --------------------------------------------------------------------------------------------
* 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, NULL);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force)
{
return SetFloat(section, key, value, force, NULL);
}
/* --------------------------------------------------------------------------------------------
* 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, NULL);
}
/* --------------------------------------------------------------------------------------------
* Add or update a double value.
*/
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force)
{
return SetBoolean(section, key, value, force, NULL);
}
/* --------------------------------------------------------------------------------------------
* 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, NULL, NULL, false);
}
/* --------------------------------------------------------------------------------------------
* Delete an entire section, or a key from a section.
*/
bool DeleteValue(CSStr section, CSStr key)
{
return DeleteValue(section, key, NULL, 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_

85
modules/ini/Entries.cpp Normal file
View File

@ -0,0 +1,85 @@
// ------------------------------------------------------------------------------------------------
#include "Entries.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
Int32 Entries::Cmp(const Entries & o) const
{
if (m_Elem == o.m_Elem)
return 0;
else if (this > &o)
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
{
if (m_List.empty() || m_Elem == m_List.end())
_SqMod->SqThrow("Invalid INI entry [item]");
else
return m_Elem->pItem;
return _SC("");
}
// ------------------------------------------------------------------------------------------------
CSStr Entries::GetComment() const
{
if (m_List.empty() || m_Elem == m_List.end())
_SqMod->SqThrow("Invalid INI entry [comment]");
else
return m_Elem->pComment;
return _SC("");
}
// ------------------------------------------------------------------------------------------------
Int32 Entries::GetOrder() const
{
if (m_List.empty() || m_Elem == m_List.end())
_SqMod->SqThrow("Invalid INI entry [order]");
else
return m_Elem->nOrder;
return -1;
}
} // Namespace:: SqMod

220
modules/ini/Entries.hpp Normal file
View File

@ -0,0 +1,220 @@
#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.
*/
CSStr Typename() const
{
return _SC("SqIniEntries");
}
/* --------------------------------------------------------------------------------------------
* 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 (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());
}
/* --------------------------------------------------------------------------------------------
* Sort the entries by their load order but empty name always goes first.
*/
void SortByLoadOrderEmptyFirst()
{
if (!m_List.empty())
m_List.sort(DocumentRef::Type::Entry::LoadOrderEmptyFirst());
}
/* --------------------------------------------------------------------------------------------
* 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_

414
modules/ini/Module.cpp Normal file
View File

@ -0,0 +1,414 @@
// --------------------------------------------------------------------------------------------
#include "Module.hpp"
#include "Common.hpp"
#include "Entries.hpp"
#include "Document.hpp"
// --------------------------------------------------------------------------------------------
#include <sqrat.h>
// --------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
// --------------------------------------------------------------------------------------------
#if defined(WIN32) || defined(_WIN32)
#include <Windows.h>
#endif
namespace SqMod {
// --------------------------------------------------------------------------------------------
PluginFuncs* _Func = NULL;
PluginCallbacks* _Clbk = NULL;
PluginInfo* _Info = NULL;
// --------------------------------------------------------------------------------------------
HSQAPI _SqAPI = NULL;
HSQEXPORTS _SqMod = NULL;
HSQUIRRELVM _SqVM = NULL;
/* ------------------------------------------------------------------------------------------------
* 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 database (if any)
DefaultVM::Set(NULL);
}
/* --------------------------------------------------------------------------------------------
* 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 = strtol(ver, NULL, 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 int OnInternalCommand(unsigned int type, const char * text)
{
switch(type)
{
case SQMOD_INITIALIZE_CMD:
if (CheckAPIVer(text))
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 int OnInitServer()
{
return 1;
}
static void OnShutdownServer(void)
{
// The server may still send callbacks
UnbindCallbacks();
}
// ------------------------------------------------------------------------------------------------
void BindCallbacks()
{
_Clbk->OnInitServer = OnInitServer;
_Clbk->OnInternalCommand = OnInternalCommand;
_Clbk->OnShutdownServer = OnShutdownServer;
}
// ------------------------------------------------------------------------------------------------
void UnbindCallbacks()
{
_Clbk->OnInitServer = NULL;
_Clbk->OnInternalCommand = NULL;
_Clbk->OnShutdownServer = NULL;
}
// --------------------------------------------------------------------------------------------
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)
.Func(_SC("_tostring"), &IniResult::ToString)
.Func(_SC("_typename"), &IniResult::Typename)
/* Properties */
.Prop(_SC("Valid"), &IniResult::IsValid)
.Prop(_SC("Action"), &IniResult::GetAction)
.Prop(_SC("Result"), &IniResult::GetResult)
/* Functions */
.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)
.Func(_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)
/* Functions */
.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)
.Func(_SC("SortByLoadOrderEmptyFirst"), &Entries::SortByLoadOrderEmptyFirst)
);
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)
.Func(_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)
/* Functions */
.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))
.Const(_SC("BadRef"), Int32(SI_BADREF))
);
}
// --------------------------------------------------------------------------------------------
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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 (host_plugin_id > (info->nPluginId))
{
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 information
_Info->uPluginVer = SQINI_VERSION;
strcpy(_Info->szName, 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;
}

41
modules/ini/Module.hpp Normal file
View File

@ -0,0 +1,41 @@
#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_

33
modules/irc/Common.cpp Normal file
View File

@ -0,0 +1,33 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <libircclient.h>
#include <libirc_rfcnumeric.h>
// ------------------------------------------------------------------------------------------------
static SQChar g_Buffer[512];
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
CSStr GetNick(CSStr origin)
{
// Attempt to retrieve the nickname
irc_target_get_nick(origin, g_Buffer, sizeof(g_Buffer));
// Return the nickname that could be retrieved
return g_Buffer;
}
// ------------------------------------------------------------------------------------------------
CSStr GetHost(CSStr target)
{
// Attempt to retrieve the host
irc_target_get_host(target, g_Buffer, sizeof(g_Buffer));
// Return the host that could be retrieved
return g_Buffer;
}
} // Namespace:: SqMod

40
modules/irc/Common.hpp Normal file
View File

@ -0,0 +1,40 @@
#ifndef _SQIRC_COMMON_HPP_
#define _SQIRC_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "ModBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQIRC_NAME "Squirrel IRC Module"
#define SQIRC_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQIRC_COPYRIGHT "Copyright (C) 2016 Sandu Liviu Catalin"
#define SQIRC_HOST_NAME "SqModIRCHost"
#define SQIRC_VERSION 001
#define SQIRC_VERSION_STR "0.0.1"
#define SQIRC_VERSION_MAJOR 0
#define SQIRC_VERSION_MINOR 0
#define SQIRC_VERSION_PATCH 1
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
class Session;
/* ------------------------------------------------------------------------------------------------
* Extract the name from the specified origin.
*/
CSStr GetNick(CSStr origin);
/* ------------------------------------------------------------------------------------------------
* Extract the host from the specified origin.
*/
CSStr GetHost(CSStr target);
} // Namespace:: SqMod
#endif // _SQIRC_COMMON_HPP_

620
modules/irc/Module.cpp Normal file
View File

@ -0,0 +1,620 @@
// --------------------------------------------------------------------------------------------
#include "Module.hpp"
#include "Common.hpp"
#include "Session.hpp"
// --------------------------------------------------------------------------------------------
#include <sqrat.h>
// --------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
// --------------------------------------------------------------------------------------------
#if defined(WIN32) || defined(_WIN32)
#include <Windows.h>
#include <Winsock2.h>
#endif
namespace SqMod {
// --------------------------------------------------------------------------------------------
PluginFuncs* _Func = NULL;
PluginCallbacks* _Clbk = NULL;
PluginInfo* _Info = NULL;
// --------------------------------------------------------------------------------------------
HSQAPI _SqAPI = NULL;
HSQEXPORTS _SqMod = NULL;
HSQUIRRELVM _SqVM = NULL;
/* ------------------------------------------------------------------------------------------------
* 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.", SQIRC_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", SQIRC_NAME);
}
/* --------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQIRC_NAME);
// Terminate all session and release script resources
Session::Terminate();
// Release the current database (if any)
DefaultVM::Set(NULL);
}
/* --------------------------------------------------------------------------------------------
* Update the plugin on each frame.
*/
static void OnFrame(float /*delta*/)
{
// Update the sessions and pool for events
Session::Process();
}
/* --------------------------------------------------------------------------------------------
* 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 = strtol(ver, NULL, 10);
// Check against version mismatch
if (vernum == SQMOD_API_VER)
return true;
// Log the incident
OutputError("API version mismatch on %s", SQIRC_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 int OnInternalCommand(unsigned int type, const char * text)
{
switch(type)
{
case SQMOD_INITIALIZE_CMD:
if (CheckAPIVer(text))
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 int OnInitServer()
{
return 1;
}
static void OnShutdownServer(void)
{
// The server may still send callbacks
UnbindCallbacks();
}
// ------------------------------------------------------------------------------------------------
void BindCallbacks()
{
_Clbk->OnInitServer = OnInitServer;
_Clbk->OnFrame = OnFrame;
_Clbk->OnInternalCommand = OnInternalCommand;
_Clbk->OnShutdownServer = OnShutdownServer;
}
// ------------------------------------------------------------------------------------------------
void UnbindCallbacks()
{
_Clbk->OnInitServer = NULL;
_Clbk->OnFrame = NULL;
_Clbk->OnInternalCommand = NULL;
_Clbk->OnShutdownServer = NULL;
}
// --------------------------------------------------------------------------------------------
void RegisterAPI(HSQUIRRELVM vm)
{
Table ircns(vm);
ircns.Bind(_SC("Session"), Class< Session, NoCopy< Session > >(vm, _SC("SqIrcSession"))
/* Constructors */
.Ctor()
/* Core Metamethods */
.Func(_SC("_cmp"), &Session::Cmp)
.Func(_SC("_typename"), &Session::Typename)
.Func(_SC("_tostring"), &Session::ToString)
/* Properties */
.Prop(_SC("Valid"), &Session::IsValid)
.Prop(_SC("Connected"), &Session::IsConnected)
.Prop(_SC("Tag"), &Session::GetTag, &Session::SetTag)
.Prop(_SC("Data"), &Session::GetData, &Session::SetData)
.Prop(_SC("Server"), &Session::GetServer, &Session::SetServer)
.Prop(_SC("Password"), &Session::GetPassword, &Session::SetPassword)
.Prop(_SC("Nick"), &Session::GetNick, &Session::SetNick)
.Prop(_SC("User"), &Session::GetUser, &Session::SetUser)
.Prop(_SC("Name"), &Session::GetName, &Session::SetName)
.Prop(_SC("Port"), &Session::GetPort, &Session::SetPort)
.Prop(_SC("PoolTime"), &Session::GetPoolTime, &Session::SetPoolTime)
.Prop(_SC("LastCode"), &Session::GetLastCode)
.Prop(_SC("Tries"), &Session::GetTries, &Session::SetTries)
.Prop(_SC("Wait"), &Session::GetWait, &Session::SetWait)
.Prop(_SC("LeftTries"), &Session::GetLeftTries, &Session::SetLeftTries)
.Prop(_SC("NextTry"), &Session::GetNextTry, &Session::SetNextTry)
.Prop(_SC("SessionTime"), &Session::GetSessionTime)
.Prop(_SC("Reconnecting"), &Session::GetReconnect)
.Prop(_SC("IPv6"), &Session::GetIPv6)
.Prop(_SC("Server"), &Session::GetServer, &Session::SetServer)
.Prop(_SC("CtcpVersion"), (void (Session::*)(void))(NULL), &Session::SetCtcpVersion)
.Prop(_SC("ErrNo"), &Session::GetErrNo)
.Prop(_SC("ErrStr"), &Session::GetErrStr)
.Prop(_SC("OnConnect"), &Session::GetOnConnect)
.Prop(_SC("OnNick"), &Session::GetOnNick)
.Prop(_SC("OnQuit"), &Session::GetOnQuit)
.Prop(_SC("OnJoin"), &Session::GetOnJoin)
.Prop(_SC("OnPart"), &Session::GetOnPart)
.Prop(_SC("OnMode"), &Session::GetOnMode)
.Prop(_SC("OnUmode"), &Session::GetOnUmode)
.Prop(_SC("OnTopic"), &Session::GetOnTopic)
.Prop(_SC("OnKick"), &Session::GetOnKick)
.Prop(_SC("OnChannel"), &Session::GetOnChannel)
.Prop(_SC("OnPrivMsg"), &Session::GetOnPrivMsg)
.Prop(_SC("OnNotice"), &Session::GetOnNotice)
.Prop(_SC("OnChannelNotice"), &Session::GetOnChannelNotice)
.Prop(_SC("OnInvite"), &Session::GetOnInvite)
.Prop(_SC("OnCtcpReq"), &Session::GetOnCtcpReq)
.Prop(_SC("OnCtcpRep"), &Session::GetOnCtcpRep)
.Prop(_SC("OnCtcpAction"), &Session::GetOnCtcpAction)
.Prop(_SC("OnUnknown"), &Session::GetOnUnknown)
.Prop(_SC("OnNumeric"), &Session::GetOnNumeric)
.Prop(_SC("OnDccChatReq"), &Session::GetOnDccChatReq)
.Prop(_SC("OnDccSendReq"), &Session::GetOnDccSendReq)
/* Functions */
.Overload< Int32 (Session::*)(void) >(_SC("Connect"), &Session::Connect)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr) >(_SC("Connect"), &Session::Connect)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr, CSStr) >(_SC("Connect"), &Session::Connect)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr, CSStr, CSStr) >(_SC("Connect"), &Session::Connect)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr, CSStr, CSStr, CSStr) >(_SC("Connect"), &Session::Connect)
.Overload< Int32 (Session::*)(void) >(_SC("Connect6"), &Session::Connect6)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr) >(_SC("Connect6"), &Session::Connect6)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr, CSStr) >(_SC("Connect6"), &Session::Connect6)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr, CSStr, CSStr) >(_SC("Connect6"), &Session::Connect6)
.Overload< Int32 (Session::*)(CSStr, Uint32, CSStr, CSStr, CSStr, CSStr) >(_SC("Connect6"), &Session::Connect6)
.Func(_SC("Disconnect"), &Session::Disconnect)
.Overload< Int32 (Session::*)(CSStr) >(_SC("CmdJoin"), &Session::CmdJoin)
.Overload< Int32 (Session::*)(CSStr, CSStr) >(_SC("CmdJoin"), &Session::CmdJoin)
.Func(_SC("CmdPart"), &Session::CmdPart)
.Func(_SC("CmdInvite"), &Session::CmdInvite)
.Func(_SC("CmdNames"), &Session::CmdNames)
.Overload< Int32 (Session::*)(void) >(_SC("CmdList"), &Session::CmdList)
.Overload< Int32 (Session::*)(CSStr) >(_SC("CmdList"), &Session::CmdList)
.Overload< Int32 (Session::*)(CSStr) >(_SC("CmdTopic"), &Session::CmdTopic)
.Overload< Int32 (Session::*)(CSStr, CSStr) >(_SC("CmdTopic"), &Session::CmdTopic)
.Overload< Int32 (Session::*)(CSStr) >(_SC("CmdChannelMode"), &Session::CmdChannelMode)
.Overload< Int32 (Session::*)(CSStr, CSStr) >(_SC("CmdChannelMode"), &Session::CmdChannelMode)
.Overload< Int32 (Session::*)(void) >(_SC("CmdUserMode"), &Session::CmdUserMode)
.Overload< Int32 (Session::*)(CSStr) >(_SC("CmdUserMode"), &Session::CmdUserMode)
.Overload< Int32 (Session::*)(CSStr, CSStr) >(_SC("CmdKick"), &Session::CmdKick)
.Overload< Int32 (Session::*)(CSStr, CSStr, CSStr) >(_SC("CmdKick"), &Session::CmdKick)
.Func(_SC("CmdMsg"), &Session::CmdMsg)
.Func(_SC("CmdMe"), &Session::CmdMe)
.Func(_SC("CmdNotice"), &Session::CmdNotice)
.Func(_SC("CmdCtcpRequest"), &Session::CmdCtcpRequest)
.Func(_SC("CmdCtcpReply"), &Session::CmdCtcpReply)
.Func(_SC("CmdNick"), &Session::CmdNick)
.Func(_SC("CmdWhois"), &Session::CmdWhois)
.Overload< Int32 (Session::*)(void) >(_SC("CmdQuit"), &Session::CmdQuit)
.Overload< Int32 (Session::*)(CSStr) >(_SC("CmdQuit"), &Session::CmdQuit)
.Func(_SC("SendRaw"), &Session::SendRaw)
.Func(_SC("DestroyDcc"), &Session::DestroyDcc)
.Func(_SC("SetCtcpVersion"), &Session::SetCtcpVersion)
.Func(_SC("SetOption"), &Session::SetOption)
.Func(_SC("ResetOption"), &Session::ResetOption)
.Func(_SC("BindConnect"), &Session::BindOnConnect)
.Func(_SC("BindNick"), &Session::BindOnNick)
.Func(_SC("BindQuit"), &Session::BindOnQuit)
.Func(_SC("BindJoin"), &Session::BindOnJoin)
.Func(_SC("BindPart"), &Session::BindOnPart)
.Func(_SC("BindMode"), &Session::BindOnMode)
.Func(_SC("BindUmode"), &Session::BindOnUmode)
.Func(_SC("BindTopic"), &Session::BindOnTopic)
.Func(_SC("BindKick"), &Session::BindOnKick)
.Func(_SC("BindChannel"), &Session::BindOnChannel)
.Func(_SC("BindPrivMsg"), &Session::BindOnPrivMsg)
.Func(_SC("BindNotice"), &Session::BindOnNotice)
.Func(_SC("BindChannelNotice"), &Session::BindOnChannelNotice)
.Func(_SC("BindInvite"), &Session::BindOnInvite)
.Func(_SC("BindCtcpReq"), &Session::BindOnCtcpReq)
.Func(_SC("BindCtcpRep"), &Session::BindOnCtcpRep)
.Func(_SC("BindCtcpAction"), &Session::BindOnCtcpAction)
.Func(_SC("BindUnknown"), &Session::BindOnUnknown)
.Func(_SC("BindNumeric"), &Session::BindOnNumeric)
.Func(_SC("BindDccChatReq"), &Session::BindOnDccChatReq)
.Func(_SC("BindDccSendReq"), &Session::BindOnDccSendReq)
.SquirrelFunc(_SC("CmdMsgF"), &Session::CmdMsgF)
.SquirrelFunc(_SC("CmdMeF"), &Session::CmdMeF)
.SquirrelFunc(_SC("CmdNoticeF"), &Session::CmdNoticeF)
);
ircns.Func(_SC("GetNick"), &GetNick);
ircns.Func(_SC("GetHost"), &GetHost);
ircns.Func(_SC("GetErrStr"), &irc_strerror);
RootTable(vm).Bind(_SC("SqIrc"), ircns);
Sqrat::ConstTable(vm).Enum(_SC("SqIrcErr"), Sqrat::Enumeration(vm)
.Const(_SC("Ok"), LIBIRC_ERR_OK)
.Const(_SC("InVal"), LIBIRC_ERR_INVAL)
.Const(_SC("Resolv"), LIBIRC_ERR_RESOLV)
.Const(_SC("Socket"), LIBIRC_ERR_SOCKET)
.Const(_SC("Connect"), LIBIRC_ERR_CONNECT)
.Const(_SC("Closed"), LIBIRC_ERR_CLOSED)
.Const(_SC("NoMem"), LIBIRC_ERR_NOMEM)
.Const(_SC("Accept"), LIBIRC_ERR_ACCEPT)
.Const(_SC("NoDccSend"), LIBIRC_ERR_NODCCSEND)
.Const(_SC("Read"), LIBIRC_ERR_READ)
.Const(_SC("Write"), LIBIRC_ERR_WRITE)
.Const(_SC("State"), LIBIRC_ERR_STATE)
.Const(_SC("Timeout"), LIBIRC_ERR_TIMEOUT)
.Const(_SC("OpenFile"), LIBIRC_ERR_OPENFILE)
.Const(_SC("Terminated"), LIBIRC_ERR_TERMINATED)
.Const(_SC("NoIPv6"), LIBIRC_ERR_NOIPV6)
.Const(_SC("SSLNotSupported"), LIBIRC_ERR_SSL_NOT_SUPPORTED)
.Const(_SC("SSLInitFailed"), LIBIRC_ERR_SSL_INIT_FAILED)
.Const(_SC("ConnectSSLFailed"), LIBIRC_ERR_CONNECT_SSL_FAILED)
.Const(_SC("SSLCertVerifyFailed"), LIBIRC_ERR_SSL_CERT_VERIFY_FAILED)
.Const(_SC("Max"), LIBIRC_ERR_MAX)
);
Sqrat::ConstTable(vm).Enum(_SC("SqIrcOpt"), Sqrat::Enumeration(vm)
.Const(_SC("Debug"), LIBIRC_OPTION_DEBUG)
.Const(_SC("StripNicks"), LIBIRC_OPTION_STRIPNICKS)
.Const(_SC("SSLNoVerify"), LIBIRC_OPTION_SSL_NO_VERIFY)
);
Sqrat::ConstTable(vm).Enum(_SC("SqIrcRFC"), Sqrat::Enumeration(vm)
.Const(_SC("RPL_WELCOME"), LIBIRC_RFC_RPL_WELCOME)
.Const(_SC("RPL_YOURHOST"), LIBIRC_RFC_RPL_YOURHOST)
.Const(_SC("RPL_CREATED"), LIBIRC_RFC_RPL_CREATED)
.Const(_SC("RPL_MYINFO"), LIBIRC_RFC_RPL_MYINFO)
.Const(_SC("RPL_BOUNCE"), LIBIRC_RFC_RPL_BOUNCE)
.Const(_SC("RPL_NONE"), LIBIRC_RFC_RPL_NONE)
.Const(_SC("RPL_USERHOST"), LIBIRC_RFC_RPL_USERHOST)
.Const(_SC("RPL_ISON"), LIBIRC_RFC_RPL_ISON)
.Const(_SC("RPL_AWAY"), LIBIRC_RFC_RPL_AWAY)
.Const(_SC("RPL_UNAWAY"), LIBIRC_RFC_RPL_UNAWAY)
.Const(_SC("RPL_NOWAWAY"), LIBIRC_RFC_RPL_NOWAWAY)
.Const(_SC("RPL_WHOISUSER"), LIBIRC_RFC_RPL_WHOISUSER)
.Const(_SC("RPL_WHOISSERVER"), LIBIRC_RFC_RPL_WHOISSERVER)
.Const(_SC("RPL_WHOISOPERATOR"), LIBIRC_RFC_RPL_WHOISOPERATOR)
.Const(_SC("RPL_WHOISIDLE"), LIBIRC_RFC_RPL_WHOISIDLE)
.Const(_SC("RPL_ENDOFWHOIS"), LIBIRC_RFC_RPL_ENDOFWHOIS)
.Const(_SC("RPL_WHOISCHANNELS"), LIBIRC_RFC_RPL_WHOISCHANNELS)
.Const(_SC("RPL_WHOWASUSER"), LIBIRC_RFC_RPL_WHOWASUSER)
.Const(_SC("RPL_ENDOFWHOWAS"), LIBIRC_RFC_RPL_ENDOFWHOWAS)
.Const(_SC("RPL_LISTSTART"), LIBIRC_RFC_RPL_LISTSTART)
.Const(_SC("RPL_LIST"), LIBIRC_RFC_RPL_LIST)
.Const(_SC("RPL_LISTEND"), LIBIRC_RFC_RPL_LISTEND)
.Const(_SC("RPL_UNIQOPIS"), LIBIRC_RFC_RPL_UNIQOPIS)
.Const(_SC("RPL_CHANNELMODEIS"), LIBIRC_RFC_RPL_CHANNELMODEIS)
.Const(_SC("RPL_NOTOPIC"), LIBIRC_RFC_RPL_NOTOPIC)
.Const(_SC("RPL_TOPIC"), LIBIRC_RFC_RPL_TOPIC)
.Const(_SC("RPL_INVITING"), LIBIRC_RFC_RPL_INVITING)
.Const(_SC("RPL_SUMMONING"), LIBIRC_RFC_RPL_SUMMONING)
.Const(_SC("RPL_INVITELIST"), LIBIRC_RFC_RPL_INVITELIST)
.Const(_SC("RPL_ENDOFINVITELIST"), LIBIRC_RFC_RPL_ENDOFINVITELIST)
.Const(_SC("RPL_EXCEPTLIST"), LIBIRC_RFC_RPL_EXCEPTLIST)
.Const(_SC("RPL_ENDOFEXCEPTLIST"), LIBIRC_RFC_RPL_ENDOFEXCEPTLIST)
.Const(_SC("RPL_VERSION"), LIBIRC_RFC_RPL_VERSION)
.Const(_SC("RPL_WHOREPLY"), LIBIRC_RFC_RPL_WHOREPLY)
.Const(_SC("RPL_ENDOFWHO"), LIBIRC_RFC_RPL_ENDOFWHO)
.Const(_SC("RPL_NAMREPLY"), LIBIRC_RFC_RPL_NAMREPLY)
.Const(_SC("RPL_ENDOFNAMES"), LIBIRC_RFC_RPL_ENDOFNAMES)
.Const(_SC("RPL_LINKS"), LIBIRC_RFC_RPL_LINKS)
.Const(_SC("RPL_ENDOFLINKS"), LIBIRC_RFC_RPL_ENDOFLINKS)
.Const(_SC("RPL_BANLIST"), LIBIRC_RFC_RPL_BANLIST)
.Const(_SC("RPL_ENDOFBANLIST"), LIBIRC_RFC_RPL_ENDOFBANLIST)
.Const(_SC("RPL_INFO"), LIBIRC_RFC_RPL_INFO)
.Const(_SC("RPL_ENDOFINFO"), LIBIRC_RFC_RPL_ENDOFINFO)
.Const(_SC("RPL_MOTDSTART"), LIBIRC_RFC_RPL_MOTDSTART)
.Const(_SC("RPL_MOTD"), LIBIRC_RFC_RPL_MOTD)
.Const(_SC("RPL_ENDOFMOTD"), LIBIRC_RFC_RPL_ENDOFMOTD)
.Const(_SC("RPL_YOUREOPER"), LIBIRC_RFC_RPL_YOUREOPER)
.Const(_SC("RPL_REHASHING"), LIBIRC_RFC_RPL_REHASHING)
.Const(_SC("RPL_YOURESERVICE"), LIBIRC_RFC_RPL_YOURESERVICE)
.Const(_SC("RPL_TIME"), LIBIRC_RFC_RPL_TIME)
.Const(_SC("RPL_USERSSTART"), LIBIRC_RFC_RPL_USERSSTART)
.Const(_SC("RPL_USERS"), LIBIRC_RFC_RPL_USERS)
.Const(_SC("RPL_ENDOFUSERS"), LIBIRC_RFC_RPL_ENDOFUSERS)
.Const(_SC("RPL_NOUSERS"), LIBIRC_RFC_RPL_NOUSERS)
.Const(_SC("RPL_TRACELINK"), LIBIRC_RFC_RPL_TRACELINK)
.Const(_SC("RPL_TRACECONNECTING"), LIBIRC_RFC_RPL_TRACECONNECTING)
.Const(_SC("RPL_TRACEHANDSHAKE"), LIBIRC_RFC_RPL_TRACEHANDSHAKE)
.Const(_SC("RPL_TRACEUNKNOWN"), LIBIRC_RFC_RPL_TRACEUNKNOWN)
.Const(_SC("RPL_TRACEOPERATOR"), LIBIRC_RFC_RPL_TRACEOPERATOR)
.Const(_SC("RPL_TRACEUSER"), LIBIRC_RFC_RPL_TRACEUSER)
.Const(_SC("RPL_TRACESERVER"), LIBIRC_RFC_RPL_TRACESERVER)
.Const(_SC("RPL_TRACESERVICE"), LIBIRC_RFC_RPL_TRACESERVICE)
.Const(_SC("RPL_TRACENEWTYPE"), LIBIRC_RFC_RPL_TRACENEWTYPE)
.Const(_SC("RPL_TRACECLASS"), LIBIRC_RFC_RPL_TRACECLASS)
.Const(_SC("RPL_TRACELOG"), LIBIRC_RFC_RPL_TRACELOG)
.Const(_SC("RPL_TRACEEND"), LIBIRC_RFC_RPL_TRACEEND)
.Const(_SC("RPL_STATSLINKINFO"), LIBIRC_RFC_RPL_STATSLINKINFO)
.Const(_SC("RPL_STATSCOMMANDS"), LIBIRC_RFC_RPL_STATSCOMMANDS)
.Const(_SC("RPL_ENDOFSTATS"), LIBIRC_RFC_RPL_ENDOFSTATS)
.Const(_SC("RPL_STATSUPTIME"), LIBIRC_RFC_RPL_STATSUPTIME)
.Const(_SC("RPL_STATSOLINE"), LIBIRC_RFC_RPL_STATSOLINE)
.Const(_SC("RPL_UMODEIS"), LIBIRC_RFC_RPL_UMODEIS)
.Const(_SC("RPL_SERVLIST"), LIBIRC_RFC_RPL_SERVLIST)
.Const(_SC("RPL_SERVLISTEND"), LIBIRC_RFC_RPL_SERVLISTEND)
.Const(_SC("RPL_LUSERCLIENT"), LIBIRC_RFC_RPL_LUSERCLIENT)
.Const(_SC("RPL_LUSEROP"), LIBIRC_RFC_RPL_LUSEROP)
.Const(_SC("RPL_LUSERUNKNOWN"), LIBIRC_RFC_RPL_LUSERUNKNOWN)
.Const(_SC("RPL_LUSERCHANNELS"), LIBIRC_RFC_RPL_LUSERCHANNELS)
.Const(_SC("RPL_LUSERME"), LIBIRC_RFC_RPL_LUSERME)
.Const(_SC("RPL_ADMINME"), LIBIRC_RFC_RPL_ADMINME)
.Const(_SC("RPL_ADMINLOC1"), LIBIRC_RFC_RPL_ADMINLOC1)
.Const(_SC("RPL_ADMINLOC2"), LIBIRC_RFC_RPL_ADMINLOC2)
.Const(_SC("RPL_ADMINEMAIL"), LIBIRC_RFC_RPL_ADMINEMAIL)
.Const(_SC("RPL_TRYAGAIN"), LIBIRC_RFC_RPL_TRYAGAIN)
.Const(_SC("ERR_NOSUCHNICK"), LIBIRC_RFC_ERR_NOSUCHNICK)
.Const(_SC("ERR_NOSUCHSERVER"), LIBIRC_RFC_ERR_NOSUCHSERVER)
.Const(_SC("ERR_NOSUCHCHANNEL"), LIBIRC_RFC_ERR_NOSUCHCHANNEL)
.Const(_SC("ERR_CANNOTSENDTOCHAN"), LIBIRC_RFC_ERR_CANNOTSENDTOCHAN)
.Const(_SC("ERR_TOOMANYCHANNELS"), LIBIRC_RFC_ERR_TOOMANYCHANNELS)
.Const(_SC("ERR_WASNOSUCHNICK"), LIBIRC_RFC_ERR_WASNOSUCHNICK)
.Const(_SC("ERR_TOOMANYTARGETS"), LIBIRC_RFC_ERR_TOOMANYTARGETS)
.Const(_SC("ERR_NOSUCHSERVICE"), LIBIRC_RFC_ERR_NOSUCHSERVICE)
.Const(_SC("ERR_NOORIGIN"), LIBIRC_RFC_ERR_NOORIGIN)
.Const(_SC("ERR_NORECIPIENT"), LIBIRC_RFC_ERR_NORECIPIENT)
.Const(_SC("ERR_NOTEXTTOSEND"), LIBIRC_RFC_ERR_NOTEXTTOSEND)
.Const(_SC("ERR_NOTOPLEVEL"), LIBIRC_RFC_ERR_NOTOPLEVEL)
.Const(_SC("ERR_WILDTOPLEVEL"), LIBIRC_RFC_ERR_WILDTOPLEVEL)
.Const(_SC("ERR_BADMASK"), LIBIRC_RFC_ERR_BADMASK)
.Const(_SC("ERR_UNKNOWNCOMMAND"), LIBIRC_RFC_ERR_UNKNOWNCOMMAND)
.Const(_SC("ERR_NOMOTD"), LIBIRC_RFC_ERR_NOMOTD)
.Const(_SC("ERR_NOADMININFO"), LIBIRC_RFC_ERR_NOADMININFO)
.Const(_SC("ERR_FILEERROR"), LIBIRC_RFC_ERR_FILEERROR)
.Const(_SC("ERR_NONICKNAMEGIVEN"), LIBIRC_RFC_ERR_NONICKNAMEGIVEN)
.Const(_SC("ERR_ERRONEUSNICKNAME"), LIBIRC_RFC_ERR_ERRONEUSNICKNAME)
.Const(_SC("ERR_NICKNAMEINUSE"), LIBIRC_RFC_ERR_NICKNAMEINUSE)
.Const(_SC("ERR_NICKCOLLISION"), LIBIRC_RFC_ERR_NICKCOLLISION)
.Const(_SC("ERR_UNAVAILRESOURCE"), LIBIRC_RFC_ERR_UNAVAILRESOURCE)
.Const(_SC("ERR_USERNOTINCHANNEL"), LIBIRC_RFC_ERR_USERNOTINCHANNEL)
.Const(_SC("ERR_NOTONCHANNEL"), LIBIRC_RFC_ERR_NOTONCHANNEL)
.Const(_SC("ERR_USERONCHANNEL"), LIBIRC_RFC_ERR_USERONCHANNEL)
.Const(_SC("ERR_NOLOGIN"), LIBIRC_RFC_ERR_NOLOGIN)
.Const(_SC("ERR_SUMMONDISABLED"), LIBIRC_RFC_ERR_SUMMONDISABLED)
.Const(_SC("ERR_USERSDISABLED"), LIBIRC_RFC_ERR_USERSDISABLED)
.Const(_SC("ERR_NOTREGISTERED"), LIBIRC_RFC_ERR_NOTREGISTERED)
.Const(_SC("ERR_NEEDMOREPARAMS"), LIBIRC_RFC_ERR_NEEDMOREPARAMS)
.Const(_SC("ERR_ALREADYREGISTRED"), LIBIRC_RFC_ERR_ALREADYREGISTRED)
.Const(_SC("ERR_NOPERMFORHOST"), LIBIRC_RFC_ERR_NOPERMFORHOST)
.Const(_SC("ERR_PASSWDMISMATCH"), LIBIRC_RFC_ERR_PASSWDMISMATCH)
.Const(_SC("ERR_YOUREBANNEDCREEP"), LIBIRC_RFC_ERR_YOUREBANNEDCREEP)
.Const(_SC("ERR_YOUWILLBEBANNED"), LIBIRC_RFC_ERR_YOUWILLBEBANNED)
.Const(_SC("ERR_KEYSET"), LIBIRC_RFC_ERR_KEYSET)
.Const(_SC("ERR_CHANNELISFULL"), LIBIRC_RFC_ERR_CHANNELISFULL)
.Const(_SC("ERR_UNKNOWNMODE"), LIBIRC_RFC_ERR_UNKNOWNMODE)
.Const(_SC("ERR_INVITEONLYCHAN"), LIBIRC_RFC_ERR_INVITEONLYCHAN)
.Const(_SC("ERR_BANNEDFROMCHAN"), LIBIRC_RFC_ERR_BANNEDFROMCHAN)
.Const(_SC("ERR_BADCHANNELKEY"), LIBIRC_RFC_ERR_BADCHANNELKEY)
.Const(_SC("ERR_BADCHANMASK"), LIBIRC_RFC_ERR_BADCHANMASK)
.Const(_SC("ERR_NOCHANMODES"), LIBIRC_RFC_ERR_NOCHANMODES)
.Const(_SC("ERR_BANLISTFULL"), LIBIRC_RFC_ERR_BANLISTFULL)
.Const(_SC("ERR_NOPRIVILEGES"), LIBIRC_RFC_ERR_NOPRIVILEGES)
.Const(_SC("ERR_CHANOPRIVSNEEDED"), LIBIRC_RFC_ERR_CHANOPRIVSNEEDED)
.Const(_SC("ERR_CANTKILLSERVER"), LIBIRC_RFC_ERR_CANTKILLSERVER)
.Const(_SC("ERR_RESTRICTED"), LIBIRC_RFC_ERR_RESTRICTED)
.Const(_SC("ERR_UNIQOPPRIVSNEEDED"), LIBIRC_RFC_ERR_UNIQOPPRIVSNEEDED)
.Const(_SC("ERR_NOOPERHOST"), LIBIRC_RFC_ERR_NOOPERHOST)
.Const(_SC("ERR_UMODEUNKNOWNFLAG"), LIBIRC_RFC_ERR_UMODEUNKNOWNFLAG)
.Const(_SC("ERR_USERSDONTMATCH"), LIBIRC_RFC_ERR_USERSDONTMATCH)
);
}
// --------------------------------------------------------------------------------------------
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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", SQIRC_NAME);
OutputMessage("Author: %s", SQIRC_AUTHOR);
OutputMessage("Legal: %s", SQIRC_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", SQIRC_NAME);
// Don't load!
return SQMOD_FAILURE;
}
// Should never reach this point but just in case
else if (host_plugin_id > (info->nPluginId))
{
OutputError("%s loaded after the host plugin", SQIRC_NAME);
// Don't load!
return SQMOD_FAILURE;
}
#if defined(_WIN32)
WSADATA wsa_data;
// Initialize the sockets on windows
if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
{
OutputError("Unable to start because the windows sockets could not be initialized");
return SQMOD_FAILURE;
}
#endif // _WIN32
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plugin information
_Info->uPluginVer = SQIRC_VERSION;
strcpy(_Info->szName, SQIRC_HOST_NAME);
// Bind callbacks
BindCallbacks();
// Notify that the plugin was successfully loaded
OutputMessage("Successfully loaded %s", SQIRC_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

41
modules/irc/Module.hpp Normal file
View File

@ -0,0 +1,41 @@
#ifndef _SQIRC_MODULE_HPP_
#define _SQIRC_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 // _SQIRC_MODULE_HPP_

1038
modules/irc/Session.cpp Normal file

File diff suppressed because it is too large Load Diff

1398
modules/irc/Session.hpp Normal file

File diff suppressed because it is too large Load Diff

24
modules/sample/Common.cpp Normal file
View File

@ -0,0 +1,24 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <stdlib.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
int SampleFunction()
{
OutputMessage("Hello from the sample plugin function!");
return rand();
}
// ------------------------------------------------------------------------------------------------
void SampleType::SampleMethod() const
{
OutputMessage("I have the values %d and %d", m_MyVal, mMyNum);
}
} // Namespace:: SqMod

66
modules/sample/Common.hpp Normal file
View File

@ -0,0 +1,66 @@
#ifndef _SQSAMPLE_COMMON_HPP_
#define _SQSAMPLE_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "ModBase.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQSAMPLE_NAME "Squirrel Sample Module"
#define SQSAMPLE_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQSAMPLE_COPYRIGHT "Copyright (C) 2016 Sandu Liviu Catalin"
#define SQSAMPLE_HOST_NAME "SqModSampleHost"
#define SQSAMPLE_VERSION 001
#define SQSAMPLE_VERSION_STR "0.0.1"
#define SQSAMPLE_VERSION_MAJOR 0
#define SQSAMPLE_VERSION_MINOR 0
#define SQSAMPLE_VERSION_PATCH 1
/* --------------------------------------------------------------------------------------------
* Sample Plugin API
*/
int SampleFunction();
class SampleType
{
private:
int m_MyVal;
public:
int mMyNum;
SampleType()
: m_MyVal(0), mMyNum(0)
{
}
SampleType(int num)
: m_MyVal(num * 2), mMyNum(num)
{
}
int GetMyVal() const
{
return m_MyVal;
}
void SetMyVal(int val)
{
m_MyVal = val;
}
void SampleMethod() const;
};
} // Namespace:: SqMod
#endif // _SQSAMPLE_COMMON_HPP_

310
modules/sample/Module.cpp Normal file
View File

@ -0,0 +1,310 @@
// --------------------------------------------------------------------------------------------
#include "Module.hpp"
#include "Common.hpp"
// --------------------------------------------------------------------------------------------
#include <sqrat.h>
// --------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
// --------------------------------------------------------------------------------------------
#if defined(WIN32) || defined(_WIN32)
#include <Windows.h>
#endif
namespace SqMod {
// --------------------------------------------------------------------------------------------
PluginFuncs* _Func = NULL;
PluginCallbacks* _Clbk = NULL;
PluginInfo* _Info = NULL;
// --------------------------------------------------------------------------------------------
HSQAPI _SqAPI = NULL;
HSQEXPORTS _SqMod = NULL;
HSQUIRRELVM _SqVM = NULL;
/* ------------------------------------------------------------------------------------------------
* 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.", SQSAMPLE_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", SQSAMPLE_NAME);
}
/* --------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQSAMPLE_NAME);
// Release the current database (if any)
DefaultVM::Set(NULL);
// Release script resources...
}
/* --------------------------------------------------------------------------------------------
* 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 = strtol(ver, NULL, 10);
// Check against version mismatch
if (vernum == SQMOD_API_VER)
return true;
// Log the incident
OutputError("API version mismatch on %s", SQSAMPLE_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 int OnInternalCommand(unsigned int type, const char * text)
{
switch(type)
{
case SQMOD_INITIALIZE_CMD:
if (CheckAPIVer(text))
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 int OnInitServer()
{
return 1;
}
static void OnShutdownServer(void)
{
// The server may still send callbacks
UnbindCallbacks();
}
// ------------------------------------------------------------------------------------------------
void BindCallbacks()
{
_Clbk->OnInitServer = OnInitServer;
_Clbk->OnInternalCommand = OnInternalCommand;
_Clbk->OnShutdownServer = OnShutdownServer;
}
// ------------------------------------------------------------------------------------------------
void UnbindCallbacks()
{
_Clbk->OnInitServer = NULL;
_Clbk->OnInternalCommand = NULL;
_Clbk->OnShutdownServer = NULL;
}
// --------------------------------------------------------------------------------------------
void RegisterAPI(HSQUIRRELVM vm)
{
RootTable(vm).Bind(_SC("SampleType"), Class< SampleType >(vm, _SC("SampleType"))
.Ctor()
.Ctor< int >()
.Var(_SC("MyNum"), &SampleType::mMyNum)
.Prop(_SC("MyVal"), &SampleType::GetMyVal, &SampleType::SetMyVal)
.Func(_SC("SampleMethod"), &SampleType::SampleMethod)
);
RootTable(vm).Func(_SC("SampleFunction"), &SampleFunction);
}
// --------------------------------------------------------------------------------------------
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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", SQSAMPLE_NAME);
OutputMessage("Author: %s", SQSAMPLE_AUTHOR);
OutputMessage("Legal: %s", SQSAMPLE_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", SQSAMPLE_NAME);
// Don't load!
return SQMOD_FAILURE;
}
// Should never reach this point but just in case
else if (host_plugin_id > (info->nPluginId))
{
OutputError("%s loaded after the host plugin", SQSAMPLE_NAME);
// Don't load!
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plugin information
_Info->uPluginVer = SQSAMPLE_VERSION;
strcpy(_Info->szName, SQSAMPLE_HOST_NAME);
// Bind callbacks
BindCallbacks();
// Notify that the plugin was successfully loaded
OutputMessage("Successfully loaded %s", SQSAMPLE_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

41
modules/sample/Module.hpp Normal file
View File

@ -0,0 +1,41 @@
#ifndef _SQSAMPLE_MODULE_HPP_
#define _SQSAMPLE_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 // _SQSAMPLE_MODULE_HPP_

193
modules/xml/Attribute.cpp Normal file
View File

@ -0,0 +1,193 @@
// ------------------------------------------------------------------------------------------------
#include "Attribute.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <sqrat.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
bool Attribute::Validate() const
{
if (m_Doc)
return true;
// Invalid document reference
_SqMod->SqThrow("Invalid XML document reference");
return false;
}
// ------------------------------------------------------------------------------------------------
void Attribute::SetName(CSStr name)
{
if (!m_Attr.set_name(name))
_SqMod->SqThrow("Unable to set xml attribute name");
}
// ------------------------------------------------------------------------------------------------
void Attribute::SetValue(CSStr name)
{
if (!m_Attr.set_value(name))
_SqMod->SqThrow("Unable to set xml attribute value");
}
// ------------------------------------------------------------------------------------------------
Object Attribute::AsLong(Object & def) const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object >::push(_SqVM, def);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Push a long integer instance with the requested value on the stack
_SqMod->PushSLongObject(_SqVM, m_Attr.as_llong(longint));
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
Object Attribute::AsUlong(Object & def) const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object >::push(_SqVM, def);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Push a long integer instance with the requested value on the stack
_SqMod->PushULongObject(_SqVM, m_Attr.as_ullong(longint));
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
bool Attribute::ApplyLong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Int64 longint = 0;
// Whether the operation succeeded
bool res = false;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
res = m_Attr.set_value(longint);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the result
return res;
}
// ------------------------------------------------------------------------------------------------
bool Attribute::ApplyUlong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Uint64 longint = 0;
// Whether the operation succeeded
bool res = false;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
res = m_Attr.set_value(longint);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the result
return res;
}
// ------------------------------------------------------------------------------------------------
Object Attribute::GetLong() const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push a long integer instance with the requested value on the stack
_SqMod->PushSLongObject(_SqVM, m_Attr.as_llong());
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
void Attribute::SetLong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
m_Attr = longint;
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
}
// ------------------------------------------------------------------------------------------------
Object Attribute::GetUlong() const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push a long integer instance with the requested value on the stack
_SqMod->PushULongObject(_SqVM, m_Attr.as_ullong());
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
void Attribute::SetUlong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
m_Attr = longint;
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
}
} // Namespace:: SqMod

427
modules/xml/Attribute.hpp Normal file
View File

@ -0,0 +1,427 @@
#ifndef _XML_ATTRIBUTE_HPP_
#define _XML_ATTRIBUTE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* A light-weight handle for manipulating attributes in DOM tree.
*/
class Attribute
{
// --------------------------------------------------------------------------------------------
friend class Node;
protected:
// --------------------------------------------------------------------------------------------
typedef xml_attribute Type;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Attribute(const DocumentRef doc, const Type & attr)
: m_Doc(doc), m_Attr(attr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
bool Validate() const;
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; /* The main xml document instance. */
Type m_Attr; /* The managed node attribute. */
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Attribute()
: m_Doc(), m_Attr()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Attribute(const Attribute & o)
: m_Doc(o.m_Doc), m_Attr(o.m_Attr)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Attribute()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Attribute & operator = (const Attribute & o)
{
m_Doc = o.m_Doc;
m_Attr = o.m_Attr;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Attribute & o)
{
if (m_Attr == o.m_Attr)
return 0;
else if (m_Attr > o.m_Attr)
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_Attr.value();
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml 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 the attribute is empty.
*/
bool IsEmpty() const
{
return m_Attr.empty();
}
/* --------------------------------------------------------------------------------------------
* Get hash value (unique for handles to the same object).
*/
SQInteger GetHashValue() const
{
return (SQInteger)m_Attr.hash_value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute name.
*/
CSStr GetName() const
{
return m_Attr.name();
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute name.
*/
void SetName(CSStr name);
/* --------------------------------------------------------------------------------------------
* Modify the attribute name.
*/
bool ApplyName(CSStr name)
{
return m_Attr.set_name(name);
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute value.
*/
CSStr GetValue() const
{
return m_Attr.value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve attribute value.
*/
void SetValue(CSStr name);
/* --------------------------------------------------------------------------------------------
* Modify the attribute value.
*/
bool ApplyValue(CSStr value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string or the specified default value if empty.
*/
CSStr AsString(CSStr def) const
{
return m_Attr.as_string(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer or the specified default value if empty.
*/
Int32 AsInt(Int32 def) const
{
return m_Attr.as_int(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer or the specified default value if empty.
*/
Uint32 AsUint(Uint32 def) const
{
return m_Attr.as_uint(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point or the specified default value if empty.
*/
SQFloat AsFloat(SQFloat def) const
{
return (SQFloat)m_Attr.as_float(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point or the specified default value if empty.
*/
SQFloat AsDouble(SQFloat def) const
{
return (SQFloat)m_Attr.as_double(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer or the specified default value if empty.
*/
Object AsLong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer or the specified default value if empty.
*/
Object AsUlong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean or the specified default value if empty.
*/
bool AsBool(bool def) const
{
return m_Attr.as_bool(def);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
bool ApplyString(CSStr value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
bool ApplyInt(Int32 value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
bool ApplyUint(Uint32 value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
bool ApplyFloat(SQFloat value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
bool ApplyDouble(SQFloat value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
bool ApplyLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
bool ApplyUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
bool ApplyBool(bool value)
{
return m_Attr.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string.
*/
CSStr GetString() const
{
return m_Attr.as_string();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
void SetString(CSStr value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer.
*/
Int32 GetInt() const
{
return m_Attr.as_int();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
void SetInt(Int32 value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer.
*/
Uint32 GetUint() const
{
return m_Attr.as_uint();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
void SetUint(Uint32 value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point.
*/
SQFloat GetFloat() const
{
return (SQFloat)m_Attr.as_float();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
void SetFloat(SQFloat value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point.
*/
SQFloat GetDouble() const
{
return (SQFloat)m_Attr.as_double();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
void SetDouble(SQFloat value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer.
*/
Object GetLong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
void SetLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer.
*/
Object GetUlong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
void SetUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean.
*/
bool GetBool() const
{
return m_Attr.as_bool();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
void SetBool(bool value)
{
m_Attr = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve next attribute in the attribute list of the parent node.
*/
Attribute NextAttribute() const
{
return Attribute(m_Doc, m_Attr.next_attribute());
}
/* --------------------------------------------------------------------------------------------
* Retrieve previous attribute in the attribute list of the parent node.
*/
Attribute PrevAttribute() const
{
return Attribute(m_Doc, m_Attr.previous_attribute());
}
};
} // Namespace:: SqMod
#endif // _XML_ATTRIBUTE_HPP_

25
modules/xml/Common.cpp Normal file
View File

@ -0,0 +1,25 @@
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
bool ParseResult::Validate() const
{
if (m_Doc)
return true;
// Invalid document reference
_SqMod->SqThrow("Invalid XML document reference");
return false;
}
// ------------------------------------------------------------------------------------------------
void ParseResult::Check() const
{
if (m_Result.status != status_ok)
_SqMod->SqThrow("XML parse error [%s]", m_Result.description());
}
} // Namespace:: SqMod

392
modules/xml/Common.hpp Normal file
View File

@ -0,0 +1,392 @@
#ifndef _XML_COMMON_HPP_
#define _XML_COMMON_HPP_
// ------------------------------------------------------------------------------------------------
#include "ModBase.hpp"
// ------------------------------------------------------------------------------------------------
#include <assert.h>
// ------------------------------------------------------------------------------------------------
#include <pugixml.hpp>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* SOFTWARE INFORMATION
*/
#define SQXML_NAME "Squirrel XML Module"
#define SQXML_AUTHOR "Sandu Liviu Catalin (S.L.C)"
#define SQXML_COPYRIGHT "Copyright (C) 2016 Sandu Liviu Catalin"
#define SQXML_HOST_NAME "SqModXMLHost"
#define SQXML_VERSION 001
#define SQXML_VERSION_STR "0.0.1"
#define SQXML_VERSION_MAJOR 0
#define SQXML_VERSION_MINOR 0
#define SQXML_VERSION_PATCH 1
// ------------------------------------------------------------------------------------------------
using namespace pugi;
// ------------------------------------------------------------------------------------------------
class Node;
class Text;
class Document;
class Attribute;
class XPathNode;
class XPathNodeSet;
class XPathVariable;
class XPathVariableSet;
class XPathVariableQuery;
/* ------------------------------------------------------------------------------------------------
* Manages a reference counted xml document instance.
*/
class DocumentRef
{
// --------------------------------------------------------------------------------------------
friend class Document;
public:
// --------------------------------------------------------------------------------------------
typedef xml_document 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. */
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(VoidP /* unused */)
: m_Ptr(new Type())
, 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();
}
/* --------------------------------------------------------------------------------------------
* 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;
}
/* --------------------------------------------------------------------------------------------
* 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 != NULL);
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator for obtaining a reference of the managed pointer.
*/
Reference operator * () const
{
assert(m_Ptr != NULL);
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 ParseResult
{
// --------------------------------------------------------------------------------------------
friend class Document;
friend class Node;
protected:
// --------------------------------------------------------------------------------------------
typedef xml_parse_result Result;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
ParseResult(const DocumentRef doc, const Result & result)
: m_Doc(doc), m_Result(result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
bool Validate() const;
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; /* The main xml document instance. */
Result m_Result; /* The managed parse result. */
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ParseResult()
: m_Doc(), m_Result()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
ParseResult(const ParseResult & o)
: m_Doc(o.m_Doc), m_Result(o.m_Result)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ParseResult()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
ParseResult & operator = (const ParseResult & o)
{
m_Doc = o.m_Doc;
m_Result = o.m_Result;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const ParseResult & o)
{
if (m_Result.status == o.m_Result.status)
return 0;
else if (m_Result.status > o.m_Result.status)
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_Result.description();
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc.Count();
}
/* --------------------------------------------------------------------------------------------
* Cast to bool operator.
*/
bool IsOk() const
{
return m_Result;
}
/* --------------------------------------------------------------------------------------------
* Parsing status code.
*/
Int32 GetStatus() const
{
return (Int32)m_Result.status;
}
/* --------------------------------------------------------------------------------------------
* Last parsed offset. (in char_t units from start of input data)
*/
SQInteger GetOffset() const
{
return (SQInteger)m_Result.offset;
}
/* --------------------------------------------------------------------------------------------
* Source document encoding.
*/
Int32 GetEncoding() const
{
return m_Result.encoding;
}
/* --------------------------------------------------------------------------------------------
* Retrieve error description as a string.
*/
CSStr GetDescription() const
{
return m_Result.description();
}
/* --------------------------------------------------------------------------------------------
* Check the parse result and throw the necessary errors.
*/
void Check() const;
};
} // Namespace:: SqMod
#endif // _XML_COMMON_HPP_

41
modules/xml/Document.cpp Normal file
View File

@ -0,0 +1,41 @@
// ------------------------------------------------------------------------------------------------
#include "Document.hpp"
#include "Node.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
bool Document::Validate() const
{
if (m_Doc)
return true;
// Invalid document reference
_SqMod->SqThrow("Invalid XML document reference");
return false;
}
// ------------------------------------------------------------------------------------------------
bool Document::CanLoad() const
{
// Is the document even valid?
if (!Validate())
return false;
// Are there any other references?
else if (m_Doc.Count() == 1)
return true;
// To load new values now, would mean to cause undefined behavior in existing references
_SqMod->SqThrow("Loading is disabled while document is referenced");
return false;
}
// ------------------------------------------------------------------------------------------------
Node Document::GetNode() const
{
if (m_Doc)
return Node(m_Doc, m_Doc->document_element());
return Node();
}
} // Namespace:: SqMod

221
modules/xml/Document.hpp Normal file
View File

@ -0,0 +1,221 @@
#ifndef _XML_DOCUMENT_HPP_
#define _XML_DOCUMENT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Class that can read/write and alter the contents of XML files.
*/
class Document
{
protected:
// --------------------------------------------------------------------------------------------
typedef xml_document Type;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Document(const Document & o);
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Document & operator = (const Document & o);
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
bool Validate() const;
/* --------------------------------------------------------------------------------------------
* See if the document is allowed to overwrite its contents and throw an error if not.
*/
bool CanLoad() const;
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; /* The main xml document instance. */
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Document()
: m_Doc(NULL)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Document()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Document & o) const
{
if (m_Doc && !o.m_Doc)
return 1;
else if (!m_Doc && o.m_Doc)
return -1;
else if (!m_Doc && !o.m_Doc)
return 0;
else if (*m_Doc == *o.m_Doc)
return 0;
else if (*m_Doc > *o.m_Doc)
return 1;
else
return -1;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
if (m_Doc)
return m_Doc->name();
return _SC("");
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml document.
*/
bool IsValid() const
{
return m_Doc;
}
/* --------------------------------------------------------------------------------------------
* Return the number of active references to this document instance.
*/
Uint32 GetRefCount() const
{
return m_Doc ? *(m_Doc.m_Ref) : 0;
}
/* --------------------------------------------------------------------------------------------
* Removes all nodes, leaving the empty document.
*/
void Reset()
{
if (Validate())
m_Doc->reset();
}
/* --------------------------------------------------------------------------------------------
* Removes all nodes, then copies the entire contents of the specified document.
*/
void Reset(const Document & doc)
{
if (Validate() && doc.Validate())
m_Doc->reset(*doc.m_Doc);
}
/* --------------------------------------------------------------------------------------------
* Load document from zero-terminated string. (LoadString collides with the windows api)
*/
ParseResult LoadData(CSStr source)
{
if (CanLoad())
return ParseResult(m_Doc, m_Doc->load_string(source));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Load document from zero-terminated string. (LoadString collides with the windows api)
*/
ParseResult LoadData(CSStr source, Uint32 options)
{
if (CanLoad())
return ParseResult(m_Doc, m_Doc->load_string(source, options));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Load document from file on disk.
*/
ParseResult LoadFile(CSStr filepath)
{
if (CanLoad())
return ParseResult(m_Doc, m_Doc->load_file(filepath));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Load document from file on disk.
*/
ParseResult LoadFile(CSStr filepath, Uint32 options)
{
if (CanLoad())
return ParseResult(m_Doc, m_Doc->load_file(filepath, options));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Load document from file on disk.
*/
ParseResult LoadFile(CSStr filepath, Uint32 options, Int32 encoding)
{
if (CanLoad())
return ParseResult(m_Doc, m_Doc->load_file(filepath, options, (xml_encoding)encoding));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath)
{
if (Validate())
m_Doc->save_file(filepath);
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath, CSStr indent)
{
if (Validate())
m_Doc->save_file(filepath, indent);
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath, CSStr indent, Uint32 format)
{
if (Validate())
m_Doc->save_file(filepath, indent, format);
}
/* --------------------------------------------------------------------------------------------
* Save XML to file on disk.
*/
void SaveFile(CSStr filepath, CSStr indent, Uint32 format, Int32 encoding)
{
if (Validate())
m_Doc->save_file(filepath, indent, format, (xml_encoding)encoding);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the document root node.
*/
Node GetNode() const;
};
} // Namespace:: SqMod
#endif // _XML_DOCUMENT_HPP_

592
modules/xml/Module.cpp Normal file
View File

@ -0,0 +1,592 @@
// --------------------------------------------------------------------------------------------
#include "Module.hpp"
#include "Common.hpp"
#include "Attribute.hpp"
#include "Text.hpp"
#include "Node.hpp"
#include "Document.hpp"
// --------------------------------------------------------------------------------------------
#include <sqrat.h>
// --------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
// --------------------------------------------------------------------------------------------
#if defined(WIN32) || defined(_WIN32)
#include <Windows.h>
#endif
namespace SqMod {
// --------------------------------------------------------------------------------------------
PluginFuncs* _Func = NULL;
PluginCallbacks* _Clbk = NULL;
PluginInfo* _Info = NULL;
// --------------------------------------------------------------------------------------------
HSQAPI _SqAPI = NULL;
HSQEXPORTS _SqMod = NULL;
HSQUIRRELVM _SqVM = NULL;
/* ------------------------------------------------------------------------------------------------
* 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.", SQXML_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", SQXML_NAME);
}
/* --------------------------------------------------------------------------------------------
* The virtual machine is about to be terminated and script resources should be released.
*/
void OnSquirrelTerminate()
{
OutputMessage("Terminating: %s", SQXML_NAME);
// Release the current database (if any)
DefaultVM::Set(NULL);
}
/* --------------------------------------------------------------------------------------------
* 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 = strtol(ver, NULL, 10);
// Check against version mismatch
if (vernum == SQMOD_API_VER)
return true;
// Log the incident
OutputError("API version mismatch on %s", SQXML_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 int OnInternalCommand(unsigned int type, const char * text)
{
switch(type)
{
case SQMOD_INITIALIZE_CMD:
if (CheckAPIVer(text))
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 int OnInitServer()
{
return 1;
}
static void OnShutdownServer(void)
{
// The server may still send callbacks
UnbindCallbacks();
}
// ------------------------------------------------------------------------------------------------
void BindCallbacks()
{
_Clbk->OnInitServer = OnInitServer;
_Clbk->OnInternalCommand = OnInternalCommand;
_Clbk->OnShutdownServer = OnShutdownServer;
}
// ------------------------------------------------------------------------------------------------
void UnbindCallbacks()
{
_Clbk->OnInitServer = NULL;
_Clbk->OnInternalCommand = NULL;
_Clbk->OnShutdownServer = NULL;
}
// --------------------------------------------------------------------------------------------
void RegisterAPI(HSQUIRRELVM vm)
{
Table xmlns(vm);
xmlns.Bind(_SC("ParseResult"), Class< ParseResult >(vm, _SC("SqXmlParseResult"))
/* Constructors */
.Ctor()
.Ctor< const ParseResult & >()
/* Core Metamethods */
.Func(_SC("_cmp"), &ParseResult::Cmp)
.Func(_SC("_tostring"), &ParseResult::ToString)
/* Properties */
.Prop(_SC("Valid"), &ParseResult::IsValid)
.Prop(_SC("References"), &ParseResult::GetRefCount)
.Prop(_SC("Ok"), &ParseResult::IsOk)
.Prop(_SC("Status"), &ParseResult::GetStatus)
.Prop(_SC("Offset"), &ParseResult::GetOffset)
.Prop(_SC("Encoding"), &ParseResult::GetEncoding)
.Prop(_SC("Description"), &ParseResult::GetDescription)
/* Functions */
.Func(_SC("Check"), &ParseResult::Check)
);
xmlns.Bind(_SC("Attribute"), Class< Attribute >(vm, _SC("SqXmlAttribute"))
/* Constructors */
.Ctor()
.Ctor< const Attribute & >()
/* Core Metamethods */
.Func(_SC("_cmp"), &Attribute::Cmp)
.Func(_SC("_tostring"), &Attribute::ToString)
/* Properties */
.Prop(_SC("Valid"), &Attribute::IsValid)
.Prop(_SC("References"), &Attribute::GetRefCount)
.Prop(_SC("Empty"), &Attribute::IsEmpty)
.Prop(_SC("Hash"), &Attribute::GetHashValue)
.Prop(_SC("Name"), &Attribute::GetName, &Attribute::SetName)
.Prop(_SC("Value"), &Attribute::GetValue, &Attribute::SetValue)
.Prop(_SC("Int"), &Attribute::GetInt, &Attribute::SetInt)
.Prop(_SC("Uint"), &Attribute::GetUint, &Attribute::SetUint)
.Prop(_SC("Float"), &Attribute::GetFloat, &Attribute::SetFloat)
.Prop(_SC("Double"), &Attribute::GetDouble, &Attribute::SetDouble)
.Prop(_SC("Long"), &Attribute::GetLong, &Attribute::SetLong)
.Prop(_SC("Ulong"), &Attribute::GetUlong, &Attribute::SetUlong)
.Prop(_SC("Bool"), &Attribute::GetBool, &Attribute::SetBool)
.Prop(_SC("Next"), &Attribute::NextAttribute)
.Prop(_SC("Prev"), &Attribute::PrevAttribute)
/* Functions */
.Func(_SC("SetName"), &Attribute::ApplyName)
.Func(_SC("SetValue"), &Attribute::ApplyValue)
.Func(_SC("AsString"), &Attribute::AsString)
.Func(_SC("AsInt"), &Attribute::AsInt)
.Func(_SC("AsUint"), &Attribute::AsUint)
.Func(_SC("AsFloat"), &Attribute::AsFloat)
.Func(_SC("AsDouble"), &Attribute::AsDouble)
.Func(_SC("AsLong"), &Attribute::AsLong)
.Func(_SC("AsUlong"), &Attribute::AsUlong)
.Func(_SC("AsBool"), &Attribute::AsBool)
.Func(_SC("SetString"), &Attribute::ApplyString)
.Func(_SC("SetInt"), &Attribute::ApplyInt)
.Func(_SC("SetUint"), &Attribute::ApplyUint)
.Func(_SC("SetFloat"), &Attribute::ApplyFloat)
.Func(_SC("SetDouble"), &Attribute::ApplyDouble)
.Func(_SC("SetLong"), &Attribute::ApplyLong)
.Func(_SC("SetUlong"), &Attribute::ApplyUlong)
.Func(_SC("SetBool"), &Attribute::ApplyBool)
);
xmlns.Bind(_SC("Text"), Class< Text >(vm, _SC("SqXmlText"))
/* Constructors */
.Ctor()
.Ctor< const Text & >()
/* Core Metamethods */
.Func(_SC("_cmp"), &Text::Cmp)
.Func(_SC("_tostring"), &Text::ToString)
/* Properties */
.Prop(_SC("Valid"), &Text::IsValid)
.Prop(_SC("References"), &Text::GetRefCount)
.Prop(_SC("Empty"), &Text::IsEmpty)
.Prop(_SC("Value"), &Text::GetValue)
.Prop(_SC("Int"), &Text::GetInt, &Text::SetInt)
.Prop(_SC("Uint"), &Text::GetUint, &Text::SetUint)
.Prop(_SC("Float"), &Text::GetFloat, &Text::SetFloat)
.Prop(_SC("Double"), &Text::GetDouble, &Text::SetDouble)
.Prop(_SC("Long"), &Text::GetLong, &Text::SetLong)
.Prop(_SC("Ulong"), &Text::GetUlong, &Text::SetUlong)
.Prop(_SC("Bool"), &Text::GetBool, &Text::SetBool)
.Prop(_SC("Data"), &Text::GetData)
/* Functions */
.Func(_SC("AsString"), &Text::AsString)
.Func(_SC("AsInt"), &Text::AsInt)
.Func(_SC("AsUint"), &Text::AsUint)
.Func(_SC("AsFloat"), &Text::AsFloat)
.Func(_SC("AsDouble"), &Text::AsDouble)
.Func(_SC("AsLong"), &Text::AsLong)
.Func(_SC("AsUlong"), &Text::AsUlong)
.Func(_SC("AsBool"), &Text::AsBool)
.Func(_SC("SetString"), &Text::ApplyString)
.Func(_SC("SetInt"), &Text::ApplyInt)
.Func(_SC("SetUint"), &Text::ApplyUint)
.Func(_SC("SetFloat"), &Text::ApplyFloat)
.Func(_SC("SetDouble"), &Text::ApplyDouble)
.Func(_SC("SetLong"), &Text::ApplyLong)
.Func(_SC("SetUlong"), &Text::ApplyUlong)
.Func(_SC("SetBool"), &Text::ApplyBool)
);
xmlns.Bind(_SC("Node"), Class< Node >(vm, _SC("SqXmlNode"))
/* Constructors */
.Ctor()
.Ctor< const Node & >()
/* Core Metamethods */
.Func(_SC("_cmp"), &Node::Cmp)
.Func(_SC("_tostring"), &Node::ToString)
/* Properties */
.Prop(_SC("Valid"), &Node::IsValid)
.Prop(_SC("References"), &Node::GetRefCount)
.Prop(_SC("Empty"), &Node::IsEmpty)
.Prop(_SC("Hash"), &Node::GetHashValue)
.Prop(_SC("OffsetDebug"), &Node::GetOffsetDebug)
.Prop(_SC("Type"), &Node::GetType)
.Prop(_SC("Name"), &Node::GetName, &Node::SetName)
.Prop(_SC("Value"), &Node::GetValue, &Node::SetValue)
.Prop(_SC("FirstAttr"), &Node::GetFirstAttr)
.Prop(_SC("LastAttr"), &Node::GetLastAttr)
.Prop(_SC("FirstChild"), &Node::GetFirstChild)
.Prop(_SC("LastChild"), &Node::GetLastChild)
.Prop(_SC("NextSibling"), &Node::GetNextSibling)
.Prop(_SC("PrevSibling"), &Node::GetPrevSibling)
.Prop(_SC("Parent"), &Node::GetParent)
.Prop(_SC("Root"), &Node::GetRoot)
.Prop(_SC("Text"), &Node::GetText)
.Prop(_SC("ChildValue"), &Node::GetChildValue)
/* Functions */
.Overload< ParseResult (Node::*)(CSStr) >(_SC("AppendBuffer"), &Node::AppendBuffer)
.Overload< ParseResult (Node::*)(CSStr, Uint32) >(_SC("AppendBuffer"), &Node::AppendBuffer)
.Overload< ParseResult (Node::*)(CSStr, Uint32, Int32) >(_SC("AppendBuffer"), &Node::AppendBuffer)
.Func(_SC("SetName"), &Node::ApplyName)
.Func(_SC("SetValue"), &Node::ApplyValue)
.Func(_SC("GetChild"), &Node::Child)
.Func(_SC("GetAttr"), &Node::GetAttribute)
.Func(_SC("GetAttribute"), &Node::GetAttribute)
.Func(_SC("GetAttrFrom"), &Node::AttributeFrom)
.Func(_SC("GetAttributeFrom"), &Node::AttributeFrom)
.Func(_SC("GetNextSibling"), &Node::NextSibling)
.Func(_SC("GetPrevSibling"), &Node::PrevSibling)
.Func(_SC("GetChildValue"), &Node::ChildValue)
.Func(_SC("AppendAttr"), &Node::AppendAttr)
.Func(_SC("PrependAttr"), &Node::PrependAttr)
.Func(_SC("InsertAttrAfter"), &Node::InsertAttrAfter)
.Func(_SC("InsertAttrBefore"), &Node::InsertAttrBefore)
.Func(_SC("AppendAttrCopy"), &Node::AppendAttrCopy)
.Func(_SC("PrependAttrCopy"), &Node::PrependAttrCopy)
.Func(_SC("InsertAttrCopyAfter"), &Node::InsertAttrCopyAfter)
.Func(_SC("InsertAttrCopyBefore"), &Node::InsertAttrCopyBefore)
.Func(_SC("AppendChild"), &Node::AppendChild)
.Func(_SC("PrependChild"), &Node::PrependChild)
.Func(_SC("AppendChildNode"), &Node::AppendChildNode)
.Func(_SC("PrependChildNode"), &Node::PrependChildNode)
.Func(_SC("AppendChildType"), &Node::AppendChildType)
.Func(_SC("PrependChildType"), &Node::PrependChildType)
.Func(_SC("InsertChildAfter"), &Node::InsertChildAfter)
.Func(_SC("InsertChildBefore"), &Node::InsertChildBefore)
.Func(_SC("InsertChildTypeAfter"), &Node::InsertChildTypeAfter)
.Func(_SC("InsertChildTypeBefore"), &Node::InsertChildTypeBefore)
.Func(_SC("AppendCopy"), &Node::AppendCopy)
.Func(_SC("PrependCopy"), &Node::PrependCopy)
.Func(_SC("InsertCopyAfter"), &Node::InsertCopyAfter)
.Func(_SC("InsertCopyBefore"), &Node::InsertCopyBefore)
.Func(_SC("AppendMove"), &Node::AppendMove)
.Func(_SC("PrependMove"), &Node::PrependMove)
.Func(_SC("InsertMoveAfter"), &Node::InsertMoveAfter)
.Func(_SC("InsertMoveBefore"), &Node::InsertMoveBefore)
.Func(_SC("RemoveAttr"), &Node::RemoveAttr)
.Func(_SC("RemoveAttrInst"), &Node::RemoveAttrInst)
.Func(_SC("RemoveChild"), &Node::RemoveChild)
.Func(_SC("RemoveChildInst"), &Node::RemoveChildInst)
.Overload< Node (Node::*)(CSStr, CSStr) const >(_SC("FindChildByAttr"), &Node::FindChildByAttr)
.Overload< Node (Node::*)(CSStr, CSStr, CSStr) const >(_SC("FindChildByAttr"), &Node::FindChildByAttr)
.Func(_SC("FindElemByPath"), &Node::FindElemByPath)
);
xmlns.Bind(_SC("Document"), Class< Document, NoCopy< Document > >(vm, _SC("SqXmlDocument"))
/* Constructors */
.Ctor()
/* Core Metamethods */
.Func(_SC("_cmp"), &Document::Cmp)
.Func(_SC("_tostring"), &Document::ToString)
/* Properties */
.Prop(_SC("Valid"), &Document::IsValid)
.Prop(_SC("References"), &Document::GetRefCount)
.Prop(_SC("Node"), &Document::GetNode)
/* Functions */
.Overload< void (Document::*)(void) >(_SC("Reset"), &Document::Reset)
.Overload< void (Document::*)(const Document &) >(_SC("Reset"), &Document::Reset)
.Overload< ParseResult (Document::*)(CSStr) >(_SC("LoadString"), &Document::LoadData)
.Overload< ParseResult (Document::*)(CSStr, Uint32) >(_SC("LoadString"), &Document::LoadData)
.Overload< ParseResult (Document::*)(CSStr) >(_SC("LoadFile"), &Document::LoadFile)
.Overload< ParseResult (Document::*)(CSStr, Uint32) >(_SC("LoadFile"), &Document::LoadFile)
.Overload< ParseResult (Document::*)(CSStr, Uint32, Int32) >(_SC("LoadFile"), &Document::LoadFile)
.Overload< void (Document::*)(CSStr) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< void (Document::*)(CSStr, CSStr) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< void (Document::*)(CSStr, CSStr, Uint32) >(_SC("SaveFile"), &Document::SaveFile)
.Overload< void (Document::*)(CSStr, CSStr, Uint32, Int32) >(_SC("SaveFile"), &Document::SaveFile)
);
RootTable(vm).Bind(_SC("SqXml"), xmlns);
ConstTable(vm).Enum(_SC("SqXmlNodeType"), Enumeration(vm)
.Const(_SC("Null"), Int32(node_null))
.Const(_SC("Document"), Int32(node_document))
.Const(_SC("Element"), Int32(node_element))
.Const(_SC("PCData"), Int32(node_pcdata))
.Const(_SC("CData"), Int32(node_cdata))
.Const(_SC("Comment"), Int32(node_comment))
.Const(_SC("Pi"), Int32(node_pi))
.Const(_SC("Declaration"), Int32(node_declaration))
.Const(_SC("Doctype"), Int32(node_doctype))
);
ConstTable(vm).Enum(_SC("SqXmlParse"), Enumeration(vm)
.Const(_SC("Minimal"), Int32(parse_minimal))
.Const(_SC("Default"), Int32(parse_default))
.Const(_SC("Full"), Int32(parse_full))
.Const(_SC("Pi"), Int32(parse_pi))
.Const(_SC("Comments"), Int32(parse_comments))
.Const(_SC("CData"), Int32(parse_cdata))
.Const(_SC("WSPCData"), Int32(parse_ws_pcdata))
.Const(_SC("Escapes"), Int32(parse_escapes))
.Const(_SC("EOL"), Int32(parse_eol))
.Const(_SC("WConvAttribute"), Int32(parse_wconv_attribute))
.Const(_SC("WNormAttribute"), Int32(parse_wnorm_attribute))
.Const(_SC("Declaration"), Int32(parse_declaration))
.Const(_SC("Doctype"), Int32(parse_doctype))
.Const(_SC("WSPCDataSingle"), Int32(parse_ws_pcdata_single))
.Const(_SC("TrimPCData"), Int32(parse_trim_pcdata))
.Const(_SC("Fragment"), Int32(parse_fragment))
.Const(_SC("EmbedPCData"), Int32(parse_embed_pcdata))
);
ConstTable(vm).Enum(_SC("SqXmlEncoding"), Enumeration(vm)
.Const(_SC("Auto"), Int32(encoding_auto))
.Const(_SC("Utf8"), Int32(encoding_utf8))
.Const(_SC("Utf16LE"), Int32(encoding_utf16_le))
.Const(_SC("Utf16BE"), Int32(encoding_utf16_be))
.Const(_SC("Utf16"), Int32(encoding_utf16))
.Const(_SC("Utf32LE"), Int32(encoding_utf32_le))
.Const(_SC("Utf32BE"), Int32(encoding_utf32_be))
.Const(_SC("Utf32"), Int32(encoding_utf32))
.Const(_SC("WChar"), Int32(encoding_wchar))
.Const(_SC("Latin1"), Int32(encoding_latin1))
);
ConstTable(vm).Enum(_SC("SqXmlFormat"), Enumeration(vm)
.Const(_SC("Indent"), Int32(format_indent))
.Const(_SC("WriteBOM"), Int32(format_write_bom))
.Const(_SC("Raw"), Int32(format_raw))
.Const(_SC("NoDeclaration"), Int32(format_no_declaration))
.Const(_SC("NoEscapes"), Int32(format_no_escapes))
.Const(_SC("SaveFileText"), Int32(format_save_file_text))
.Const(_SC("IndentAttributes"), Int32(format_indent_attributes))
.Const(_SC("Default"), Int32(format_default))
);
ConstTable(vm).Enum(_SC("SqXmlParseStatus"), Enumeration(vm)
.Const(_SC("Ok"), Int32(status_ok))
.Const(_SC("FileNotFound"), Int32(status_file_not_found))
.Const(_SC("IOError"), Int32(status_io_error))
.Const(_SC("OutOfMemory"), Int32(status_out_of_memory))
.Const(_SC("InternalError"), Int32(status_internal_error))
.Const(_SC("UnrecognizedTag"), Int32(status_unrecognized_tag))
.Const(_SC("BadPi"), Int32(status_bad_pi))
.Const(_SC("BadComment"), Int32(status_bad_comment))
.Const(_SC("BadCData"), Int32(status_bad_cdata))
.Const(_SC("BadDoctype"), Int32(status_bad_doctype))
.Const(_SC("BadPCData"), Int32(status_bad_pcdata))
.Const(_SC("BadStartElement"), Int32(status_bad_start_element))
.Const(_SC("BadAttribute"), Int32(status_bad_attribute))
.Const(_SC("BadEndElement"), Int32(status_bad_end_element))
.Const(_SC("EndElementMismatch"), Int32(status_end_element_mismatch))
.Const(_SC("AppendInvalidRoot"), Int32(status_append_invalid_root))
.Const(_SC("NoDocumentElement"), Int32(status_no_document_element))
);
ConstTable(vm).Enum(_SC("SqXmlXpathValueType"), Enumeration(vm)
.Const(_SC("None"), Int32(xpath_type_none))
.Const(_SC("NodeSet"), Int32(xpath_type_node_set))
.Const(_SC("Number"), Int32(xpath_type_number))
.Const(_SC("String"), Int32(xpath_type_string))
.Const(_SC("Boolean"), Int32(xpath_type_boolean))
);
}
// --------------------------------------------------------------------------------------------
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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);
printf("[SQMOD] ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
vprintf(msg, args);
puts("");
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
#else
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
vprintf(msg, args);
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", SQXML_NAME);
OutputMessage("Author: %s", SQXML_AUTHOR);
OutputMessage("Legal: %s", SQXML_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", SQXML_NAME);
// Don't load!
return SQMOD_FAILURE;
}
// Should never reach this point but just in case
else if (host_plugin_id > (info->nPluginId))
{
OutputError("%s loaded after the host plugin", SQXML_NAME);
// Don't load!
return SQMOD_FAILURE;
}
// Store server proxies
_Func = functions;
_Clbk = callbacks;
_Info = info;
// Assign plugin information
_Info->uPluginVer = SQXML_VERSION;
strcpy(_Info->szName, SQXML_HOST_NAME);
// Bind callbacks
BindCallbacks();
// Notify that the plugin was successfully loaded
OutputMessage("Successfully loaded %s", SQXML_NAME);
// Dummy spacing
puts("");
// Done!
return SQMOD_SUCCESS;
}

41
modules/xml/Module.hpp Normal file
View File

@ -0,0 +1,41 @@
#ifndef _XML_MODULE_HPP_
#define _XML_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 // _XML_MODULE_HPP_

118
modules/xml/Node.cpp Normal file
View File

@ -0,0 +1,118 @@
// ------------------------------------------------------------------------------------------------
#include "Node.hpp"
#include "Attribute.hpp"
#include "Text.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
bool Node::Validate() const
{
if (m_Doc)
return true;
// Invalid document reference
_SqMod->SqThrow("Invalid XML document reference");
return false;
}
// ------------------------------------------------------------------------------------------------
void Node::SetName(CSStr name)
{
if (!m_Node.set_name(name))
_SqMod->SqThrow("Unable to set XML node name");
}
// ------------------------------------------------------------------------------------------------
void Node::SetValue(CSStr name)
{
if (!m_Node.set_value(name))
_SqMod->SqThrow("Unable to set XML node value");
}
// ------------------------------------------------------------------------------------------------
Attribute Node::GetFirstAttr() const
{
return Attribute(m_Doc, m_Node.first_attribute());
}
// ------------------------------------------------------------------------------------------------
Attribute Node::GetLastAttr() const
{
return Attribute(m_Doc, m_Node.last_attribute());
}
// ------------------------------------------------------------------------------------------------
Text Node::GetText() const
{
return Text(m_Doc, m_Node.text());
}
// ------------------------------------------------------------------------------------------------
Attribute Node::GetAttribute(CSStr name) const
{
return Attribute(m_Doc, m_Node.attribute(name));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::AttributeFrom(CSStr name, Attribute & attr) const
{
return Attribute(m_Doc, m_Node.attribute(name, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::AppendAttr(CSStr name)
{
return Attribute(m_Doc, m_Node.append_attribute(name));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::PrependAttr(CSStr name)
{
return Attribute(m_Doc, m_Node.prepend_attribute(name));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrAfter(CSStr name, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_attribute_after(name, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrBefore(CSStr name, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_attribute_before(name, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::AppendAttrCopy(const Attribute & proto)
{
return Attribute(m_Doc, m_Node.append_copy(proto.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::PrependAttrCopy(const Attribute & proto)
{
return Attribute(m_Doc, m_Node.prepend_copy(proto.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrCopyAfter(const Attribute & proto, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_copy_after(proto.m_Attr, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
Attribute Node::InsertAttrCopyBefore(const Attribute & proto, const Attribute & attr)
{
return Attribute(m_Doc, m_Node.insert_copy_before(proto.m_Attr, attr.m_Attr));
}
// ------------------------------------------------------------------------------------------------
bool Node::RemoveAttrInst(const Attribute & attr)
{
return m_Node.remove_attribute(attr.m_Attr);
}
} // Namespace:: SqMod

580
modules/xml/Node.hpp Normal file
View File

@ -0,0 +1,580 @@
#ifndef _XML_NODE_HPP_
#define _XML_NODE_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* A light-weight handle for manipulating nodes in DOM tree.
*/
class Node
{
// --------------------------------------------------------------------------------------------
friend class Document;
friend class Text;
protected:
// --------------------------------------------------------------------------------------------
typedef xml_node Type;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Node(const DocumentRef doc, const Type & node)
: m_Doc(doc), m_Node(node)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
bool Validate() const;
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; /* The main xml document instance. */
Type m_Node; /* The managed document node. */
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Node()
: m_Doc(), m_Node()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Node(const Node & o)
: m_Doc(o.m_Doc), m_Node(o.m_Node)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Node()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Node & operator = (const Node & o)
{
m_Doc = o.m_Doc;
m_Node = o.m_Node;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Node & o)
{
if (m_Node == o.m_Node)
return 0;
else if (m_Node > o.m_Node)
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_Node.value();
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml 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 the node is empty.
*/
bool IsEmpty() const
{
return m_Node.empty();
}
/* --------------------------------------------------------------------------------------------
* Get hash value (unique for handles to the same object).
*/
SQInteger GetHashValue() const
{
return (SQInteger)m_Node.hash_value();
}
/* --------------------------------------------------------------------------------------------
* Get node offset in parsed file/string (in char_t units) for debugging purposes.
*/
SQInteger GetOffsetDebug() const
{
return (SQInteger)m_Node.offset_debug();
}
/* --------------------------------------------------------------------------------------------
* Retrieve node type.
*/
Int32 GetType() const
{
return (Int32)m_Node.type();
}
/* --------------------------------------------------------------------------------------------
* Retrieve node name.
*/
CSStr GetName() const
{
return m_Node.name();
}
/* --------------------------------------------------------------------------------------------
* Retrieve node name.
*/
void SetName(CSStr name);
/* --------------------------------------------------------------------------------------------
* Modify the node name.
*/
bool ApplyName(CSStr name)
{
return m_Node.set_name(name);
}
/* --------------------------------------------------------------------------------------------
* Retrieve node value.
*/
CSStr GetValue() const
{
return m_Node.value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve node value.
*/
void SetValue(CSStr name);
/* --------------------------------------------------------------------------------------------
* Modify the node value.
*/
bool ApplyValue(CSStr value)
{
return m_Node.set_value(value);
}
/* --------------------------------------------------------------------------------------------
* Parses buffer as an XML document fragment and appends all nodes as children of this node.
*/
ParseResult AppendBuffer(CSStr source)
{
if (source)
return ParseResult(m_Doc, m_Node.append_buffer(source,
std::char_traits< SQChar >::length(source) * sizeof(SQChar)));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Parses buffer as an XML document fragment and appends all nodes as children of this node.
*/
ParseResult AppendBuffer(CSStr source, Uint32 options)
{
if (source)
return ParseResult(m_Doc, m_Node.append_buffer(source,
std::char_traits< SQChar >::length(source) * sizeof(SQChar), options));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Parses buffer as an XML document fragment and appends all nodes as children of this node.
*/
ParseResult AppendBuffer(CSStr source, Uint32 options, Int32 encoding)
{
if (source)
return ParseResult(m_Doc, m_Node.append_buffer(source,
std::char_traits< SQChar >::length(source) * sizeof(SQChar)
, options, (xml_encoding)encoding));
return ParseResult();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the first child attribute.
*/
Attribute GetFirstAttr() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the last child attribute.
*/
Attribute GetLastAttr() const;
/* --------------------------------------------------------------------------------------------
* Retrieve the first child node.
*/
Node GetFirstChild() const
{
return Node(m_Doc, m_Node.first_child());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the last child node.
*/
Node GetLastChild() const
{
return Node(m_Doc, m_Node.last_child());
}
/* --------------------------------------------------------------------------------------------
* Get next sibling in the children list of the parent node.
*/
Node GetNextSibling() const
{
return Node(m_Doc, m_Node.next_sibling());
}
/* --------------------------------------------------------------------------------------------
* Get previous sibling in the children list of the parent node
*/
Node GetPrevSibling() const
{
return Node(m_Doc, m_Node.previous_sibling());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the parent node.
*/
Node GetParent() const
{
return Node(m_Doc, m_Node.parent());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the root node.
*/
Node GetRoot() const
{
return Node(m_Doc, m_Node.root());
}
/* --------------------------------------------------------------------------------------------
* Retrieve the text object for the current node.
*/
Text GetText() const;
/* --------------------------------------------------------------------------------------------
* Retrieve child node with the specified name.
*/
Node Child(CSStr name) const
{
return Node(m_Doc, m_Node.child(name));
}
/* --------------------------------------------------------------------------------------------
* Retrieve child attribute with the specified name.
*/
Attribute GetAttribute(CSStr name) const;
/* --------------------------------------------------------------------------------------------
* Retrieve next sibling with the specified name.
*/
Node NextSibling(CSStr name) const
{
return Node(m_Doc, m_Node.next_sibling(name));
}
/* --------------------------------------------------------------------------------------------
* Retrieve previous sibling with the specified name.
*/
Node PrevSibling(CSStr name) const
{
return Node(m_Doc, m_Node.previous_sibling(name));
}
/* --------------------------------------------------------------------------------------------
* Retrieve child attribute, starting the search from a hint.
*/
Attribute AttributeFrom(CSStr name, Attribute & attr) const;
/* --------------------------------------------------------------------------------------------
* Get child value of current node; that is, value of the first child node of type PCDATA/CDATA.
*/
CSStr GetChildValue() const
{
return m_Node.child_value();
}
/* --------------------------------------------------------------------------------------------
* Retrieve child value of child with specified name.
*/
CSStr ChildValue(CSStr name) const
{
return m_Node.child_value(name);
}
/* --------------------------------------------------------------------------------------------
* Append a child attribute with the specified name.
*/
Attribute AppendAttr(CSStr name);
/* --------------------------------------------------------------------------------------------
* Prepend a child attribute with the specified name.
*/
Attribute PrependAttr(CSStr name);
/* --------------------------------------------------------------------------------------------
* Insert a child attribute with the specified name, after the specified node.
*/
Attribute InsertAttrAfter(CSStr name, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Insert a child attribute with the specified name, before the specified node.
*/
Attribute InsertAttrBefore(CSStr name, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Append a copy of the specified attribute as a child.
*/
Attribute AppendAttrCopy(const Attribute & proto);
/* --------------------------------------------------------------------------------------------
* Prepend a copy of the specified attribute as a child.
*/
Attribute PrependAttrCopy(const Attribute & proto);
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified attribute as a child after the specified attribute.
*/
Attribute InsertAttrCopyAfter(const Attribute & proto, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified attribute as a child before the specified attribute.
*/
Attribute InsertAttrCopyBefore(const Attribute & proto, const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Append a basic child node with the specified name.
*/
Node AppendChild(CSStr name)
{
return Node(m_Doc, m_Node.append_child(name));
}
/* --------------------------------------------------------------------------------------------
* Prepend a basic child node with the specified name.
*/
Node PrependChild(CSStr name)
{
return Node(m_Doc, m_Node.prepend_child(name));
}
/* --------------------------------------------------------------------------------------------
* Append a basic child node.
*/
Node AppendChildNode()
{
return Node(m_Doc, m_Node.append_child());
}
/* --------------------------------------------------------------------------------------------
* Prepend a basic child node.
*/
Node PrependChildNode()
{
return Node(m_Doc, m_Node.prepend_child());
}
/* --------------------------------------------------------------------------------------------
* Append a basic child node with the specified type.
*/
Node AppendChildType(Int32 type)
{
return Node(m_Doc, m_Node.append_child((xml_node_type)type));
}
/* --------------------------------------------------------------------------------------------
* Prepend a basic child node with the specified type.
*/
Node PrependChildType(Int32 type)
{
return Node(m_Doc, m_Node.prepend_child((xml_node_type)type));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified name, after the specified node.
*/
Node InsertChildAfter(CSStr name, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_after(name, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified name, before the specified node.
*/
Node InsertChildBefore(CSStr name, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_before(name, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified type, after the specified node.
*/
Node InsertChildTypeAfter(Int32 type, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_after((xml_node_type)type, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a basic child node with the specified type, before the specified node.
*/
Node InsertChildTypeBefore(Int32 type, const Node & node)
{
return Node(m_Doc, m_Node.insert_child_before((xml_node_type)type, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Append a copy of the specified node as a child.
*/
Node AppendCopy(const Node & proto)
{
return Node(m_Doc, m_Node.append_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Prepend a copy of the specified node as a child.
*/
Node PrependCopy(const Node & proto)
{
return Node(m_Doc, m_Node.prepend_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified node as a child after the specified node.
*/
Node InsertCopyAfter(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_after(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert a copy of the specified node as a child before the specified node.
*/
Node InsertCopyBefore(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_before(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Append the specified node as a child and take ownersip of it.
*/
Node AppendMove(const Node & proto)
{
return Node(m_Doc, m_Node.append_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Prepend the specified node as a child and take ownersip of it.
*/
Node PrependMove(const Node & proto)
{
return Node(m_Doc, m_Node.prepend_copy(proto.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert the specified node as a child after the specified node and take ownersip of it.
*/
Node InsertMoveAfter(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_after(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Insert the specified node as a child before the specified node and take ownersip of it.
*/
Node InsertMoveBefore(const Node & proto, const Node & node)
{
return Node(m_Doc, m_Node.insert_copy_before(proto.m_Node, node.m_Node));
}
/* --------------------------------------------------------------------------------------------
* Remove the child attribute matching the specified name.
*/
bool RemoveAttr(CSStr name)
{
return m_Node.remove_attribute(name);
}
/* --------------------------------------------------------------------------------------------
* Remove the specified attribute.
*/
bool RemoveAttrInst(const Attribute & attr);
/* --------------------------------------------------------------------------------------------
* Remove the child node matching the specified name.
*/
bool RemoveChild(CSStr name)
{
return m_Node.remove_child(name);
}
/* --------------------------------------------------------------------------------------------
* Remove the specified node.
*/
bool RemoveChildInst(const Node & node)
{
return m_Node.remove_child(node.m_Node);
}
/* --------------------------------------------------------------------------------------------
* Find child node by attribute name/value.
*/
Node FindChildByAttr(CSStr attr_name, CSStr attr_value) const
{
return Node(m_Doc, m_Node.find_child_by_attribute(attr_name, attr_value));
}
/* --------------------------------------------------------------------------------------------
* Find child node by attribute name/value.
*/
Node FindChildByAttr(CSStr name, CSStr attr_name, CSStr attr_value) const
{
return Node(m_Doc, m_Node.find_child_by_attribute(name, attr_name, attr_value));
}
/* --------------------------------------------------------------------------------------------
* Search for a node by path consisting of node names and . or .. elements.
*/
Node FindElemByPath(CSStr path, SQChar delimiter) const
{
return Node(m_Doc, m_Node.first_element_by_path(path, delimiter));
}
};
} // Namespace:: SqMod
#endif // _XML_NODE_HPP_

198
modules/xml/Text.cpp Normal file
View File

@ -0,0 +1,198 @@
// ------------------------------------------------------------------------------------------------
#include "Text.hpp"
#include "Node.hpp"
#include "Module.hpp"
// ------------------------------------------------------------------------------------------------
#include <string.h>
#include <sqrat.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
bool Text::Validate() const
{
if (m_Doc)
return true;
// Invalid document reference
_SqMod->SqThrow("Invalid XML document reference");
return false;
}
// ------------------------------------------------------------------------------------------------
Int32 Text::Cmp(const Text & o)
{
if (strcmp(m_Text.get(), o.m_Text.get()) == 0)
return 0;
else if (strlen(m_Text.get()) > strlen(o.m_Text.get()))
return 1;
else
return -1;
}
// ------------------------------------------------------------------------------------------------
Object Text::AsLong(Object & def) const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object >::push(_SqVM, def);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Push a long integer instance with the requested value on the stack
_SqMod->PushSLongObject(_SqVM, m_Text.as_llong(longint));
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
Object Text::AsUlong(Object & def) const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object >::push(_SqVM, def);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Push a long integer instance with the requested value on the stack
_SqMod->PushULongObject(_SqVM, m_Text.as_ullong(longint));
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
bool Text::ApplyLong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Int64 longint = 0;
// Whether the operation succeeded
bool res = false;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
res = m_Text.set(longint);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the result
return res;
}
// ------------------------------------------------------------------------------------------------
bool Text::ApplyUlong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Uint64 longint = 0;
// Whether the operation succeeded
bool res = false;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
res = m_Text.set(longint);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the result
return res;
}
// ------------------------------------------------------------------------------------------------
Object Text::GetLong() const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push a long integer instance with the requested value on the stack
_SqMod->PushSLongObject(_SqVM, m_Text.as_llong());
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
void Text::SetLong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Int64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetSLongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
m_Text = longint;
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
}
// ------------------------------------------------------------------------------------------------
Object Text::GetUlong() const
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push a long integer instance with the requested value on the stack
_SqMod->PushULongObject(_SqVM, m_Text.as_ullong());
// Obtain the object from the stack
Var< Object > inst(_SqVM, -1);
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
// Return the long integer instance
return inst.value;
}
// ------------------------------------------------------------------------------------------------
void Text::SetUlong(Object & value)
{
// Obtain the initial stack size
const Int32 top = sq_gettop(_SqVM);
// Push the specified object onto the stack
Var< Object & >::push(_SqVM, value);
// The resulted long integer value
Uint64 longint = 0;
// Attempt to get the numeric value inside the specified object
if (SQ_FAILED(_SqMod->GetULongValue(_SqVM, -1, &longint)))
_SqMod->SqThrow("Invalid long integer specified");
// Assign the obtained value
else
m_Text = longint;
// Remove an pushed values (if any) to restore the stack
sq_pop(_SqVM, sq_gettop(_SqVM) - top);
}
// ------------------------------------------------------------------------------------------------
Node Text::GetData() const
{
return Node(m_Doc, m_Text.data());
}
} // Namespace:: SqMod

365
modules/xml/Text.hpp Normal file
View File

@ -0,0 +1,365 @@
#ifndef _XML_TEXT_HPP_
#define _XML_TEXT_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* A helper for working with text inside PCDATA nodes.
*/
class Text
{
// --------------------------------------------------------------------------------------------
friend class Node;
protected:
// --------------------------------------------------------------------------------------------
typedef xml_text Type;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
Text(const DocumentRef doc, const Type & text)
: m_Doc(doc), m_Text(text)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Validate the document reference and throw an error if invalid.
*/
bool Validate() const;
private:
// ---------------------------------------------------------------------------------------------
DocumentRef m_Doc; /* The main xml document instance. */
Type m_Text; /* The managed document node. */
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Text()
: m_Doc(), m_Text()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Text(const Text & o)
: m_Doc(o.m_Doc), m_Text(o.m_Text)
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Text()
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Text & operator = (const Text & o)
{
m_Doc = o.m_Doc;
m_Text = o.m_Text;
return *this;
}
/* --------------------------------------------------------------------------------------------
* Used by the script engine to compare two instances of this type.
*/
Int32 Cmp(const Text & o);
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
return m_Text.get();
}
/* --------------------------------------------------------------------------------------------
* See whether this instance references a valid xml 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 the text is empty.
*/
bool IsEmpty() const
{
return m_Text.empty();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the text value.
*/
CSStr GetValue() const
{
return m_Text.get();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string or the specified default value if empty.
*/
CSStr AsString(CSStr def) const
{
return m_Text.as_string(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer or the specified default value if empty.
*/
Int32 AsInt(Int32 def) const
{
return m_Text.as_int(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer or the specified default value if empty.
*/
Uint32 AsUint(Uint32 def) const
{
return m_Text.as_uint(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point or the specified default value if empty.
*/
SQFloat AsFloat(SQFloat def) const
{
return (SQFloat)m_Text.as_float(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point or the specified default value if empty.
*/
SQFloat AsDouble(SQFloat def) const
{
return (SQFloat)m_Text.as_double(def);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer or the specified default value if empty.
*/
Object AsLong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer or the specified default value if empty.
*/
Object AsUlong(Object & def) const;
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean or the specified default value if empty.
*/
bool AsBool(bool def) const
{
return m_Text.as_bool(def);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
bool ApplyString(CSStr value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
bool ApplyInt(Int32 value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
bool ApplyUint(Uint32 value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
bool ApplyFloat(SQFloat value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
bool ApplyDouble(SQFloat value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
bool ApplyLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
bool ApplyUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
bool ApplyBool(bool value)
{
return m_Text.set(value);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a string.
*/
CSStr GetString() const
{
return m_Text.as_string();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a string.
*/
void SetString(CSStr value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a integer.
*/
Int32 GetInt() const
{
return m_Text.as_int();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a integer.
*/
void SetInt(Int32 value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned integer.
*/
Uint32 GetUint() const
{
return m_Text.as_uint();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned integer.
*/
void SetUint(Uint32 value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a floating point.
*/
SQFloat GetFloat() const
{
return (SQFloat)m_Text.as_float();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a floating point.
*/
void SetFloat(SQFloat value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a double floating point.
*/
SQFloat GetDouble() const
{
return (SQFloat)m_Text.as_double();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a double floating point.
*/
void SetDouble(SQFloat value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a long integer.
*/
Object GetLong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a long integer.
*/
void SetLong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a unsigned long integer.
*/
Object GetUlong() const;
/* --------------------------------------------------------------------------------------------
* Modify the value as a unsigned long integer.
*/
void SetUlong(Object & value);
/* --------------------------------------------------------------------------------------------
* Retrieve the value as a boolean.
*/
bool GetBool() const
{
return m_Text.as_bool();
}
/* --------------------------------------------------------------------------------------------
* Modify the value as a boolean.
*/
void SetBool(bool value)
{
m_Text = value;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the data node (node_pcdata or node_cdata) for this object.
*/
Node GetData() const;
};
} // Namespace:: SqMod
#endif // _XML_TEXT_HPP_