mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
117 lines
4.3 KiB
C++
117 lines
4.3 KiB
C++
// ------------------------------------------------------------------------------------------------
|
|
#include "Database.hpp"
|
|
#include "SockAddr.hpp"
|
|
#include "LookupResult.hpp"
|
|
#include "Module.hpp"
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
#include <sqrat.h>
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
namespace SqMod {
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
SQInteger Database::Typename(HSQUIRRELVM vm)
|
|
{
|
|
static const SQChar name[] = _SC("SqMMDBDatabase");
|
|
sq_pushstring(vm, name, sizeof(name));
|
|
return 1;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
void Database::Validate() const
|
|
{
|
|
// Is the document handle valid?
|
|
if (!m_Db)
|
|
STHROWF("Invalid Maxmind database reference");
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
Int32 Database::Cmp(const Database & o) 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
|
|
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));
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
LookupResult Database::LookupString(CSStr addr)
|
|
{
|
|
// Validate the database handle
|
|
Validate();
|
|
// Validate the specified string
|
|
if (!addr || strlen(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);
|
|
// 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);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
LookupResult Database::LookupSockAddr(SockAddr & addr)
|
|
{
|
|
// Validate the database handle
|
|
Validate();
|
|
// 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);
|
|
// 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);
|
|
}
|
|
|
|
} // Namespace:: SqMod
|