diff --git a/exceptions.hpp b/exceptions.hpp index fe2124f..436ca7d 100644 --- a/exceptions.hpp +++ b/exceptions.hpp @@ -1,5 +1,7 @@ #ifndef __EXCEPTIONS_HPP #define __EXCEPTIONS_HPP +#include +#include #include @@ -14,8 +16,12 @@ struct DesyncError : public std::exception { const char *what() const throw() { return "Server has desynced!!!"; } - DesyncError() { - std::cout << "DESCONACCREKO" << std::endl; - } +}; + +struct InsufficientArgsError : public ParseError { + using ParseError::ParseError; + + InsufficientArgsError(std::string_view where, size_t expected, size_t given) + : ParseError::ParseError(fmt::format("In {} event: Insufficient arguments expected. Given {} but expected {}", where, given, expected)) {} }; #endif diff --git a/instance.cpp b/instance.cpp index 010aecd..72c2ab5 100644 --- a/instance.cpp +++ b/instance.cpp @@ -20,9 +20,7 @@ using namespace Utility; void Event::parse(std::string_view str) { auto split = strSplit(str, ' ', 2); // Check split size - if (split.size() < 2) { - throw ParseError("In event parser: Events are expected to have both a sender and name"); - } + argsSizeCheck("basic", split, 2); // Move values split[0] = {split[0].data()+1, split[0].size()-1}; // Erase leading ':' auto id_len = split[0].size(); @@ -113,9 +111,7 @@ void ModeSet::parse(std::string_view in, NetworkInfo &netInfo) { void User::parse_euid(const Event& event, NetworkInfo& netInfo) { this->server = std::get(event.sender.id); // Check size - if (event.args.size() < 10) { - throw ParseError("In euid parser: This euid event does not have enough arguments"); - } + argsSizeCheck("EUID", event.args, 10); // Move values nick = event.args[0]; hops = std::stoull(std::string(event.args[1])); @@ -140,9 +136,7 @@ void User::removeChannel(const u_Channel& channel) { void Channel::parse_sjoin(const Event& event, Cache& cache, NetworkInfo& netInfo) { this->server = std::get(event.sender.id); // Check size - if (event.args.size() < 3) { - throw ParseError("In euid parser: This euid event does not have enough arguments"); - } + argsSizeCheck("SJOIN", event.args, 3); // Move values name = std::move(event.args[1]); mode.parse(event.args[2], netInfo); @@ -401,15 +395,11 @@ async::result Instance::process(Event event) { res->get()->umode.parse(event.text, netInfo); } else if (event.name == "ENCAP") { // Get args - if (event.args.size() < 3) { - throw ParseError("In encap event parser: at least * and encap name need to be passed"); - } + argsSizeCheck("ENCAP", event.args, 3); if (event.args[1] == "SU") { // User logged in // Check args - if (event.args.size() < 5) { - throw ParseError("In encap su event parser: this encap requires UID as first argument and optionally login name as second one"); - } + argsSizeCheck("ENCAP (SU)", event.args, 5); // Find user in cache auto res = cache.find_user_by_uid(event.args[2]); if (res == cache.users.end()) { @@ -447,10 +437,7 @@ async::result Instance::process(Event event) { res->get()->topic = event.text; } else if (event.name == "JOIN") { // User joined existing channel - // Split args - if (event.args.size() < 3) { - throw ParseError("In join event parser: join even did not receive enough arguments (expected 3)"); - } + argsSizeCheck("JOIN", event.args, 3); // Get channel from cache auto c_res = cache.find_channel_by_name(event.args[1]); if (c_res == cache.channels.end()) { @@ -483,12 +470,10 @@ async::result Instance::process(Event event) { u_res->get()->removeChannel(*c_res); } else if (event.name == "TMODE" || event.name == "BMASK") { // Channel modes changed + argsSizeCheck(event.name, event.args, 3); // Split args std::string_view modes, channelName; { - if (event.args.size() < 3) { - throw ParseError("In MODE/BMASK event parser: did not receive enough arguments (expected 3)"); - } channelName = event.args[1]; modes = event.args[2]; } diff --git a/utility.cpp b/utility.cpp index 7c52bec..fecc697 100644 --- a/utility.cpp +++ b/utility.cpp @@ -1,6 +1,7 @@ #include "utility.hpp" #include "uid.hpp" #include "instance.hpp" +#include "exceptions.hpp" #include #include @@ -31,6 +32,12 @@ std::tuple colonSplit(std::string_view s) { // Split there return {s.substr(0, colonPos), s.substr(colonPos+2, s.size()-1)}; } + +void argsSizeCheck(std::string_view where, std::vector args, size_t expected) { + if (args.size() < expected) { + throw InsufficientArgsError(where, expected, args.size()); + } +} } static const char UUIDChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; diff --git a/utility.hpp b/utility.hpp index c027042..0b9260c 100644 --- a/utility.hpp +++ b/utility.hpp @@ -12,5 +12,6 @@ constexpr size_t strSplitInf = 0; std::vector strSplit(std::string_view s, char delimiter, size_t times = strSplitInf); std::tuple colonSplit(std::string_view s); +void argsSizeCheck(std::string_view where, std::vector args, size_t expected); } #endif