diff --git a/cbp/ModMMDB.cbp b/cbp/ModMMDB.cbp
index 8f8ed618..4d4d8fca 100644
--- a/cbp/ModMMDB.cbp
+++ b/cbp/ModMMDB.cbp
@@ -106,9 +106,9 @@
+
-
@@ -129,8 +129,8 @@
-
+
@@ -410,6 +410,7 @@
+
@@ -428,10 +429,18 @@
+
+
+
+
+
+
+
+
diff --git a/cbp/default.workspace b/cbp/default.workspace
index 60f92715..317ea370 100644
--- a/cbp/default.workspace
+++ b/cbp/default.workspace
@@ -7,5 +7,6 @@
+
diff --git a/modules/mmdb/Common.cpp b/modules/mmdb/Common.cpp
index 61aa8981..9b3c602d 100644
--- a/modules/mmdb/Common.cpp
+++ b/modules/mmdb/Common.cpp
@@ -2,24 +2,451 @@
#include "Common.hpp"
// ------------------------------------------------------------------------------------------------
+#include
#include
+#include
+
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
-DbRef::Pointer DbRef::Create()
+// N[0] - contains least significant bits, N[3] - most significant
+static SQChar * Bin128ToDec(const Uint32 N[4])
{
- return reinterpret_cast< Pointer >(std::malloc(sizeof(Type)));
+ // log10(x) = log2(x) / log2(10) ~= log2(x) / 3.322
+ static SQChar s[128 / 3 + 1 + 1];
+ Uint32 n[4];
+ SQChar * p = s;
+ int i;
+
+ std::memset(s, '0', sizeof(s) - 1);
+ s[sizeof(s) - 1] = '\0';
+
+ std::memcpy(n, N, sizeof(n));
+
+ for (i = 0; i < 128; i++)
+ {
+ int j, carry;
+
+ carry = (n[3] >= 0x80000000);
+ // Shift n[] left, doubling it
+ n[3] = ((n[3] << 1) & 0xFFFFFFFF) + (n[2] >= 0x80000000);
+ n[2] = ((n[2] << 1) & 0xFFFFFFFF) + (n[1] >= 0x80000000);
+ n[1] = ((n[1] << 1) & 0xFFFFFFFF) + (n[0] >= 0x80000000);
+ n[0] = ((n[0] << 1) & 0xFFFFFFFF);
+
+ // Add s[] to itself in decimal, doubling it
+ for (j = sizeof(s) - 2; j >= 0; j--)
+ {
+ s[j] += s[j] - '0' + carry;
+
+ carry = (s[j] > '9');
+
+ if (carry)
+ {
+ s[j] -= 10;
+ }
+ }
+ }
+
+ while ((p[0] == '0') && (p < &s[sizeof(s) - 2]))
+ {
+ p++;
+ }
+
+ return p;
}
// ------------------------------------------------------------------------------------------------
-void DbRef::Destroy(Pointer db)
+CSStr AsTypeStr(Uint32 id)
{
- if (db)
+ switch (id)
{
- std::free(db);
+ case MMDB_DATA_TYPE_EXTENDED: return _SC("extended");
+ case MMDB_DATA_TYPE_POINTER: return _SC("pointer");
+ case MMDB_DATA_TYPE_UTF8_STRING: return _SC("string");
+ case MMDB_DATA_TYPE_DOUBLE: return _SC("double");
+ case MMDB_DATA_TYPE_BYTES: return _SC("bytes");
+ case MMDB_DATA_TYPE_UINT16: return _SC("uint16");
+ case MMDB_DATA_TYPE_UINT32: return _SC("uint32");
+ case MMDB_DATA_TYPE_MAP: return _SC("map");
+ case MMDB_DATA_TYPE_INT32: return _SC("int32");
+ case MMDB_DATA_TYPE_UINT64: return _SC("uint64");
+ case MMDB_DATA_TYPE_UINT128: return _SC("uint128");
+ case MMDB_DATA_TYPE_ARRAY: return _SC("array");
+ case MMDB_DATA_TYPE_CONTAINER: return _SC("container");
+ case MMDB_DATA_TYPE_END_MARKER: return _SC("endmarker");
+ case MMDB_DATA_TYPE_BOOLEAN: return _SC("boolean");
+ case MMDB_DATA_TYPE_FLOAT: return _SC("float");
+ default: return _SC("unknonw");
}
}
+// ------------------------------------------------------------------------------------------------
+bool GetEntryAsBool(const MMDB_entry_data_s & ed)
+{
+ bool value = false;
+ // Identify the type of entry data
+ switch (ed.type)
+ {
+ case MMDB_DATA_TYPE_POINTER: {
+ value = ed.pointer > 0;
+ } break;
+ case MMDB_DATA_TYPE_UTF8_STRING: {
+ if (ed.data_size > 0)
+ {
+ value = ConvTo< bool >::From(reinterpret_cast< CSStr >(ed.utf8_string));
+ }
+ } break;
+ case MMDB_DATA_TYPE_DOUBLE: {
+ value = ConvTo< bool >::From(ed.double_value);
+ } break;
+ case MMDB_DATA_TYPE_BYTES: {
+ for (Uint32 i = 0; i < ed.data_size; ++i)
+ {
+ if (ed.bytes[i] != 0)
+ {
+ value = true;
+ // Found somethinf that isn't 0
+ break;
+ }
+ }
+ } break;
+ case MMDB_DATA_TYPE_UINT16: {
+ value = ConvTo< bool >::From(ed.uint16);
+ } break;
+ case MMDB_DATA_TYPE_UINT32: {
+ value = ConvTo< bool >::From(ed.uint16);
+ } break;
+ case MMDB_DATA_TYPE_INT32: {
+ value = ConvTo< bool >::From(ed.uint16);
+ } break;
+ case MMDB_DATA_TYPE_UINT64: {
+ value = ConvTo< bool >::From(ed.uint16);
+ } break;
+ case MMDB_DATA_TYPE_UINT128: {
+#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
+ for (Uint32 i = 0; i < sizeof(ed.uint128); ++i)
+ {
+ if (ed.uint128[i] != 0)
+ {
+ value = true;
+ // Found somethinf that isn't 0
+ break;
+ }
+ }
+#else
+ value = ed.uint128 > 0;
+#endif // MMDB_UINT128_IS_BYTE_ARRAY
+
+ } break;
+ case MMDB_DATA_TYPE_BOOLEAN: {
+ value = ed.boolean ? true : false;
+ } break;
+ case MMDB_DATA_TYPE_FLOAT: {
+ value = ConvTo< bool >::From(ed.float_value);
+ } break;
+ default:
+ STHROWF("Unsupported conversion from (%s) to (boolean)", AsTypeStr(ed.type));
+ }
+ // Return the extracted value
+ return value;
+}
+
+// ------------------------------------------------------------------------------------------------
+SQInteger GetEntryAsInteger(const MMDB_entry_data_s & ed)
+{
+ SQInteger value = 0;
+ // Identify the type of entry data
+ switch (ed.type)
+ {
+ case MMDB_DATA_TYPE_POINTER: {
+ value = static_cast< SQInteger >(ed.pointer);
+ } break;
+ case MMDB_DATA_TYPE_UTF8_STRING: {
+ if (ed.data_size > 0)
+ {
+ value = ConvTo< SQInteger >::From(reinterpret_cast< CSStr >(ed.utf8_string));
+ }
+ } break;
+ case MMDB_DATA_TYPE_DOUBLE: {
+ value = ConvTo< SQInteger >::From(ed.double_value);
+ } break;
+ case MMDB_DATA_TYPE_BYTES: {
+ std::memcpy(&value, ed.bytes, Clamp(ed.data_size, 0U, sizeof(value)));
+ } break;
+ case MMDB_DATA_TYPE_UINT16: {
+ value = ConvTo< SQInteger >::From(ed.uint16);
+ } break;
+ case MMDB_DATA_TYPE_UINT32: {
+ value = ConvTo< SQInteger >::From(ed.uint32);
+ } break;
+ case MMDB_DATA_TYPE_INT32: {
+ value = ConvTo< SQInteger >::From(ed.int32);
+ } break;
+ case MMDB_DATA_TYPE_UINT64: {
+ value = ConvTo< SQInteger >::From(ed.uint64);
+ } break;
+ case MMDB_DATA_TYPE_UINT128: {
+#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
+ std::memcpy(&value, ed.uint128, sizeof(value));
+#else
+ std::memcpy(&value, &ed.uint128, sizeof(value));
+#endif // MMDB_UINT128_IS_BYTE_ARRAY
+ } break;
+ case MMDB_DATA_TYPE_BOOLEAN: {
+ value = ed.boolean ? 1 : 0;
+ } break;
+ case MMDB_DATA_TYPE_FLOAT: {
+ value = ConvTo< SQInteger >::From(ed.float_value);
+ } break;
+ default:
+ STHROWF("Unsupported conversion from (%s) to (integer)", AsTypeStr(ed.type));
+ }
+ // Return the extracted value
+ return value;
+}
+
+// ------------------------------------------------------------------------------------------------
+SQFloat GetEntryAsFloat(const MMDB_entry_data_s & ed)
+{
+ SQFloat value = 0.0;
+ // Identify the type of entry data
+ switch (ed.type)
+ {
+ case MMDB_DATA_TYPE_POINTER: {
+ value = ConvTo< SQFloat >::From(static_cast< SQInteger >(ed.pointer));
+ } break;
+ case MMDB_DATA_TYPE_UTF8_STRING: {
+ if (ed.data_size > 0)
+ {
+ value = ConvTo< SQFloat >::From(reinterpret_cast< CSStr >(ed.utf8_string));
+ }
+ } break;
+ case MMDB_DATA_TYPE_DOUBLE: {
+ value = ConvTo< SQFloat >::From(ed.double_value);
+ } break;
+ case MMDB_DATA_TYPE_BYTES: {
+ // Not our problem if the result will be junk!
+ std::memcpy(&value, ed.bytes, Clamp(ed.data_size, 0U, sizeof(value)));
+ } break;
+ case MMDB_DATA_TYPE_UINT16: {
+ value = ConvTo< SQFloat >::From(ed.uint16);
+ } break;
+ case MMDB_DATA_TYPE_UINT32: {
+ value = ConvTo< SQFloat >::From(ed.uint32);
+ } break;
+ case MMDB_DATA_TYPE_INT32: {
+ value = ConvTo< SQFloat >::From(ed.int32);
+ } break;
+ case MMDB_DATA_TYPE_UINT64: {
+ value = ConvTo< SQFloat >::From(ed.uint64);
+ } break;
+ case MMDB_DATA_TYPE_UINT128: {
+ SQInteger num;
+ // Convert to integer first
+#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
+ std::memcpy(&num, ed.uint128, sizeof(num));
+#else
+ std::memcpy(&num, &ed.uint128, sizeof(num));
+#endif // MMDB_UINT128_IS_BYTE_ARRAY
+ // Now convert to float
+ value = ConvTo< SQFloat >::From(num);
+ } break;
+ case MMDB_DATA_TYPE_BOOLEAN: {
+ value = ed.boolean ? 1.0 : 0.0;
+ } break;
+ case MMDB_DATA_TYPE_FLOAT: {
+ value = ConvTo< SQFloat >::From(ed.float_value);
+ } break;
+ default:
+ STHROWF("Unsupported conversion from (%s) to (float)", AsTypeStr(ed.type));
+ }
+ // Return the extracted value
+ return value;
+}
+
+// ------------------------------------------------------------------------------------------------
+Object GetEntryAsLong(const MMDB_entry_data_s & ed)
+{
+ Uint64 value = 0;
+ // Identify the type of entry data
+ switch (ed.type)
+ {
+ case MMDB_DATA_TYPE_POINTER: {
+ value = static_cast< Uint64 >(ed.pointer);
+ } break;
+ case MMDB_DATA_TYPE_UTF8_STRING: {
+ if (ed.data_size > 0)
+ {
+ value = ConvTo< Uint64 >::From(reinterpret_cast< CSStr >(ed.utf8_string));
+ }
+ } break;
+ case MMDB_DATA_TYPE_DOUBLE: {
+ value = ConvTo< Uint64 >::From(ed.double_value);
+ } break;
+ case MMDB_DATA_TYPE_BYTES: {
+ std::memcpy(&value, ed.bytes, Clamp(ed.data_size, 0U, sizeof(value)));
+ } break;
+ case MMDB_DATA_TYPE_UINT16: {
+ value = ConvTo< Uint64 >::From(ed.uint16);
+ } break;
+ case MMDB_DATA_TYPE_UINT32: {
+ value = ConvTo< Uint64 >::From(ed.uint32);
+ } break;
+ case MMDB_DATA_TYPE_INT32: {
+ value = ConvTo< Uint64 >::From(ed.int32);
+ } break;
+ case MMDB_DATA_TYPE_UINT64: {
+ value = ConvTo< Uint64 >::From(ed.uint64);
+ } break;
+ case MMDB_DATA_TYPE_UINT128: {
+#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
+ std::memcpy(&value, ed.uint128, sizeof(value));
+#else
+ std::memcpy(&value, &ed.uint128, sizeof(value));
+#endif // MMDB_UINT128_IS_BYTE_ARRAY
+ } break;
+ case MMDB_DATA_TYPE_BOOLEAN: {
+ value = ed.boolean ? 1 : 0;
+ } break;
+ case MMDB_DATA_TYPE_FLOAT: {
+ value = ConvTo< Uint64 >::From(ed.float_value);
+ } break;
+ default:
+ STHROWF("Unsupported conversion from (%s) to (long)", AsTypeStr(ed.type));
+ }
+ // Obtain the initial stack size
+ const StackGuard sg;
+ // Push a long integer instance with the requested value on the stack
+ SqMod_PushULongObject(DefaultVM::Get(), value);
+ // Obtain the object from the stack and return it
+ return Var< Object >(DefaultVM::Get(), -1).value;
+}
+
+// ------------------------------------------------------------------------------------------------
+Object GetEntryAsString(const MMDB_entry_data_s & ed)
+{
+ // Obtain the initial stack size
+ const StackGuard sg;
+ // The default vm
+ HSQUIRRELVM vm = DefaultVM::Get();
+ // Identify the type of entry data
+ switch (ed.type)
+ {
+ case MMDB_DATA_TYPE_POINTER: {
+ sq_pushstring(vm, ToStrF("%p", ed.pointer), -1);
+ } break;
+ case MMDB_DATA_TYPE_UTF8_STRING: {
+ sq_pushstring(vm, ed.utf8_string, ed.data_size);
+ } break;
+ case MMDB_DATA_TYPE_DOUBLE: {
+ sq_pushstring(vm, ToStrF("%f", ed.double_value), -1);
+ } break;
+ case MMDB_DATA_TYPE_BYTES: {
+ sq_pushstring(vm, reinterpret_cast< CSStr >(ed.bytes), ed.data_size / sizeof(SQChar));
+ } break;
+ case MMDB_DATA_TYPE_UINT16: {
+ sq_pushstring(vm, ToStrF("%u", ed.uint16), -1);
+ } break;
+ case MMDB_DATA_TYPE_UINT32: {
+ sq_pushstring(vm, ToStrF("%u", ed.uint32), -1);
+ } break;
+ case MMDB_DATA_TYPE_INT32: {
+ sq_pushstring(vm, ToStrF("%d", ed.int32), -1);
+ } break;
+ case MMDB_DATA_TYPE_UINT64: {
+ sq_pushstring(vm, ToStrF("%llu", ed.uint64), -1);
+ } break;
+ case MMDB_DATA_TYPE_UINT128: {
+#if defined(MMDB_UINT128_IS_BYTE_ARRAY) && (MMDB_UINT128_IS_BYTE_ARRAY == 1)
+ sq_pushstring(vm, Bin128ToDec(reinterpret_cast< const Uint32 * >(ed.uint128)), -1);
+#else
+ sq_pushstring(vm, Bin128ToDec(reinterpret_cast< const Uint32 * >(&ed.uint128)), -1);
+#endif // MMDB_UINT128_IS_BYTE_ARRAY
+ } break;
+ case MMDB_DATA_TYPE_BOOLEAN: {
+ sq_pushstring(vm, ed.boolean ? _SC("true") : _SC("false"), -1);
+ } break;
+ case MMDB_DATA_TYPE_FLOAT: {
+ sq_pushstring(vm, ToStrF("%f", ed.float_value), -1);
+ } break;
+ default:
+ STHROWF("Unsupported conversion from (%s) to (string)", AsTypeStr(ed.type));
+ }
+ // Obtain the object from the stack and return it
+ return Var< Object >(vm, -1).value;
+}
+
+// ------------------------------------------------------------------------------------------------
+Object GetEntryAsBytes(const MMDB_entry_data_s & ed)
+{
+ // Obtain the initial stack size
+ const StackGuard sg;
+ // The result of operations
+ SQRESULT res = SQ_OK;
+ // The default vm
+ HSQUIRRELVM vm = DefaultVM::Get();
+ // Identify the type of entry data
+ switch (ed.type)
+ {
+ case MMDB_DATA_TYPE_POINTER: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.pointer), sizeof(ed.pointer), 0);
+ } break;
+ case MMDB_DATA_TYPE_UTF8_STRING: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(ed.utf8_string), ed.data_size, 0);
+ } break;
+ case MMDB_DATA_TYPE_DOUBLE: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.double_value), sizeof(ed.double_value), 0);
+ } break;
+ case MMDB_DATA_TYPE_BYTES: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(ed.bytes), ed.data_size, 0);
+ } break;
+ case MMDB_DATA_TYPE_UINT16: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.uint16), sizeof(ed.uint16), 0);
+ } break;
+ case MMDB_DATA_TYPE_UINT32: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.uint32), sizeof(ed.uint32), 0);
+ } break;
+ case MMDB_DATA_TYPE_INT32: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.int32), sizeof(ed.int32), 0);
+ } break;
+ case MMDB_DATA_TYPE_UINT64: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.uint64), sizeof(ed.uint64), 0);
+ } break;
+ case MMDB_DATA_TYPE_UINT128: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.uint128), sizeof(ed.uint128), 0);
+ } break;
+ case MMDB_DATA_TYPE_BOOLEAN: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.boolean), sizeof(ed.boolean), 0);
+ } break;
+ case MMDB_DATA_TYPE_FLOAT: {
+ res = SqMod_PushBufferData(vm,
+ reinterpret_cast< const char * >(&ed.float_value),
+ sizeof(ed.float_value), 0);
+ } break;
+ default:
+ STHROWF("Unsupported conversion from (%s) to (buffer)", AsTypeStr(ed.type));
+ }
+ // Did we fail to push the buffer o the stack?
+ if (SQ_FAILED(res))
+ {
+ STHROWF("Failed to convert the (%s) value to a buffer.", AsTypeStr(ed.type));
+ }
+ // Obtain the object from the stack and return it
+ return Var< Object >(vm, -1).value;
+}
+
+
} // Namespace:: SqMod
diff --git a/modules/mmdb/Common.hpp b/modules/mmdb/Common.hpp
index d2fb11c6..4c4ffa82 100644
--- a/modules/mmdb/Common.hpp
+++ b/modules/mmdb/Common.hpp
@@ -23,257 +23,74 @@ namespace SqMod {
#define SQMMDB_VERSION_MINOR 0
#define SQMMDB_VERSION_PATCH 1
+/* ------------------------------------------------------------------------------------------------
+ * Handle validation.
+*/
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ #define SQMOD_VALIDATE(x) (x).Validate(__FILE__, __LINE__)
+ #define SQMOD_GET_VALID(x) (x).GetValid(__FILE__, __LINE__)
+ #define SQMOD_GET_VALID_ELEM(x) (x).GetValidElem(__FILE__, __LINE__)
+#else
+ #define SQMOD_VALIDATE(x) (x).Validate()
+ #define SQMOD_GET_VALID(x) (x).GetValid()
+ #define SQMOD_GET_VALID_ELEM(x) (x).GetValidElem()
+#endif // _DEBUG
+
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
class Database;
+class Metadata;
+class Description;
class SockAddr;
+class EntryData;
class EntryDataList;
class LookupResult;
/* ------------------------------------------------------------------------------------------------
- * Manages a reference counted INI document instance.
+ * Forward declarations.
*/
-class DbRef
-{
- // --------------------------------------------------------------------------------------------
- friend class Database;
+struct DbHnd;
-public:
+/* ------------------------------------------------------------------------------------------------
+ * Common typedefs.
+*/
+typedef SharedPtr< DbHnd > DbRef;
- // --------------------------------------------------------------------------------------------
- typedef MMDB_s Type; // The managed type.
+/* ------------------------------------------------------------------------------------------------
+ * Used to retrieve the string representation of the specified type identifier.
+*/
+CSStr AsTypeStr(Uint32 id);
- // --------------------------------------------------------------------------------------------
- typedef Type* Pointer; // Pointer to the managed type.
- typedef const Type* ConstPtr; // Constant pointer to the managed type.
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the value from the specified entry data as a boolean.
+*/
+bool GetEntryAsBool(const MMDB_entry_data_s & ed);
- // --------------------------------------------------------------------------------------------
- typedef Type& Reference; // Reference to the managed type.
- typedef const Type& ConstRef; // Constant reference to the managed type.
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the value from the specified entry data as a native integer.
+*/
+SQInteger GetEntryAsInteger(const MMDB_entry_data_s & ed);
- // --------------------------------------------------------------------------------------------
- typedef unsigned int Counter; // Reference counter type.
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the value from the specified entry data as a floating point.
+*/
+SQFloat GetEntryAsFloat(const MMDB_entry_data_s & ed);
-private:
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the value from the specified entry data as a long integer.
+*/
+Object GetEntryAsLong(const MMDB_entry_data_s & ed);
- // --------------------------------------------------------------------------------------------
- Pointer m_Ptr; // The document reader, writer and manager instance.
- Counter* m_Ref; // Reference count to the managed instance.
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the value from the specified entry data as a string.
+*/
+Object GetEntryAsString(const MMDB_entry_data_s & ed);
- /* --------------------------------------------------------------------------------------------
- * Creates a database structure.
- */
- static Pointer Create();
-
- /* --------------------------------------------------------------------------------------------
- * Destroyes the specified database structure.
- */
- static void Destroy(Pointer db);
-
- /* --------------------------------------------------------------------------------------------
- * 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)
- {
- MMDB_close(m_Ptr);
- Destroy(m_Ptr);
- delete m_Ref;
- m_Ptr = NULL;
- m_Ref = NULL;
- }
- }
-
- /* --------------------------------------------------------------------------------------------
- * Base constructor.
- */
- DbRef(bool make)
- : m_Ptr(make ? Create() : NULL), m_Ref(m_Ptr ? new Counter(1) : NULL)
- {
- /* ... */
- }
-
-public:
-
- /* --------------------------------------------------------------------------------------------
- * Default constructor (null).
- */
- DbRef()
- : m_Ptr(NULL), m_Ref(NULL)
- {
- /* ... */
- }
-
- /* --------------------------------------------------------------------------------------------
- * Copy constructor.
- */
- DbRef(const DbRef & o)
- : m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
-
- {
- Grab();
- }
-
- /* --------------------------------------------------------------------------------------------
- * Move constructor.
- */
- DbRef(DbRef && o)
- : m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
-
- {
- o.m_Ptr = NULL;
- o.m_Ref = NULL;
- }
-
- /* --------------------------------------------------------------------------------------------
- * Destructor.
- */
- ~DbRef()
- {
- Drop();
- }
-
- /* --------------------------------------------------------------------------------------------
- * Copy assignment operator.
- */
- DbRef & operator = (const DbRef & o)
- {
- if (m_Ptr != o.m_Ptr)
- {
- Drop();
- m_Ptr = o.m_Ptr;
- m_Ref = o.m_Ref;
- Grab();
- }
- return *this;
- }
-
- /* --------------------------------------------------------------------------------------------
- * Move assignment operator.
- */
- DbRef & operator = (DbRef && 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 DbRef & o) const
- {
- return (m_Ptr == o.m_Ptr);
- }
-
- /* --------------------------------------------------------------------------------------------
- * Perform an inequality comparison between two document instances.
- */
- bool operator != (const DbRef & 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 raw handle structure pointer.
- */
- Pointer DbPtr()
- {
- return m_Ptr;
- }
-
- /* --------------------------------------------------------------------------------------------
- * Retrieve the raw handle structure pointer.
- */
- Pointer DbPtr() const
- {
- return m_Ptr;
- }
-
- /* --------------------------------------------------------------------------------------------
- * Retrieve the number of active references to the managed instance.
- */
- Counter Count() const
- {
- return (m_Ptr && m_Ref) ? (*m_Ref) : 0;
- }
-};
+/* ------------------------------------------------------------------------------------------------
+ * Retrieve the value from the specified entry data as a stream of bytes.
+*/
+Object GetEntryAsBytes(const MMDB_entry_data_s & ed);
} // Namespace:: SqMod
diff --git a/modules/mmdb/Database.cpp b/modules/mmdb/Database.cpp
index 681829e2..9fd09c49 100644
--- a/modules/mmdb/Database.cpp
+++ b/modules/mmdb/Database.cpp
@@ -1,7 +1,9 @@
// ------------------------------------------------------------------------------------------------
#include "Database.hpp"
#include "SockAddr.hpp"
+#include "Metadata.hpp"
#include "LookupResult.hpp"
+#include "EntryDataList.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@@ -9,104 +11,142 @@ namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Database::Typename(HSQUIRRELVM vm)
{
- static const SQChar name[] = _SC("SqMMDBDatabase");
+ static const SQChar name[] = _SC("SqMMDatabase");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+void Database::Validate(CCStr file, Int32 line) const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
+ }
+}
+#else
void Database::Validate() const
{
- // Is the document handle valid?
- if (!m_Db)
- STHROWF("Invalid Maxmind database reference");
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference");
+ }
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+const DbRef & Database::GetValid(CCStr file, Int32 line) const
+{
+ Validate(file, line);
+ return m_Handle;
+}
+#else
+const DbRef & Database::GetValid() const
+{
+ Validate();
+ return m_Handle;
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+Metadata Database::GetMetadata() const
+{
+ return Metadata(m_Handle, &(SQMOD_GET_VALID(*this)->mDb).metadata);
}
// ------------------------------------------------------------------------------------------------
-Int32 Database::Cmp(const Database & o) const
+Object Database::GetMetadataAsEntryDataList() const
{
- if (m_Db == o.m_Db)
- return 0;
- else if (m_Db.m_Ptr > o.m_Db.m_Ptr)
- return 1;
- else
- return -1;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Database::Open(CSStr filepath)
-{
- Open(filepath, 0);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Database::Open(CSStr filepath, Uint32 flags)
-{
- // Is there a database handle available?
- if (!m_Db)
- m_Db = DbRef(true); // Create a database handle
- // Check if the database handle could be allocated one more time
- if (!m_Db)
- STHROWF("Unable to create a Maxmind database reference");
- // Are there any other references?
- else if (m_Db.Count() > 1)
- // To load new values now, would mean to cause undefined behavior in existing references
- STHROWF("Loading is disabled while database is referenced");
- // Validate the specified file path
- else if (!filepath || strlen(filepath) <= 0)
- STHROWF("Invalid database file path");
- // Let's attempt to open the specified database
- const Int32 status = MMDB_open(filepath, flags, m_Db.m_Ptr);
- // Validate the result of the operation
+ MMDB_entry_data_list_s * entry_data_list = nullptr;
+ // Attempt to retrieve the database meta-data as an entry data list
+ const int status = MMDB_get_metadata_as_entry_data_list(&(SQMOD_GET_VALID(*this)->mDb), &entry_data_list);
+ // Validate the status code
if (status != MMDB_SUCCESS)
{
- // Release the database reference
- m_Db.Drop();
- // Now it's safe to throw the error
- STHROWF("Unable to open the specified database [%s]", MMDB_strerror(status));
+ STHROWF("Unable to get entry data list [%s]", MMDB_strerror(status));
}
+ // Return the resulted list
+ return Object(new EntryDataList(m_Handle, entry_data_list));
}
// ------------------------------------------------------------------------------------------------
LookupResult Database::LookupString(CSStr addr)
{
// Validate the database handle
- Validate();
+ SQMOD_VALIDATE(*this);
// Validate the specified string
- if (!addr || strlen(addr) <= 0)
+ if (!addr || *addr == '\0')
+ {
STHROWF("Invalid address string");
+ }
// Dummy variables to obtain the status codes
int gai_error, mmdb_error;
// Attempt to perform the actual lookup
- MMDB_lookup_result_s result = MMDB_lookup_string(m_Db, addr, &gai_error, &mmdb_error);
+ MMDB_lookup_result_s result = MMDB_lookup_string(&m_Handle->mDb, addr, &gai_error, &mmdb_error);
// Validate the result of the getaddrinfo() function call
if (gai_error != 0)
+ {
STHROWF("Unable to resolve address (%s) because [%s]", addr, gai_strerror(gai_error));
+ }
// Validate the lookup status code
else if (mmdb_error != MMDB_SUCCESS)
+ {
STHROWF("Unable to lookup address (%s) because [%s]", addr, MMDB_strerror(mmdb_error));
+ }
// Now it's safe to return the lookup result
- return LookupResult(m_Db, result);
+ return LookupResult(m_Handle, result);
}
// ------------------------------------------------------------------------------------------------
LookupResult Database::LookupSockAddr(SockAddr & addr)
{
// Validate the database handle
- Validate();
+ SQMOD_VALIDATE(*this);
// Validate the specified socket address
if (!addr.IsValid())
+ {
STHROWF("Invalid address instance");
+ }
// Dummy variable to obtain the status codes
int mmdb_error;
// Attempt to perform the actual lookup
- MMDB_lookup_result_s result = MMDB_lookup_sockaddr(m_Db, addr.GetHandle()->ai_addr, &mmdb_error);
+ MMDB_lookup_result_s result = MMDB_lookup_sockaddr(&m_Handle->mDb, addr.GetHandle()->ai_addr, &mmdb_error);
// Validate the lookup status code
if (mmdb_error != MMDB_SUCCESS)
+ {
STHROWF("Unable to lookup address (%s) because [%s]",
addr.GetAddress(), MMDB_strerror(mmdb_error));
+ }
// Now it's safe to return the lookup result
- return LookupResult(m_Db, result);
+ return LookupResult(m_Handle, result);
+}
+
+// ================================================================================================
+void Register_Database(Table & mmns)
+{
+ mmns.Bind(_SC("Database"),
+ Class< Database >(mmns.GetVM(), _SC("SqMMDatabase"))
+ // Constructors
+ .Ctor()
+ .Ctor< CSStr >()
+ .Ctor< CSStr, Uint32 >()
+ // Meta-methods
+ .SquirrelFunc(_SC("_typename"), &Database::Typename)
+ .Func(_SC("_tostring"), &Database::ToString)
+ // Properties
+ .Prop(_SC("IsValid"), &Database::IsValid)
+ .Prop(_SC("References"), &Database::GetRefCount)
+ .Prop(_SC("Metadata"), &Database::GetMetadata)
+ .Prop(_SC("MetadataAsEntryDataList"), &Database::GetMetadataAsEntryDataList)
+ // Member Methods
+ .Func(_SC("LookupString"), &Database::LookupString)
+ .Func(_SC("LookupSockAddr"), &Database::LookupSockAddr)
+ // Member Overloads
+ .Overload< void (Database::*)(CSStr) >(_SC("Open"), &Database::Open)
+ .Overload< void (Database::*)(CSStr, Uint32) >(_SC("Open"), &Database::Open)
+ );
}
} // Namespace:: SqMod
diff --git a/modules/mmdb/Database.hpp b/modules/mmdb/Database.hpp
index 7cac2749..991057b4 100644
--- a/modules/mmdb/Database.hpp
+++ b/modules/mmdb/Database.hpp
@@ -2,7 +2,7 @@
#define _SQMMDB_DATABASE_HPP_
// ------------------------------------------------------------------------------------------------
-#include "Common.hpp"
+#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@@ -15,24 +15,29 @@ class Database
protected:
/* --------------------------------------------------------------------------------------------
- * Copy constructor. (disabled)
- */
- Database(const Database &);
-
- /* --------------------------------------------------------------------------------------------
- * Copy assignment operator. (disabled)
- */
- Database & operator = (const Database &);
-
- /* --------------------------------------------------------------------------------------------
- * Validate the document reference and throw an error if invalid.
+ * Validate the managed database handle and throw an error if invalid.
*/
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ void Validate(CCStr file, Int32 line) const;
+#else
void Validate() const;
+#endif // _DEBUG
+
+private:
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ const DbRef & GetValid(CCStr file, Int32 line) const;
+#else
+ const DbRef & GetValid() const;
+#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
- DbRef m_Db; /* The main INI document instance. */
+ DbRef m_Handle; /* The main INI document instance. */
public:
@@ -40,7 +45,7 @@ public:
* Default constructor.
*/
Database()
- : m_Db()
+ : m_Handle()
{
/* ... */
}
@@ -49,39 +54,46 @@ public:
* Base constructor.
*/
Database(CSStr filepath)
- : m_Db()
+ : m_Handle(new DbHnd(filepath, 0))
{
- Open(filepath, 0);
+ /* ... */
}
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
Database(CSStr filepath, Uint32 flags)
- : m_Db()
- {
- Open(filepath, flags);
- }
-
- /* --------------------------------------------------------------------------------------------
- * Destructor.
- */
- ~Database()
+ : m_Handle(new DbHnd(filepath, flags))
{
/* ... */
}
/* --------------------------------------------------------------------------------------------
- * Used by the script engine to compare two instances of this type.
+ * Copy constructor.
*/
- Int32 Cmp(const Database & o) const;
+ Database(const Database & o) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move constructor.
+ */
+ Database(Database && o) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy assignment operator.
+ */
+ Database & operator = (const Database & o) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move assignment operator.
+ */
+ Database & operator = (Database && o) = default;
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
CSStr ToString() const
{
- return _SC("");
+ return m_Handle ? m_Handle->mDb.filename : _SC("");
}
/* --------------------------------------------------------------------------------------------
@@ -94,7 +106,7 @@ public:
*/
bool IsValid() const
{
- return m_Db;
+ return m_Handle;
}
/* --------------------------------------------------------------------------------------------
@@ -102,18 +114,42 @@ public:
*/
Uint32 GetRefCount() const
{
- return m_Db.Count();
+ return m_Handle.Count();
}
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
- void Open(CSStr filepath);
+ void Open(CSStr filepath)
+ {
+ Open(filepath, 0);
+ }
/* --------------------------------------------------------------------------------------------
* Attempt to open the specified database.
*/
- void Open(CSStr filepath, Uint32 addr);
+ void Open(CSStr filepath, Uint32 flags)
+ {
+ // Make sure there isn't another database handle
+ if (!m_Handle)
+ {
+ m_Handle = DbRef(new DbHnd(filepath, flags));
+ }
+ else
+ {
+ STHROWF("Loading is disabled while database is referenced");
+ }
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the metadata associated with the managed database handle.
+ */
+ Metadata GetMetadata() const;
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the metadata associated with the managed database handle as an entry data list.
+ */
+ Object GetMetadataAsEntryDataList() const;
/* --------------------------------------------------------------------------------------------
* Look up an IP address that is passed in as a null-terminated string.
diff --git a/modules/mmdb/Description.cpp b/modules/mmdb/Description.cpp
new file mode 100644
index 00000000..09865bed
--- /dev/null
+++ b/modules/mmdb/Description.cpp
@@ -0,0 +1,87 @@
+// ------------------------------------------------------------------------------------------------
+#include "Description.hpp"
+
+// ------------------------------------------------------------------------------------------------
+#include
+#include
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+// ------------------------------------------------------------------------------------------------
+SQInteger Description::Typename(HSQUIRRELVM vm)
+{
+ static const SQChar name[] = _SC("SqMMDescription");
+ sq_pushstring(vm, name, sizeof(name));
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+void Description::Validate(CCStr file, Int32 line) const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
+ }
+}
+#else
+void Description::Validate() const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference");
+ }
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+Description::Pointer Description::GetValid(CCStr file, Int32 line) const
+{
+ Validate(file, line);
+ // Validate the referenced description
+ if (!m_Description)
+ {
+ SqThrowF("Invalid Maxmind meta-data description reference =>[%s:%d]", file, line);
+ }
+ // Return the description pointer
+ return m_Description;
+}
+#else
+Description::Pointer Description::GetValid() const
+{
+ Validate();
+ // Validate the referenced description
+ if (!m_Description)
+ {
+ SqThrowF("Invalid Maxmind meta-data description reference");
+ }
+ // Return the description pointer
+ return m_Description;
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+
+
+
+// ================================================================================================
+void Register_Description(Table & mmns)
+{
+ mmns.Bind(_SC("Description"),
+ Class< Description >(mmns.GetVM(), _SC("SqMMDescription"))
+ // Constructors
+ .Ctor()
+ .Ctor< const Description & >()
+ // Meta-methods
+ .SquirrelFunc(_SC("_typename"), &Description::Typename)
+ .Func(_SC("_tostring"), &Description::ToString)
+ // Properties
+ .Prop(_SC("IsValid"), &Description::IsValid)
+ .Prop(_SC("Value"), &Description::GetDescriptionValue)
+ .Prop(_SC("Language"), &Description::GetDescriptionLanguage)
+ );
+}
+
+} // Namespace:: SqMod
diff --git a/modules/mmdb/Description.hpp b/modules/mmdb/Description.hpp
new file mode 100644
index 00000000..a77bd8ce
--- /dev/null
+++ b/modules/mmdb/Description.hpp
@@ -0,0 +1,154 @@
+#ifndef _SQMMDB_DESCRIPTION_HPP_
+#define _SQMMDB_DESCRIPTION_HPP_
+
+// ------------------------------------------------------------------------------------------------
+#include "Handle/Database.hpp"
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+/* ------------------------------------------------------------------------------------------------
+ * Class that can hold and be used inspect meta-data descriptions.
+*/
+class Description
+{
+ // --------------------------------------------------------------------------------------------
+ friend class Metadata; // Only a valid meta-data instance can construct this type.
+
+protected:
+
+ // --------------------------------------------------------------------------------------------
+ typedef MMDB_description_s 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.
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ void Validate(CCStr file, Int32 line) const;
+#else
+ void Validate() const;
+#endif // _DEBUG
+
+private:
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ Pointer GetValid(CCStr file, Int32 line) const;
+#else
+ Pointer GetValid() const;
+#endif // _DEBUG
+
+private:
+
+ // ---------------------------------------------------------------------------------------------
+ DbRef m_Handle; // The database associated with this meta-data description.
+ Pointer m_Description; // The inspected meta-data description structure.
+
+ /* --------------------------------------------------------------------------------------------
+ * Construct and with a specific meta-data.
+ */
+ Description(const DbRef & db, Pointer metadata)
+ : m_Handle(db), m_Description(metadata)
+ {
+ /* ... */
+ }
+
+public:
+
+ /* --------------------------------------------------------------------------------------------
+ * Default constructor. (null)
+ */
+ Description()
+ : m_Handle(), m_Description(nullptr)
+ {
+ /* ... */
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor.
+ */
+ Description(const Description &) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move constructor.
+ */
+ Description(Description &&) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy assignment operator.
+ */
+ Description & operator = (const Description &) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move assignment operator.
+ */
+ Description & operator = (Description &&) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the internal result structure reference.
+ */
+ Pointer GetHandle()
+ {
+ return m_Description;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the internal result structure reference.
+ */
+ ConstPtr GetHandle() const
+ {
+ return m_Description;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Used by the script engine to convert an instance of this type to a string.
+ */
+ CSStr ToString() const
+ {
+ return m_Description ? m_Description->description : _SC("");
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Used by the script engine to retrieve the name from instances of this type.
+ */
+ static SQInteger Typename(HSQUIRRELVM vm);
+
+ /* --------------------------------------------------------------------------------------------
+ * See whether this instance references a valid database and result structure.
+ */
+ bool IsValid() const
+ {
+ return m_Handle && m_Description;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value of the managed description handle.
+ */
+ CSStr GetDescriptionValue() const
+ {
+ return SQMOD_GET_VALID(*this)->description;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the language of the managed description handle.
+ */
+ CSStr GetDescriptionLanguage() const
+ {
+ return SQMOD_GET_VALID(*this)->language;
+ }
+
+};
+
+} // Namespace:: SqMod
+
+#endif // _SQMMDB_DESCRIPTION_HPP_
diff --git a/modules/mmdb/EntryData.cpp b/modules/mmdb/EntryData.cpp
new file mode 100644
index 00000000..5d6a33e6
--- /dev/null
+++ b/modules/mmdb/EntryData.cpp
@@ -0,0 +1,87 @@
+// ------------------------------------------------------------------------------------------------
+#include "EntryData.hpp"
+
+// ------------------------------------------------------------------------------------------------
+#include
+#include
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+// ------------------------------------------------------------------------------------------------
+SQInteger EntryData::Typename(HSQUIRRELVM vm)
+{
+ static const SQChar name[] = _SC("SqMMEntryData");
+ sq_pushstring(vm, name, sizeof(name));
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+void EntryData::Validate(CCStr file, Int32 line) const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
+ }
+}
+#else
+void EntryData::Validate() const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference");
+ }
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+const DbRef & EntryData::GetValid(CCStr file, Int32 line) const
+{
+ Validate(file, line);
+ return m_Handle;
+}
+#else
+const DbRef & EntryData::GetValid() const
+{
+ Validate();
+ return m_Handle;
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+EntryData::EntryData()
+ : m_Handle(), m_Entry()
+{
+ std::memset(&m_Entry, 0, sizeof(Type));
+}
+
+// ================================================================================================
+void Register_EntryData(Table & mmns)
+{
+ mmns.Bind(_SC("EntryData"),
+ Class< EntryData >(mmns.GetVM(), _SC("SqMMEntryData"))
+ // Constructors
+ .Ctor()
+ .Ctor< const EntryData & >()
+ // Meta-methods
+ .SquirrelFunc(_SC("_typename"), &EntryData::Typename)
+ .Func(_SC("_tostring"), &EntryData::ToString)
+ // Properties
+ .Prop(_SC("IsValid"), &EntryData::IsValid)
+ .Prop(_SC("TypeName"), &EntryData::TypeName)
+ .Prop(_SC("HasData"), &EntryData::HasData)
+ .Prop(_SC("Type"), &EntryData::GetType)
+ .Prop(_SC("Offset"), &EntryData::GetOffset)
+ .Prop(_SC("DataSize"), &EntryData::DataSize)
+ .Prop(_SC("String"), &EntryData::GetString)
+ .Prop(_SC("Integer"), &EntryData::GetInteger)
+ .Prop(_SC("Float"), &EntryData::GetFloat)
+ .Prop(_SC("Long"), &EntryData::GetLong)
+ .Prop(_SC("Bool"), &EntryData::GetBool)
+ .Prop(_SC("Bytes"), &EntryData::GetBytes)
+ );
+}
+
+} // Namespace:: SqMod
diff --git a/modules/mmdb/EntryData.hpp b/modules/mmdb/EntryData.hpp
new file mode 100644
index 00000000..a0dcc06a
--- /dev/null
+++ b/modules/mmdb/EntryData.hpp
@@ -0,0 +1,255 @@
+#ifndef _SQMMDB_ENTRYDATA_HPP_
+#define _SQMMDB_ENTRYDATA_HPP_
+
+// ------------------------------------------------------------------------------------------------
+#include "Handle/Database.hpp"
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+/* ------------------------------------------------------------------------------------------------
+ * Class that can hold and be used to inspect entry data values.
+*/
+class EntryData
+{
+ // --------------------------------------------------------------------------------------------
+ friend class LookupResult; // Only a valid lookup result instance can construct this type.
+
+protected:
+
+ // --------------------------------------------------------------------------------------------
+ typedef MMDB_entry_data_s 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.
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ void Validate(CCStr file, Int32 line) const;
+#else
+ void Validate() const;
+#endif // _DEBUG
+
+private:
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ const DbRef & GetValid(CCStr file, Int32 line) const;
+#else
+ const DbRef & GetValid() const;
+#endif // _DEBUG
+
+private:
+
+ // ---------------------------------------------------------------------------------------------
+ DbRef m_Handle; // The database from which this result comes from.
+ Type m_Entry; // The managed entry-data structure.
+
+ /* --------------------------------------------------------------------------------------------
+ * Construct and take ownership of a certain entry data.
+ */
+ EntryData(const DbRef & db, Reference entry)
+ : m_Handle(db), m_Entry(entry)
+ {
+ /* ... */
+ }
+
+public:
+
+ /* --------------------------------------------------------------------------------------------
+ * Default constructor. (null)
+ */
+ EntryData();
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor.
+ */
+ EntryData(const EntryData &) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move constructor.
+ */
+ EntryData(EntryData &&) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy assignment operator.
+ */
+ EntryData & operator = (const EntryData &) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move assignment operator.
+ */
+ EntryData & operator = (EntryData &&) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the internal result structure reference.
+ */
+ Reference GetHandle()
+ {
+ return m_Entry;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the internal result structure reference.
+ */
+ ConstRef GetHandle() const
+ {
+ return m_Entry;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Used by the script engine to convert an instance of this type to a string.
+ */
+ CSStr ToString() const
+ {
+ return AsTypeStr(m_Entry.type);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * 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 database and result structure.
+ */
+ bool IsValid() const
+ {
+ return m_Handle && m_Entry.has_data;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Used to retrieve the type of the current element as a string.
+ */
+ CSStr TypeName() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return AsTypeStr(m_Entry.type);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * See whether a valid element is currently processed.
+ */
+ bool HasData() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return ConvTo< bool >::From(m_Entry.has_data);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the type identifier of the current element.
+ */
+ SQInteger GetType() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return ConvTo< SQInteger >::From(m_Entry.type);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the offset of the current element.
+ */
+ SQInteger GetOffset() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return ConvTo< SQInteger >::From(m_Entry.offset);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the offset of the next element.
+ */
+ SQInteger DataSize() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return ConvTo< SQInteger >::From(m_Entry.data_size);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a boolean.
+ */
+ bool GetBool() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return GetEntryAsBool(m_Entry);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a native integer.
+ */
+ SQInteger GetInteger() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return GetEntryAsInteger(m_Entry);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a floating point.
+ */
+ SQFloat GetFloat() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return GetEntryAsFloat(m_Entry);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a long integer.
+ */
+ Object GetLong() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return GetEntryAsLong(m_Entry);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a string.
+ */
+ Object GetString() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return GetEntryAsString(m_Entry);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a stream of bytes.
+ */
+ Object GetBytes() const
+ {
+ // Validate the handle
+ SQMOD_VALIDATE(*this);
+ // Return the requested information
+ return GetEntryAsBytes(m_Entry);
+ }
+
+};
+
+} // Namespace:: SqMod
+
+#endif // _SQMMDB_ENTRYDATA_HPP_
diff --git a/modules/mmdb/EntryDataList.cpp b/modules/mmdb/EntryDataList.cpp
index a5fb308d..6e9461e4 100644
--- a/modules/mmdb/EntryDataList.cpp
+++ b/modules/mmdb/EntryDataList.cpp
@@ -4,6 +4,7 @@
// ------------------------------------------------------------------------------------------------
#include
#include
+#include
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@@ -11,109 +12,97 @@ namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger EntryDataList::Typename(HSQUIRRELVM vm)
{
- static const SQChar name[] = _SC("SqMMDBEntryDataList");
+ static const SQChar name[] = _SC("SqMMEntryDataList");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
-void EntryDataList::Validate() const
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+void EntryDataList::Validate(CCStr file, Int32 line) const
{
- // Is the document handle valid?
- if (!m_Db)
- STHROWF("Invalid Maxmind database reference");
- // Do we have a valid list?
- else if (!m_List)
- STHROWF("Invalid entry data list");
-}
-
-// ------------------------------------------------------------------------------------------------
-void EntryDataList::ValidateElem() const
-{
- // Is the document handle valid?
- if (!m_Db)
- STHROWF("Invalid Maxmind database reference");
- // Do we have a valid list?
- else if (!m_List)
- STHROWF("Invalid entry data list");
- // Do we have a valid element?
- else if (!m_Elem)
- STHROWF("Invalid entry data element");
-}
-
-// ------------------------------------------------------------------------------------------------
-void EntryDataList::ValidateData() const
-{
- // Is the document handle valid?
- if (!m_Db)
- STHROWF("Invalid Maxmind database reference");
- // Do we have a valid list?
- else if (!m_List)
- STHROWF("Invalid entry data list");
- // Do we have a valid element?
- else if (!m_Elem)
- STHROWF("Invalid entry data element");
- // Do we have some valid data?
- else if (!m_Elem->entry_data.has_data)
- STHROWF("Entry data element has no data");
-}
-
-// ------------------------------------------------------------------------------------------------
-CSStr EntryDataList::AsTypeStr(Uint32 id)
-{
- switch (id)
+ if (!m_Handle)
{
- case MMDB_DATA_TYPE_EXTENDED: return _SC("extended");
- case MMDB_DATA_TYPE_POINTER: return _SC("pointer");
- case MMDB_DATA_TYPE_UTF8_STRING: return _SC("string");
- case MMDB_DATA_TYPE_DOUBLE: return _SC("double");
- case MMDB_DATA_TYPE_BYTES: return _SC("bytes");
- case MMDB_DATA_TYPE_UINT16: return _SC("uint16");
- case MMDB_DATA_TYPE_UINT32: return _SC("uint32");
- case MMDB_DATA_TYPE_MAP: return _SC("map");
- case MMDB_DATA_TYPE_INT32: return _SC("int32");
- case MMDB_DATA_TYPE_UINT64: return _SC("uint64");
- case MMDB_DATA_TYPE_UINT128: return _SC("uint128");
- case MMDB_DATA_TYPE_ARRAY: return _SC("array");
- case MMDB_DATA_TYPE_CONTAINER: return _SC("container");
- case MMDB_DATA_TYPE_END_MARKER: return _SC("endmarker");
- case MMDB_DATA_TYPE_BOOLEAN: return _SC("boolean");
- case MMDB_DATA_TYPE_FLOAT: return _SC("float");
- default: return _SC("unknonw");
+ SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
}
}
+#else
+void EntryDataList::Validate() const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference");
+ }
+}
+#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
-EntryDataList::~EntryDataList()
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+EntryDataList::Pointer EntryDataList::GetValid(CCStr file, Int32 line) const
{
- // Do we have to free any list?
- if (m_List)
- MMDB_free_entry_data_list(m_List);
+ Validate(file, line);
+ // Validate the managed list
+ if (!m_List)
+ {
+ SqThrowF("Invalid Maxmind entry data list reference =>[%s:%d]", file, line);
+ }
+ // return the list
+ return m_List;
}
+#else
+EntryDataList::Pointer EntryDataList::GetValid() const
+{
+ Validate();
+ // Validate the managed list
+ if (!m_List)
+ {
+ SqThrowF("Invalid Maxmind entry data list reference");
+ }
+ // return the list
+ return m_List;
+}
+#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
-Int32 EntryDataList::Cmp(const EntryDataList & o) const
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+EntryDataList::Pointer EntryDataList::GetValidElem(CCStr file, Int32 line) const
{
- if (m_List == o.m_List)
- return 0;
- else if (m_List > o.m_List)
- return 1;
- else
- return -1;
+ Validate(file, line);
+ // Validate the current element
+ if (!m_List)
+ {
+ SqThrowF("Invalid Maxmind entry data element reference =>[%s:%d]", file, line);
+ }
+ // return the element
+ return m_Elem;
}
+#else
+EntryDataList::Pointer EntryDataList::GetValidElem() const
+{
+ Validate();
+ // Validate the current element
+ if (!m_List)
+ {
+ SqThrowF("Invalid Maxmind entry data element reference");
+ }
+ // return the element
+ return m_Elem;
+}
+#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Uint32 EntryDataList::GetCount() const
{
- // Do we even have a list?
- if (!m_List)
- return 0;
- // Get the start of the list
- Pointer elem = m_List;
// Prepare a counter
- Uint32 count = 1;
- // Loop through list elements
- while ((elem = elem->next)) ++count;
+ Uint32 count = 0;
+ // Do we even have a list?
+ if (m_List)
+ {
+ for (Pointer elem = m_List; elem; elem = elem->next)
+ {
+ ++count;
+ }
+ }
// Return the counter
return count;
}
@@ -121,258 +110,92 @@ Uint32 EntryDataList::GetCount() const
// ------------------------------------------------------------------------------------------------
bool EntryDataList::Next()
{
- // Validate the database and list handle
- Validate();
- // Do we have a valid element currently?
- if (m_Elem)
- return (m_Elem = m_Elem->next);
- // Nothing to advance
- return false;
+ // Validate the database handle
+ SQMOD_VALIDATE(*this);
+ // Attempt to fetch the next element
+ m_Elem = m_Elem ? m_Elem->next : nullptr;
+ // Return whether we have a valid element
+ return !!m_Elem;
}
// ------------------------------------------------------------------------------------------------
-bool EntryDataList::Advance(Int32 n)
+bool EntryDataList::Advance(SQInteger n)
{
- // Validate the database and list handle
- Validate();
- // Do we have a valid element currently?
- if (m_Elem)
- // Attempt to skip as many elements as possible
- while ((n > 0) && (m_Elem = m_Elem->next)) --n;
+ // Validate the database handle
+ SQMOD_VALIDATE(*this);
+ // Attempt to skip as many elements as possible
+ while (n && m_Elem)
+ {
+ // Fetch the next element
+ m_Elem = m_Elem->next;
+ // Decrease the counter
+ --n;
+ }
// Return whether we have a valid element
return m_Elem;
}
-// ------------------------------------------------------------------------------------------------
-void EntryDataList::Reset()
-{
- // Validate the database and list handle
- Validate();
- // Go back to the first element
- m_Elem = m_List;
-}
-
-// ------------------------------------------------------------------------------------------------
-CSStr EntryDataList::GetString() const
-{
- // Validate the database, list and element handle
- ValidateData();
- // Attempt to perform the requested conversion
- switch (m_Elem->entry_data.type)
- {
- case MMDB_DATA_TYPE_UTF8_STRING:
- return m_Elem->entry_data.utf8_string;
- case MMDB_DATA_TYPE_DOUBLE:
- return FmtStr("%f", m_Elem->entry_data.double_value);
- case MMDB_DATA_TYPE_UINT16:
- return FmtStr("%u", m_Elem->entry_data.uint16);
- case MMDB_DATA_TYPE_UINT32:
- return FmtStr("%u", m_Elem->entry_data.uint32);
- case MMDB_DATA_TYPE_INT32:
- return FmtStr("%d", m_Elem->entry_data.int32);
- case MMDB_DATA_TYPE_UINT64:
- return FmtStr("%llu", m_Elem->entry_data.uint64);
- case MMDB_DATA_TYPE_BOOLEAN:
- return m_Elem->entry_data.boolean ? _SC("true") : _SC("false");
- case MMDB_DATA_TYPE_FLOAT:
- return FmtStr("%f", m_Elem->entry_data.float_value);
- default:
- STHROWF("Unsupported conversion from (%s) to (string)", AsTypeStr(m_Elem->entry_data.type));
- }
- // Shouldn't really reach this point
- return _SC("");
-}
-
-// ------------------------------------------------------------------------------------------------
-SQInteger EntryDataList::GetInteger() const
-{
- // Validate the database, list and element handle
- ValidateData();
- // Attempt to perform the requested conversion
- switch (m_Elem->entry_data.type)
- {
-#ifdef _SQ64
- case MMDB_DATA_TYPE_UTF8_STRING:
- return strtoll(m_Elem->entry_data.utf8_string, NULL, 10);
- case MMDB_DATA_TYPE_DOUBLE:
- return llround(m_Elem->entry_data.double_value);
- case MMDB_DATA_TYPE_UINT16:
- return m_Elem->entry_data.uint16;
- case MMDB_DATA_TYPE_UINT32:
- return m_Elem->entry_data.uint32;
- case MMDB_DATA_TYPE_INT32:
- return m_Elem->entry_data.int32;
- case MMDB_DATA_TYPE_UINT64:
- return Clamp(m_Elem->entry_data.uint64, 0, Uint64(NumLimit< SQInteger >::Max));
- case MMDB_DATA_TYPE_BOOLEAN:
- return m_Elem->entry_data.boolean ? 1 : 0;
- case MMDB_DATA_TYPE_FLOAT:
- return llround(m_Elem->entry_data.float_value);
- default:
- STHROWF("Unsupported conversion from (%s) to (int32)", AsTypeStr(m_Elem->entry_data.type));
-#else
- case MMDB_DATA_TYPE_UTF8_STRING:
- return strtol(m_Elem->entry_data.utf8_string, NULL, 10);
- case MMDB_DATA_TYPE_DOUBLE:
- return lround(m_Elem->entry_data.double_value);
- case MMDB_DATA_TYPE_UINT16:
- return m_Elem->entry_data.uint16;
- case MMDB_DATA_TYPE_UINT32:
- return Clamp(m_Elem->entry_data.uint32, 0U, Uint32(NumLimit< SQInteger >::Max));
- case MMDB_DATA_TYPE_INT32:
- return m_Elem->entry_data.int32;
- case MMDB_DATA_TYPE_UINT64:
- return Clamp(m_Elem->entry_data.uint64, 0ULL, Uint64(NumLimit< SQInteger >::Max));
- case MMDB_DATA_TYPE_BOOLEAN:
- return m_Elem->entry_data.boolean ? 1 : 0;
- case MMDB_DATA_TYPE_FLOAT:
- return lround(m_Elem->entry_data.float_value);
- default:
- STHROWF("Unsupported conversion from (%s) to (int64)", AsTypeStr(m_Elem->entry_data.type));
-#endif // _SQ64
- }
- // Shouldn't really reach this point
- return 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-SQFloat EntryDataList::GetFloat() const
-{
- // Validate the database, list and element handle
- ValidateData();
- // Attempt to perform the requested conversion
- switch (m_Elem->entry_data.type)
- {
-#ifdef SQUSEDOUBLE
- case MMDB_DATA_TYPE_UTF8_STRING:
- return static_cast< SQFloat >(strtod(m_Elem->entry_data.utf8_string, NULL));
-#else
- return static_cast< SQFloat >(strtof(m_Elem->entry_data.utf8_string, NULL));
-#endif // SQUSEDOUBLE
- case MMDB_DATA_TYPE_DOUBLE:
- return static_cast< SQFloat >(m_Elem->entry_data.double_value);
- case MMDB_DATA_TYPE_UINT16:
- return static_cast< SQFloat >(m_Elem->entry_data.uint16);
- case MMDB_DATA_TYPE_UINT32:
- return static_cast< SQFloat >(round(m_Elem->entry_data.uint32));
- case MMDB_DATA_TYPE_INT32:
- return static_cast< SQFloat >(round(m_Elem->entry_data.int32));
- case MMDB_DATA_TYPE_UINT64:
- return static_cast< SQFloat >(round(m_Elem->entry_data.uint64));
- case MMDB_DATA_TYPE_BOOLEAN:
- return m_Elem->entry_data.boolean ? 1.0 : 0.0;
- case MMDB_DATA_TYPE_FLOAT:
- return static_cast< SQFloat >(m_Elem->entry_data.float_value);
- default:
- STHROWF("Unsupported conversion from (%s) to (float)", AsTypeStr(m_Elem->entry_data.type));
- }
- // Shouldn't really reach this point
- return 0.0;
-}
-
-// ------------------------------------------------------------------------------------------------
-Object EntryDataList::GetLong() const
-{
- // Validate the database, list and element handle
- ValidateData();
- // Where the long number is retrieved
- Uint64 longint = 0;
- Int64 slong = 0;
- // Attempt to perform the requested conversion
- switch (m_Elem->entry_data.type)
- {
- case MMDB_DATA_TYPE_UTF8_STRING:
- longint = strtoull(m_Elem->entry_data.utf8_string, NULL, 10);
- break;
- case MMDB_DATA_TYPE_DOUBLE:
- {
- slong = llround(m_Elem->entry_data.double_value);
- longint = slong >= 0 ? slong : 0;
- } break;
- case MMDB_DATA_TYPE_UINT16:
- longint = m_Elem->entry_data.uint16;
- break;
- case MMDB_DATA_TYPE_UINT32:
- longint = m_Elem->entry_data.uint32;
- break;
- case MMDB_DATA_TYPE_INT32:
- longint = m_Elem->entry_data.int32 >= 0 ? m_Elem->entry_data.int32 : 0;
- break;
- case MMDB_DATA_TYPE_UINT64:
- longint = m_Elem->entry_data.uint64;
- break;
- case MMDB_DATA_TYPE_BOOLEAN:
- longint = m_Elem->entry_data.boolean ? 1 : 0;
- break;
- case MMDB_DATA_TYPE_FLOAT:
- {
- slong = llround(m_Elem->entry_data.float_value);
- longint = slong >= 0 ? slong : 0;
- }
- break;
- default:
- STHROWF("Unsupported conversion from (%s) to (uint64)", AsTypeStr(m_Elem->entry_data.type));
- }
- // Obtain the initial stack size
- const StackGuard sg;
- // Push a long integer instance with the requested value on the stack
- SqMod_PushULongObject(DefaultVM::Get(), longint);
- // Get the object from the stack and return it
- return Var< Object >(DefaultVM::Get(), -1).value;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool EntryDataList::GetBool() const
-{
- // Validate the database, list and element handle
- ValidateData();
- // Attempt to perform the requested conversion
- switch (m_Elem->entry_data.type)
- {
- case MMDB_DATA_TYPE_UTF8_STRING:
- return !!(m_Elem->entry_data.utf8_string);
- case MMDB_DATA_TYPE_DOUBLE:
- return EpsGt(m_Elem->entry_data.double_value, 0.0d);
- case MMDB_DATA_TYPE_UINT16:
- return (m_Elem->entry_data.uint16 > 0);
- case MMDB_DATA_TYPE_UINT32:
- return (m_Elem->entry_data.uint32 > 0);
- case MMDB_DATA_TYPE_INT32:
- return (m_Elem->entry_data.int32 > 0);
- case MMDB_DATA_TYPE_UINT64:
- return (m_Elem->entry_data.uint64 > 0);
- case MMDB_DATA_TYPE_BOOLEAN:
- return m_Elem->entry_data.boolean;
- case MMDB_DATA_TYPE_FLOAT:
- return EpsGt(m_Elem->entry_data.float_value, 0.0f);
- default:
- STHROWF("Unsupported conversion from (%s) to (boolean)", AsTypeStr(m_Elem->entry_data.type));
- }
- // Shouldn't really reach this point
- return false;
-}
-
// ------------------------------------------------------------------------------------------------
void EntryDataList::DumpTo(CSStr filepath, Int32 indent) const
{
// Validate the database and list handle
- Validate();
+ SQMOD_VALIDATE(*this);
// Validate the specified file path
- if (!filepath || strlen(filepath) <= 0)
+ if (!filepath || *filepath == '\0')
+ {
STHROWF("Invalid file path");
+ }
// Attempt to open the specified file
FILE * fp = fopen(filepath, "w");
// Validate the file handle
if (!fp)
+ {
STHROWF("Unable to open file %s", filepath);
+ }
// Attempt to dump the entry data list
Int32 status = MMDB_dump_entry_data_list(fp, m_List, indent);
// Close the file handle
fclose(fp);
// Validate the result of the operation
if (status != MMDB_SUCCESS)
- // Now it's safe to throw the error
+ {
STHROWF("Unable to dump the list [%s]", MMDB_strerror(status));
+ }
+}
+
+// ================================================================================================
+void Register_EntryDataList(Table & mmns)
+{
+ mmns.Bind(_SC("EntryDataList"),
+ Class< EntryDataList, NoCopy< EntryDataList > >(mmns.GetVM(), _SC("SqMMEntryDataList"))
+ // Constructors
+ .Ctor()
+ // Meta-methods
+ .SquirrelFunc(_SC("_typename"), &EntryDataList::Typename)
+ .Func(_SC("_tostring"), &EntryDataList::ToString)
+ // Properties
+ .Prop(_SC("IsValid"), &EntryDataList::IsValid)
+ .Prop(_SC("HaveElement"), &EntryDataList::HaveElement)
+ .Prop(_SC("TypeName"), &EntryDataList::TypeName)
+ .Prop(_SC("Count"), &EntryDataList::GetCount)
+ .Prop(_SC("HasData"), &EntryDataList::HasData)
+ .Prop(_SC("Type"), &EntryDataList::GetType)
+ .Prop(_SC("Offset"), &EntryDataList::GetOffset)
+ .Prop(_SC("DataSize"), &EntryDataList::DataSize)
+ .Prop(_SC("String"), &EntryDataList::GetString)
+ .Prop(_SC("Integer"), &EntryDataList::GetInteger)
+ .Prop(_SC("Float"), &EntryDataList::GetFloat)
+ .Prop(_SC("Long"), &EntryDataList::GetLong)
+ .Prop(_SC("Bool"), &EntryDataList::GetBool)
+ .Prop(_SC("Bytes"), &EntryDataList::GetBytes)
+ // Member methods
+ .Func(_SC("Next"), &EntryDataList::Next)
+ .Func(_SC("Advance"), &EntryDataList::Advance)
+ .Func(_SC("Reset"), &EntryDataList::Reset)
+ // Member Overloads
+ .Overload< void (EntryDataList::*)(CSStr) const >(_SC("DumpTo"), &EntryDataList::DumpTo)
+ .Overload< void (EntryDataList::*)(CSStr, Int32) const >(_SC("DumpTo"), &EntryDataList::DumpTo)
+ );
}
} // Namespace:: SqMod
diff --git a/modules/mmdb/EntryDataList.hpp b/modules/mmdb/EntryDataList.hpp
index 3fa26638..b0f1e1df 100644
--- a/modules/mmdb/EntryDataList.hpp
+++ b/modules/mmdb/EntryDataList.hpp
@@ -1,17 +1,21 @@
-#ifndef _SQMMDB_LOOKUPRESULT_HPP_
-#define _SQMMDB_LOOKUPRESULT_HPP_
+#ifndef _SQMMDB_ENTRYDATALIST_HPP_
+#define _SQMMDB_ENTRYDATALIST_HPP_
// ------------------------------------------------------------------------------------------------
-#include "Common.hpp"
+#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
- * Class that can be used to traverse a list of results.
+ * Class that can hold and be used inspect database meta-data.
*/
class EntryDataList
{
+ // --------------------------------------------------------------------------------------------
+ friend class Database; // Only a valid database instance can construct this type.
+ friend class LookupResult; // Only a valid lookup result instance can construct this type.
+
protected:
// --------------------------------------------------------------------------------------------
@@ -26,37 +30,46 @@ protected:
typedef const Type& ConstRef; // Constant reference to the managed type.
/* --------------------------------------------------------------------------------------------
- * Validate the database pointer and list handle and throw an error if invalid.
+ * Validate the managed database handle and throw an error if invalid.
*/
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ void Validate(CCStr file, Int32 line) const;
+#else
void Validate() const;
+#endif // _DEBUG
+
+private:
/* --------------------------------------------------------------------------------------------
- * Do a regular validation and also validate the currently processed element.
+ * Validate the managed database handle and throw an error if invalid.
*/
- void ValidateElem() const;
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ Pointer GetValid(CCStr file, Int32 line) const;
+#else
+ Pointer GetValid() const;
+#endif // _DEBUG
/* --------------------------------------------------------------------------------------------
- * Do a regular validation and also validate the currently processed element data.
+ * Validate the managed database handle and throw an error if invalid.
*/
- void ValidateData() const;
-
- /* --------------------------------------------------------------------------------------------
- * Used to retrieve the string representation of the specified type identifier.
- */
- static CSStr AsTypeStr(Uint32 id);
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ Pointer GetValidElem(CCStr file, Int32 line) const;
+#else
+ Pointer GetValidElem() const;
+#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
- DbRef m_Db; /* The database from which this list comes from. */
- Pointer m_List; /* The managed entry data list. */
- Pointer m_Elem; /* The currently processed element from the list. */
+ DbRef m_Handle; // The database associated with this meta-data.
+ Pointer m_List; // The managed entry data list.
+ Pointer m_Elem; // The currently processed element from the list.
/* --------------------------------------------------------------------------------------------
- * Base constructor.
+ * Construct and with a specific entry list.
*/
EntryDataList(const DbRef & db, Pointer list)
- : m_Db(db), m_List(list), m_Elem(list)
+ : m_Handle(db), m_List(list), m_Elem(list)
{
/* ... */
}
@@ -64,9 +77,13 @@ private:
public:
/* --------------------------------------------------------------------------------------------
- * Default constructor.
+ * Default constructor. (null)
*/
- EntryDataList();
+ EntryDataList()
+ : m_Handle(), m_List(nullptr), m_Elem(nullptr)
+ {
+ /* ... */
+ }
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
@@ -77,7 +94,7 @@ public:
* Move constructor.
*/
EntryDataList(EntryDataList && o)
- : m_Db(o.m_Db)
+ : m_Handle(o.m_Handle)
, m_List(o.m_List)
, m_Elem(o.m_Elem)
{
@@ -88,7 +105,14 @@ public:
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
- ~EntryDataList();
+ ~EntryDataList()
+ {
+ // Do we have to free any list?
+ if (m_List)
+ {
+ MMDB_free_entry_data_list(m_List);
+ }
+ }
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
@@ -102,7 +126,7 @@ public:
{
if (m_List != o.m_List)
{
- m_Db = o.m_Db;
+ m_Handle = o.m_Handle;
m_List = o.m_List;
m_Elem = o.m_Elem;
o.m_List = nullptr;
@@ -112,7 +136,7 @@ public:
}
/* --------------------------------------------------------------------------------------------
- * Retrieve the internal entry data list structure pointer.
+ * Retrieve the internal result structure reference.
*/
Pointer GetHandle()
{
@@ -120,18 +144,13 @@ public:
}
/* --------------------------------------------------------------------------------------------
- * Retrieve the internal entry data list structure pointer.
+ * Retrieve the internal result structure reference.
*/
- Pointer GetHandle() const
+ ConstPtr GetHandle() const
{
return m_List;
}
- /* --------------------------------------------------------------------------------------------
- * Used by the script engine to compare two instances of this type.
- */
- Int32 Cmp(const EntryDataList & o) const;
-
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
@@ -146,11 +165,11 @@ public:
static SQInteger Typename(HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
- * See whether this instance references a valid database and entry data list structure.
+ * See whether this instance references a valid database and result structure.
*/
bool IsValid() const
{
- return m_Db && m_List;
+ return m_Handle && m_List;
}
/* --------------------------------------------------------------------------------------------
@@ -164,12 +183,9 @@ public:
/* --------------------------------------------------------------------------------------------
* Used to retrieve the type of the current element as a string.
*/
- CSStr TypeStr() const
+ CSStr TypeName() const
{
- // Validate the database and list handle
- Validate();
- // return the requested information
- return m_Elem ? AsTypeStr(m_Elem->entry_data.type) : _SC("invalid");
+ return AsTypeStr(SQMOD_GET_VALID_ELEM(*this)->entry_data.type);
}
/* --------------------------------------------------------------------------------------------
@@ -185,22 +201,22 @@ public:
/* --------------------------------------------------------------------------------------------
* Advance a certain number of elements.
*/
- bool Advance(Int32 n);
+ bool Advance(SQInteger n);
/* --------------------------------------------------------------------------------------------
* Go back to the first element in the list.
*/
- void Reset();
+ void Reset()
+ {
+ m_Elem = SQMOD_GET_VALID_ELEM(*this);
+ }
/* --------------------------------------------------------------------------------------------
* See whether a valid element is currently processed.
*/
bool HasData() const
{
- // Validate the database, list and element handle
- ValidateElem();
- // Return the requested information
- return m_Elem->entry_data.has_data;
+ return ConvTo< bool >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.has_data);
}
/* --------------------------------------------------------------------------------------------
@@ -208,10 +224,7 @@ public:
*/
SQInteger GetType() const
{
- // Validate the database, list and element handle
- ValidateElem();
- // Return the requested information
- return static_cast< SQInteger >(m_Elem->entry_data.type);
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.type);
}
/* --------------------------------------------------------------------------------------------
@@ -219,21 +232,7 @@ public:
*/
SQInteger GetOffset() const
{
- // Validate the database, list and element handle
- ValidateElem();
- // Return the requested information
- return static_cast< SQInteger >(m_Elem->entry_data.offset);
- }
-
- /* --------------------------------------------------------------------------------------------
- * Retrieve the offset of the next element.
- */
- SQInteger GetOffsetToNext() const
- {
- // Validate the database, list and element handle
- ValidateElem();
- // Return the requested information
- return static_cast< SQInteger >(m_Elem->entry_data.offset_to_next);
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.offset);
}
/* --------------------------------------------------------------------------------------------
@@ -241,41 +240,61 @@ public:
*/
SQInteger DataSize() const
{
- // Validate the database, list and element handle
- ValidateElem();
- // Return the requested information
- return static_cast< SQInteger >(m_Elem->entry_data.data_size);
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID_ELEM(*this)->entry_data.data_size);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a boolean.
+ */
+ bool GetBool() const
+ {
+ return GetEntryAsBool(SQMOD_GET_VALID_ELEM(*this)->entry_data);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a native integer.
+ */
+ SQInteger GetInteger() const
+ {
+ return GetEntryAsInteger(SQMOD_GET_VALID_ELEM(*this)->entry_data);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a floating point.
+ */
+ SQFloat GetFloat() const
+ {
+ return GetEntryAsFloat(SQMOD_GET_VALID_ELEM(*this)->entry_data);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the value from the current element as a long integer.
+ */
+ Object GetLong() const
+ {
+ return GetEntryAsLong(SQMOD_GET_VALID_ELEM(*this)->entry_data);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the value from the current element as a string.
*/
- CSStr GetString() const;
+ Object GetString() const
+ {
+ return GetEntryAsString(SQMOD_GET_VALID_ELEM(*this)->entry_data);
+ }
/* --------------------------------------------------------------------------------------------
- * Retrieve the value from the current element as a native integer.
+ * Retrieve the value from the current element as a stream of bytes.
*/
- SQInteger GetInteger() const;
-
- /* --------------------------------------------------------------------------------------------
- * Retrieve the value from the current element as a floating point.
- */
- SQFloat GetFloat() const;
-
- /* --------------------------------------------------------------------------------------------
- * Retrieve the value from the current element as a long integer.
- */
- Object GetLong() const;
-
- /* --------------------------------------------------------------------------------------------
- * Retrieve the value from the current element as a boolean.
- */
- bool GetBool() const;
+ Object GetBytes() const
+ {
+ return GetEntryAsBytes(SQMOD_GET_VALID_ELEM(*this)->entry_data);
+ }
/* --------------------------------------------------------------------------------------------
* Dumpt the contents of the list to the specified list.
*/
- void DumpTo(CSStr filepath)
+ void DumpTo(CSStr filepath) const
{
DumpTo(filepath, 0);
}
@@ -288,4 +307,4 @@ public:
} // Namespace:: SqMod
-#endif // _SQMMDB_LOOKUPRESULT_HPP_
+#endif // _SQMMDB_ENTRYDATALIST_HPP_
diff --git a/modules/mmdb/Handle/Database.cpp b/modules/mmdb/Handle/Database.cpp
new file mode 100644
index 00000000..4743962b
--- /dev/null
+++ b/modules/mmdb/Handle/Database.cpp
@@ -0,0 +1,32 @@
+// ------------------------------------------------------------------------------------------------
+#include "Handle/Database.hpp"
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+// ------------------------------------------------------------------------------------------------
+DbHnd::DbHnd(CSStr filepath, Uint32 flags)
+ : mDb()
+{
+ // Validate the specified file path
+ if (!filepath || *filepath == '\0')
+ {
+ STHROWF("Invalid database file path");
+ }
+ // Let's attempt to open the specified database
+ const Int32 status = MMDB_open(filepath, flags, &mDb);
+ // Validate the result of the operation
+ if (status != MMDB_SUCCESS)
+ {
+ STHROWF("Unable to open the specified database [%s]", MMDB_strerror(status));
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+DbHnd::~DbHnd()
+{
+ // We don't need the database handle anymore
+ MMDB_close(&mDb);
+}
+
+} // Namespace:: SqMod
\ No newline at end of file
diff --git a/modules/mmdb/Handle/Database.hpp b/modules/mmdb/Handle/Database.hpp
new file mode 100644
index 00000000..cc686b33
--- /dev/null
+++ b/modules/mmdb/Handle/Database.hpp
@@ -0,0 +1,69 @@
+#ifndef _SQMMDB_HANDLE_DATABASE_HPP_
+#define _SQMMDB_HANDLE_DATABASE_HPP_
+
+// ------------------------------------------------------------------------------------------------
+#include "Common.hpp"
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+/* ------------------------------------------------------------------------------------------------
+ * Manages a reference counted INI document instance.
+*/
+class DbHnd
+{
+ // --------------------------------------------------------------------------------------------
+ friend class Database;
+
+public:
+
+ // --------------------------------------------------------------------------------------------
+ typedef MMDB_s 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.
+
+public:
+
+ // --------------------------------------------------------------------------------------------
+ MMDB_s mDb; // The managed database handle.
+
+ /* --------------------------------------------------------------------------------------------
+ * Default constructor.
+ */
+ DbHnd(CSStr filepath, Uint32 flags);
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor. (disabled)
+ */
+ DbHnd(const DbHnd & o) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move constructor. (disabled)
+ */
+ DbHnd(DbHnd && o) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Destructor.
+ */
+ ~DbHnd();
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy assignment operator. (disabled)
+ */
+ DbHnd & operator = (const DbHnd & o) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move assignment operator. (disabled)
+ */
+ DbHnd & operator = (DbHnd && o) = delete;
+};
+
+} // Namespace:: SqMod
+
+#endif // _SQMMDB_HANDLE_DATABASE_HPP_
diff --git a/modules/mmdb/LookupResult.cpp b/modules/mmdb/LookupResult.cpp
index 26692d19..62564246 100644
--- a/modules/mmdb/LookupResult.cpp
+++ b/modules/mmdb/LookupResult.cpp
@@ -1,5 +1,12 @@
// ------------------------------------------------------------------------------------------------
#include "LookupResult.hpp"
+#include "EntryData.hpp"
+#include "EntryDataList.hpp"
+
+// ------------------------------------------------------------------------------------------------
+#include
+#include
+#include
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@@ -7,47 +14,164 @@ namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger LookupResult::Typename(HSQUIRRELVM vm)
{
- static const SQChar name[] = _SC("SqMMDBLookupResult");
+ static const SQChar name[] = _SC("SqMMLookupResult");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+void LookupResult::Validate(CCStr file, Int32 line) const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
+ }
+}
+#else
void LookupResult::Validate() const
{
- // Is the document handle valid?
- if (!m_Db)
- STHROWF("Invalid Maxmind database reference");
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference");
+ }
}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+const DbRef & LookupResult::GetValid(CCStr file, Int32 line) const
+{
+ Validate(file, line);
+ return m_Handle;
+}
+#else
+const DbRef & LookupResult::GetValid() const
+{
+ Validate();
+ return m_Handle;
+}
+#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
LookupResult::LookupResult()
- : m_Db(), m_Result()
+ : m_Handle(), m_Result()
{
- memset(&m_Result, 0, sizeof(Type));
+ std::memset(&m_Result, 0, sizeof(Type));
}
// ------------------------------------------------------------------------------------------------
-Int32 LookupResult::Cmp(const LookupResult & o) const
+Object LookupResult::GetEntryDataList()
{
- if (m_Db == o.m_Db)
- return 0;
- else if (m_Db.DbPtr() > o.m_Db.DbPtr())
- return 1;
- else
- return -1;
+ // See if there's an entry
+ if (!m_Result.found_entry)
+ {
+ STHROWF("Result does not have an entry");
+ }
+
+ MMDB_entry_data_list_s * entry_data_list = nullptr;
+ // Attempt to retrieve the entire entry data list at once
+ const int status = MMDB_get_entry_data_list(&m_Result.entry, &entry_data_list);
+ // Validate the status code
+ if (status != MMDB_SUCCESS)
+ {
+ STHROWF("Unable to get entry data list [%s]", MMDB_strerror(status));
+ }
+ // Return the resulted list
+ return Object(new EntryDataList(m_Handle, entry_data_list));
}
// ------------------------------------------------------------------------------------------------
-EntryDataList LookupResult::GetValueA(CSStr path, Array & arr) const
+SQInteger LookupResult::GetValue(HSQUIRRELVM vm)
{
+ const Int32 top = sq_gettop(vm);
+ // The lookup result instance
+ LookupResult * lookup = nullptr;
+ // Attempt to extract the lookup result instance
+ try
+ {
+ lookup = Var< LookupResult * >(vm, 1).value;
+ }
+ catch (const Sqrat::Exception & e)
+ {
+ return sq_throwerror(vm, e.what());
+ }
+ // Do we have a valid lookup result instance?
+ if (!lookup)
+ {
+ return sq_throwerror(vm, "Invalid lookup result instance");
+ }
+ // See if there's an entry
+ else if (!(lookup->m_Result.found_entry))
+ {
+ return sq_throwerror(vm, "Result does not have an entry");
+ }
+ typedef std::vector< StackStrF > ArgList;
+ // The list of extracted arguments
+ ArgList arglist;
+ // Extract each argument as a string
+ for (SQInteger i = 2; i <= top; ++i)
+ {
+ arglist.emplace_back(vm, i, false);
+ // Did we fail to extract the argument value?
+ if (SQ_FAILED(arglist.back().mRes))
+ {
+ return arglist.back().mRes; // Propagate the error
+ }
+ }
+
+ typedef std::vector< CSStr > PtrList;
+ // The list of pointers to path segments
+ PtrList ptrlist;
+ // Grab the pointers to argument values
+ for (const auto & a : arglist)
+ {
+ ptrlist.push_back(a.mPtr);
+ }
+ // Push null to specify the end of the list
+ ptrlist.push_back(nullptr);
+
+ MMDB_entry_data_s entry_data;
+ // Attempt to retrieve the entire entry data list at once
+ const int status = MMDB_aget_value(&(lookup->m_Result.entry), &entry_data, ptrlist.data());
+ // Validate the status code
+ if (status != MMDB_SUCCESS)
+ {
+ return sq_throwerror(vm, ToStrF("Unable to get entry data [%s]", MMDB_strerror(status)));
+ }
+ // Push the resulted list object onto the stack
+ try
+ {
+ ClassType< EntryData >::PushInstance(vm, new EntryData(lookup->m_Handle, entry_data));
+ }
+ catch (const Sqrat::Exception & e)
+ {
+ return sq_throwerror(vm, e.what());
+ }
+ // Specify that we returned a value
+ return 1;
}
-// ------------------------------------------------------------------------------------------------
-EntryDataList LookupResult::GetValueT(CSStr path, Table & tbl) const
+// ================================================================================================
+void Register_LookupResult(Table & mmns)
{
-
+ mmns.Bind(_SC("LookupResult"),
+ Class< LookupResult >(mmns.GetVM(), _SC("SqMMLookupResult"))
+ // Constructors
+ .Ctor()
+ .Ctor< const LookupResult & >()
+ // Meta-methods
+ .SquirrelFunc(_SC("_typename"), &LookupResult::Typename)
+ .Func(_SC("_tostring"), &LookupResult::ToString)
+ // Properties
+ .Prop(_SC("IsValid"), &LookupResult::IsValid)
+ .Prop(_SC("FoundEntry"), &LookupResult::FoundEntry)
+ .Prop(_SC("NetMask"), &LookupResult::GetNetMask)
+ .Prop(_SC("EntryDataList"), &LookupResult::GetEntryDataList)
+ // Squirrel functions
+ .SquirrelFunc(_SC("GetValue"), &LookupResult::GetValue)
+ );
}
} // Namespace:: SqMod
diff --git a/modules/mmdb/LookupResult.hpp b/modules/mmdb/LookupResult.hpp
index 857b56a6..8940553b 100644
--- a/modules/mmdb/LookupResult.hpp
+++ b/modules/mmdb/LookupResult.hpp
@@ -2,7 +2,7 @@
#define _SQMMDB_LOOKUPRESULT_HPP_
// ------------------------------------------------------------------------------------------------
-#include "Common.hpp"
+#include "Handle/Database.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@@ -29,21 +29,36 @@ protected:
typedef const Type& ConstRef; // Constant reference to the managed type.
/* --------------------------------------------------------------------------------------------
- * Validate the database pointer and throw an error if invalid.
+ * Validate the managed database handle and throw an error if invalid.
*/
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ void Validate(CCStr file, Int32 line) const;
+#else
void Validate() const;
+#endif // _DEBUG
+
+private:
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ const DbRef & GetValid(CCStr file, Int32 line) const;
+#else
+ const DbRef & GetValid() const;
+#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
- DbRef m_Db; /* The database from which this result comes from. */
- Type m_Result; /* The managed result structure. */
+ DbRef m_Handle; // The database from which this result comes from.
+ Type m_Result; // The managed result structure.
/* --------------------------------------------------------------------------------------------
* Construct and take ownership of a certain result.
*/
LookupResult(const DbRef & db, Reference result)
- : m_Db(db), m_Result(result)
+ : m_Handle(db), m_Result(result)
{
/* ... */
}
@@ -99,11 +114,6 @@ public:
return m_Result;
}
- /* --------------------------------------------------------------------------------------------
- * Used by the script engine to compare two instances of this type.
- */
- Int32 Cmp(const LookupResult & o) const;
-
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/
@@ -122,7 +132,7 @@ public:
*/
bool IsValid() const
{
- return m_Db && m_Result.found_entry;
+ return m_Handle && m_Result.found_entry;
}
/* --------------------------------------------------------------------------------------------
@@ -131,7 +141,7 @@ public:
bool FoundEntry() const
{
// Validate the database handle
- Validate();
+ SQMOD_VALIDATE(*this);
// Return the requested information
return m_Result.found_entry;
}
@@ -142,21 +152,20 @@ public:
SQInteger GetNetMask() const
{
// Validate the database handle
- Validate();
+ SQMOD_VALIDATE(*this);
// Return the requested information
return static_cast< SQInteger >(m_Result.netmask);
}
/* --------------------------------------------------------------------------------------------
- * Lookup data in the associated result using an array as the path.
+ * Retrieve the entire entry data list.
*/
- EntryDataList GetValueA(CSStr path, Array & arr) const;
+ Object GetEntryDataList();
/* --------------------------------------------------------------------------------------------
- * Lookup data in the associated result using a table as the path.
+ * Lookup data in the associated result using the specified path.
*/
- EntryDataList GetValueT(CSStr path, Table & tbl) const;
-
+ static SQInteger GetValue(HSQUIRRELVM vm);
};
} // Namespace:: SqMod
diff --git a/modules/mmdb/Metadata.cpp b/modules/mmdb/Metadata.cpp
new file mode 100644
index 00000000..93a73228
--- /dev/null
+++ b/modules/mmdb/Metadata.cpp
@@ -0,0 +1,108 @@
+// ------------------------------------------------------------------------------------------------
+#include "Metadata.hpp"
+#include "Description.hpp"
+
+// ------------------------------------------------------------------------------------------------
+#include
+#include
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+// ------------------------------------------------------------------------------------------------
+SQInteger Metadata::Typename(HSQUIRRELVM vm)
+{
+ static const SQChar name[] = _SC("SqMMMetadata");
+ sq_pushstring(vm, name, sizeof(name));
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+void Metadata::Validate(CCStr file, Int32 line) const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
+ }
+}
+#else
+void Metadata::Validate() const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid Maxmind database reference");
+ }
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+Metadata::Pointer Metadata::GetValid(CCStr file, Int32 line) const
+{
+ Validate(file, line);
+ // Validate the referenced meta-data
+ if (!m_Metadata)
+ {
+ SqThrowF("Invalid Maxmind meta-data reference =>[%s:%d]", file, line);
+ }
+ // Return the meta-data pointer
+ return m_Metadata;
+}
+#else
+Metadata::Pointer Metadata::GetValid() const
+{
+ Validate();
+ // Validate the referenced meta-data
+ if (!m_Metadata)
+ {
+ SqThrowF("Invalid Maxmind meta-data reference");
+ }
+ // Return the meta-data pointer
+ return m_Metadata;
+}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+Description Metadata::GetDescriptionHandle(Uint32 idx) const
+{
+ // Validate the specified index
+ if (idx > SQMOD_GET_VALID(*this)->description.count)
+ {
+ STHROWF("The specified description index is out of range: %u > %u", idx, m_Metadata->description.count);
+ }
+ // Return the requested description
+ return Description(m_Handle, m_Metadata->description.descriptions[idx]);
+}
+
+// ================================================================================================
+void Register_Metadata(Table & mmns)
+{
+ mmns.Bind(_SC("Metadata"),
+ Class< Metadata >(mmns.GetVM(), _SC("SqMMMetadata"))
+ // Constructors
+ .Ctor()
+ .Ctor< const Metadata & >()
+ // Meta-methods
+ .SquirrelFunc(_SC("_typename"), &Metadata::Typename)
+ .Func(_SC("_tostring"), &Metadata::ToString)
+ // Properties
+ .Prop(_SC("IsValid"), &Metadata::IsValid)
+ .Prop(_SC("NodeCount"), &Metadata::GetNodeCount)
+ .Prop(_SC("RecordSize"), &Metadata::GetRecordSize)
+ .Prop(_SC("IpVersion"), &Metadata::GetIpVersion)
+ .Prop(_SC("DatabaseType"), &Metadata::GetDatabaseType)
+ .Prop(_SC("LanguageCount"), &Metadata::GetLanguageCount)
+ .Prop(_SC("BinaryFormatMajorVersion"), &Metadata::GetBinaryFormatMajorVersion)
+ .Prop(_SC("BinaryFormatMinorVersion"), &Metadata::GetBinaryFormatMinorVersion)
+ .Prop(_SC("BuildEpoch"), &Metadata::GetBuildEpoch)
+ .Prop(_SC("DescriptionCount"), &Metadata::GetDescriptionCount)
+ // Member methods
+ .Func(_SC("GetLanguageName"), &Metadata::GetLanguageName)
+ .Func(_SC("GetDescriptionHandle"), &Metadata::GetDescriptionHandle)
+ .Func(_SC("GetDescriptionValue"), &Metadata::GetDescriptionValue)
+ .Func(_SC("GetDescriptionLanguage"), &Metadata::GetDescriptionLanguage)
+ );
+}
+
+} // Namespace:: SqMod
diff --git a/modules/mmdb/Metadata.hpp b/modules/mmdb/Metadata.hpp
new file mode 100644
index 00000000..b8728fc2
--- /dev/null
+++ b/modules/mmdb/Metadata.hpp
@@ -0,0 +1,262 @@
+#ifndef _SQMMDB_METADATA_HPP_
+#define _SQMMDB_METADATA_HPP_
+
+// ------------------------------------------------------------------------------------------------
+#include "Handle/Database.hpp"
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+/* ------------------------------------------------------------------------------------------------
+ * Class that can hold and be used inspect database meta-data.
+*/
+class Metadata
+{
+ // --------------------------------------------------------------------------------------------
+ friend class Database; // Only a valid database instance can construct this type.
+
+protected:
+
+ // --------------------------------------------------------------------------------------------
+ typedef MMDB_metadata_s 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.
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ void Validate(CCStr file, Int32 line) const;
+#else
+ void Validate() const;
+#endif // _DEBUG
+
+private:
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed database handle and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ Pointer GetValid(CCStr file, Int32 line) const;
+#else
+ Pointer GetValid() const;
+#endif // _DEBUG
+
+private:
+
+ // ---------------------------------------------------------------------------------------------
+ DbRef m_Handle; // The database associated with this meta-data.
+ Pointer m_Metadata; // The inspected meta-data structure.
+
+ /* --------------------------------------------------------------------------------------------
+ * Construct and with a specific meta-data.
+ */
+ Metadata(const DbRef & db, Pointer metadata)
+ : m_Handle(db), m_Metadata(metadata)
+ {
+ /* ... */
+ }
+
+public:
+
+ /* --------------------------------------------------------------------------------------------
+ * Default constructor. (null)
+ */
+ Metadata()
+ : m_Handle(), m_Metadata(nullptr)
+ {
+ /* ... */
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor.
+ */
+ Metadata(const Metadata &) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move constructor.
+ */
+ Metadata(Metadata &&) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy assignment operator.
+ */
+ Metadata & operator = (const Metadata &) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move assignment operator.
+ */
+ Metadata & operator = (Metadata &&) = default;
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the internal result structure reference.
+ */
+ Pointer GetHandle()
+ {
+ return m_Metadata;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the internal result structure reference.
+ */
+ ConstPtr GetHandle() const
+ {
+ return m_Metadata;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Used by the script engine to convert an instance of this type to a string.
+ */
+ CSStr ToString() const
+ {
+ return m_Metadata ? m_Metadata->database_type : _SC("");
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Used by the script engine to retrieve the name from instances of this type.
+ */
+ static SQInteger Typename(HSQUIRRELVM vm);
+
+ /* --------------------------------------------------------------------------------------------
+ * See whether this instance references a valid database and result structure.
+ */
+ bool IsValid() const
+ {
+ return m_Handle && m_Metadata;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the node count.
+ */
+ SQInteger GetNodeCount() const
+ {
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->node_count);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the record size.
+ */
+ SQInteger GetRecordSize() const
+ {
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->record_size);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the IP version.
+ */
+ SQInteger GetIpVersion() const
+ {
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->ip_version);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the database type.
+ */
+ CSStr GetDatabaseType() const
+ {
+ return SQMOD_GET_VALID(*this)->database_type;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the number of language names.
+ */
+ SQInteger GetLanguageCount() const
+ {
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->languages.count);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the name of a certain language.
+ */
+ CSStr GetLanguageName(Uint32 idx) const
+ {
+ // Validate the specified index
+ if (idx > SQMOD_GET_VALID(*this)->languages.count)
+ {
+ STHROWF("The specified language index is out of range: %u > %u", idx, m_Metadata->languages.count);
+ }
+ // Return the requested name
+ return m_Metadata->languages.names[idx];
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the major version of the binary format.
+ */
+ SQInteger GetBinaryFormatMajorVersion() const
+ {
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->binary_format_major_version);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the minor version of the binary format.
+ */
+ SQInteger GetBinaryFormatMinorVersion() const
+ {
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->binary_format_minor_version);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the build epoch.
+ */
+ Object GetBuildEpoch() const
+ {
+ // Obtain the initial stack size
+ const StackGuard sg;
+ // Push a long integer instance with the requested value on the stack
+ SqMod_PushULongObject(DefaultVM::Get(), ConvTo< Uint64 >::From(SQMOD_GET_VALID(*this)->build_epoch));
+ // Obtain the object from the stack and return it
+ return Var< Object >(DefaultVM::Get(), -1).value;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the number of available description handles.
+ */
+ SQInteger GetDescriptionCount() const
+ {
+ return ConvTo< SQInteger >::From(SQMOD_GET_VALID(*this)->description.count);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the handle of a certain description.
+ */
+ Description GetDescriptionHandle(Uint32 idx) const;
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the description of a certain description handle.
+ */
+ CSStr GetDescriptionValue(Uint32 idx) const
+ {
+ // Validate the specified index
+ if (idx > SQMOD_GET_VALID(*this)->description.count)
+ {
+ STHROWF("The specified description index is out of range: %u > %u", idx, m_Metadata->description.count);
+ }
+ // Return the requested description value
+ return m_Metadata->description.descriptions[idx]->description;
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Retrieve the language of a certain description handle.
+ */
+ CSStr GetDescriptionLanguage(Uint32 idx) const
+ {
+ // Validate the specified index
+ if (idx > SQMOD_GET_VALID(*this)->description.count)
+ {
+ STHROWF("The specified description index is out of range: %u > %u", idx, m_Metadata->description.count);
+ }
+ // Return the requested description language
+ return m_Metadata->description.descriptions[idx]->language;
+ }
+
+};
+
+} // Namespace:: SqMod
+
+#endif // _SQMMDB_METADATA_HPP_
diff --git a/modules/mmdb/Module.cpp b/modules/mmdb/Module.cpp
index 03b803e6..acd7100c 100644
--- a/modules/mmdb/Module.cpp
+++ b/modules/mmdb/Module.cpp
@@ -8,6 +8,15 @@
// ------------------------------------------------------------------------------------------------
namespace SqMod {
+// ------------------------------------------------------------------------------------------------
+extern void Register_Database(Table & mmns);
+extern void Register_Description(Table & mmns);
+extern void Register_EntryData(Table & mmns);
+extern void Register_EntryDataList(Table & mmns);
+extern void Register_LookupResult(Table & mmns);
+extern void Register_Metadata(Table & mmns);
+extern void Register_SockAddr(Table & mmns);
+
/* ------------------------------------------------------------------------------------------------
* Register the module API under the obtained virtual machine.
*/
@@ -21,6 +30,21 @@ static bool RegisterAPI(HSQUIRRELVM vm)
return false;
}
+ Table mmns(vm);
+
+ Register_Database(mmns);
+ Register_Description(mmns);
+ Register_EntryData(mmns);
+ Register_EntryDataList(mmns);
+ Register_LookupResult(mmns);
+ Register_Metadata(mmns);
+ Register_SockAddr(mmns);
+
+ mmns.Func(_SC("StrError"), MMDB_strerror);
+ mmns.Func(_SC("LibVersion"), MMDB_lib_version);
+
+ RootTable(vm).Bind(_SC("SqMMDB"), mmns);
+
// Registration was successful
return true;
}
diff --git a/modules/mmdb/SearchNode.cpp b/modules/mmdb/SearchNode.cpp
new file mode 100644
index 00000000..e69de29b
diff --git a/modules/mmdb/SearchNode.hpp b/modules/mmdb/SearchNode.hpp
new file mode 100644
index 00000000..e69de29b
diff --git a/modules/mmdb/SockAddr.cpp b/modules/mmdb/SockAddr.cpp
index 96fb8419..180cce23 100644
--- a/modules/mmdb/SockAddr.cpp
+++ b/modules/mmdb/SockAddr.cpp
@@ -7,22 +7,48 @@ namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger SockAddr::Typename(HSQUIRRELVM vm)
{
- static const SQChar name[] = _SC("SqMMDBSockAddr");
+ static const SQChar name[] = _SC("SqMMSockAddr");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+void SockAddr::Validate(CCStr file, Int32 line) const
+{
+ if (!m_Handle)
+ {
+ SqThrowF("Invalid sockaddr structure handle =>[%s:%d]", file, line);
+ }
+}
+#else
void SockAddr::Validate() const
{
- // Is the document handle valid?
if (!m_Handle)
- STHROWF("Invalid sockaddr structure handle");
+ {
+ SqThrowF("Invalid sockaddr structure handle");
+ }
}
+#endif // _DEBUG
+
+// ------------------------------------------------------------------------------------------------
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+SockAddr::Pointer SockAddr::GetValid(CCStr file, Int32 line) const
+{
+ Validate(file, line);
+ return m_Handle;
+}
+#else
+SockAddr::Pointer SockAddr::GetValid() const
+{
+ Validate();
+ return m_Handle;
+}
+#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
SockAddr::SockAddr(CSStr addr)
- : m_Handle(NULL), m_Addres(_SC(""))
+ : m_Handle(nullptr), m_Addres(_SC(""))
{
struct addrinfo hints;
// Configure the hints structure
@@ -31,13 +57,15 @@ SockAddr::SockAddr(CSStr addr)
// We set ai_socktype so that we only get one result back
hints.ai_socktype = SOCK_STREAM;
// Attempt to obtain information about the specified address
- Int32 status = getaddrinfo(addr, NULL, &hints, &m_Handle);
+ Int32 status = getaddrinfo(addr, nullptr, &hints, &m_Handle);
// Validate the success of the operation
if (!status)
{
// See if we must free any handles (just in case)
if (m_Handle)
+ {
freeaddrinfo(m_Handle);
+ }
// Now it's safe to throw the error
STHROWF("Unable to query the specified address for information [%s]", gai_strerror(status));
}
@@ -49,19 +77,26 @@ SockAddr::SockAddr(CSStr addr)
SockAddr::~SockAddr()
{
if (m_Handle)
+ {
freeaddrinfo(m_Handle);
+ }
}
-// ------------------------------------------------------------------------------------------------
-Int32 SockAddr::Cmp(const SockAddr & o) const
+// ================================================================================================
+void Register_SockAddr(Table & mmns)
{
- if (m_Handle == o.m_Handle)
- return 0;
- else if (m_Handle > o.m_Handle)
- return 1;
- else
- return -1;
+ mmns.Bind(_SC("SockAddr"),
+ Class< SockAddr, NoCopy< SockAddr > >(mmns.GetVM(), _SC("SqMMSockAddr"))
+ // Constructors
+ .Ctor()
+ .Ctor< CSStr >()
+ // Meta-methods
+ .SquirrelFunc(_SC("_typename"), &SockAddr::Typename)
+ .Func(_SC("_tostring"), &SockAddr::ToString)
+ // Properties
+ .Prop(_SC("IsValid"), &SockAddr::IsValid)
+ .Prop(_SC("Address"), &SockAddr::GetAddress)
+ );
}
-
} // Namespace:: SqMod
diff --git a/modules/mmdb/Sockaddr.hpp b/modules/mmdb/Sockaddr.hpp
index 80e79c63..7114be1d 100644
--- a/modules/mmdb/Sockaddr.hpp
+++ b/modules/mmdb/Sockaddr.hpp
@@ -26,15 +26,29 @@ protected:
typedef const Type& ConstRef; // Constant reference to the managed type.
/* --------------------------------------------------------------------------------------------
- * Validate the sockaddr pointer and throw an error if invalid.
+ * Validate the managed sockaddr pointer and throw an error if invalid.
*/
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ void Validate(CCStr file, Int32 line) const;
+#else
void Validate() const;
+#endif // _DEBUG
+private:
+
+ /* --------------------------------------------------------------------------------------------
+ * Validate the managed sockaddr pointer and throw an error if invalid.
+ */
+#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
+ Pointer GetValid(CCStr file, Int32 line) const;
+#else
+ Pointer GetValid() const;
+#endif // _DEBUG
private:
// ---------------------------------------------------------------------------------------------
- Pointer m_Handle; /* The managed sockaddr structure. */
- String m_Addres; /* The address that was queried for information. */
+ Pointer m_Handle; // The managed sockaddr structure.
+ String m_Addres; // The address that was queried for information.
public:
@@ -42,7 +56,7 @@ public:
* Default constructor.
*/
SockAddr()
- : m_Handle(NULL), m_Addres(_SC(""))
+ : m_Handle(nullptr), m_Addres(_SC(""))
{
/* ... */
}
@@ -55,7 +69,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
- SockAddr(const SockAddr &) = delete;
+ SockAddr(const SockAddr & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor.
@@ -75,7 +89,7 @@ public:
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
- SockAddr & operator = (const SockAddr &) = delete;
+ SockAddr & operator = (const SockAddr & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
@@ -107,11 +121,6 @@ public:
return m_Handle;
}
- /* --------------------------------------------------------------------------------------------
- * Used by the script engine to compare two instances of this type.
- */
- Int32 Cmp(const SockAddr & o) const;
-
/* --------------------------------------------------------------------------------------------
* Used by the script engine to convert an instance of this type to a string.
*/