From a792ae525e57fc3ea1e3bda5bdf1710c94f4c490 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Fri, 3 Jun 2016 21:31:34 +0300 Subject: [PATCH] Update the XML module to work with the modified API. Separate the XML handles into their own source files. --- cbp/ModXML.cbp | 9 +- modules/xml/Attribute.cpp | 4 - modules/xml/Attribute.hpp | 8 +- modules/xml/Common.cpp | 110 ------- modules/xml/Common.hpp | 469 +--------------------------- modules/xml/Document.cpp | 1 - modules/xml/Document.hpp | 9 +- modules/xml/Handle/Document.cpp | 16 + modules/xml/Handle/Document.hpp | 236 ++++++++++++++ modules/xml/Module.cpp | 187 +++-------- modules/xml/Module.hpp | 41 --- modules/xml/Node.cpp | 1 - modules/xml/Node.hpp | 9 +- modules/xml/Text.cpp | 4 - modules/xml/Text.hpp | 8 +- modules/xml/Wrapper/ParseResult.cpp | 34 ++ modules/xml/Wrapper/ParseResult.hpp | 178 +++++++++++ 17 files changed, 539 insertions(+), 785 deletions(-) create mode 100644 modules/xml/Handle/Document.cpp create mode 100644 modules/xml/Handle/Document.hpp delete mode 100644 modules/xml/Module.hpp create mode 100644 modules/xml/Wrapper/ParseResult.cpp create mode 100644 modules/xml/Wrapper/ParseResult.hpp diff --git a/cbp/ModXML.cbp b/cbp/ModXML.cbp index e56789e8..a9a685c8 100644 --- a/cbp/ModXML.cbp +++ b/cbp/ModXML.cbp @@ -417,12 +417,19 @@ + + - + + + + + + diff --git a/modules/xml/Attribute.cpp b/modules/xml/Attribute.cpp index 2a228e88..ed4ad814 100644 --- a/modules/xml/Attribute.cpp +++ b/modules/xml/Attribute.cpp @@ -1,9 +1,5 @@ // ------------------------------------------------------------------------------------------------ #include "Attribute.hpp" -#include "Module.hpp" - -// ------------------------------------------------------------------------------------------------ -#include // ------------------------------------------------------------------------------------------------ namespace SqMod { diff --git a/modules/xml/Attribute.hpp b/modules/xml/Attribute.hpp index 20cd00eb..72b12898 100644 --- a/modules/xml/Attribute.hpp +++ b/modules/xml/Attribute.hpp @@ -1,8 +1,8 @@ -#ifndef _XML_ATTRIBUTE_HPP_ -#define _XML_ATTRIBUTE_HPP_ +#ifndef _SQXML_ATTRIBUTE_HPP_ +#define _SQXML_ATTRIBUTE_HPP_ // ------------------------------------------------------------------------------------------------ -#include "Common.hpp" +#include "Handle/Document.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -442,4 +442,4 @@ public: } // Namespace:: SqMod -#endif // _XML_ATTRIBUTE_HPP_ \ No newline at end of file +#endif // _SQXML_ATTRIBUTE_HPP_ \ No newline at end of file diff --git a/modules/xml/Common.cpp b/modules/xml/Common.cpp index cfbac701..f54b3f1a 100644 --- a/modules/xml/Common.cpp +++ b/modules/xml/Common.cpp @@ -1,119 +1,9 @@ // ------------------------------------------------------------------------------------------------ #include "Common.hpp" -#include "Module.hpp" - -// ------------------------------------------------------------------------------------------------ -#include - -// ------------------------------------------------------------------------------------------------ -#include // ------------------------------------------------------------------------------------------------ namespace SqMod { -// ------------------------------------------------------------------------------------------------ -static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations. -// ------------------------------------------------------------------------------------------------ -SStr GetTempBuff() -{ - return g_Buffer; -} - -// ------------------------------------------------------------------------------------------------ -Uint32 GetTempBuffSize() -{ - return sizeof(g_Buffer); -} - -// ------------------------------------------------------------------------------------------------ -void SqThrowF(CSStr str, ...) -{ - // Initialize the argument list - va_list args; - va_start (args, str); - // Write the requested contents - if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) - { - strcpy(g_Buffer, "Unknown error has occurred"); - } - // Release the argument list - va_end(args); - // Throw the exception with the resulted message - throw Sqrat::Exception(g_Buffer); -} - -// ------------------------------------------------------------------------------------------------ -CSStr FmtStr(CSStr str, ...) -{ - // Initialize the argument list - va_list args; - va_start (args, str); - // Write the requested contents - if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) - { - g_Buffer[0] = 0; // Make sure the string is terminated - } - // Release the argument list - va_end(args); - // Return the data from the buffer - return g_Buffer; -} - -// ------------------------------------------------------------------------------------------------ -StackGuard::StackGuard() - : m_VM(_SqVM), m_Top(sq_gettop(m_VM)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -StackGuard::StackGuard(HSQUIRRELVM vm) - : m_VM(vm), m_Top(sq_gettop(vm)) -{ - /* ... */ -} - -// ------------------------------------------------------------------------------------------------ -StackGuard::~StackGuard() -{ - sq_pop(m_VM, sq_gettop(m_VM) - m_Top); -} - -// ------------------------------------------------------------------------------------------------ -void DocumentRef::Validate() const -{ - if (!m_Ptr) - { - STHROWF("Invalid XML document reference"); - } -} - -// ------------------------------------------------------------------------------------------------ -SQInteger ParseResult::Typename(HSQUIRRELVM vm) -{ - static const SQChar name[] = _SC("SqXmlParseResult"); - sq_pushstring(vm, name, sizeof(name)); - return 1; -} - -// ------------------------------------------------------------------------------------------------ -void ParseResult::Validate() const -{ - // Is the documen handle valid? - if (!m_Doc) - { - STHROWF("Invalid XML document reference"); - } -} - -// ------------------------------------------------------------------------------------------------ -void ParseResult::Check() const -{ - if (m_Result.status != status_ok) - { - STHROWF("XML parse error [%s]", m_Result.description()); - } -} } // Namespace:: SqMod diff --git a/modules/xml/Common.hpp b/modules/xml/Common.hpp index 2b136fe6..36bc68c4 100644 --- a/modules/xml/Common.hpp +++ b/modules/xml/Common.hpp @@ -1,21 +1,12 @@ -#ifndef _XML_COMMON_HPP_ -#define _XML_COMMON_HPP_ +#ifndef _SQXML_COMMON_HPP_ +#define _SQXML_COMMON_HPP_ // ------------------------------------------------------------------------------------------------ -#include "ModBase.hpp" - -// ------------------------------------------------------------------------------------------------ -#include +#include "Base/Utility.hpp" // ------------------------------------------------------------------------------------------------ #include -// ------------------------------------------------------------------------------------------------ -extern "C" { - struct SQVM; - typedef struct SQVM* HSQUIRRELVM; -} /*extern "C"*/ - // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -45,458 +36,8 @@ class XPathNodeSet; class XPathVariable; class XPathVariableSet; class XPathVariableQuery; - -/* ------------------------------------------------------------------------------------------------ - * Retrieve the temporary buffer. -*/ -SStr GetTempBuff(); - -/* ------------------------------------------------------------------------------------------------ - * Retrieve the size of the temporary buffer. -*/ -Uint32 GetTempBuffSize(); - -/* ------------------------------------------------------------------------------------------------ - * Throw a formatted exception. -*/ -void SqThrowF(CSStr str, ...); - -/* ------------------------------------------------------------------------------------------------ - * Generate a formatted string. -*/ -CSStr FmtStr(CSStr str, ...); - -/* ------------------------------------------------------------------------------------------------ - * Implements RAII to restore the VM stack to it's initial size on function exit. -*/ -struct StackGuard -{ - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - StackGuard(); - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - StackGuard(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~StackGuard(); - -private: - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. - */ - StackGuard(const StackGuard &); - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - StackGuard(StackGuard &&); - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - StackGuard & operator = (const StackGuard &); - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - StackGuard & operator = (StackGuard &&); - -private: - - // -------------------------------------------------------------------------------------------- - HSQUIRRELVM m_VM; // The VM where the stack should be restored. - Int32 m_Top; // The top of the stack when this instance was created. -}; - -/* ------------------------------------------------------------------------------------------------ - * Manages a reference counted 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. */ - - /* -------------------------------------------------------------------------------------------- - * Validate the managed handle and throw exception if invalid. - */ - void Validate() const; - -private: - - // -------------------------------------------------------------------------------------------- - Pointer m_Ptr; /* The document reader, writer and manager instance. */ - Counter* m_Ref; /* Reference count to the managed instance. */ - - /* -------------------------------------------------------------------------------------------- - * Grab a strong reference to a document instance. - */ - void Grab() - { - if (m_Ptr) - ++(*m_Ref); - } - - /* -------------------------------------------------------------------------------------------- - * Drop a strong reference to a document instance. - */ - void Drop() - { - if (m_Ptr && --(*m_Ref) == 0) - { - delete m_Ptr; - delete m_Ref; - m_Ptr = NULL; - m_Ref = NULL; - } - } - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - DocumentRef(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(); - } - - /* -------------------------------------------------------------------------------------------- - * Move constructor. - */ - DocumentRef(DocumentRef && o) - : m_Ptr(o.m_Ptr), m_Ref(o.m_Ref) - { - o.m_Ptr = NULL; - o.m_Ref = NULL; - } - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~DocumentRef() - { - Drop(); - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. - */ - DocumentRef & operator = (const DocumentRef & o) - { - if (m_Ptr != o.m_Ptr) - { - Drop(); - m_Ptr = o.m_Ptr; - m_Ref = o.m_Ref; - Grab(); - } - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. - */ - DocumentRef & operator = (DocumentRef && o) - { - if (m_Ptr != o.m_Ptr) - { - m_Ptr = o.m_Ptr; - m_Ref = o.m_Ref; - o.m_Ptr = NULL; - o.m_Ref = NULL; - } - return *this; - } - - /* -------------------------------------------------------------------------------------------- - * Perform an equality comparison between two document instances. - */ - bool operator == (const DocumentRef & o) const - { - return (m_Ptr == o.m_Ptr); - } - - /* -------------------------------------------------------------------------------------------- - * Perform an inequality comparison between two document instances. - */ - bool operator != (const DocumentRef & o) const - { - return (m_Ptr != o.m_Ptr); - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to boolean for use in boolean operations. - */ - operator bool () const - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance pointer. - */ - operator Pointer () - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance pointer. - */ - operator ConstPtr () const - { - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance reference. - */ - operator Reference () - { - assert(m_Ptr); - return *m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Implicit conversion to the managed instance reference. - */ - operator ConstRef () const - { - assert(m_Ptr); - return *m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Member operator for dereferencing the managed pointer. - */ - Pointer operator -> () const - { - assert(m_Ptr); - return m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Indirection operator for obtaining a reference of the managed pointer. - */ - Reference operator * () const - { - assert(m_Ptr); - return *m_Ptr; - } - - /* -------------------------------------------------------------------------------------------- - * Retrieve the number of active references to the managed instance. - */ - Counter Count() const - { - return (m_Ptr && m_Ref) ? (*m_Ref) : 0; - } -}; - -/* ------------------------------------------------------------------------------------------------ - * Allows the user to inspect the result of certain operations and act accordingly. -*/ -class 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. - */ - void 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(); - } - - /* -------------------------------------------------------------------------------------------- - * Used by the script engine to retrieve the name from instances of this type. - */ - static SQInteger Typename(HSQUIRRELVM vm); - - /* -------------------------------------------------------------------------------------------- - * See whether this instance references a valid 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; -}; +class ParseResult; } // Namespace:: SqMod -#endif // _XML_COMMON_HPP_ +#endif // _SQXML_COMMON_HPP_ diff --git a/modules/xml/Document.cpp b/modules/xml/Document.cpp index f3254d3c..afbeb5a7 100644 --- a/modules/xml/Document.cpp +++ b/modules/xml/Document.cpp @@ -1,7 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Document.hpp" #include "Node.hpp" -#include "Module.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { diff --git a/modules/xml/Document.hpp b/modules/xml/Document.hpp index 130e026f..0c5bcb1e 100644 --- a/modules/xml/Document.hpp +++ b/modules/xml/Document.hpp @@ -1,8 +1,9 @@ -#ifndef _XML_DOCUMENT_HPP_ -#define _XML_DOCUMENT_HPP_ +#ifndef _SQXML_DOCUMENT_HPP_ +#define _SQXML_DOCUMENT_HPP_ // ------------------------------------------------------------------------------------------------ -#include "Common.hpp" +#include "Handle/Document.hpp" +#include "Wrapper/ParseResult.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -253,4 +254,4 @@ public: } // Namespace:: SqMod -#endif // _XML_DOCUMENT_HPP_ +#endif // _SQXML_DOCUMENT_HPP_ diff --git a/modules/xml/Handle/Document.cpp b/modules/xml/Handle/Document.cpp new file mode 100644 index 00000000..f3b7cbe5 --- /dev/null +++ b/modules/xml/Handle/Document.cpp @@ -0,0 +1,16 @@ +// ------------------------------------------------------------------------------------------------ +#include "Handle/Document.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +void DocumentRef::Validate() const +{ + if (!m_Ptr) + { + STHROWF("Invalid XML document reference"); + } +} + +} // Namespace:: SqMod diff --git a/modules/xml/Handle/Document.hpp b/modules/xml/Handle/Document.hpp new file mode 100644 index 00000000..4e6ffe9d --- /dev/null +++ b/modules/xml/Handle/Document.hpp @@ -0,0 +1,236 @@ +#ifndef _SQXML_HANDLE_DOCUMENT_HPP_ +#define _SQXML_HANDLE_DOCUMENT_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "Common.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * 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. */ + + /* -------------------------------------------------------------------------------------------- + * Validate the managed handle and throw exception if invalid. + */ + void Validate() const; + +private: + + // -------------------------------------------------------------------------------------------- + Pointer m_Ptr; /* The document reader, writer and manager instance. */ + Counter* m_Ref; /* Reference count to the managed instance. */ + + /* -------------------------------------------------------------------------------------------- + * Grab a strong reference to a document instance. + */ + void Grab() + { + if (m_Ptr) + { + ++(*m_Ref); + } + } + + /* -------------------------------------------------------------------------------------------- + * Drop a strong reference to a document instance. + */ + void Drop() + { + if (m_Ptr && --(*m_Ref) == 0) + { + delete m_Ptr; + delete m_Ref; + m_Ptr = NULL; + m_Ref = NULL; + } + } + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + DocumentRef(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(); + } + + /* -------------------------------------------------------------------------------------------- + * Move constructor. + */ + DocumentRef(DocumentRef && o) + : m_Ptr(o.m_Ptr), m_Ref(o.m_Ref) + { + o.m_Ptr = NULL; + o.m_Ref = NULL; + } + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~DocumentRef() + { + Drop(); + } + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + DocumentRef & operator = (const DocumentRef & o) + { + if (m_Ptr != o.m_Ptr) + { + Drop(); + m_Ptr = o.m_Ptr; + m_Ref = o.m_Ref; + Grab(); + } + return *this; + } + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. + */ + DocumentRef & operator = (DocumentRef && o) + { + if (m_Ptr != o.m_Ptr) + { + m_Ptr = o.m_Ptr; + m_Ref = o.m_Ref; + o.m_Ptr = NULL; + o.m_Ref = NULL; + } + return *this; + } + + /* -------------------------------------------------------------------------------------------- + * Perform an equality comparison between two document instances. + */ + bool operator == (const DocumentRef & o) const + { + return (m_Ptr == o.m_Ptr); + } + + /* -------------------------------------------------------------------------------------------- + * Perform an inequality comparison between two document instances. + */ + bool operator != (const DocumentRef & o) const + { + return (m_Ptr != o.m_Ptr); + } + + /* -------------------------------------------------------------------------------------------- + * Implicit conversion to boolean for use in boolean operations. + */ + operator bool () const + { + return m_Ptr; + } + + /* -------------------------------------------------------------------------------------------- + * Implicit conversion to the managed instance pointer. + */ + operator Pointer () + { + return m_Ptr; + } + + /* -------------------------------------------------------------------------------------------- + * Implicit conversion to the managed instance pointer. + */ + operator ConstPtr () const + { + return m_Ptr; + } + + /* -------------------------------------------------------------------------------------------- + * Implicit conversion to the managed instance reference. + */ + operator Reference () + { + assert(m_Ptr); + return *m_Ptr; + } + + /* -------------------------------------------------------------------------------------------- + * Implicit conversion to the managed instance reference. + */ + operator ConstRef () const + { + assert(m_Ptr); + return *m_Ptr; + } + + /* -------------------------------------------------------------------------------------------- + * Member operator for dereferencing the managed pointer. + */ + Pointer operator -> () const + { + assert(m_Ptr); + return m_Ptr; + } + + /* -------------------------------------------------------------------------------------------- + * Indirection operator for obtaining a reference of the managed pointer. + */ + Reference operator * () const + { + assert(m_Ptr); + return *m_Ptr; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the number of active references to the managed instance. + */ + Counter Count() const + { + return (m_Ptr && m_Ref) ? (*m_Ref) : 0; + } +}; + +} // Namespace:: SqMod + +#endif // _SQXML_HANDLE_DOCUMENT_HPP_ diff --git a/modules/xml/Module.cpp b/modules/xml/Module.cpp index 87f9963c..53b13b99 100644 --- a/modules/xml/Module.cpp +++ b/modules/xml/Module.cpp @@ -1,38 +1,20 @@ -// -------------------------------------------------------------------------------------------- -#include "Module.hpp" +// ------------------------------------------------------------------------------------------------ #include "Common.hpp" #include "Attribute.hpp" #include "Text.hpp" #include "Node.hpp" #include "Document.hpp" +#include "Wrapper/ParseResult.hpp" -// -------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ #include #include -#include - -// -------------------------------------------------------------------------------------------- -#include - -// -------------------------------------------------------------------------------------------- -#if defined(WIN32) || defined(_WIN32) - #include -#endif +// ------------------------------------------------------------------------------------------------ namespace SqMod { -// -------------------------------------------------------------------------------------------- -PluginFuncs* _Func = nullptr; -PluginCallbacks* _Clbk = nullptr; -PluginInfo* _Info = nullptr; - -// -------------------------------------------------------------------------------------------- -HSQAPI _SqAPI = nullptr; -HSQEXPORTS _SqMod = nullptr; -HSQUIRRELVM _SqVM = nullptr; - /* ------------------------------------------------------------------------------------------------ - * Bind speciffic functions to certain server events. + * Bind specific functions to certain server events. */ void BindCallbacks(); @@ -41,22 +23,22 @@ void 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. +/* ------------------------------------------------------------------------------------------------ + * Initialize the plug-in by obtaining the API provided by the host plug-in. */ void OnSquirrelInitialize() { - // Attempt to import the plugin API exported by the host plugin + // Attempt to import the plug-in API exported by the host plug-in _SqMod = sq_api_import(_Func); - // Did we failed to obtain the plugin exports? - if(!_SqMod) + // Did we failed to obtain the plug-in exports? + if (!_SqMod) { - OutputError("Failed to attach [%s] on host plugin.", SQXML_NAME); + OutputError("Failed to attach [%s] on host plug-in.", SQXML_NAME); } else { @@ -67,12 +49,12 @@ void OnSquirrelInitialize() } } -/* -------------------------------------------------------------------------------------------- +/* ------------------------------------------------------------------------------------------------ * Load the module on the virtual machine provided by the host module. */ void OnSquirrelLoad() { - // Make sure that we have a valid plugin API + // Make sure that we have a valid plug-in API if (!_SqMod) { return; // Unable to proceed! @@ -92,23 +74,28 @@ void OnSquirrelLoad() 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 null objects just in case + NullObject().Release(); + NullTable().Release(); + NullArray().Release(); + NullFunction().ReleaseGently(); // Release the current virtual machine, if any DefaultVM::Set(nullptr); } -/* -------------------------------------------------------------------------------------------- +/* ------------------------------------------------------------------------------------------------ * Validate the module API to make sure we don't run into issues. */ bool CheckAPIVer(CCStr ver) { // Obtain the numeric representation of the API version - long vernum = std::strtol(ver, nullptr, 10); + const LongI vernum = std::strtol(ver, nullptr, 10); // Check against version mismatch if (vernum == SQMOD_API_VER) { @@ -121,8 +108,8 @@ bool CheckAPIVer(CCStr ver) return false; } -/* -------------------------------------------------------------------------------------------- - * React to command sent by other plugins. +/* ------------------------------------------------------------------------------------------------ + * React to command sent by other plug-ins. */ static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) { @@ -145,8 +132,8 @@ static uint8_t OnPluginCommand(uint32_t command_identifier, CCStr message) return 1; } -/* -------------------------------------------------------------------------------------------- - * The server was initialized and this plugin was loaded successfully. +/* ------------------------------------------------------------------------------------------------ + * The server was initialized and this plug-in was loaded successfully. */ static uint8_t OnServerInitialise() { @@ -175,7 +162,7 @@ void UnbindCallbacks() _Clbk->OnPluginCommand = nullptr; } -// -------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ void RegisterAPI(HSQUIRRELVM vm) { Table xmlns(vm); @@ -184,7 +171,7 @@ void RegisterAPI(HSQUIRRELVM vm) // Constructors .Ctor() .Ctor< const ParseResult & >() - // Core Metamethods + // Core Meta-methods .Func(_SC("_cmp"), &ParseResult::Cmp) .SquirrelFunc(_SC("_typename"), &ParseResult::Typename) .Func(_SC("_tostring"), &ParseResult::ToString) @@ -204,7 +191,7 @@ void RegisterAPI(HSQUIRRELVM vm) // Constructors .Ctor() .Ctor< const Attribute & >() - // Core Metamethods + // Core Meta-methods .Func(_SC("_cmp"), &Attribute::Cmp) .SquirrelFunc(_SC("_typename"), &Attribute::Typename) .Func(_SC("_tostring"), &Attribute::ToString) @@ -249,7 +236,7 @@ void RegisterAPI(HSQUIRRELVM vm) // Constructors .Ctor() .Ctor< const Text & >() - // Core Metamethods + // Core Meta-methods .Func(_SC("_cmp"), &Text::Cmp) .SquirrelFunc(_SC("_typename"), &Text::Typename) .Func(_SC("_tostring"), &Text::ToString) @@ -289,7 +276,7 @@ void RegisterAPI(HSQUIRRELVM vm) // Constructors .Ctor() .Ctor< const Node & >() - // Core Metamethods + // Core Meta-methods .Func(_SC("_cmp"), &Node::Cmp) .SquirrelFunc(_SC("_typename"), &Node::Typename) .Func(_SC("_tostring"), &Node::ToString) @@ -364,7 +351,7 @@ void RegisterAPI(HSQUIRRELVM vm) xmlns.Bind(_SC("Document"), Class< Document, NoCopy< Document > >(vm, _SC("SqXmlDocument")) // Constructors .Ctor() - // Core Metamethods + // Core Meta-methods .Func(_SC("_cmp"), &Document::Cmp) .SquirrelFunc(_SC("_typename"), &Document::Typename) .Func(_SC("_tostring"), &Document::ToString) @@ -473,119 +460,33 @@ void RegisterAPI(HSQUIRRELVM vm) ); } -// -------------------------------------------------------------------------------------------- -void OutputMessageImpl(const char * msg, va_list args) -{ -#if defined(WIN32) || defined(_WIN32) - HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csb_before; - GetConsoleScreenBufferInfo( hstdout, &csb_before); - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); - std::printf("[SQMOD] "); - - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - std::vprintf(msg, args); - std::puts(""); - - SetConsoleTextAttribute(hstdout, csb_before.wAttributes); -#else - std::printf("%c[0;32m[SQMOD]%c[0m", 27, 27); - std::vprintf(msg, args); - std::puts(""); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputErrorImpl(const char * msg, va_list args) -{ -#if defined(WIN32) || defined(_WIN32) - HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csb_before; - GetConsoleScreenBufferInfo( hstdout, &csb_before); - SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); - std::printf("[SQMOD] "); - - SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - std::vprintf(msg, args); - std::puts(""); - - SetConsoleTextAttribute(hstdout, csb_before.wAttributes); -#else - std::printf("%c[0;91m[SQMOD]%c[0m", 27, 27); - std::vprintf(msg, args); - std::puts(""); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputDebug(const char * msg, ...) -{ -#ifdef _DEBUG - // Initialize the arguments list - va_list args; - va_start(args, msg); - // Call the output function - OutputMessageImpl(msg, args); - // Finalize the arguments list - va_end(args); -#else - SQMOD_UNUSED_VAR(msg); -#endif -} - -// -------------------------------------------------------------------------------------------- -void OutputMessage(const char * msg, ...) -{ - // Initialize the arguments list - va_list args; - va_start(args, msg); - // Call the output function - OutputMessageImpl(msg, args); - // Finalize the arguments list - va_end(args); -} - -// -------------------------------------------------------------------------------------------- -void OutputError(const char * msg, ...) -{ - // Initialize the arguments list - va_list args; - va_start(args, msg); - // Call the output function - OutputErrorImpl(msg, args); - // Finalize the arguments list - va_end(args); -} - } // Namespace:: SqMod -// -------------------------------------------------------------------------------------------- -SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallbacks* callbacks, PluginInfo* info) +// ------------------------------------------------------------------------------------------------ +SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info) { using namespace SqMod; - // Output plugin header + // Output plug-in header puts(""); OutputMessage("--------------------------------------------------------------------"); - OutputMessage("Plugin: %s", SQXML_NAME); + OutputMessage("Plug-in: %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 + // Attempt to find the host plug-in ID + const int host_plugin_id = functions->FindPlugin(SQMOD_HOST_NAME); + // See if our plug-in was loaded after the host plug-in if (host_plugin_id < 0) { - OutputError("%s could find the host plugin", SQXML_NAME); + OutputError("%s could find the host plug-in", SQXML_NAME); // Don't load! return SQMOD_FAILURE; } // Should never reach this point but just in case else if (static_cast< Uint32 >(host_plugin_id) > info->pluginId) { - OutputError("%s loaded after the host plugin", SQXML_NAME); + OutputError("%s loaded after the host plug-in", SQXML_NAME); // Don't load! return SQMOD_FAILURE; } @@ -593,15 +494,15 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallb _Func = functions; _Clbk = callbacks; _Info = info; - // Assign plugin version + // Assign plug-in version _Info->pluginVersion = SQXML_VERSION; _Info->apiMajorVersion = PLUGIN_API_MAJOR; _Info->apiMinorVersion = PLUGIN_API_MINOR; - // Assign the plugin name + // Assign the plug-in name std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQXML_HOST_NAME); // Bind callbacks BindCallbacks(); - // Notify that the plugin was successfully loaded + // Notify that the plug-in was successfully loaded OutputMessage("Successfully loaded %s", SQXML_NAME); // Dummy spacing puts(""); diff --git a/modules/xml/Module.hpp b/modules/xml/Module.hpp deleted file mode 100644 index 93b598df..00000000 --- a/modules/xml/Module.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#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_ diff --git a/modules/xml/Node.cpp b/modules/xml/Node.cpp index 1fb308ac..3f135c8d 100644 --- a/modules/xml/Node.cpp +++ b/modules/xml/Node.cpp @@ -2,7 +2,6 @@ #include "Node.hpp" #include "Attribute.hpp" #include "Text.hpp" -#include "Module.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { diff --git a/modules/xml/Node.hpp b/modules/xml/Node.hpp index 5affcbb7..611b3cd0 100644 --- a/modules/xml/Node.hpp +++ b/modules/xml/Node.hpp @@ -1,8 +1,9 @@ -#ifndef _XML_NODE_HPP_ -#define _XML_NODE_HPP_ +#ifndef _SQXML_NODE_HPP_ +#define _SQXML_NODE_HPP_ // ------------------------------------------------------------------------------------------------ -#include "Common.hpp" +#include "Handle/Document.hpp" +#include "Wrapper/ParseResult.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -609,4 +610,4 @@ public: } // Namespace:: SqMod -#endif // _XML_NODE_HPP_ +#endif // _SQXML_NODE_HPP_ diff --git a/modules/xml/Text.cpp b/modules/xml/Text.cpp index 49bde447..a0d363e9 100644 --- a/modules/xml/Text.cpp +++ b/modules/xml/Text.cpp @@ -1,14 +1,10 @@ // ------------------------------------------------------------------------------------------------ #include "Text.hpp" #include "Node.hpp" -#include "Module.hpp" // ------------------------------------------------------------------------------------------------ #include -// ------------------------------------------------------------------------------------------------ -#include - // ------------------------------------------------------------------------------------------------ namespace SqMod { diff --git a/modules/xml/Text.hpp b/modules/xml/Text.hpp index 2b97aaa7..8806756e 100644 --- a/modules/xml/Text.hpp +++ b/modules/xml/Text.hpp @@ -1,8 +1,8 @@ -#ifndef _XML_TEXT_HPP_ -#define _XML_TEXT_HPP_ +#ifndef _SQXML_TEXT_HPP_ +#define _SQXML_TEXT_HPP_ // ------------------------------------------------------------------------------------------------ -#include "Common.hpp" +#include "Handle/Document.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -362,4 +362,4 @@ public: } // Namespace:: SqMod -#endif // _XML_TEXT_HPP_ \ No newline at end of file +#endif // _SQXML_TEXT_HPP_ \ No newline at end of file diff --git a/modules/xml/Wrapper/ParseResult.cpp b/modules/xml/Wrapper/ParseResult.cpp new file mode 100644 index 00000000..f6a4e6b4 --- /dev/null +++ b/modules/xml/Wrapper/ParseResult.cpp @@ -0,0 +1,34 @@ +// ------------------------------------------------------------------------------------------------ +#include "Wrapper/ParseResult.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +SQInteger ParseResult::Typename(HSQUIRRELVM vm) +{ + static const SQChar name[] = _SC("SqXmlParseResult"); + sq_pushstring(vm, name, sizeof(name)); + return 1; +} + +// ------------------------------------------------------------------------------------------------ +void ParseResult::Validate() const +{ + // Is the documen handle valid? + if (!m_Doc) + { + STHROWF("Invalid XML document reference"); + } +} + +// ------------------------------------------------------------------------------------------------ +void ParseResult::Check() const +{ + if (m_Result.status != status_ok) + { + STHROWF("XML parse error [%s]", m_Result.description()); + } +} + +} // Namespace:: SqMod \ No newline at end of file diff --git a/modules/xml/Wrapper/ParseResult.hpp b/modules/xml/Wrapper/ParseResult.hpp new file mode 100644 index 00000000..f4b273eb --- /dev/null +++ b/modules/xml/Wrapper/ParseResult.hpp @@ -0,0 +1,178 @@ +#ifndef _SQXML_WRAPPER_PARSERESULT_HPP_ +#define _SQXML_WRAPPER_PARSERESULT_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "Handle/Document.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * 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. + */ + void 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(); + } + + /* -------------------------------------------------------------------------------------------- + * Used by the script engine to retrieve the name from instances of this type. + */ + static SQInteger Typename(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * See whether this instance references a valid 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 // _SQXML_WRAPPER_PARSERESULT_HPP_