From 90165eead3d3bdbaf7403eb947a41b4a7513b161 Mon Sep 17 00:00:00 2001 From: Jessica James Date: Mon, 29 Nov 2021 00:44:25 -0600 Subject: [PATCH] Replaced findi usage with jessilib; removed some other methods; way more code adjustment than anticipated --- src/common/Command.cpp | 16 +- src/common/Config.cpp | 73 ++++--- src/common/GenericCommand.cpp | 3 +- src/common/INIConfig.cpp | 48 ++--- src/common/IRC_Client.cpp | 120 +++++------ src/common/SecureSocket.cpp | 10 +- src/include/Jupiter/Command.h | 6 +- src/include/Jupiter/Config.h | 42 ++-- src/include/Jupiter/DataBuffer_Imp.h | 4 +- src/include/Jupiter/HTTP_QueryString.h | 15 -- src/include/Jupiter/IRC_Client.h | 24 +-- src/include/Jupiter/Readable_String.h | 59 +----- src/include/Jupiter/Readable_String_Imp.h | 238 +--------------------- src/include/Jupiter/SecureSocket.h | 4 +- src/include/Jupiter/String.hpp | 15 ++ src/include/Jupiter/String_Type.h | 2 + src/include/Jupiter/String_Type_Imp.h | 16 +- src/jessilib | 2 +- 18 files changed, 231 insertions(+), 466 deletions(-) diff --git a/src/common/Command.cpp b/src/common/Command.cpp index 8ed6c89..904bf74 100644 --- a/src/common/Command.cpp +++ b/src/common/Command.cpp @@ -17,11 +17,12 @@ */ #include +#include "jessilib/unicode.hpp" #include "Command.h" #include "String.hpp" struct Jupiter::Command::Data { // TODO: remove pimpl - std::vector triggers; + std::vector triggers; }; Jupiter::Command::Command() { @@ -40,11 +41,11 @@ Jupiter::Command::~Command() { // Command Functions -void Jupiter::Command::addTrigger(const Jupiter::ReadableString &trigger) { +void Jupiter::Command::addTrigger(std::string_view trigger) { m_data->triggers.emplace_back(trigger); } -const Jupiter::ReadableString &Jupiter::Command::getTrigger(size_t index) const { +std::string_view Jupiter::Command::getTrigger(size_t index) const { return m_data->triggers[index]; } @@ -52,8 +53,11 @@ size_t Jupiter::Command::getTriggerCount() const { return m_data->triggers.size(); } -bool Jupiter::Command::matches(const Jupiter::ReadableString &in_trigger) const { - for (const auto& trigger : m_data->triggers) - if (trigger.equalsi(in_trigger)) return true; +bool Jupiter::Command::matches(std::string_view in_trigger) const { + for (const auto& trigger : m_data->triggers) { + if (jessilib::equalsi(trigger, in_trigger)) { + return true; + } + } return false; } \ No newline at end of file diff --git a/src/common/Config.cpp b/src/common/Config.cpp index 283a6f3..6248df5 100644 --- a/src/common/Config.cpp +++ b/src/common/Config.cpp @@ -29,9 +29,9 @@ Jupiter::Config& Jupiter::Config::operator=(const Config& in_config) { return *this; } -const Jupiter::ReadableString &Jupiter::Config::get(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_default_value) const +std::string_view Jupiter::Config::get(std::string_view in_key, std::string_view in_default_value) const { - auto value = m_table.find(in_key); + auto value = m_table.find(JUPITER_WRAP_CONFIG_KEY(in_key)); if (value != m_table.end()) { return value->second; } @@ -39,10 +39,10 @@ const Jupiter::ReadableString &Jupiter::Config::get(const Jupiter::ReadableStrin return in_default_value; } -Jupiter::Config *Jupiter::Config::getSection(const Jupiter::ReadableString &in_key) const +Jupiter::Config *Jupiter::Config::getSection(std::string_view in_key) const { if (m_sections != nullptr) { - auto section = m_sections->find(in_key); + auto section = m_sections->find(JUPITER_WRAP_CONFIG_KEY(in_key)); if (section != m_sections->end()) { return §ion->second; } @@ -51,56 +51,69 @@ Jupiter::Config *Jupiter::Config::getSection(const Jupiter::ReadableString &in_k return nullptr; } -Jupiter::Config &Jupiter::Config::getSectionReference(const Jupiter::ReadableString &in_key) +Jupiter::Config &Jupiter::Config::getSectionReference(std::string_view in_key) { if (m_sections == nullptr) { m_sections = std::make_unique(); } - Config& section = (*m_sections)[in_key]; + auto section = m_sections->find(JUPITER_WRAP_CONFIG_KEY(in_key)); + if (section == m_sections->end()) { + // for some reason msvc doesn't like emplace + section = m_sections->try_emplace(static_cast(in_key)).first; + } - if (section.m_name.empty()) { - section.m_name = static_cast(in_key); + if (section->second.m_name.empty()) { + section->second.m_name = in_key; } - return section; + return section->second; } -bool Jupiter::Config::set(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_value) -{ - return m_table.insert_or_assign(in_key, in_value).second; +bool Jupiter::Config::set(std::string_view in_key, std::string in_value) { + return m_table.insert_or_assign(static_cast(in_key), std::move(in_value)).second; } -bool Jupiter::Config::remove(const Jupiter::ReadableString &in_key) -{ - return m_table.erase(in_key) > 0; +bool Jupiter::Config::remove(std::string_view in_key) { + auto value = m_table.find(JUPITER_WRAP_CONFIG_KEY(in_key)); + if (value == m_table.end()) { + return false; + } + + m_table.erase(value); + return true; } -bool Jupiter::Config::removeSection(const Jupiter::ReadableString &in_key) -{ - return m_sections != nullptr && m_sections->erase(in_key) > 0; +bool Jupiter::Config::removeSection(std::string_view in_key) { + if (m_sections == nullptr) { + return false; + } + + auto section = m_sections->find(JUPITER_WRAP_CONFIG_KEY(in_key)); + if (section == m_sections->end()) { + return false; + } + + m_sections->erase(section); + return true; } -const std::string &Jupiter::Config::getName() const -{ +const std::string &Jupiter::Config::getName() const { return m_name; } -void Jupiter::Config::erase() -{ +void Jupiter::Config::erase() { m_table.clear(); m_sections = nullptr; } -bool Jupiter::Config::read(const char *in_filename) -{ +bool Jupiter::Config::read(const char *in_filename) { m_name = in_filename; return this->read_internal(in_filename); } -bool Jupiter::Config::read(const std::string_view& in_filename) -{ - m_name = static_cast(in_filename); +bool Jupiter::Config::read(std::string_view in_filename) { + m_name = in_filename; return this->read_internal(m_name.c_str()); } @@ -114,7 +127,7 @@ bool Jupiter::Config::write(const char *in_filename) return this->write_internal(in_filename); } -bool Jupiter::Config::write(const Jupiter::ReadableString &in_filename) +bool Jupiter::Config::write(std::string_view in_filename) { return this->write(static_cast(in_filename).c_str()); } @@ -131,7 +144,7 @@ bool Jupiter::Config::reload(const char *in_filename) return this->read(in_filename); } -bool Jupiter::Config::reload(const Jupiter::ReadableString &in_filename) +bool Jupiter::Config::reload(std::string_view in_filename) { this->erase(); return this->read(in_filename); @@ -146,7 +159,7 @@ const Jupiter::Config::SectionHashTable &Jupiter::Config::getSections() const { } /** Operators */ -Jupiter::Config &Jupiter::Config::operator[](const Jupiter::ReadableString &in_key) +Jupiter::Config &Jupiter::Config::operator[](std::string_view in_key) { return this->getSectionReference(in_key); } diff --git a/src/common/GenericCommand.cpp b/src/common/GenericCommand.cpp index 10fcfed..07c7ee4 100644 --- a/src/common/GenericCommand.cpp +++ b/src/common/GenericCommand.cpp @@ -227,7 +227,8 @@ void Jupiter::GenericCommandNamespace::updateHelp() { m_should_update_help = false; std::vector commands = getCommands(); - Jupiter::StringL tmp_help(commands.size() * 8); + std::string tmp_help; + tmp_help.reserve(commands.size() * 8); for (const auto& command : commands) { tmp_help += command->getTrigger(); diff --git a/src/common/INIConfig.cpp b/src/common/INIConfig.cpp index 894cfb9..3f28e66 100644 --- a/src/common/INIConfig.cpp +++ b/src/common/INIConfig.cpp @@ -53,9 +53,10 @@ void Jupiter::INIConfig::write_helper(FILE *in_file, const Jupiter::Config *in_s fputc('\t', in_file); // Write entry - table_entry.first.print(in_file); + fwrite(table_entry.first.data(), sizeof(char), table_entry.first.size(), in_file); fputs(" = ", in_file); - table_entry.second.println(in_file); + fwrite(table_entry.second.data(), sizeof(char), table_entry.second.size(), in_file); + fputs("\r\n", in_file); } // Write subsections @@ -80,16 +81,15 @@ bool Jupiter::INIConfig::write_internal(const char *in_filename) return true; } -bool Jupiter::INIConfig::read_internal(const char *in_filename) -{ - Jupiter::ReferenceString line; +bool Jupiter::INIConfig::read_internal(const char *in_filename) { + std::string_view line; std::stack section_stack; section_stack.push(this); auto process_line = [&line, §ion_stack]() { - const char *itr = line.ptr(); + const char *itr = line.data(); const char *end = itr + line.size(); // guaranteed to be greater than itr // Shift to right of spaces @@ -98,7 +98,7 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) if (++itr == end) return; // Line is purely whitespace - line.shiftRight(itr - line.ptr()); + line.remove_prefix(itr - line.data()); if (*itr == ';') return; // Comment @@ -112,7 +112,7 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) for (++itr; itr != end && *itr == '['; ++itr) ++depth; - line.shiftRight(itr - line.ptr()); + line.remove_prefix(itr - line.data()); while (end != itr) { @@ -124,7 +124,7 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) } } - line.set(itr, end - itr); + line = std::string_view(itr, end - itr); // Add section to stack; pop sections or push blanks as necessary @@ -132,9 +132,9 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) section_stack.pop(); while (depth > section_stack.size()) - section_stack.push(std::addressof(section_stack.top()->getSectionReference(Jupiter::ReferenceString::empty))); + section_stack.push(std::addressof(section_stack.top()->getSectionReference({}))); - section_stack.push(§ion_stack.top()->getSectionReference(line)); + section_stack.push(§ion_stack.top()->getSectionReference(static_cast(line))); } else { @@ -146,7 +146,7 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) // end now points to a non-space character within the bounds ++end; - line.truncate(itr + line.size() - end); + line.remove_suffix(itr + line.size() - end); // Parse key (can be empty) @@ -154,9 +154,9 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) if (++itr == end) return; // Error: no assignment exists; ignore line - Jupiter::ReferenceString key; + std::string_view key; - if (itr != line.ptr()) + if (itr != line.data()) { // Truncate spaces from key; a non-space character is guaranteed end = itr - 1; @@ -164,9 +164,9 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) while (isspace(*end)) --end; - key = line.substring(size_t{ 0 }, end + 1 - line.ptr()); + key = line.substr(size_t{ 0 }, end + 1 - line.data()); - end = line.ptr() + line.size(); + end = line.data() + line.size(); } // Parse value (can be empty) @@ -177,13 +177,13 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) while (isspace(*itr)) ++itr; - line.shiftRight(itr - line.ptr()); + line.remove_prefix(itr - line.data()); } else - line = Jupiter::ReferenceString::empty; + line = std::string_view{}; // Add entry to current table on stack - section_stack.top()->set(key, line); + section_stack.top()->set(KeyType{key}, static_cast(line)); } }; @@ -214,7 +214,7 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) end = itr + buffer.size(); // Reset line - line.set(buffer.ptr(), 0); + line = std::string_view(buffer.ptr(), 0); // Parse buffer for lines while (itr != end) @@ -223,8 +223,8 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) if (*itr == '\n' || *itr == '\r') { // Process line - line.set(buffer.ptr(), itr - buffer.ptr()); - if (line.isNotEmpty()) + line = std::string_view(buffer.ptr(), itr - buffer.ptr()); + if (!line.empty()) process_line(); // Keep iterating until next non-newline character @@ -253,8 +253,8 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) } // Process data remaining in buffer as a line - line.set(buffer.ptr(), buffer.size()); - if (line.isNotEmpty()) + line = std::string_view(buffer.ptr(), buffer.size()); + if (!line.empty()) process_line(); // File has been successfully read, or an error occurred. diff --git a/src/common/IRC_Client.cpp b/src/common/IRC_Client.cpp index cbe5bd1..726d08e 100644 --- a/src/common/IRC_Client.cpp +++ b/src/common/IRC_Client.cpp @@ -20,6 +20,7 @@ #include #include #include "jessilib/split.hpp" +#include "jessilib/unicode.hpp" #include "Jupiter.h" #include "Functions.h" #include "IRC_Client.h" @@ -38,6 +39,7 @@ #endif // _WIN32 using namespace Jupiter::literals; +using namespace std::literals; Jupiter::IRC::Client::Client(Jupiter::Config *in_primary_section, Jupiter::Config *in_secondary_section) { @@ -55,11 +57,11 @@ Jupiter::IRC::Client::Client(Jupiter::Config *in_primary_section, Jupiter::Confi m_realname = Jupiter::IRC::Client::readConfigValue("RealName"_jrs, "Jupiter IRC Client"_jrs); m_sasl_password = Jupiter::IRC::Client::readConfigValue("SASL.Password"_jrs); - if (m_sasl_password.isEmpty()) + if (m_sasl_password.empty()) m_sasl_password = Jupiter::IRC::Client::readConfigValue("SASL.Pass"_jrs); m_sasl_account = Jupiter::IRC::Client::readConfigValue("SASL.Account"_jrs); - if (m_sasl_account.isEmpty()) + if (m_sasl_account.empty()) m_sasl_account = m_nickname; m_auto_part_message = Jupiter::IRC::Client::readConfigValue("AutoPartMessage"_jrs); @@ -67,13 +69,13 @@ Jupiter::IRC::Client::Client(Jupiter::Config *in_primary_section, Jupiter::Confi m_ssl = Jupiter::IRC::Client::readConfigBool("SSL"_jrs); m_ssl_certificate = Jupiter::IRC::Client::readConfigValue("Certificate"_jrs); m_ssl_key = Jupiter::IRC::Client::readConfigValue("Key"_jrs); - if (m_ssl_certificate.isEmpty()) + if (m_ssl_certificate.empty()) { m_ssl_certificate = Jupiter::IRC::Client::readConfigValue("Cert"_jrs); - if (m_ssl_certificate.isEmpty()) + if (m_ssl_certificate.empty()) m_ssl_certificate = m_ssl_key; } - if (m_ssl_key.isEmpty()) + if (m_ssl_key.empty()) m_ssl_key = m_ssl_certificate; m_join_on_kick = Jupiter::IRC::Client::readConfigBool("AutoJoinOnKick"_jrs); @@ -93,7 +95,7 @@ Jupiter::IRC::Client::Client(Jupiter::Config *in_primary_section, Jupiter::Confi if (m_ssl) { Jupiter::SecureTCPSocket *t = new Jupiter::SecureTCPSocket(); - if (m_ssl_certificate.isNotEmpty()) + if (!m_ssl_certificate.empty()) t->setCertificate(m_ssl_certificate, m_ssl_key); m_socket.reset(t); @@ -253,12 +255,12 @@ const Jupiter::ReadableString &Jupiter::IRC::Client::getPrefixModes() const return m_prefix_modes; } -const Jupiter::ReadableString &Jupiter::IRC::Client::getNickname() const +std::string_view Jupiter::IRC::Client::getNickname() const { return m_nickname; } -const Jupiter::ReadableString &Jupiter::IRC::Client::getRealname() const +std::string_view Jupiter::IRC::Client::getRealname() const { return m_realname; } @@ -396,9 +398,9 @@ void Jupiter::IRC::Client::setAutoReconnect(int val) m_max_reconnect_attempts = val; } -void Jupiter::IRC::Client::joinChannel(const Jupiter::ReadableString &in_channel) +void Jupiter::IRC::Client::joinChannel(std::string_view in_channel) { - m_socket->send(Jupiter::StringS::Format("JOIN %.*s" ENDL, in_channel.size(), in_channel.ptr())); + m_socket->send(Jupiter::StringS::Format("JOIN %.*s" ENDL, in_channel.size(), in_channel.data())); } void Jupiter::IRC::Client::joinChannel(const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &in_password) @@ -413,9 +415,9 @@ void Jupiter::IRC::Client::partChannel(const Jupiter::ReadableString &in_channel m_channels[in_channel].setType(-2); } -void Jupiter::IRC::Client::partChannel(const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &in_message) +void Jupiter::IRC::Client::partChannel(const Jupiter::ReadableString &in_channel, std::string_view in_message) { - m_socket->send(Jupiter::StringS::Format("PART %.*s :%.*s" ENDL, in_channel.size(), in_channel.ptr(), in_message.size(), in_message.ptr())); + m_socket->send(Jupiter::StringS::Format("PART %.*s :%.*s" ENDL, in_channel.size(), in_channel.ptr(), in_message.size(), in_message.data())); m_channels[in_channel].setType(-2); } @@ -558,7 +560,7 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { m_socket.reset(t); m_ssl = true; // toggle blocking to prevent error - if (m_ssl_certificate.isNotEmpty()) + if (!m_ssl_certificate.empty()) t->setCertificate(m_ssl_certificate, m_ssl_key); bool goodSSL; @@ -596,7 +598,7 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { if (w2.equalsi("CAP")) { Jupiter::ReferenceString w4 = Jupiter::ReferenceString::getWord(line, 3, WHITESPACE); - if (w4.equals("LS")) + if (w4 == "LS"sv) { Jupiter::ReferenceString listParams = Jupiter::ReferenceString::gotoWord(line, 4, WHITESPACE); if (listParams[0] == ':') listParams.shiftRight(1); @@ -611,7 +613,7 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { else if (curr.equalsi("userhost-in-names")) req += "userhost-in-names "; else if (curr.equalsi("sasl")) { - if (m_sasl_password.isNotEmpty()) + if (!m_sasl_password.empty()) { req += "sasl "_jrs; sasl = true; @@ -667,19 +669,19 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { case Error::NICKNAMEINUSE: // 433 case Error::NICKCOLLISION: // 436 case Error::BANNICKCHANGE: // 437 -- Note: This conflicts with another token. - const Jupiter::ReadableString &altNick = Jupiter::IRC::Client::readConfigValue("AltNick"_jrs); - const Jupiter::ReadableString &configNick = Jupiter::IRC::Client::readConfigValue("Nick"_jrs, "Jupiter"_jrs); + std::string_view altNick = Jupiter::IRC::Client::readConfigValue("AltNick"_jrs); + std::string_view configNick = Jupiter::IRC::Client::readConfigValue("Nick"_jrs, "Jupiter"_jrs); - if (altNick.isNotEmpty() && m_nickname.equalsi(altNick)) // The alternate nick failed. + if (!altNick.empty() && jessilib::equalsi(m_nickname, altNick)) // The alternate nick failed. { m_nickname = configNick; m_nickname += "1"; m_socket->send("NICK "_jrs + m_nickname + ENDL); } - else if (m_nickname.equalsi(configNick)) // The config nick failed + else if (jessilib::equalsi(m_nickname, configNick)) // The config nick failed { - if (altNick.isEmpty()) + if (altNick.empty()) { if (erroneous_nickname) break; // If this nick is invalid, adding numbers won't help. @@ -698,8 +700,9 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { { if (m_nickname.size() > configNick.size()) { - int n = Jupiter_strtoi_nospace_s(m_nickname.ptr() + configNick.size(), m_nickname.size() - configNick.size(), 10); - m_nickname.format("%.*s%d", configNick.size(), configNick.ptr(), n + 1); + int n = Jupiter_strtoi_nospace_s(m_nickname.data() + configNick.size(), m_nickname.size() - configNick.size(), 10); + m_nickname = configNick; + m_nickname += std::to_string(n + 1); m_socket->send("NICK "_jrs + m_nickname + ENDL); } @@ -832,7 +835,7 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { Jupiter::ReferenceString message = rawmessage.substring(rawmessage.find(' ') + 1, rawmessage.find(IRC::CTCP)); if (message[message.size() - 1] == IRC::CTCP) message.truncate(1); - if (command.equals("ACTION")) + if (command == "ACTION"sv) { this->OnAction(chan, nick, message); for (auto& plugin : Jupiter::plugins) { @@ -846,14 +849,14 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { response += " :" IRCCTCP; response += command; response += ' '; - if (command.equals("PING")) response += message; - else if (command.equals("VERSION")) response += Jupiter::version; - else if (command.equals("FINGER")) response += "Oh, yeah, a little to the left."; - else if (command.equals("SOURCE")) response += "https://github.com/JAJames/Jupiter"; - else if (command.equals("USERINFO")) response += "Hey, I'm Jupiter! If you have questions, ask Agent! (GitHub: JAJames; Discord: Agent#0001)"; - else if (command.equals("CLIENTINFO")) response += "I'll tell you what I don't know: This command!"; - else if (command.equals("TIME")) response += getTime(); - else if (command.equals("ERRMSG")) response += message; + if (command == "PING"sv) response += message; + else if (command == "VERSION"sv) response += Jupiter::version; + else if (command == "FINGER"sv) response += "Oh, yeah, a little to the left."; + else if (command == "SOURCE"sv) response += "https://github.com/JAJames/Jupiter"; + else if (command == "USERINFO"sv) response += "Hey, I'm Jupiter! If you have questions, ask Agent! (GitHub: JAJames; Discord: Agent#0001)"; + else if (command == "CLIENTINFO"sv) response += "I'll tell you what I don't know: This command!"; + else if (command == "TIME"sv) response += getTime(); + else if (command == "ERRMSG"sv) response += message; else { response = "NOTICE "; @@ -938,7 +941,7 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { auto channel = getChannel(chan); - if (m_nickname.equalsi(nick)) + if (jessilib::equalsi(m_nickname, nick)) { // TODO: Optimize by simply wiping channel data, rather than removing and re-adding if (channel != nullptr) @@ -950,7 +953,7 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { if (channel->getType() < 0) { - if (m_auto_part_message.isNotEmpty()) + if (!m_auto_part_message.empty()) Jupiter::IRC::Client::partChannel(chan, m_auto_part_message); else Jupiter::IRC::Client::partChannel(chan); @@ -1179,16 +1182,16 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { } else { - if (w1.equals("PING")) + if (w1 == "PING"sv) { m_socket->send(Jupiter::StringS::Format("PONG %.*s" ENDL, w2.size(), w2.ptr())); } - else if (w1.equals("NICK")) + else if (w1 == "NICK"sv) { if (w2.isNotEmpty()) m_nickname = w2; } - else if (w1.equals("ERROR")) + else if (w1 == "ERROR"sv) { Jupiter::ReferenceString reason = Jupiter::ReferenceString::substring(line, line.find(':') + 1); this->OnError(reason); @@ -1197,9 +1200,9 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { } Jupiter::IRC::Client::disconnect(); } - else if (w1.equals("AUTHENTICATE")) + else if (w1 == "AUTHENTICATE"sv) { - if (m_sasl_password.isNotEmpty()) + if (!m_sasl_password.empty()) { Jupiter::StringS auth_str = m_nickname + '\0' + m_sasl_account + '\0' + m_sasl_password; @@ -1230,8 +1233,8 @@ int Jupiter::IRC::Client::process_line(std::string_view in_line) { bool Jupiter::IRC::Client::connect() { - const Jupiter::ReadableString &clientAddress = Jupiter::IRC::Client::readConfigValue("ClientAddress"_jrs); - if (m_socket->connect(m_server_hostname.c_str(), m_server_port, clientAddress.isEmpty() ? nullptr : static_cast(clientAddress).c_str(), (unsigned short)Jupiter::IRC::Client::readConfigLong("ClientPort"_jrs)) == false) + std::string_view clientAddress = Jupiter::IRC::Client::readConfigValue("ClientAddress"_jrs); + if (m_socket->connect(m_server_hostname.c_str(), m_server_port, clientAddress.empty() ? nullptr : static_cast(clientAddress).c_str(), (unsigned short)Jupiter::IRC::Client::readConfigLong("ClientPort"_jrs)) == false) return false; m_socket->setBlocking(false); @@ -1260,7 +1263,7 @@ void Jupiter::IRC::Client::disconnect(bool stayDead) if (m_ssl) { Jupiter::SecureTCPSocket *t = new Jupiter::SecureTCPSocket(std::move(*m_socket)); - if (m_ssl_certificate.isNotEmpty()) + if (!m_ssl_certificate.empty()) t->setCertificate(m_ssl_certificate, m_ssl_key); m_socket.reset(t); @@ -1365,13 +1368,12 @@ int Jupiter::IRC::Client::think() return handle_error(tmp); } -const Jupiter::ReadableString &Jupiter::IRC::Client::readConfigValue(const Jupiter::ReadableString &key, const Jupiter::ReadableString &defaultValue) const +std::string_view Jupiter::IRC::Client::readConfigValue(const Jupiter::ReadableString &key, const Jupiter::ReadableString &defaultValue) const { if (m_primary_section != nullptr) { - const Jupiter::ReadableString &val = m_primary_section->get(key); - - if (val.isNotEmpty()) + std::string_view val = m_primary_section->get(key); + if (!val.empty()) return val; } @@ -1385,10 +1387,10 @@ bool Jupiter::IRC::Client::readConfigBool(const Jupiter::ReadableString &key, bo { if (m_primary_section != nullptr) { - const Jupiter::ReadableString &val = m_primary_section->get(key); + std::string_view val = m_primary_section->get(key); - if (val.isNotEmpty()) - return val.asBool(); + if (!val.empty()) + return Jupiter::ReferenceString{val}.asBool(); } if (m_secondary_section != nullptr) @@ -1401,10 +1403,10 @@ int Jupiter::IRC::Client::readConfigInt(const Jupiter::ReadableString &key, int { if (m_primary_section != nullptr) { - const Jupiter::ReadableString &val = m_primary_section->get(key); + std::string_view val = m_primary_section->get(key); - if (val.isNotEmpty()) - return val.asInt(); + if (!val.empty()) + return Jupiter::ReferenceString{val}.asInt(); } if (m_secondary_section != nullptr) @@ -1417,10 +1419,10 @@ long Jupiter::IRC::Client::readConfigLong(const Jupiter::ReadableString &key, lo { if (m_primary_section != nullptr) { - const Jupiter::ReadableString &val = m_primary_section->get(key); + std::string_view val = m_primary_section->get(key); - if (val.isNotEmpty()) - return val.asInt(); + if (!val.empty()) + return Jupiter::ReferenceString{val}.asInt(); } if (m_secondary_section != nullptr) @@ -1433,10 +1435,10 @@ double Jupiter::IRC::Client::readConfigDouble(const Jupiter::ReadableString &key { if (m_primary_section != nullptr) { - const Jupiter::ReadableString &val = m_primary_section->get(key); + std::string_view val = m_primary_section->get(key); - if (val.isNotEmpty()) - return val.asDouble(); + if (!val.empty()) + return Jupiter::ReferenceString{val}.asDouble(); } if (m_secondary_section != nullptr) @@ -1530,12 +1532,12 @@ bool Jupiter::IRC::Client::registerClient() const char *localHostname = Jupiter::Socket::getLocalHostname(); Jupiter::StringS messageToSend; - messageToSend.format("USER %.*s %s %.*s :%.*s" ENDL, m_nickname.size(), m_nickname.ptr(), localHostname, m_server_hostname.size(), m_server_hostname.c_str(), m_realname.size(), m_realname.ptr()); + messageToSend.format("USER %.*s %s %.*s :%.*s" ENDL, m_nickname.size(), m_nickname.data(), localHostname, m_server_hostname.size(), m_server_hostname.c_str(), m_realname.size(), m_realname.data()); if (m_socket->send(messageToSend) <= 0) result = false; - messageToSend.format("NICK %.*s" ENDL, m_nickname.size(), m_nickname.ptr()); + messageToSend.format("NICK %.*s" ENDL, m_nickname.size(), m_nickname.data()); if (m_socket->send(messageToSend) <= 0) result = false; diff --git a/src/common/SecureSocket.cpp b/src/common/SecureSocket.cpp index 0e18421..3bfc021 100644 --- a/src/common/SecureSocket.cpp +++ b/src/common/SecureSocket.cpp @@ -178,15 +178,15 @@ bool loadCertificate(SSL_CTX *context, const char *cert, const char *key) return true; } -void Jupiter::SecureSocket::setCertificate(const Jupiter::ReadableString &cert, const Jupiter::ReadableString &key) +void Jupiter::SecureSocket::setCertificate(std::string cert, std::string key) { - Jupiter::SecureSocket::SSLdata_->cert = static_cast(cert); - Jupiter::SecureSocket::SSLdata_->key = static_cast(key); + Jupiter::SecureSocket::SSLdata_->cert = std::move(cert); + Jupiter::SecureSocket::SSLdata_->key = std::move(key); } -void Jupiter::SecureSocket::setCertificate(const Jupiter::ReadableString &pem) +void Jupiter::SecureSocket::setCertificate(std::string_view pem) { - Jupiter::SecureSocket::setCertificate(pem, pem); + Jupiter::SecureSocket::setCertificate(static_cast(pem), static_cast(pem)); } bool Jupiter::SecureSocket::connect(const char *hostname, unsigned short iPort, const char *clientAddress, unsigned short clientPort) diff --git a/src/include/Jupiter/Command.h b/src/include/Jupiter/Command.h index f75ab16..0a235f2 100644 --- a/src/include/Jupiter/Command.h +++ b/src/include/Jupiter/Command.h @@ -41,7 +41,7 @@ namespace Jupiter * * @param trigger Trigger to add to the command. */ - void addTrigger(const Jupiter::ReadableString &trigger); + void addTrigger(std::string_view trigger); /** * @brief Fetches a command's specified trigger. @@ -49,7 +49,7 @@ namespace Jupiter * @param index Index of the trigger to return. * @return Trigger of the command at the specified index. */ - const Jupiter::ReadableString &getTrigger(size_t index = 0) const; + std::string_view getTrigger(size_t index = 0) const; /** * @brief Returns the number of triggers accepted by the command. @@ -65,7 +65,7 @@ namespace Jupiter * @param trigger Trigger to check against the trigger list. * @return True if a match was found, false otherwise. */ - bool matches(const Jupiter::ReadableString &trigger) const; + bool matches(std::string_view trigger) const; /** * @brief Returns a brief explanation and syntax description about a command. diff --git a/src/include/Jupiter/Config.h b/src/include/Jupiter/Config.h index 8949c5d..098b98b 100644 --- a/src/include/Jupiter/Config.h +++ b/src/include/Jupiter/Config.h @@ -46,8 +46,16 @@ namespace Jupiter { public: /** Hash_Table type for sections */ - using SectionHashTable = std::unordered_map; - using ValuesHashTable = std::unordered_map; + using SectionHashTable = std::unordered_map, std::equal_to<>>; + using ValuesHashTable = std::unordered_map, std::equal_to<>>; + +#ifdef __cpp_lib_generic_unordered_lookup + using KeyType = std::string_view; +#define JUPITER_WRAP_CONFIG_KEY(in_key) in_key +#else // We can't use std::string_view for InKeyType until GCC 11 & clang 12, and I still want to support GCC 9 + using KeyType = std::string; +#define JUPITER_WRAP_CONFIG_KEY(in_key) static_cast(in_key) +#endif // __cpp_lib_generic_unordered_lookup Config() = default; Config(const Config& in_config); @@ -62,7 +70,7 @@ namespace Jupiter * @param in_default_value Value to return if no such entry exists * @return Value of the entry if it exists, an empty string otherwise. */ - const Jupiter::ReadableString &get(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_default_value = Jupiter::ReferenceString::empty) const; + std::string_view get(std::string_view in_key, std::string_view in_default_value = std::string_view{}) const; /** * @brief Fetches the value of an entry and interprets it as another type. @@ -73,7 +81,7 @@ namespace Jupiter * @param in_default_value Value to return if no such entry exists * @return Value of the entry if it exists, 0 otherwise. */ - template T get(const Jupiter::ReadableString &in_key, T in_default_value = 0) const; + template T get(std::string_view in_key, T in_default_value = 0) const; /** * @brief Fetches a section based on its name @@ -81,7 +89,7 @@ namespace Jupiter * @param in_key Name of the section to fetch * @return Pointer to a section if it exists, nullptr otherwise */ - Config *getSection(const Jupiter::ReadableString &in_key) const; + Config *getSection(std::string_view in_key) const; /** * @brief Fetches a section based on its name @@ -90,7 +98,7 @@ namespace Jupiter * @param in_key Name of the section to fetch * @return Reference to the section */ - Config &getSectionReference(const Jupiter::ReadableString &in_key); + Config &getSectionReference(std::string_view in_key); /** * @brief Sets an entry's value in the table @@ -99,7 +107,7 @@ namespace Jupiter * @param in_value Value to write to the entry * @return True if a new entry was added, false if an entry was overwritten */ - bool set(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_value); + bool set(std::string_view in_key, std::string in_value); /** * @brief Removes an entry from the table @@ -107,7 +115,7 @@ namespace Jupiter * @param in_key Key of the entry to remove * @return True if an entry was removed, false otherwise */ - bool remove(const Jupiter::ReadableString &in_key); + bool remove(std::string_view in_key); /** * @brief Removes a section from the table @@ -115,7 +123,7 @@ namespace Jupiter * @param in_key Key of the section to remove * @return True if an entry was removed, false otherwise */ - bool removeSection(const Jupiter::ReadableString &in_key); + bool removeSection(std::string_view in_key); /** * @brief Fetches the name of this config section @@ -123,7 +131,7 @@ namespace Jupiter * * @return Name of this section */ - const std::string &getName() const; + const std::string& getName() const; /** * @brief Erases all data from this section @@ -144,7 +152,7 @@ namespace Jupiter * @param in_filename Name of the file to read from * @return True on success, false otherwise */ - bool read(const std::string_view& in_filename); + bool read(std::string_view in_filename); /** * @brief Writes config data to the last read file @@ -167,7 +175,7 @@ namespace Jupiter * @param in_filename Name of the file to write to * @return True on success, false otherwise */ - bool write(const Jupiter::ReadableString &in_filename); + bool write(std::string_view in_filename); /** * @brief Empties config data from memory and reads from the last read file @@ -190,7 +198,7 @@ namespace Jupiter * @param in_filename Name of the file to read from * @return True on success, false otherwise */ - bool reload(const Jupiter::ReadableString &in_filename); + bool reload(std::string_view in_filename); /** * @brief Fetches a reference to this config's entry table @@ -207,7 +215,7 @@ namespace Jupiter const SectionHashTable &getSections() const; /** Subscript operator */ - Config &operator[](const Jupiter::ReadableString &in_key); + Config &operator[](std::string_view in_key); /** Used for low-level string operations */ class Buffer : public Jupiter::StringL @@ -245,14 +253,14 @@ namespace Jupiter /** Template function implementations */ -template inline T Jupiter::Config::get(const Jupiter::ReadableString &in_key, T in_default_value) const +template inline T Jupiter::Config::get(std::string_view in_key, T in_default_value) const { - auto result = m_table.find(in_key); + auto result = m_table.find(JUPITER_WRAP_CONFIG_KEY(in_key)); if (result == m_table.end()) return in_default_value; - return static_cast(result->second); + return static_cast(Jupiter::ReferenceString{result->second}); } /** Re-enable warnings */ diff --git a/src/include/Jupiter/DataBuffer_Imp.h b/src/include/Jupiter/DataBuffer_Imp.h index 280ad03..0a88157 100644 --- a/src/include/Jupiter/DataBuffer_Imp.h +++ b/src/include/Jupiter/DataBuffer_Imp.h @@ -311,7 +311,7 @@ template<> struct _Jupiter_DataBuffer_partial_specialization_impl_std_stringbegin(); auto end = data->end(); while (itr != end) - buffer->push::value_type>(*itr++); + buffer->push::value_type>(*itr++); } }; @@ -322,7 +322,7 @@ template<> struct _Jupiter_DataBuffer_partial_specialization_impl_std_string r; r.reserve(size_); while (size_-- != 0) - r.push_back(Jupiter::DataBuffer::interpret_data::value_type>(head)); + r.push_back(Jupiter::DataBuffer::interpret_data::value_type>(head)); return r; } }; diff --git a/src/include/Jupiter/HTTP_QueryString.h b/src/include/Jupiter/HTTP_QueryString.h index be5d1d3..d18dc61 100644 --- a/src/include/Jupiter/HTTP_QueryString.h +++ b/src/include/Jupiter/HTTP_QueryString.h @@ -30,21 +30,6 @@ namespace Jupiter { - template - struct str_hash { - using is_transparent = std::true_type; - - // C++17 introduces a requirement that these two operators return the same values for same CharT type, but not - // any requirement that std::hash<> be able to accept both key types. This just ties them for convenience - auto operator()(std::basic_string_view in_key) const noexcept { - return std::hash>()(in_key); - } - - auto operator()(const std::basic_string& in_key) const noexcept { - return std::hash>()(in_key); - } - }; - namespace HTTP { /** diff --git a/src/include/Jupiter/IRC_Client.h b/src/include/Jupiter/IRC_Client.h index 0682ce6..1335578 100644 --- a/src/include/Jupiter/IRC_Client.h +++ b/src/include/Jupiter/IRC_Client.h @@ -495,14 +495,14 @@ namespace Jupiter * * @return String containing a nickame. */ - const Jupiter::ReadableString &getNickname() const; + std::string_view getNickname() const; /** * @brief Returns the client's real name. * * @return String containing a name. */ - const Jupiter::ReadableString &getRealname() const; + std::string_view getRealname() const; /** * @brief Returns the server's name @@ -627,7 +627,7 @@ namespace Jupiter * * @param channel Channel to join. */ - void joinChannel(const Jupiter::ReadableString &in_channel); + void joinChannel(std::string_view in_channel); /** * @brief Sends a join request with a password. @@ -650,7 +650,7 @@ namespace Jupiter * @param channel Channel to part. * @param message Reason for parting. */ - void partChannel(const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &in_message); + void partChannel(const Jupiter::ReadableString &in_channel, std::string_view in_message); /** * @brief Gets the access level of a user. @@ -732,7 +732,7 @@ namespace Jupiter * @param in_default_value Optional parameter specifying the default value to return if none is found. * @return String containing the key value if it exists, in_default_value otherwise. */ - const Jupiter::ReadableString &readConfigValue(const Jupiter::ReadableString &key, const Jupiter::ReadableString &in_default_value = Jupiter::ReferenceString::empty) const; + std::string_view readConfigValue(const Jupiter::ReadableString &key, const Jupiter::ReadableString &in_default_value = Jupiter::ReferenceString::empty) const; /** * @brief Returns a key's value as a boolean. @@ -833,11 +833,11 @@ namespace Jupiter std::string m_server_hostname; bool m_ssl; - Jupiter::StringS m_ssl_certificate; - Jupiter::StringS m_ssl_key; + std::string m_ssl_certificate; + std::string m_ssl_key; - Jupiter::StringS m_sasl_account; - Jupiter::StringS m_sasl_password; + std::string m_sasl_account; + std::string m_sasl_password; int m_connection_status; Jupiter::StringS m_primary_section_name; @@ -846,8 +846,8 @@ namespace Jupiter std::string m_log_file_name; std::string m_last_line; Jupiter::StringS m_server_name; - Jupiter::StringS m_nickname; - Jupiter::StringS m_realname; + std::string m_nickname; + std::string m_realname; Jupiter::StringS m_prefix_modes = "ov"; Jupiter::StringS m_prefixes = "@+"; @@ -861,7 +861,7 @@ namespace Jupiter ChannelTableType m_channels; bool m_join_on_kick; - Jupiter::StringS m_auto_part_message; + std::string m_auto_part_message; time_t m_reconnect_delay; time_t m_reconnect_time; int m_max_reconnect_attempts; diff --git a/src/include/Jupiter/Readable_String.h b/src/include/Jupiter/Readable_String.h index 0265465..11eb82e 100644 --- a/src/include/Jupiter/Readable_String.h +++ b/src/include/Jupiter/Readable_String.h @@ -72,14 +72,15 @@ namespace Jupiter * * @return True if the String is empty, false otherwise. */ - virtual bool isEmpty() const; + bool isEmpty() const { return size() == 0; }; + bool empty() const { return size() == 0; }; /** * @brief Checks if the String is not empty. * * @return True if the String is not empty, false otherwise. */ - virtual bool isNotEmpty() const; + virtual bool isNotEmpty() const { return !empty(); }; /** * @brief Checks if the string contains an element with the specified value. @@ -99,17 +100,6 @@ namespace Jupiter size_t find(const T &value, size_t index = 0) const; size_t find(const Readable_String &in) const; - /** - * @brief Returns the index of the first element in the string with the specified value. - * Note: Case insensitive. Returns false for any type other than char and wchar_t. - * - * @param value Value of the element to search for. - * @param index Index of the match to return (i.e: 0 returns the first match). - * @return The index of an element if one is found, INVALID_INDEX otherwise. - */ - size_t findi(const T &value, size_t index = 0) const; - size_t findi(const Readable_String &in) const; - /** * @brief Returns the number of elements of the string which match the input string. * @@ -120,32 +110,6 @@ namespace Jupiter size_t span(const T *str) const; size_t span(const T &in) const; - /** - * @brief Compares another string against the String. - * - * @param in String to compare against. - * @return 0 if the strings are equal, negative if the first mismatched character is greater in the String, or positive if it's less. - */ - int compare(const Readable_String &in) const; - int compare(const std::basic_string &in) const; - int compare(const T *in) const; - int compare(const T &in) const; - int compare(const std::nullptr_t) const; - - /** - * @brief Checks if the strings are equal. - * Note: Case sensitive. - * - * @param in String to compare against. - * @return True if the contents of the strings are equal, false otherwise. - */ - bool equals(const Readable_String &in) const; - bool equals(const std::basic_string &in) const; - bool equals(const T *in, size_t len) const; - bool equals(const T *in) const; - bool equals(const T &in) const; - bool equals(const std::nullptr_t) const; - /** * @brief Checks if the strings are equal. * Note: Case insensitive. Returns false for any type other than char and wchar_t. @@ -156,9 +120,7 @@ namespace Jupiter bool equalsi(const Readable_String &in) const; bool equalsi(const std::basic_string &in) const; bool equalsi(const T *in, size_t len) const; - bool equalsi(const T *in) const; bool equalsi(const T &in) const; - bool equalsi(const std::nullptr_t) const; /** * @brief Checks if the String matches a wildcard format. @@ -273,29 +235,26 @@ namespace Jupiter inline const T &operator[](size_t index) const { return this->get(index); }; /** Comparative operators */ - inline bool operator==(const Readable_String &right)const{ return this->equals(right); } - inline bool operator==(const std::basic_string &right)const{ return this->equals(right); } - inline bool operator==(const T *right)const{ return this->equals(right); } - inline bool operator==(const T right)const{ return this->equals(right); } + inline bool operator==(const Readable_String& right)const{ return operator==(std::basic_string_view{right}); } + inline bool operator==(const std::basic_string& right)const{ return operator==(std::basic_string_view{right}); } + inline bool operator==(const std::basic_string_view& right)const{ return std::basic_string_view(ptr(), size()) == right; } + inline bool operator==(const T right)const{ return this->size() == 1 && this->get(0) == right; } + inline bool operator==(std::nullptr_t) = delete; inline bool operator!=(const Readable_String &right)const{ return !operator==(right); } inline bool operator!=(const std::basic_string &right)const{ return !operator==(right); } - inline bool operator!=(const T *right)const{ return !operator==(right); } inline bool operator!=(const T right)const{ return !operator==(right); } + inline bool operator!=(std::nullptr_t) = delete; inline bool operator<(const Readable_String &right)const{ return this->compare(right) < 0; } inline bool operator<(const std::basic_string &right)const{ return this->compare(right) < 0; } - inline bool operator<(const T *right)const{ return this->compare(right) < 0; } inline bool operator<(const T right)const{ return this->compare(right) < 0; } inline bool operator>(const Readable_String &right)const{ return this->compare(right) > 0; } inline bool operator>(const std::basic_string &right)const{ return this->compare(right) > 0; } - inline bool operator>(const T *right)const{ return this->compare(right) > 0; } inline bool operator>(const T right)const{ return this->compare(right) > 0; } inline bool operator<=(const Readable_String &right)const{ return !operator>(right); } inline bool operator<=(const std::basic_string &right)const{ return !operator>(right); } - inline bool operator<=(const T *right)const{ return !operator>(right); } inline bool operator<=(const T right)const{ return !operator>(right); } inline bool operator>=(const Readable_String &right)const{ return !operator<(right); } inline bool operator>=(const std::basic_string &right)const{ return !operator<(right); } - inline bool operator>=(const T *right)const{ return !operator<(right); } inline bool operator>=(const T right)const{ return !operator<(right); } /** Conversion operators */ diff --git a/src/include/Jupiter/Readable_String_Imp.h b/src/include/Jupiter/Readable_String_Imp.h index 57128a5..3766505 100644 --- a/src/include/Jupiter/Readable_String_Imp.h +++ b/src/include/Jupiter/Readable_String_Imp.h @@ -33,18 +33,6 @@ * Readable_String */ -// isEmpty - -template bool Jupiter::Readable_String::isEmpty() const -{ - return this->size() == 0; -} - -template bool Jupiter::Readable_String::isNotEmpty() const -{ - return this->size() != 0; -} - // contains template bool Jupiter::Readable_String::contains(const T &value) const @@ -73,7 +61,7 @@ template size_t Jupiter::Readable_String::find(const Jupiter::Rea if (in.size() > this->size()) return Jupiter::INVALID_INDEX; if (in.size() == this->size()) - return this->equals(in) ? 0 : Jupiter::INVALID_INDEX; + return (*this == in) ? 0 : Jupiter::INVALID_INDEX; if (in.isEmpty()) return 0; @@ -86,82 +74,6 @@ template size_t Jupiter::Readable_String::find(const Jupiter::Rea return Jupiter::INVALID_INDEX; } -// findi - -template<> size_t inline Jupiter::Readable_String::findi(const char &value, size_t index) const -{ - const char upperValue = (const char) toupper(value); - for (size_t i = 0; i != this->size(); i++) - { - if (toupper(this->get(i)) == upperValue) - { - if (index == 0) return i; - else index--; - } - } - return Jupiter::INVALID_INDEX; -} - -template<> size_t inline Jupiter::Readable_String::findi(const wchar_t &value, size_t index) const -{ - const wchar_t upperValue = towupper(value); - for (size_t i = 0; i != this->size(); i++) - { - if (towupper(this->get(i)) == upperValue) - { - if (index == 0) return i; - else index--; - } - } - return Jupiter::INVALID_INDEX; -} - -template size_t Jupiter::Readable_String::findi(const T &value, size_t index) const -{ - return Jupiter::INVALID_INDEX; -} - -template<> size_t inline Jupiter::Readable_String::findi(const Jupiter::Readable_String &in) const -{ - if (in.size() > this->size()) - return Jupiter::INVALID_INDEX; - if (in.size() == this->size()) - return this->equalsi(in) ? 0 : Jupiter::INVALID_INDEX; - if (in.isEmpty()) - return 0; - - for (size_t i = 0, j; i != this->size() - in.size() + 1; i++) - { - j = 0; - while (toupper(this->get(i + j)) == toupper(in.get(j))) - if (++j == in.size()) return i; - } - return Jupiter::INVALID_INDEX; -} - -template<> size_t inline Jupiter::Readable_String::findi(const Jupiter::Readable_String &in) const -{ - if (in.size() > this->size()) - return Jupiter::INVALID_INDEX; - if (in.size() == this->size()) - return this->equalsi(in) ? 0 : Jupiter::INVALID_INDEX; - if (in.isEmpty()) - return 0; - - for (size_t i = 0, j; i != this->size() - in.size() + 1; i++) - { - j = 0; - while (towupper(this->get(i + j)) == towupper(in.get(j))) - if (++j == in.size()) return i; - } - return Jupiter::INVALID_INDEX; -} - -template size_t Jupiter::Readable_String::findi(const Jupiter::Readable_String &) const -{ - return Jupiter::INVALID_INDEX; -} - // span() template size_t Jupiter::Readable_String::span(const Jupiter::Readable_String &in) const @@ -188,118 +100,6 @@ template size_t Jupiter::Readable_String::span(const T &in) const return index; } -// compare() - -template int Jupiter::Readable_String::compare(const Jupiter::Readable_String &in) const -{ - // rewrite to compare multiple bytes at a time. - size_t index = 0; - while (this->get(index) == in.get(index)) - { - index++; - if (index == in.size()) - { - if (index == this->size()) return 0; - return 1; - } - if (index == this->size()) return 0 - in.get(index); - } - return this->get(index) - in.get(index); -} - -template int Jupiter::Readable_String::compare(const std::basic_string &in) const -{ - // rewrite to compare multiple bytes at a time. - size_t index = 0; - while (this->get(index) == in.at(index)) - { - index++; - if (index == in.size()) - { - if (index == this->size()) return 0; - return 1; - } - if (index == this->size()) return 0 - in.at(index); - } - return this->get(index) - in.at(index); -} - -template int Jupiter::Readable_String::compare(const T *s2) const -{ - if (this->size() == 0) return 0 - *s2; - size_t index = 0; - while (this->get(index) == *s2) - { - index++; - if (*s2 == 0) - { - if (index == this->size()) return 0; - return 1; - } - s2++; - if (index == this->size()) return 0 - *s2; - } - return this->get(index) - *s2; -} - -template int Jupiter::Readable_String::compare(const T &in) const -{ - if (this->size() == 0) return 0 - in; - return this->get(0) - in; -} - -template int Jupiter::Readable_String::compare(const std::nullptr_t) const -{ - if (this->size() == 0) return true; - return this->get(0); -} - -// equals() - -template bool Jupiter::Readable_String::equals(const Jupiter::Readable_String &in) const -{ - return this->equals(in.ptr(), in.size()); -} - -template bool Jupiter::Readable_String::equals(const std::basic_string &in) const -{ - return this->equals(in.data(), in.size()); -} - -template bool Jupiter::Readable_String::equals(const T *in, size_t len) const -{ - if (this->size() != len) - return false; - // rewrite to compare multiple bytes at a time. - in += len; - while (len != 0) - if (this->get(--len) != *(--in)) - return false; - - return true; -} - -template bool Jupiter::Readable_String::equals(const T *in) const -{ - if (in == nullptr) return this->isEmpty(); - for (size_t index = 0; index != this->size(); index++) - { - if (*in == 0 || this->get(index) != *in) return false; - in++; - } - return *in == 0; -} - -template bool Jupiter::Readable_String::equals(const T &in) const -{ - return this->size() == 1 && this->get(0) == in; -} - -template bool Jupiter::Readable_String::equals(std::nullptr_t) const -{ - return this->size() == 0; -} - // equalsi() template bool Jupiter::Readable_String::equalsi(const Jupiter::Readable_String &in) const @@ -339,34 +139,7 @@ template<> bool inline Jupiter::Readable_String::equalsi(const wchar_t template bool Jupiter::Readable_String::equalsi(const T *in, size_t len) const { - return this->equals(in); // Concept of "case" not supported for type. -} - -template<> bool inline Jupiter::Readable_String::equalsi(const char *in) const -{ - if (in == nullptr) return this->size() == 0; - for (size_t index = 0; index != this->size(); index++) - { - if (*in == 0 || toupper(this->get(index)) != toupper(*in)) return false; - in++; - } - return *in == 0; -} - -template<> bool inline Jupiter::Readable_String::equalsi(const wchar_t *in) const -{ - if (in == nullptr) return this->size() == 0; - for (size_t index = 0; index != this->size(); index++) - { - if (*in == 0 || towupper(this->get(index)) != towupper(*in)) return false; - in++; - } - return *in == 0; -} - -template bool Jupiter::Readable_String::equalsi(const T *in) const -{ - return this->equals(in); // Concept of "case" not supported for type. + return *this == std::basic_string_view(in); // Concept of "case" not supported for type. } template<> bool inline Jupiter::Readable_String::equalsi(const char &in) const @@ -381,12 +154,7 @@ template<> bool inline Jupiter::Readable_String::equalsi(const wchar_t template bool Jupiter::Readable_String::equalsi(const T &in) const { - return this->equals(in); // Concept of "case" not supported for type. -} - -template bool Jupiter::Readable_String::equalsi(const std::nullptr_t) const -{ - return this->size() == 0; + return *this == in; // Concept of "case" not supported for type. } // match() diff --git a/src/include/Jupiter/SecureSocket.h b/src/include/Jupiter/SecureSocket.h index 5429eee..d4e8194 100644 --- a/src/include/Jupiter/SecureSocket.h +++ b/src/include/Jupiter/SecureSocket.h @@ -79,7 +79,7 @@ namespace Jupiter * @param key String containing file location of private key. * @return True on success, false otherwise. */ - void setCertificate(const Jupiter::ReadableString &cert, const Jupiter::ReadableString &key); + void setCertificate(std::string cert, std::string key); /** * @brief Loads a certificate and key for use. @@ -87,7 +87,7 @@ namespace Jupiter * @param pem Combined certificate/key file. * @return True on success, false otherwise. */ - void setCertificate(const Jupiter::ReadableString &pem); + void setCertificate(std::string_view pem); /** * @brief Interface to provide simple connection establishing. diff --git a/src/include/Jupiter/String.hpp b/src/include/Jupiter/String.hpp index 04d939c..f46909b 100644 --- a/src/include/Jupiter/String.hpp +++ b/src/include/Jupiter/String.hpp @@ -456,6 +456,21 @@ namespace Jupiter return static_cast(Jupiter::fnv1a_32(in)); } }; + + template + struct str_hash { + using is_transparent = std::true_type; + + // C++17 introduces a requirement that these two operators return the same values for same CharT type, but not + // any requirement that std::hash<> be able to accept both key types. This just ties them for convenience + auto operator()(std::basic_string_view in_key) const noexcept { + return std::hash>()(in_key); + } + + auto operator()(const std::basic_string& in_key) const noexcept { + return std::hash>()(in_key); + } + }; } /** Re-enable warning */ diff --git a/src/include/Jupiter/String_Type.h b/src/include/Jupiter/String_Type.h index a552cfd..f02e293 100644 --- a/src/include/Jupiter/String_Type.h +++ b/src/include/Jupiter/String_Type.h @@ -192,6 +192,7 @@ namespace Jupiter virtual size_t replace(size_t index, size_t length, const T &value); virtual size_t replace(size_t index, size_t length, const T *value, size_t valueSize); virtual size_t replace(size_t index, size_t length, const Jupiter::Readable_String &value); + virtual size_t replace(size_t index, size_t length, std::basic_string_view value); /** * @brief Replaces all instances of one value with another value. @@ -211,6 +212,7 @@ namespace Jupiter virtual size_t replace(const T *target, size_t targetSize, const Jupiter::Readable_String &value); virtual size_t replace(const Jupiter::Readable_String &target, const T *value, size_t valueSize); virtual size_t replace(const Jupiter::Readable_String &target, const Jupiter::Readable_String &value); + virtual size_t replace(std::basic_string_view target, std::basic_string_view value); /** * @brief Copies the data from the input string and concatenates it to the end of String. diff --git a/src/include/Jupiter/String_Type_Imp.h b/src/include/Jupiter/String_Type_Imp.h index ac2cffe..2895848 100644 --- a/src/include/Jupiter/String_Type_Imp.h +++ b/src/include/Jupiter/String_Type_Imp.h @@ -553,11 +553,14 @@ template size_t Jupiter::String_Type::replace(size_t index, size_ return Jupiter::String_Type::length; } -template size_t Jupiter::String_Type::replace(size_t index, size_t targetSize, const Jupiter::Readable_String &value) -{ +template size_t Jupiter::String_Type::replace(size_t index, size_t targetSize, const Jupiter::Readable_String &value) { return this->replace(index, targetSize, value.ptr(), value.size()); } +template size_t Jupiter::String_Type::replace(size_t index, size_t targetSize, std::basic_string_view value) { + return this->replace(index, targetSize, value.data(), value.size()); +} + template size_t Jupiter::String_Type::replace(const T &target, const T &value) { for (size_t i = 0; i != Jupiter::String_Type::length; i++) @@ -599,7 +602,7 @@ template size_t Jupiter::String_Type::replace(const T *target, si Jupiter::String_Type::length = i; } - else if (targetSize == Jupiter::String_Type::length && this->equals(target, targetSize)) + else if (targetSize == Jupiter::String_Type::length && *this == std::basic_string_view(target, targetSize)) return this->set(value); } return Jupiter::String_Type::length; @@ -702,7 +705,7 @@ template size_t Jupiter::String_Type::replace(const T *target, si Jupiter::String_Type::length = i; } } - else if (targetSize == Jupiter::String_Type::length && this->equals(target, targetSize)) + else if (targetSize == Jupiter::String_Type::length && *this == std::basic_string_view(target, targetSize)) return this->set(value); } return Jupiter::String_Type::length; @@ -723,6 +726,11 @@ template size_t Jupiter::String_Type::replace(const Jupiter::Read return this->replace(target.ptr(), target.size(), value.ptr(), value.size()); } +template size_t Jupiter::String_Type::replace(std::basic_string_view target, std::basic_string_view value) +{ + return this->replace(target.data(), target.size(), value.data(), value.size()); +} + // concat template size_t Jupiter::String_Type::concat(const T *in, size_t inSize) diff --git a/src/jessilib b/src/jessilib index 9d5d8b0..f714a1d 160000 --- a/src/jessilib +++ b/src/jessilib @@ -1 +1 @@ -Subproject commit 9d5d8b0abba01eaccd15d79ef63d2f7d13e94b50 +Subproject commit f714a1da00dfd9f1f6ef9a8350099318ddd4734e