diff --git a/cbp/ModIRC.cbp b/cbp/ModIRC.cbp index dc466e07..9431fb36 100644 --- a/cbp/ModIRC.cbp +++ b/cbp/ModIRC.cbp @@ -16,6 +16,7 @@ + @@ -37,6 +38,7 @@ + @@ -59,6 +61,7 @@ + @@ -81,6 +84,7 @@ + @@ -183,6 +187,7 @@ + @@ -208,6 +213,7 @@ + @@ -234,6 +240,7 @@ + @@ -260,6 +267,7 @@ + @@ -370,7 +378,10 @@ + + + diff --git a/modules/irc/Common.cpp b/modules/irc/Common.cpp index 006fe12a..d024fb1f 100644 --- a/modules/irc/Common.cpp +++ b/modules/irc/Common.cpp @@ -2,15 +2,76 @@ #include "Common.hpp" #include "Module.hpp" +// ------------------------------------------------------------------------------------------------ +#include + +// ------------------------------------------------------------------------------------------------ +#include + // ------------------------------------------------------------------------------------------------ #include #include // ------------------------------------------------------------------------------------------------ -static SQChar g_Buffer[512]; +namespace SqMod { // ------------------------------------------------------------------------------------------------ -namespace SqMod { +static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations. + +// ------------------------------------------------------------------------------------------------ +SStr GetTempBuff() +{ + return g_Buffer; +} + +// ------------------------------------------------------------------------------------------------ +Uint32 GetTempBuffSize() +{ + return sizeof(g_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +void SqThrowF(CSStr str, ...) +{ + // Initialize the argument list + va_list args; + va_start (args, str); + // Write the requested contents + if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) + strcpy(g_Buffer, "Unknown error has occurred"); + // Release the argument list + va_end(args); + // Throw the exception with the resulted message + throw Sqrat::Exception(g_Buffer); +} + +// ------------------------------------------------------------------------------------------------ +CSStr FmtStr(CSStr str, ...) +{ + // Initialize the argument list + va_list args; + va_start (args, str); + // Write the requested contents + if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) + g_Buffer[0] = 0; /* make sure the string is terminated */ + // Release the argument list + va_end(args); + // Return the data from the buffer + return g_Buffer; +} + +// ------------------------------------------------------------------------------------------------ +StackGuard::StackGuard(HSQUIRRELVM vm) + : m_Top(sq_gettop(vm)), m_VM(vm) +{ + /* ... */ +} + +// ------------------------------------------------------------------------------------------------ +StackGuard::~StackGuard() +{ + sq_pop(m_VM, sq_gettop(m_VM) - m_Top); +} // ------------------------------------------------------------------------------------------------ CSStr GetNick(CSStr origin) diff --git a/modules/irc/Common.hpp b/modules/irc/Common.hpp index 07d06155..715257be 100644 --- a/modules/irc/Common.hpp +++ b/modules/irc/Common.hpp @@ -4,6 +4,12 @@ // ------------------------------------------------------------------------------------------------ #include "ModBase.hpp" +// ------------------------------------------------------------------------------------------------ +extern "C" { + struct SQVM; + typedef struct SQVM* HSQUIRRELVM; +} /*extern "C"*/ + // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -25,6 +31,70 @@ namespace SqMod { */ class Session; +/* ------------------------------------------------------------------------------------------------ + * Retrieve the temporary buffer. +*/ +SStr GetTempBuff(); + +/* ------------------------------------------------------------------------------------------------ + * Retrieve the size of the temporary buffer. +*/ +Uint32 GetTempBuffSize(); + +/* ------------------------------------------------------------------------------------------------ + * Throw a formatted exception. +*/ +void SqThrowF(CSStr str, ...); + +/* ------------------------------------------------------------------------------------------------ + * Generate a formatted string. +*/ +CSStr FmtStr(CSStr str, ...); + +/* ------------------------------------------------------------------------------------------------ + * Implements RAII to restore the VM stack to it's initial size on function exit. +*/ +struct StackGuard +{ + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + StackGuard(HSQUIRRELVM vm); + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~StackGuard(); + +private: + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + StackGuard(const StackGuard &); + + /* -------------------------------------------------------------------------------------------- + * Move constructor. + */ + StackGuard(StackGuard &&); + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + StackGuard & operator = (const StackGuard &); + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. + */ + StackGuard & operator = (StackGuard &&); + +private: + + // -------------------------------------------------------------------------------------------- + Int32 m_Top; /* The top of the stack when this instance was created. */ + HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */ +}; + /* ------------------------------------------------------------------------------------------------ * Extract the name from the specified origin. */ diff --git a/modules/irc/Module.cpp b/modules/irc/Module.cpp index a177aec1..6eeb48b1 100644 --- a/modules/irc/Module.cpp +++ b/modules/irc/Module.cpp @@ -186,7 +186,7 @@ void RegisterAPI(HSQUIRRELVM vm) .Ctor() /* Core Metamethods */ .Func(_SC("_cmp"), &Session::Cmp) - .Func(_SC("_typename"), &Session::Typename) + .SquirrelFunc(_SC("_typename"), &Session::Typename) .Func(_SC("_tostring"), &Session::ToString) /* Properties */ .Prop(_SC("Valid"), &Session::IsValid) diff --git a/modules/irc/Session.cpp b/modules/irc/Session.cpp index 8259a745..33186cd5 100644 --- a/modules/irc/Session.cpp +++ b/modules/irc/Session.cpp @@ -24,6 +24,14 @@ Session* Session::s_Session = NULL; // ------------------------------------------------------------------------------------------------ Session::Sessions Session::s_Sessions; +// ------------------------------------------------------------------------------------------------ +SQInteger Session::Typename(HSQUIRRELVM vm) +{ + static SQChar name[] = _SC("SqIrcSession"); + sq_pushstring(vm, name, sizeof(name)); + return 1; +} + // ------------------------------------------------------------------------------------------------ void Session::Process() { @@ -199,43 +207,41 @@ void Session::Destroy() } // ------------------------------------------------------------------------------------------------ -bool Session::Validate() const -{ - if (m_Session) - return true; - // Invalid session instance - _SqMod->SqThrow("Invalid IRC session (%s)", m_Tag.c_str()); - return false; -} - -// ------------------------------------------------------------------------------------------------ -bool Session::ConnectedThrow() const +void Session::Validate() const { + // Do we have a valid session handle? if (!m_Session) - _SqMod->SqThrow("Invalid IRC session (%s)", m_Tag.c_str()); - else if (!irc_is_connected(m_Session)) - _SqMod->SqThrow("Session is not connected (%s)", m_Tag.c_str()); - else - return true; - return false; + SqThrowF("Invalid IRC session"); } // ------------------------------------------------------------------------------------------------ -bool Session::NotConnected() const +void Session::ValidateConnection() const { - if (!m_Session || !irc_is_connected(m_Session) || !m_Reconnect) - return true; - _SqMod->SqThrow("Already connected or trying connect to IRC server (%s)", m_Tag.c_str()); - return !m_Session; + // Do we have a valid session handle? + if (!m_Session) + SqThrowF("Invalid IRC session"); + // Is the session connected? + else if (!irc_is_connected(m_Session)) + SqThrowF("Session is not connected"); +} + +// ------------------------------------------------------------------------------------------------ +void Session::IsNotConnected() const +{ + // Do we have a session that is not connected or trying to connect? + if (m_Session && (irc_is_connected(m_Session) || m_Reconnect)) + SqThrowF("Already connected or trying connect to IRC server"); } // ------------------------------------------------------------------------------------------------ bool Session::ValidateEventSession(Session * ptr) { + // Is the session instance valid? if (ptr) return true; - // Invalid session instance + // We can't throw an error here so we simply log it _SqMod->LogErr("Cannot forward IRC event without a session container"); + // Invalid session instance return false; } @@ -260,9 +266,10 @@ Session::Session() { if (!m_Session) { - _SqMod->SqThrow("Unable to create an IRC session"); // Explicitly make sure no further calls can be made to this session m_Session = NULL; + // Now it's safe to throw the error + SqThrowF("Unable to create an IRC session"); } else { @@ -270,26 +277,18 @@ Session::Session() irc_set_ctx(m_Session, this); // Is this the only session instance? if (!s_Session && s_Sessions.empty()) - { s_Session = this; - } + // Is this the second session instance? else if (s_Sessions.empty()) { s_Sessions.push_back(s_Session); s_Session = NULL; s_Sessions.push_back(this); } + // This is part of multiple session instances else - { s_Sessions.push_back(this); - } } - // Because Sqrat is majorly stupid and clears the error message - // then does an assert on debug builds thinking the type wasn't registered - // or throws a generic "unknown error" message on release builds - // we have to use this approach - if (Sqrat::Error::Occurred(_SqVM)) - _SqMod->LogErr("%s", Sqrat::Error::Message(_SqVM).c_str()); } // ------------------------------------------------------------------------------------------------ @@ -309,260 +308,233 @@ Session::~Session() // ------------------------------------------------------------------------------------------------ void Session::SetNick(CSStr nick) { + // Validate the handle + Validate(); + // Validate the specified nick name if (!nick || strlen(nick) <= 0) - _SqMod->SqThrow("Invalid IRC nickname"); + SqThrowF("Invalid IRC nickname"); + // Do we have to issue a nickname command? else if (Connected()) irc_cmd_nick(m_Session, nick); - else if (Validate()) + // Simply save the specified nickname + else m_Nick.assign(nick); } // ------------------------------------------------------------------------------------------------ void Session::SetPort(Uint32 num) { + // The port cannot be changed once connected! + IsNotConnected(); + // Validate the specified port number if (num > 0xFFFF) - _SqMod->SqThrow("Port number is out of range: %u > %u", num, 0xFFFF); - else if (Validate() && NotConnected()) - m_Port = num; + SqThrowF("Port number is out of range: %u > %u", num, 0xFFFF); + // Assign the specified port number + m_Port = num; } // ------------------------------------------------------------------------------------------------ Int32 Session::CmdNick(CSStr nick) { + // Make sure the session is connected + ValidateConnection(); + // Validate the specified nick name if (!nick || strlen(nick) <= 0) - _SqMod->SqThrow("Invalid IRC nickname"); - else if (ConnectedThrow()) - return irc_cmd_nick(m_Session, nick); - return -1; + SqThrowF("Invalid IRC nickname"); + // Issue the command and return the result + return irc_cmd_nick(m_Session, nick); } // ------------------------------------------------------------------------------------------------ Object Session::GetNextTry() const { // Obtain the initial stack size - const Int32 top = sq_gettop(_SqVM); + const StackGuard sg(_SqVM); // Attempt to push a time-stamp instance on the stack _SqMod->PushTimestamp(_SqVM, m_NextTry); - // Obtain the object from the stack - Var< Object > inst(_SqVM, -1); - // Remove an pushed values (if any) to restore the stack - sq_pop(_SqVM, sq_gettop(_SqVM) - top); - // Return the timestamp instance - return inst.value; + // Obtain the object from the stack and return it + return Var< Object >(_SqVM, -1).value; } // ------------------------------------------------------------------------------------------------ void Session::SetNextTry(Object & tm) { // Obtain the initial stack size - const Int32 top = sq_gettop(_SqVM); + const StackGuard sg(_SqVM); // Push the specified object onto the stack Var< Object >::push(_SqVM, tm); // The resulted times-tamp value Int64 microseconds = 0; // Attempt to get the numeric value inside the specified object if (SQ_FAILED(_SqMod->GetTimestamp(_SqVM, -1, µseconds))) - _SqMod->SqThrow("Invalid time-stamp specified"); - else - m_NextTry = microseconds; - // Remove an pushed values (if any) to restore the stack - sq_pop(_SqVM, sq_gettop(_SqVM) - top); + SqThrowF("Invalid time-stamp specified"); + // Assign the specified timestamp value + m_NextTry = microseconds; } // ------------------------------------------------------------------------------------------------ Object Session::GetSessionTime() const { // Obtain the initial stack size - const Int32 top = sq_gettop(_SqVM); + const StackGuard sg(_SqVM); // Attempt to push a time-stamp instance on the stack if (m_SessionTime) _SqMod->PushTimestamp(_SqVM, _SqMod->GetEpochTimeMicro() - m_SessionTime); + // This session was not connected yet else _SqMod->PushTimestamp(_SqVM, 0); - // Obtain the object from the stack - Var< Object > inst(_SqVM, -1); - // Remove an pushed values (if any) to restore the stack - sq_pop(_SqVM, sq_gettop(_SqVM) - top); - // Return the timestamp instance - return inst.value; + // Obtain the object from the stack and return it + return Var< Object >(_SqVM, -1).value; } // ------------------------------------------------------------------------------------------------ Int32 Session::Connect() { - // Are we even allowed to try to connect? - if (!Validate() || !NotConnected()) - return -1; /* No point in going forward */ - // Did we already try to connect? - else if (m_Reconnect) - _SqMod->SqThrow("Attempting to connect IRC while connection was already issued"); + // Validate the handle + Validate(); + // Make sure we are allowed to connect + IsNotConnected(); // Validate the specified server - else if (!m_Server.empty()) - _SqMod->SqThrow("Attempting to connect IRC without specifying a server"); + if (!m_Server.empty()) + SqThrowF("Attempting to connect IRC without specifying a server"); // Validate the specified nickname else if (!m_Nick.empty()) - _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname"); - else - { - // Enable the reconnection system - m_Reconnect = true; - // Reset the number of tries - m_LeftTries = m_Tries; - // Set the time-point for the next try - m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); - // This is not an IPv6 connection - m_IPv6 = false; - // Attempt to connect the session and return the result - return irc_connect(m_Session, m_Server.c_str(), m_Port, - m_Passwd.empty() ? NULL : m_Passwd.c_str(), - m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() - ); - } - // Connection denied before even attempted - return -1; + SqThrowF("Attempting to connect IRC without specifying a nickname"); + // Enable the reconnection system + m_Reconnect = true; + // Reset the number of tries + m_LeftTries = m_Tries; + // Set the time-point for the next try + m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); + // This is not an IPv6 connection + m_IPv6 = false; + // Attempt to connect the session and return the result + return irc_connect(m_Session, m_Server.c_str(), m_Port, + m_Passwd.empty() ? NULL : m_Passwd.c_str(), + m_Nick.c_str(), + m_User.empty() ? NULL : m_User.c_str(), + m_Name.empty() ? NULL : m_Name.c_str() + ); } // ------------------------------------------------------------------------------------------------ Int32 Session::Connect(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSStr user, CSStr name) { - // Are we even allowed to try to connect? - if (!Validate() || !NotConnected()) - return -1; /* No point in going forward */ - // Did we already try to connect? - else if (m_Reconnect) - _SqMod->SqThrow("Attempting to connect IRC while connection was already issued"); + // Validate the handle + Validate(); + // Make sure we are allowed to connect + IsNotConnected(); // Validate the specified port - else if (port > 0xFFFF) - _SqMod->SqThrow("Port number is out of range: %u > %u", port, 0xFFFF); + if (port > 0xFFFF) + SqThrowF("Port number is out of range: %u > %u", port, 0xFFFF); // Validate the specified server else if (!server || strlen(server) <= 0) - _SqMod->SqThrow("Attempting to connect IRC without specifying a server"); + SqThrowF("Attempting to connect IRC without specifying a server"); // Validate the specified nickname else if (!nick || strlen(nick) <= 0) - _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname"); - else - { - // Save the specified port - m_Port = port; - // Save the specified server - m_Server.assign(server); - // Save the specified nickname - m_Nick.assign(nick); - // Save the specified password - m_Passwd.assign(!passwd ? _SC("") : passwd); - // Save the specified user - m_User.assign(!user ? _SC("") : user); - // Save the specified name - m_Name.assign(!name ? _SC("") : name); - // Enable the reconnection system - m_Reconnect = true; - // Reset the number of tries - m_LeftTries = m_Tries; - // Set the time-point for the next connection try - m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); - // This is not an IPv6 connection - m_IPv6 = false; - // Attempt to connect the session and return the result - return irc_connect(m_Session, m_Server.c_str(), m_Port, - m_Passwd.empty() ? NULL : m_Passwd.c_str(), - m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() - ); - } - // Connection denied before even attempted - return -1; + SqThrowF("Attempting to connect IRC without specifying a nickname"); + // Save the specified port + m_Port = port; + // Save the specified server + m_Server.assign(server); + // Save the specified nickname + m_Nick.assign(nick); + // Save the specified password + m_Passwd.assign(passwd ? passwd : _SC("")); + // Save the specified user + m_User.assign(user ? user : _SC("")); + // Save the specified name + m_Name.assign(name ? name : _SC("")); + // Enable the reconnection system + m_Reconnect = true; + // Reset the number of tries + m_LeftTries = m_Tries; + // Set the time-point for the next connection try + m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); + // This is not an IPv6 connection + m_IPv6 = false; + // Attempt to connect the session and return the result + return irc_connect(m_Session, m_Server.c_str(), m_Port, + m_Passwd.empty() ? NULL : m_Passwd.c_str(), + m_Nick.c_str(), + m_User.empty() ? NULL : m_User.c_str(), + m_Name.empty() ? NULL : m_Name.c_str() + ); } // ------------------------------------------------------------------------------------------------ Int32 Session::Connect6() { - // Are we even allowed to try to connect? - if (!Validate() || !NotConnected()) - return -1; /* No point in going forward */ - // Did we already try to connect? - else if (m_Reconnect) - _SqMod->SqThrow("Attempting to connect IRC while connection was already issued"); + // Validate the handle + Validate(); + // Make sure we are allowed to connect + IsNotConnected(); // Validate the specified server - else if (!m_Server.empty()) - _SqMod->SqThrow("Attempting to connect IRC without specifying a server"); + if (!m_Server.empty()) + SqThrowF("Attempting to connect IRC without specifying a server"); // Validate the specified nickname else if (!m_Nick.empty()) - _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname"); - else - { - // Enable the reconnection system - m_Reconnect = true; - // Reset the number of tries - m_LeftTries = m_Tries; - // Set the time-point for the next try - m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); - // This is an IPv6 connection - m_IPv6 = true; - // Attempt to connect the session and return the result - return irc_connect6(m_Session, m_Server.c_str(), m_Port, - m_Passwd.empty() ? NULL : m_Passwd.c_str(), - m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() - ); - } - // Connection denied before even attempted - return -1; + SqThrowF("Attempting to connect IRC without specifying a nickname"); + // Enable the reconnection system + m_Reconnect = true; + // Reset the number of tries + m_LeftTries = m_Tries; + // Set the time-point for the next try + m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); + // This is an IPv6 connection + m_IPv6 = true; + // Attempt to connect the session and return the result + return irc_connect6(m_Session, m_Server.c_str(), m_Port, + m_Passwd.empty() ? NULL : m_Passwd.c_str(), + m_Nick.c_str(), + m_User.empty() ? NULL : m_User.c_str(), + m_Name.empty() ? NULL : m_Name.c_str() + ); } // ------------------------------------------------------------------------------------------------ Int32 Session::Connect6(CSStr server, Uint32 port, CSStr nick, CSStr passwd, CSStr user, CSStr name) { - // Are we even allowed to try to connect? - if (!Validate() || !NotConnected()) - return -1; /* No point in going forward */ - // Did we already try to connect? - else if (m_Reconnect) - _SqMod->SqThrow("Attempting to connect IRC while connection was already issued"); + // Validate the handle + Validate(); + // Make sure we are allowed to connect + IsNotConnected(); // Validate the specified port - else if (port > 0xFFFF) - _SqMod->SqThrow("Port number is out of range: %u > %u", port, 0xFFFF); + if (port > 0xFFFF) + SqThrowF("Port number is out of range: %u > %u", port, 0xFFFF); // Validate the specified server else if (!server || strlen(server) <= 0) - _SqMod->SqThrow("Attempting to connect IRC without specifying a server"); + SqThrowF("Attempting to connect IRC without specifying a server"); // Validate the specified nickname else if (!nick || strlen(nick) <= 0) - _SqMod->SqThrow("Attempting to connect IRC without specifying a nickname"); - else - { - // Save the specified port - m_Port = port; - // Save the specified server - m_Server.assign(server); - // Save the specified nickname - m_Nick.assign(nick); - // Save the specified password - m_Passwd.assign(!passwd ? _SC("") : passwd); - // Save the specified user - m_User.assign(!user ? _SC("") : user); - // Save the specified name - m_Name.assign(!name ? _SC("") : name); - // Enable the reconnection system - m_Reconnect = true; - // Reset the number of tries - m_LeftTries = m_Tries; - // Set the time-point for the next connection try - m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); - // This is an IPv6 connection - m_IPv6 = true; - // Attempt to connect the session and return the result - return irc_connect6(m_Session, m_Server.c_str(), m_Port, - m_Passwd.empty() ? NULL : m_Passwd.c_str(), - m_Nick.c_str(), - m_User.empty() ? NULL : m_User.c_str(), - m_Name.empty() ? NULL : m_Name.c_str() - ); - } - // Connection denied before even attempted - return -1; + SqThrowF("Attempting to connect IRC without specifying a nickname"); + // Save the specified port + m_Port = port; + // Save the specified server + m_Server.assign(server); + // Save the specified nickname + m_Nick.assign(nick); + // Save the specified password + m_Passwd.assign(passwd ? passwd : _SC("")); + // Save the specified user + m_User.assign(user ? user : _SC("")); + // Save the specified name + m_Name.assign(name ? name : _SC("")); + // Enable the reconnection system + m_Reconnect = true; + // Reset the number of tries + m_LeftTries = m_Tries; + // Set the time-point for the next connection try + m_NextTry = (_SqMod->GetEpochTimeMicro() + (m_Wait * 1000LL)); + // This is an IPv6 connection + m_IPv6 = true; + // Attempt to connect the session and return the result + return irc_connect6(m_Session, m_Server.c_str(), m_Port, + m_Passwd.empty() ? NULL : m_Passwd.c_str(), + m_Nick.c_str(), + m_User.empty() ? NULL : m_User.c_str(), + m_Name.empty() ? NULL : m_Name.c_str() + ); } // ------------------------------------------------------------------------------------------------ @@ -585,16 +557,12 @@ void Session::ForwardEvent(Session * session, Function & listener, CCStr event, { // Is there anyone even listening to this event? if (listener.IsNull()) - { return; /* No point in going forward */ - } // Make sure that the origin can't be a null pointer else if (!origin) - { origin = _SC(""); - } // Each event must have an array of parameters (empty or not) - Array parameters(DefaultVM::Get(), count); + Array parameters(_SqVM, count); // Are the any parameters? if (params && count > 0) { @@ -602,10 +570,12 @@ void Session::ForwardEvent(Session * session, Function & listener, CCStr event, for (Uint32 i = 0; i < count; ++i) parameters.SetValue(i, params[i]); } + // Obtain the initial stack size + const StackGuard sg(_SqVM); // Obtain an object to this session instance without creating a new reference counter! - ClassType< Session >::PushInstance(DefaultVM::Get(), session); + ClassType< Session >::PushInstance(_SqVM, session); // Obtain the pushed object from the stack - Var< Object > var(DefaultVM::Get(), -1); + Var< Object > var(_SqVM, -1); // Call the event with the obtained values listener.Execute< Object &, CSStr, CSStr, Array & >(var.value, event, origin, parameters); } @@ -616,29 +586,25 @@ void Session::ForwardEvent(Session * session, Function & listener, Uint32 event, { // Is there anyone even listening to this event? if (listener.IsNull()) - { return; /* No point in going forward */ - } // Make sure that the origin can't be a null pointer else if (!origin) - { origin = _SC(""); - } // Each event must have an array of parameters (empty or not) - Array parameters(DefaultVM::Get(), count); + Array parameters(_SqVM, count); // Are the any parameters? if (params && count > 0) { // Transform the parameters into a squirrel array for (unsigned int i = 0; i < count; ++i) - { parameters.SetValue(i, params[i]); - } } + // Obtain the initial stack size + const StackGuard sg(_SqVM); // Obtain an object to this session instance without creating a new reference counter! - ClassType< Session >::PushInstance(DefaultVM::Get(), session); + ClassType< Session >::PushInstance(_SqVM, session); // Obtain the pushed object from the stack - Var< Object > var(DefaultVM::Get(), -1); + Var< Object > var(_SqVM, -1); // Call the event with the obtained values listener.Execute< Object &, Uint32, CSStr, Array & >(var.value, event, origin, parameters); } @@ -840,7 +806,7 @@ void Session::OnDccSendReq(irc_session_t * session, CCStr nick, CCStr addr, CCSt // ------------------------------------------------------------------------------------------------ SQInteger Session::CmdMsgF(HSQUIRRELVM vm) { - // Save the stack top + // Obtain the initial stack size const Int32 top = sq_gettop(vm); // Do we have a target? if (top <= 1) @@ -908,7 +874,7 @@ SQInteger Session::CmdMsgF(HSQUIRRELVM vm) // ------------------------------------------------------------------------------------------------ SQInteger Session::CmdMeF(HSQUIRRELVM vm) { - // Save the stack top + // Obtain the initial stack size const Int32 top = sq_gettop(vm); // Do we have a target? if (top <= 1) @@ -976,7 +942,7 @@ SQInteger Session::CmdMeF(HSQUIRRELVM vm) // ------------------------------------------------------------------------------------------------ SQInteger Session::CmdNoticeF(HSQUIRRELVM vm) { - // Save the stack top + // Obtain the initial stack size const Int32 top = sq_gettop(vm); // Do we have a target? if (top <= 1) diff --git a/modules/irc/Session.hpp b/modules/irc/Session.hpp index ec821cdc..a0625811 100644 --- a/modules/irc/Session.hpp +++ b/modules/irc/Session.hpp @@ -84,7 +84,17 @@ protected: /* -------------------------------------------------------------------------------------------- * Make sure a valid session exists and throw an error if it doesn't. */ - bool Validate() const; + void Validate() const; + + /* -------------------------------------------------------------------------------------------- + * See whether this session is connected to a server and throw an error if not. + */ + void ValidateConnection() const; + + /* -------------------------------------------------------------------------------------------- + * See whether this session is NOT! connected to a server and throw an error if it is. + */ + void IsNotConnected() const; /* -------------------------------------------------------------------------------------------- * See whether this session is connected to a server or not. @@ -94,16 +104,6 @@ protected: return (m_Session && irc_is_connected(m_Session)); } - /* -------------------------------------------------------------------------------------------- - * See whether this session is connected to a server and throw an error if not. - */ - bool ConnectedThrow() const; - - /* -------------------------------------------------------------------------------------------- - * See whether this session is NOT! connected to a server and throw an error if it is. - */ - bool NotConnected() const; - /* -------------------------------------------------------------------------------------------- * Validate a session instance used by an event and log an error if it's invalid. */ @@ -218,10 +218,7 @@ public: /* -------------------------------------------------------------------------------------------- * Used by the script engine to retrieve the name from instances of this type. */ - CSStr Typename() const - { - return _SC("SqIrcSession"); - } + static SQInteger Typename(HSQUIRRELVM vm); /* -------------------------------------------------------------------------------------------- * See whether this session is valid. @@ -260,8 +257,10 @@ public: */ void SetData(Object & data) { - if (Validate()) - m_Data = data; + // Validate the handle + Validate(); + // Perform the requested operation + m_Data = data; } /* -------------------------------------------------------------------------------------------- @@ -277,8 +276,12 @@ public: */ void SetServer(CSStr server) { - if (Validate() && NotConnected()) - m_Server.assign(server); + // Validate the handle + Validate(); + // Make sure we are allowed to change the server + IsNotConnected(); + // Perform the requested operation + m_Server.assign(server); } /* -------------------------------------------------------------------------------------------- @@ -293,9 +296,12 @@ public: * Modify the account password. */ void SetPassword(CSStr passwd) - { - if (Validate() && NotConnected()) - m_Passwd.assign(passwd); + { // Validate the handle + Validate(); + // Make sure we are allowed to change the server + IsNotConnected(); + // Perform the requested operation + m_Passwd.assign(passwd); } /* -------------------------------------------------------------------------------------------- @@ -324,8 +330,12 @@ public: */ void SetUser(CSStr user) { - if (Validate() && NotConnected()) - m_User.assign(user); + // Validate the handle + Validate(); + // Make sure we are allowed to change the server + IsNotConnected(); + // Perform the requested operation + m_User.assign(user); } /* -------------------------------------------------------------------------------------------- @@ -341,8 +351,12 @@ public: */ void SetName(CSStr name) { - if (Validate() && NotConnected()) - m_Name.assign(name); + // Validate the handle + Validate(); + // Make sure we are allowed to change the server + IsNotConnected(); + // Perform the requested operation + m_Name.assign(name); } /* -------------------------------------------------------------------------------------------- @@ -547,9 +561,10 @@ public: */ Int32 CmdJoin(CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_join(m_Session, channel, NULL); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_join(m_Session, channel, NULL); } /* -------------------------------------------------------------------------------------------- @@ -557,9 +572,10 @@ public: */ Int32 CmdJoin(CSStr channel, CSStr key) { - if (ConnectedThrow()) - return irc_cmd_join(m_Session, channel, key); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_join(m_Session, channel, key); } /* -------------------------------------------------------------------------------------------- @@ -567,9 +583,10 @@ public: */ Int32 CmdPart(CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_part(m_Session, channel); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_part(m_Session, channel); } /* -------------------------------------------------------------------------------------------- @@ -577,9 +594,10 @@ public: */ Int32 CmdInvite(CSStr nick, CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_invite(m_Session, nick, channel); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_invite(m_Session, nick, channel); } /* -------------------------------------------------------------------------------------------- @@ -587,9 +605,10 @@ public: */ Int32 CmdNames(CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_names(m_Session, channel); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_names(m_Session, channel); } /* -------------------------------------------------------------------------------------------- @@ -597,9 +616,10 @@ public: */ Int32 CmdList() { - if (ConnectedThrow()) - return irc_cmd_list(m_Session, NULL); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_list(m_Session, NULL); } /* -------------------------------------------------------------------------------------------- @@ -607,9 +627,10 @@ public: */ Int32 CmdList(CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_list(m_Session, channel); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_list(m_Session, channel); } /* -------------------------------------------------------------------------------------------- @@ -617,9 +638,10 @@ public: */ Int32 CmdTopic(CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_topic(m_Session, channel, NULL); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_topic(m_Session, channel, NULL); } /* -------------------------------------------------------------------------------------------- @@ -627,9 +649,10 @@ public: */ Int32 CmdTopic(CSStr channel, CSStr topic) { - if (ConnectedThrow()) - return irc_cmd_topic(m_Session, channel, topic); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_topic(m_Session, channel, topic); } /* -------------------------------------------------------------------------------------------- @@ -637,9 +660,10 @@ public: */ Int32 CmdChannelMode(CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_channel_mode(m_Session, channel, NULL); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_channel_mode(m_Session, channel, NULL); } /* -------------------------------------------------------------------------------------------- @@ -647,9 +671,10 @@ public: */ Int32 CmdChannelMode(CSStr channel, CSStr mode) { - if (ConnectedThrow()) - return irc_cmd_channel_mode(m_Session, channel, mode); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_channel_mode(m_Session, channel, mode); } /* -------------------------------------------------------------------------------------------- @@ -657,9 +682,10 @@ public: */ Int32 CmdUserMode() { - if (ConnectedThrow()) - return irc_cmd_user_mode(m_Session, NULL); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_user_mode(m_Session, NULL); } /* -------------------------------------------------------------------------------------------- @@ -667,9 +693,10 @@ public: */ Int32 CmdUserMode(CSStr mode) { - if (ConnectedThrow()) - return irc_cmd_user_mode(m_Session, mode); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_user_mode(m_Session, mode); } /* -------------------------------------------------------------------------------------------- @@ -677,9 +704,10 @@ public: */ Int32 CmdKick(CSStr nick, CSStr channel) { - if (ConnectedThrow()) - return irc_cmd_kick(m_Session, nick, channel, NULL); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_kick(m_Session, nick, channel, NULL); } /* -------------------------------------------------------------------------------------------- @@ -687,9 +715,10 @@ public: */ Int32 CmdKick(CSStr nick, CSStr channel, CSStr reason) { - if (ConnectedThrow()) - return irc_cmd_kick(m_Session, nick, channel, reason); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_kick(m_Session, nick, channel, reason); } /* -------------------------------------------------------------------------------------------- @@ -697,9 +726,10 @@ public: */ Int32 CmdMsg(CSStr nch, CSStr text) { - if (ConnectedThrow()) - return irc_cmd_msg(m_Session, nch, text); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_msg(m_Session, nch, text); } /* -------------------------------------------------------------------------------------------- @@ -707,9 +737,10 @@ public: */ Int32 CmdMe(CSStr nch, CSStr text) { - if (ConnectedThrow()) - return irc_cmd_me(m_Session, nch, text); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_me(m_Session, nch, text); } /* -------------------------------------------------------------------------------------------- @@ -717,9 +748,10 @@ public: */ Int32 CmdNotice(CSStr nch, CSStr text) { - if (ConnectedThrow()) - return irc_cmd_notice(m_Session, nch, text); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_notice(m_Session, nch, text); } /* -------------------------------------------------------------------------------------------- @@ -727,9 +759,10 @@ public: */ Int32 CmdCtcpRequest(CSStr nick, CSStr request) { - if (ConnectedThrow()) - return irc_cmd_ctcp_request(m_Session, nick, request); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_ctcp_request(m_Session, nick, request); } /* -------------------------------------------------------------------------------------------- @@ -737,9 +770,10 @@ public: */ Int32 CmdCtcpReply(CSStr nick, CSStr reply) { - if (ConnectedThrow()) - return irc_cmd_ctcp_reply(m_Session, nick, reply); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_ctcp_reply(m_Session, nick, reply); } /* -------------------------------------------------------------------------------------------- @@ -752,9 +786,10 @@ public: */ Int32 CmdWhois(CSStr nick) { - if (ConnectedThrow()) - return irc_cmd_whois(m_Session, nick); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_whois(m_Session, nick); } /* -------------------------------------------------------------------------------------------- @@ -762,9 +797,10 @@ public: */ Int32 CmdQuit() { - if (ConnectedThrow()) - return irc_cmd_quit(m_Session, NULL); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_quit(m_Session, NULL); } /* -------------------------------------------------------------------------------------------- @@ -772,9 +808,10 @@ public: */ Int32 CmdQuit(CSStr reason) { - if (ConnectedThrow()) - return irc_cmd_quit(m_Session, reason); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_cmd_quit(m_Session, reason); } /* -------------------------------------------------------------------------------------------- @@ -782,9 +819,10 @@ public: */ Int32 SendRaw(CSStr str) { - if (ConnectedThrow()) - return irc_send_raw(m_Session, str); - return -1; + // Validate the connection status + ValidateConnection(); + // Send the specified command and return the result + return irc_send_raw(m_Session, str); } /* -------------------------------------------------------------------------------------------- @@ -793,9 +831,10 @@ public: */ Int32 DestroyDcc(Uint32 dccid) { - if (ConnectedThrow()) - return irc_dcc_destroy(m_Session, dccid); - return -1; + // Validate the connection status + ValidateConnection(); + // Perform the requested operation and return the result + return irc_dcc_destroy(m_Session, dccid); } /* -------------------------------------------------------------------------------------------- @@ -803,8 +842,10 @@ public: */ void SetCtcpVersion(CSStr version) { - if (ConnectedThrow()) - irc_set_ctcp_version(m_Session, version); + // Validate the connection status + ValidateConnection(); + // Perform the requested operation + irc_set_ctcp_version(m_Session, version); } /* -------------------------------------------------------------------------------------------- @@ -812,9 +853,10 @@ public: */ Int32 GetErrNo() { - if (Validate()) - return irc_errno(m_Session); - return -1; + // Validate the handle + Validate(); + // Return the requested information + return irc_errno(m_Session); } /* -------------------------------------------------------------------------------------------- @@ -822,9 +864,10 @@ public: */ CSStr GetErrStr() { - if (Validate()) - return irc_strerror(irc_errno(m_Session)); - return _SC(""); + // Validate the handle + Validate(); + // Return the requested information + return irc_strerror(irc_errno(m_Session)); } /* -------------------------------------------------------------------------------------------- @@ -832,8 +875,10 @@ public: */ void SetOption(Uint32 option) { - if (Validate()) - return irc_option_set(m_Session, option); + // Validate the handle + Validate(); + // Perform the requested operation and return the result + return irc_option_set(m_Session, option); } /* -------------------------------------------------------------------------------------------- @@ -841,8 +886,10 @@ public: */ void ResetOption(Uint32 option) { - if (Validate()) - return irc_option_set(m_Session, option); + // Validate the handle + Validate(); + // Perform the requested operation and return the result + return irc_option_set(m_Session, option); } /* --------------------------------------------------------------------------------------------