Browse Source

Removed HashTable, CString. Added JUPITER_SOCK_EWOULDBLOCK

release/0.19
Jessica James 5 years ago
parent
commit
cf77a1b6a7
  1. 68
      src/common/Config.cpp
  2. 12
      src/common/Database.cpp
  3. 25
      src/common/File.cpp
  4. 9
      src/common/HTTP_Server.cpp
  5. 33
      src/common/INIConfig.cpp
  6. 159
      src/common/IRC_Client.cpp
  7. 11
      src/common/Plugin.cpp
  8. 11
      src/common/SecureSocket.cpp
  9. 26
      src/common/Socket.cpp
  10. 570
      src/include/Jupiter/CString.h
  11. 932
      src/include/Jupiter/CString_Imp.h
  12. 41
      src/include/Jupiter/Config.h
  13. 10
      src/include/Jupiter/Database.h
  14. 2
      src/include/Jupiter/File.h
  15. 31
      src/include/Jupiter/HTTP_QueryString.h
  16. 285
      src/include/Jupiter/Hash_Table.h
  17. 503
      src/include/Jupiter/Hash_Table_Imp.h
  18. 14
      src/include/Jupiter/IRC_Client.h
  19. 2
      src/include/Jupiter/Shift_String.h
  20. 6
      src/include/Jupiter/Socket.h
  21. 19
      src/include/Jupiter/String.hpp
  22. 2
      src/include/Jupiter/String_Imp.h
  23. 4
      src/include/Jupiter/String_Type.h
  24. 5
      src/include/Jupiter/String_Type_Imp.h

68
src/common/Config.cpp

@ -20,60 +20,70 @@
const Jupiter::Config o_null_section; const Jupiter::Config o_null_section;
const Jupiter::ReadableString &Jupiter::Config::get(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_default_value) const Jupiter::Config::Config(const Config& in_config)
{ : m_sections{ std::make_unique<SectionHashTable>(*in_config.m_sections) } {
const Jupiter::ReadableString *result = m_table.get(in_key); }
if (result == nullptr)
return in_default_value;
return *result; Jupiter::Config& Jupiter::Config::operator=(const Config& in_config) {
m_sections = std::make_unique<SectionHashTable>(*in_config.m_sections);
} }
const Jupiter::ReadableString *Jupiter::Config::getValue(const Jupiter::ReadableString &in_key) const const Jupiter::ReadableString &Jupiter::Config::get(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_default_value) const
{ {
return m_table.get(in_key); auto value = m_table.find(in_key);
if (value != m_table.end()) {
return value->second;
}
return in_default_value;
} }
Jupiter::Config *Jupiter::Config::getSection(const Jupiter::ReadableString &in_key) const Jupiter::Config *Jupiter::Config::getSection(const Jupiter::ReadableString &in_key) const
{ {
return m_sections.get(in_key); if (m_sections != nullptr) {
auto section = m_sections->find(in_key);
if (section != m_sections->end()) {
return &section->second;
}
}
return nullptr;
} }
Jupiter::Config &Jupiter::Config::getSectionReference(const Jupiter::ReadableString &in_key) Jupiter::Config &Jupiter::Config::getSectionReference(const Jupiter::ReadableString &in_key)
{ {
Config *section = m_sections.get(in_key); if (m_sections == nullptr) {
m_sections = std::make_unique<SectionHashTable>();
}
if (section == nullptr) Config& section = (*m_sections)[in_key];
{
m_sections.set(in_key); if (section.m_name.empty()) {
section = m_sections.get(in_key); section.m_name = static_cast<std::string>(in_key);
section->m_name = in_key;
return *section;
} }
return *section; return section;
} }
bool Jupiter::Config::set(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_value) bool Jupiter::Config::set(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_value)
{ {
return m_table.set(in_key, in_value); return m_table.insert_or_assign(in_key, in_value).second;
} }
bool Jupiter::Config::remove(const Jupiter::ReadableString &in_key) bool Jupiter::Config::remove(const Jupiter::ReadableString &in_key)
{ {
return m_table.remove(in_key); return m_table.erase(in_key) > 0;
} }
const Jupiter::ReadableString &Jupiter::Config::getName() const const std::string &Jupiter::Config::getName() const
{ {
return m_name; return m_name;
} }
void Jupiter::Config::erase() void Jupiter::Config::erase()
{ {
m_table.erase(); m_table.clear();
m_sections.erase(); m_sections = nullptr;
} }
bool Jupiter::Config::read(const char *in_filename) bool Jupiter::Config::read(const char *in_filename)
@ -84,7 +94,7 @@ bool Jupiter::Config::read(const char *in_filename)
bool Jupiter::Config::read(const Jupiter::ReadableString &in_filename) bool Jupiter::Config::read(const Jupiter::ReadableString &in_filename)
{ {
m_name = in_filename; m_name = static_cast<std::string>(in_filename);
return this->read_internal(m_name.c_str()); return this->read_internal(m_name.c_str());
} }
@ -100,7 +110,7 @@ bool Jupiter::Config::write(const char *in_filename)
bool Jupiter::Config::write(const Jupiter::ReadableString &in_filename) bool Jupiter::Config::write(const Jupiter::ReadableString &in_filename)
{ {
return this->write(Jupiter::CStringS(in_filename).c_str()); return this->write(static_cast<std::string>(in_filename).c_str());
} }
bool Jupiter::Config::reload() bool Jupiter::Config::reload()
@ -121,6 +131,14 @@ bool Jupiter::Config::reload(const Jupiter::ReadableString &in_filename)
return this->read(in_filename); return this->read(in_filename);
} }
const Jupiter::Config::SectionHashTable &Jupiter::Config::getSections() const {
if (m_sections == nullptr) {
const_cast<Config*>(this)->m_sections = std::make_unique<SectionHashTable>();
}
return *m_sections;
}
/** Operators */ /** Operators */
Jupiter::Config &Jupiter::Config::operator[](const Jupiter::ReadableString &in_key) Jupiter::Config &Jupiter::Config::operator[](const Jupiter::ReadableString &in_key)
{ {

12
src/common/Database.cpp

@ -25,7 +25,7 @@ struct Jupiter::Database::Data
static bool create_database(FILE *file, const Jupiter::DataBuffer *header); static bool create_database(FILE *file, const Jupiter::DataBuffer *header);
bool auto_create = true; bool auto_create = true;
Jupiter::CStringS file_name; std::string file_name;
}; };
void Jupiter::Database::process_header(FILE *) void Jupiter::Database::process_header(FILE *)
@ -38,11 +38,11 @@ void Jupiter::Database::create_header(FILE *)
bool Jupiter::Database::process_file(const Jupiter::ReadableString &file) bool Jupiter::Database::process_file(const Jupiter::ReadableString &file)
{ {
Jupiter::Database::data_->file_name = file; Jupiter::Database::data_->file_name = static_cast<std::string>(file);
return Jupiter::Database::Data::process_file(this); return Jupiter::Database::Data::process_file(this);
} }
bool Jupiter::Database::process_file(const Jupiter::CStringType &file) bool Jupiter::Database::process_file(const std::string &file)
{ {
Jupiter::Database::data_->file_name = file; Jupiter::Database::data_->file_name = file;
return Jupiter::Database::Data::process_file(this); return Jupiter::Database::Data::process_file(this);
@ -115,7 +115,7 @@ void Jupiter::Database::process_file_finish(FILE *)
{ {
} }
const Jupiter::CStringType &Jupiter::Database::getFilename() const const std::string &Jupiter::Database::getFilename() const
{ {
return Jupiter::Database::data_->file_name; return Jupiter::Database::data_->file_name;
} }
@ -135,7 +135,7 @@ bool Jupiter::Database::append(Jupiter::ReadableString &file, Jupiter::DataBuffe
return r; return r;
} }
bool Jupiter::Database::append(Jupiter::CStringType &file, Jupiter::DataBuffer &data) bool Jupiter::Database::append(std::string &file, Jupiter::DataBuffer &data)
{ {
return Jupiter::Database::append(file.c_str(), data); return Jupiter::Database::append(file.c_str(), data);
} }
@ -168,7 +168,7 @@ bool Jupiter::Database::create_database(const Jupiter::ReadableString &file, con
return r; return r;
} }
bool Jupiter::Database::create_database(const Jupiter::CStringType &file, const Jupiter::DataBuffer *header) bool Jupiter::Database::create_database(const std::string &file, const Jupiter::DataBuffer *header)
{ {
return Jupiter::Database::create_database(file.c_str(), header); return Jupiter::Database::create_database(file.c_str(), header);
} }

25
src/common/File.cpp

@ -17,10 +17,9 @@
*/ */
#include <sys/stat.h> #include <sys/stat.h>
#include <string>
#include "File.h" #include "File.h"
#include "CString.h"
#include "String.hpp" #include "String.hpp"
#include "Reference_String.h"
#include "ArrayList.h" #include "ArrayList.h"
/** /**
@ -49,7 +48,7 @@ const size_t defaultBufferSize = 8192;
struct JUPITER_API Jupiter::File::Data struct JUPITER_API Jupiter::File::Data
{ {
Jupiter::CStringS fileName; std::string fileName;
Jupiter::ArrayList<Jupiter::StringS> lines; Jupiter::ArrayList<Jupiter::StringS> lines;
Data(); Data();
@ -110,7 +109,7 @@ const Jupiter::ReadableString &Jupiter::File::getLine(size_t line) const
return *Jupiter::File::data_->lines.get(line); return *Jupiter::File::data_->lines.get(line);
} }
const Jupiter::ReadableString &Jupiter::File::getFileName() const const std::string &Jupiter::File::getFileName() const
{ {
return Jupiter::File::data_->fileName; return Jupiter::File::data_->fileName;
} }
@ -128,7 +127,7 @@ bool Jupiter::File::load(const char *file)
{ {
FILE *filePtr = fopen(file, "rb"); FILE *filePtr = fopen(file, "rb");
if (filePtr == nullptr) return false; if (filePtr == nullptr) return false;
if (Jupiter::File::data_->fileName.isEmpty()) if (Jupiter::File::data_->fileName.empty())
Jupiter::File::data_->fileName = file; Jupiter::File::data_->fileName = file;
bool r = Jupiter::File::load(filePtr); bool r = Jupiter::File::load(filePtr);
fclose(filePtr); fclose(filePtr);
@ -137,11 +136,11 @@ bool Jupiter::File::load(const char *file)
bool Jupiter::File::load(const Jupiter::ReadableString &file) bool Jupiter::File::load(const Jupiter::ReadableString &file)
{ {
Jupiter::CStringS fileName = file; std::string fileName = static_cast<std::string>(file);
FILE *filePtr = fopen(fileName.c_str(), "rb"); FILE *filePtr = fopen(fileName.c_str(), "rb");
if (filePtr == nullptr) return false; if (filePtr == nullptr) return false;
if (Jupiter::File::data_->fileName.isEmpty()) if (Jupiter::File::data_->fileName.empty())
Jupiter::File::data_->fileName = file; Jupiter::File::data_->fileName = fileName;
bool r = Jupiter::File::load(filePtr); bool r = Jupiter::File::load(filePtr);
fclose(filePtr); fclose(filePtr);
return r; return r;
@ -232,15 +231,15 @@ bool Jupiter::File::load(FILE *file)
void Jupiter::File::unload() void Jupiter::File::unload()
{ {
Jupiter::File::data_->fileName.set(""); Jupiter::File::data_->fileName.clear();
Jupiter::File::data_->lines.emptyAndDelete(); Jupiter::File::data_->lines.emptyAndDelete();
} }
bool Jupiter::File::reload() bool Jupiter::File::reload()
{ {
if (Jupiter::File::data_->fileName.isEmpty()) if (Jupiter::File::data_->fileName.empty())
return false; return false;
Jupiter::CStringS fileName(std::move(Jupiter::File::data_->fileName)); std::string fileName(std::move(Jupiter::File::data_->fileName));
Jupiter::File::unload(); Jupiter::File::unload();
return Jupiter::File::load(fileName.c_str()); return Jupiter::File::load(fileName.c_str());
} }
@ -265,7 +264,7 @@ bool Jupiter::File::reload(FILE *file)
bool Jupiter::File::sync() bool Jupiter::File::sync()
{ {
if (Jupiter::File::data_->fileName.isEmpty()) if (Jupiter::File::data_->fileName.empty())
return false; return false;
return Jupiter::File::sync(Jupiter::File::data_->fileName.c_str()); return Jupiter::File::sync(Jupiter::File::data_->fileName.c_str());
} }
@ -281,7 +280,7 @@ bool Jupiter::File::sync(const char *file)
bool Jupiter::File::sync(const Jupiter::ReadableString &file) bool Jupiter::File::sync(const Jupiter::ReadableString &file)
{ {
return Jupiter::File::sync(Jupiter::CStringS(file).c_str()); return Jupiter::File::sync(static_cast<std::string>(file).c_str());
} }
bool Jupiter::File::sync(FILE *file) bool Jupiter::File::sync(FILE *file)

9
src/common/HTTP_Server.cpp

@ -19,7 +19,6 @@
#include <ctime> #include <ctime>
#include <chrono> #include <chrono>
#include "String.hpp" #include "String.hpp"
#include "CString.h"
#include "Reference_String.h" #include "Reference_String.h"
#include "TCPSocket.h" #include "TCPSocket.h"
#include "ArrayList.h" #include "ArrayList.h"
@ -759,7 +758,7 @@ Jupiter::ReadableString *Jupiter::HTTP::Server::execute(const Jupiter::ReadableS
bool Jupiter::HTTP::Server::bind(const Jupiter::ReadableString &hostname, uint16_t port) bool Jupiter::HTTP::Server::bind(const Jupiter::ReadableString &hostname, uint16_t port)
{ {
Jupiter::TCPSocket *socket = new Jupiter::TCPSocket(); Jupiter::TCPSocket *socket = new Jupiter::TCPSocket();
if (socket->bind(Jupiter::CStringS(hostname).c_str(), port, true)) if (socket->bind(static_cast<std::string>(hostname).c_str(), port, true))
{ {
socket->setBlocking(false); socket->setBlocking(false);
Jupiter::HTTP::Server::data_->ports.add(socket); Jupiter::HTTP::Server::data_->ports.add(socket);
@ -772,7 +771,7 @@ bool Jupiter::HTTP::Server::bind(const Jupiter::ReadableString &hostname, uint16
bool Jupiter::HTTP::Server::tls_bind(const Jupiter::ReadableString &hostname, uint16_t port) bool Jupiter::HTTP::Server::tls_bind(const Jupiter::ReadableString &hostname, uint16_t port)
{ {
Jupiter::SecureTCPSocket *socket = new Jupiter::SecureTCPSocket(); Jupiter::SecureTCPSocket *socket = new Jupiter::SecureTCPSocket();
if (socket->bind(Jupiter::CStringS(hostname).c_str(), port, true)) if (socket->bind(static_cast<std::string>(hostname).c_str(), port, true))
{ {
Jupiter::HTTP::Server::data_->ports.add(socket); Jupiter::HTTP::Server::data_->ports.add(socket);
return true; return true;
@ -821,7 +820,7 @@ int Jupiter::HTTP::Server::think()
else // reject else // reject
delete Jupiter::HTTP::Server::data_->sessions.remove(index); delete Jupiter::HTTP::Server::data_->sessions.remove(index);
} }
else if (session->sock.getLastError() != 10035) else if (session->sock.getLastError() != JUPITER_SOCK_EWOULDBLOCK)
delete Jupiter::HTTP::Server::data_->sessions.remove(index); delete Jupiter::HTTP::Server::data_->sessions.remove(index);
} }
@ -869,7 +868,7 @@ int Jupiter::HTTP::Server::think()
else // reject (too large) else // reject (too large)
delete session; delete session;
} }
else if (session->sock.getLastError() == 10035) // store for more processing else if (session->sock.getLastError() == JUPITER_SOCK_EWOULDBLOCK) // store for more processing
Jupiter::HTTP::Server::data_->sessions.add(session); Jupiter::HTTP::Server::data_->sessions.add(session);
} }
} }

33
src/common/INIConfig.cpp

@ -37,7 +37,7 @@ void Jupiter::INIConfig::write_helper(FILE *in_file, const Jupiter::Config *in_s
for (index = 0; index != in_depth; ++index) for (index = 0; index != in_depth; ++index)
fputc('[', in_file); fputc('[', in_file);
in_section->getName().print(in_file); fputs(in_section->getName().c_str(), in_file);
for (index = 0; index != in_depth; ++index) for (index = 0; index != in_depth; ++index)
fputc(']', in_file); fputc(']', in_file);
@ -46,42 +46,21 @@ void Jupiter::INIConfig::write_helper(FILE *in_file, const Jupiter::Config *in_s
} }
// Write table entries // Write table entries
{ for (auto& table_entry : in_section->getTable())
auto bucket_itr = in_section->getTable().begin();
auto bucket_end = in_section->getTable().end();
std::forward_list<HashTable::Bucket::Entry>::iterator entry_itr;
while (bucket_itr != bucket_end)
{
for (entry_itr = bucket_itr->m_entries.begin(); entry_itr != bucket_itr->m_entries.end(); ++entry_itr)
{ {
// Tabs // Tabs
for (index = 1; index < in_depth; ++index) for (index = 1; index < in_depth; ++index)
fputc('\t', in_file); fputc('\t', in_file);
// Write entry // Write entry
entry_itr->key.print(in_file); table_entry.first.print(in_file);
fputs(" = ", in_file); fputs(" = ", in_file);
entry_itr->value.println(in_file); table_entry.second.println(in_file);
}
++bucket_itr;
}
} }
// Write subsections // Write subsections
{ for (auto& subsection : in_section->getSections()) {
auto bucket_itr = in_section->getSections().begin(); write_helper(in_file, &subsection.second, in_depth + 1);
auto bucket_end = in_section->getSections().end();
std::forward_list<SectionHashTable::Bucket::Entry>::iterator entry_itr;
while (bucket_itr != bucket_end)
{
for (entry_itr = bucket_itr->m_entries.begin(); entry_itr != bucket_itr->m_entries.end(); ++entry_itr)
write_helper(in_file, &entry_itr->value, in_depth + 1);
++bucket_itr;
}
} }
} }

159
src/common/IRC_Client.cpp

@ -23,7 +23,6 @@
#include "Functions.h" #include "Functions.h"
#include "IRC_Client.h" #include "IRC_Client.h"
#include "TCPSocket.h" #include "TCPSocket.h"
#include "CString.h"
#include "String.hpp" #include "String.hpp"
#include "Plugin.h" #include "Plugin.h"
#include "Base64.h" #include "Base64.h"
@ -47,9 +46,9 @@ Jupiter::IRC::Client::Client(Jupiter::Config *in_primary_section, Jupiter::Confi
if (m_primary_section != nullptr) if (m_primary_section != nullptr)
m_primary_section_name = m_primary_section->getName(); m_primary_section_name = m_primary_section->getName();
m_server_hostname = Jupiter::IRC::Client::readConfigValue("Hostname"_jrs, "irc.cncirc.net"_jrs); m_server_hostname = static_cast<std::string>(Jupiter::IRC::Client::readConfigValue("Hostname"_jrs, "irc.cncirc.net"_jrs));
m_log_file_name = Jupiter::IRC::Client::readConfigValue("LogFile"_jrs); m_log_file_name = static_cast<std::string>(Jupiter::IRC::Client::readConfigValue("LogFile"_jrs));
m_nickname = Jupiter::IRC::Client::readConfigValue("Nick"_jrs, "Jupiter"_jrs); m_nickname = Jupiter::IRC::Client::readConfigValue("Nick"_jrs, "Jupiter"_jrs);
m_realname = Jupiter::IRC::Client::readConfigValue("RealName"_jrs, "Jupiter IRC Client"_jrs); m_realname = Jupiter::IRC::Client::readConfigValue("RealName"_jrs, "Jupiter IRC Client"_jrs);
@ -86,7 +85,7 @@ Jupiter::IRC::Client::Client(Jupiter::Config *in_primary_section, Jupiter::Confi
m_output = stdout; m_output = stdout;
else else
m_output = nullptr; m_output = nullptr;
if (m_log_file_name.isNotEmpty()) if (!m_log_file_name.empty())
m_log_file = fopen(m_log_file_name.c_str(), "a+b"); m_log_file = fopen(m_log_file_name.c_str(), "a+b");
else m_log_file = nullptr; else m_log_file = nullptr;
@ -236,7 +235,7 @@ void Jupiter::IRC::Client::setSecondaryConfigSection(Jupiter::Config *in_seconda
m_secondary_section = in_secondary_section; m_secondary_section = in_secondary_section;
} }
const Jupiter::ReadableString &Jupiter::IRC::Client::getLogFile() const const std::string &Jupiter::IRC::Client::getLogFile() const
{ {
return m_log_file_name; return m_log_file_name;
} }
@ -266,7 +265,7 @@ const Jupiter::ReadableString &Jupiter::IRC::Client::getServerName() const
return m_server_name; return m_server_name;
} }
const Jupiter::ReadableString &Jupiter::IRC::Client::getServerHostname() const const std::string &Jupiter::IRC::Client::getServerHostname() const
{ {
return m_server_hostname; return m_server_hostname;
} }
@ -328,10 +327,10 @@ int Jupiter::IRC::Client::getAccessLevel(const Channel &in_channel, const Jupite
int Jupiter::IRC::Client::getAccessLevel(const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &in_nickname) const int Jupiter::IRC::Client::getAccessLevel(const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &in_nickname) const
{ {
Jupiter::IRC::Client::Channel *channel = m_channels.get(in_channel); auto channel = m_channels.find(in_channel);
if (channel != nullptr) if (channel != m_channels.end())
return this->getAccessLevel(*channel, in_nickname); return this->getAccessLevel(channel->second, in_nickname);
return 0; return 0;
} }
@ -356,7 +355,12 @@ size_t Jupiter::IRC::Client::getUserCount() const
Jupiter::IRC::Client::User *Jupiter::IRC::Client::getUser(const Jupiter::ReadableString &in_nickname) const Jupiter::IRC::Client::User *Jupiter::IRC::Client::getUser(const Jupiter::ReadableString &in_nickname) const
{ {
return m_users.get(in_nickname); auto user = m_users.find(in_nickname);
if (user != m_users.end()) {
return const_cast<User*>(&user->second);
}
return nullptr;
} }
const Jupiter::IRC::Client::ChannelTableType &Jupiter::IRC::Client::getChannels() const const Jupiter::IRC::Client::ChannelTableType &Jupiter::IRC::Client::getChannels() const
@ -371,7 +375,12 @@ size_t Jupiter::IRC::Client::getChannelCount() const
Jupiter::IRC::Client::Channel *Jupiter::IRC::Client::getChannel(const Jupiter::ReadableString &in_channel) const Jupiter::IRC::Client::Channel *Jupiter::IRC::Client::getChannel(const Jupiter::ReadableString &in_channel) const
{ {
return m_channels.get(in_channel); auto channel = m_channels.find(in_channel);
if (channel != m_channels.end()) {
return const_cast<Channel*>(&channel->second);
}
return nullptr;
} }
bool Jupiter::IRC::Client::isAutoReconnect() const bool Jupiter::IRC::Client::isAutoReconnect() const
@ -398,14 +407,14 @@ void Jupiter::IRC::Client::partChannel(const Jupiter::ReadableString &in_channel
{ {
m_socket->send(Jupiter::StringS::Format("PART %.*s" ENDL, in_channel.size(), in_channel.ptr())); m_socket->send(Jupiter::StringS::Format("PART %.*s" ENDL, in_channel.size(), in_channel.ptr()));
m_channels.get(in_channel)->setType(-2); 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, const Jupiter::ReadableString &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.ptr()));
m_channels.get(in_channel)->setType(-2); m_channels[in_channel].setType(-2);
} }
void Jupiter::IRC::Client::sendMessage(const Jupiter::ReadableString &dest, const Jupiter::ReadableString &message) void Jupiter::IRC::Client::sendMessage(const Jupiter::ReadableString &dest, const Jupiter::ReadableString &message)
@ -420,25 +429,20 @@ void Jupiter::IRC::Client::sendNotice(const Jupiter::ReadableString &dest, const
size_t Jupiter::IRC::Client::messageChannels(int type, const Jupiter::ReadableString &message) size_t Jupiter::IRC::Client::messageChannels(int type, const Jupiter::ReadableString &message)
{ {
auto message_channel_callback = [this, type, &message](ChannelTableType::Bucket::Entry &in_entry) for (auto& channel : m_channels) {
{ if (channel.second.getType() == type) {
if (in_entry.value.getType() == type) sendMessage(channel.second.getName(), message);
this->sendMessage(in_entry.value.getName(), message); }
}; }
m_channels.callback(message_channel_callback);
return m_channels.size(); return m_channels.size();
} }
size_t Jupiter::IRC::Client::messageChannels(const Jupiter::ReadableString &message) size_t Jupiter::IRC::Client::messageChannels(const Jupiter::ReadableString &message)
{ {
auto message_channel_callback = [this, &message](ChannelTableType::Bucket::Entry &in_entry) for (auto& channel : m_channels) {
{ sendMessage(channel.second.getName(), message);
this->sendMessage(in_entry.value.getName(), message); }
};
m_channels.callback(message_channel_callback);
return m_channels.size(); return m_channels.size();
} }
@ -488,7 +492,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
} }
if (port != 0) // Don't default -- could be non-compliant input. if (port != 0) // Don't default -- could be non-compliant input.
{ {
m_server_hostname = Jupiter::ReferenceString::getWord(line, 3, WHITESPACE); m_server_hostname = static_cast<std::string>(Jupiter::ReferenceString::getWord(line, 3, WHITESPACE));
m_server_port = port; m_server_port = port;
puts("Reconnecting due to old bounce."); puts("Reconnecting due to old bounce.");
this->reconnect(); this->reconnect();
@ -530,8 +534,9 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
} }
if (bouncePort != 0) if (bouncePort != 0)
{ {
m_server_hostname = Jupiter::ReferenceString::getWord(line, 4, " "); auto server_hostname = Jupiter::ReferenceString::getWord(line, 4, " ");
m_server_hostname.truncate(1); // trailing comma server_hostname.truncate(1); // trailing comma
m_server_hostname = static_cast<std::string>(server_hostname);
m_server_port = bouncePort; m_server_port = bouncePort;
puts("Reconnecting due to old bounce."); puts("Reconnecting due to old bounce.");
this->reconnect(); this->reconnect();
@ -786,21 +791,19 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
i++; i++;
} }
auto auto_join_channels_callback = [this](Jupiter::Config::SectionHashTable::Bucket::Entry &in_entry) auto join_channels_for_config = [this](Jupiter::Config *config)
{ {
if (in_entry.value.get<bool>("AutoJoin"_jrs, false)) if (config != nullptr) {
this->joinChannel(in_entry.value.getName()); for (auto& section : config->getSections()) {
if (section.second.get<bool>("AutoJoin"_jrs, false)) {
this->joinChannel(section.first);
}
}
}
}; };
Jupiter::Config *config = m_primary_section->getSection("Channels"_jrs); join_channels_for_config(m_primary_section->getSection("Channels"_jrs));
join_channels_for_config(m_secondary_section->getSection("Channels"_jrs));
if (config != nullptr)
config->getSections().callback(auto_join_channels_callback);
config = m_secondary_section->getSection("Channels"_jrs);
if (config != nullptr)
config->getSections().callback(auto_join_channels_callback);
m_connection_status = 5; m_connection_status = 5;
m_reconnect_attempts = 0; m_reconnect_attempts = 0;
@ -927,7 +930,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
if (chan[0] == ':') if (chan[0] == ':')
chan.shiftRight(1); chan.shiftRight(1);
Channel *channel = m_channels.get(chan); auto channel = getChannel(chan);
if (m_nickname.equalsi(nick)) if (m_nickname.equalsi(nick))
{ {
@ -936,7 +939,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
Client::delChannel(channel->getName()); Client::delChannel(channel->getName());
Client::addChannel(chan); Client::addChannel(chan);
channel = m_channels.get(chan); channel = getChannel(chan);
channel->m_adding_names = true; channel->m_adding_names = true;
if (channel->getType() < 0) if (channel->getType() < 0)
@ -963,10 +966,10 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
Jupiter::ReferenceString chan = Jupiter::ReferenceString::getWord(line, 2, WHITESPACE); Jupiter::ReferenceString chan = Jupiter::ReferenceString::getWord(line, 2, WHITESPACE);
if (chan.isNotEmpty()) if (chan.isNotEmpty())
{ {
Channel *channel = m_channels.get(chan); Channel *channel = getChannel(chan);
if (channel != nullptr) if (channel != nullptr)
{ {
Jupiter::IRC::Client::User *user = m_users.get(nick); Jupiter::IRC::Client::User *user = getUser(nick);
if (user != nullptr) if (user != nullptr)
{ {
channel->delUser(nick); channel->delUser(nick);
@ -985,7 +988,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
Client::delChannel(chan); Client::delChannel(chan);
if (user->getChannelCount() == 0) if (user->getChannelCount() == 0)
m_users.remove(nick); m_users.erase(nick);
} }
} }
} }
@ -1002,10 +1005,10 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
Jupiter::ReferenceString kicked = Jupiter::ReferenceString::getWord(line, 3, WHITESPACE); Jupiter::ReferenceString kicked = Jupiter::ReferenceString::getWord(line, 3, WHITESPACE);
if (kicked.isNotEmpty()) if (kicked.isNotEmpty())
{ {
Channel *channel = m_channels.get(chan); Channel *channel = getChannel(chan);
if (channel != nullptr) if (channel != nullptr)
{ {
Jupiter::IRC::Client::User *user = m_users.get(kicked); Jupiter::IRC::Client::User *user = getUser(kicked);
if (user != nullptr) if (user != nullptr)
{ {
channel->delUser(kicked); channel->delUser(kicked);
@ -1028,7 +1031,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
} }
if (user->getChannelCount() == 0) if (user->getChannelCount() == 0)
m_users.remove(kicked); m_users.erase(kicked);
} }
} }
} }
@ -1039,22 +1042,19 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
{ {
Jupiter::ReferenceString nick = getSender(line); Jupiter::ReferenceString nick = getSender(line);
Jupiter::ReferenceString message = Jupiter::ReferenceString::substring(line, line.find(':', 1) + 1); Jupiter::ReferenceString message = Jupiter::ReferenceString::substring(line, line.find(':', 1) + 1);
Jupiter::IRC::Client::User *user = m_users.get(nick); Jupiter::IRC::Client::User *user = getUser(nick);
if (user != nullptr) if (user != nullptr)
{ {
auto remove_user_callback = [&nick](ChannelTableType::Bucket::Entry &in_entry) for (auto& channel : m_channels) {
{ channel.second.delUser(nick);
in_entry.value.delUser(nick); }
};
m_channels.callback(remove_user_callback);
this->OnQuit(nick, message); this->OnQuit(nick, message);
for (size_t i = 0; i < Jupiter::plugins->size(); i++) for (size_t i = 0; i < Jupiter::plugins->size(); i++)
Jupiter::plugins->get(i)->OnQuit(this, nick, message); Jupiter::plugins->get(i)->OnQuit(this, nick, message);
m_users.remove(nick); m_users.erase(nick);
} }
} }
else if (w2.equalsi("INVITE")) else if (w2.equalsi("INVITE"))
@ -1096,7 +1096,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
tword = modestring.getWord(g, " "); tword = modestring.getWord(g, " ");
if (tword.isNotEmpty()) if (tword.isNotEmpty())
{ {
Jupiter::IRC::Client::Channel *channel = m_channels.get(chan); Jupiter::IRC::Client::Channel *channel = getChannel(chan);
if (channel != nullptr) if (channel != nullptr)
{ {
if (symb == '+') if (symb == '+')
@ -1131,7 +1131,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
Jupiter::ReferenceString chan = Jupiter::ReferenceString::getWord(line, 4, " "); Jupiter::ReferenceString chan = Jupiter::ReferenceString::getWord(line, 4, " ");
Jupiter::ReferenceString names = Jupiter::ReferenceString::substring(line, line.find(':', 1) + 1); Jupiter::ReferenceString names = Jupiter::ReferenceString::substring(line, line.find(':', 1) + 1);
Channel *channel = m_channels.get(chan); Channel *channel = getChannel(chan);
if (channel != nullptr) if (channel != nullptr)
{ {
if (channel->m_adding_names == false) if (channel->m_adding_names == false)
@ -1149,7 +1149,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
else if (numeric == Reply::ENDOFNAMES) // We're done here. else if (numeric == Reply::ENDOFNAMES) // We're done here.
{ {
Jupiter::ReferenceString chan = Jupiter::ReferenceString::getWord(line, 3, " "); Jupiter::ReferenceString chan = Jupiter::ReferenceString::getWord(line, 3, " ");
Channel *channel = m_channels.get(chan); Channel *channel = getChannel(chan);
if (channel != nullptr) if (channel != nullptr)
channel->m_adding_names = false; channel->m_adding_names = false;
@ -1209,7 +1209,7 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line)
bool Jupiter::IRC::Client::connect() bool Jupiter::IRC::Client::connect()
{ {
const Jupiter::ReadableString &clientAddress = Jupiter::IRC::Client::readConfigValue("ClientAddress"_jrs); 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 : Jupiter::CStringS(clientAddress).c_str(), (unsigned short)Jupiter::IRC::Client::readConfigLong("ClientPort"_jrs)) == false) if (m_socket->connect(m_server_hostname.c_str(), m_server_port, clientAddress.isEmpty() ? nullptr : static_cast<std::string>(clientAddress).c_str(), (unsigned short)Jupiter::IRC::Client::readConfigLong("ClientPort"_jrs)) == false)
return false; return false;
m_socket->setBlocking(false); m_socket->setBlocking(false);
@ -1335,7 +1335,7 @@ int Jupiter::IRC::Client::think()
// No incoming data; check for errors // No incoming data; check for errors
tmp = m_socket->getLastError(); tmp = m_socket->getLastError();
if (tmp == 10035) // Operation would block if (tmp == JUPITER_SOCK_EWOULDBLOCK) // Operation would block
return 0; return 0;
// Serious error; disconnect if necessary // Serious error; disconnect if necessary
@ -1440,12 +1440,12 @@ void Jupiter::IRC::Client::writeToLogs(const Jupiter::ReadableString &message)
void Jupiter::IRC::Client::delChannel(const Jupiter::ReadableString &in_channel) void Jupiter::IRC::Client::delChannel(const Jupiter::ReadableString &in_channel)
{ {
m_channels.remove(in_channel); m_channels.erase(in_channel);
} }
Jupiter::IRC::Client::User *Jupiter::IRC::Client::findUser(const Jupiter::ReadableString &in_nickname) const Jupiter::IRC::Client::User *Jupiter::IRC::Client::findUser(const Jupiter::ReadableString &in_nickname) const
{ {
return m_users.get(in_nickname); return getUser(in_nickname);
} }
Jupiter::IRC::Client::User *Jupiter::IRC::Client::findUserOrAdd(const Jupiter::ReadableString &name) Jupiter::IRC::Client::User *Jupiter::IRC::Client::findUserOrAdd(const Jupiter::ReadableString &name)
@ -1460,9 +1460,7 @@ Jupiter::IRC::Client::User *Jupiter::IRC::Client::findUserOrAdd(const Jupiter::R
user.m_nickname = nick; user.m_nickname = nick;
user.m_username = Jupiter::ReferenceString::getWord(name, 1, "!@"); user.m_username = Jupiter::ReferenceString::getWord(name, 1, "!@");
user.m_hostname = Jupiter::ReferenceString::getWord(name, 2, "!@"); user.m_hostname = Jupiter::ReferenceString::getWord(name, 2, "!@");
m_users.set(nick, user); return &m_users.emplace(nick, user).first->second;
return m_users.get(nick);
} }
void Jupiter::IRC::Client::addNamesToChannel(Channel &in_channel, Jupiter::ReadableString &in_names) void Jupiter::IRC::Client::addNamesToChannel(Channel &in_channel, Jupiter::ReadableString &in_names)
@ -1497,7 +1495,7 @@ void Jupiter::IRC::Client::addNamesToChannel(Channel &in_channel, Jupiter::Reada
void Jupiter::IRC::Client::addChannel(const Jupiter::ReadableString &in_channel) void Jupiter::IRC::Client::addChannel(const Jupiter::ReadableString &in_channel)
{ {
m_channels.set(in_channel, Channel(in_channel, this)); m_channels.emplace(in_channel, Channel(in_channel, this));
} }
bool Jupiter::IRC::Client::startCAP() bool Jupiter::IRC::Client::startCAP()
@ -1512,7 +1510,7 @@ bool Jupiter::IRC::Client::registerClient()
const char *localHostname = Jupiter::Socket::getLocalHostname(); const char *localHostname = Jupiter::Socket::getLocalHostname();
Jupiter::StringS messageToSend; 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.ptr(), m_realname.size(), m_realname.ptr()); 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());
if (m_socket->send(messageToSend) <= 0) if (m_socket->send(messageToSend) <= 0)
result = false; result = false;
@ -1596,8 +1594,8 @@ Jupiter::IRC::Client::Channel::User *Jupiter::IRC::Client::Channel::addUser(Jupi
++user->m_channel_count; ++user->m_channel_count;
m_users.set(channel_user.getNickname(), channel_user); m_users[channel_user.getNickname()] = channel_user;
return m_users.get(channel_user.getNickname()); return &m_users[channel_user.getNickname()];
} }
Jupiter::IRC::Client::Channel::User *Jupiter::IRC::Client::Channel::addUser(Jupiter::IRC::Client::User *user, const char prefix) Jupiter::IRC::Client::Channel::User *Jupiter::IRC::Client::Channel::addUser(Jupiter::IRC::Client::User *user, const char prefix)
@ -1608,18 +1606,18 @@ Jupiter::IRC::Client::Channel::User *Jupiter::IRC::Client::Channel::addUser(Jupi
++user->m_channel_count; ++user->m_channel_count;
m_users.set(channel_user.getNickname(), channel_user); m_users[channel_user.getNickname()] = channel_user;
return m_users.get(channel_user.getNickname()); return &m_users[channel_user.getNickname()];
} }
void Jupiter::IRC::Client::Channel::delUser(const Jupiter::ReadableString &in_nickname) void Jupiter::IRC::Client::Channel::delUser(const Jupiter::ReadableString &in_nickname)
{ {
m_users.remove(in_nickname); m_users.erase(in_nickname);
} }
void Jupiter::IRC::Client::Channel::addUserPrefix(const Jupiter::ReadableString &in_nickname, char prefix) void Jupiter::IRC::Client::Channel::addUserPrefix(const Jupiter::ReadableString &in_nickname, char prefix)
{ {
Channel::User *user = m_users.get(in_nickname); Channel::User *user = getUser(in_nickname);
if (user != nullptr && user->m_prefixes.contains(prefix) == false) if (user != nullptr && user->m_prefixes.contains(prefix) == false)
user->m_prefixes += prefix; user->m_prefixes += prefix;
@ -1627,7 +1625,7 @@ void Jupiter::IRC::Client::Channel::addUserPrefix(const Jupiter::ReadableString
void Jupiter::IRC::Client::Channel::delUserPrefix(const Jupiter::ReadableString &in_nickname, char prefix) void Jupiter::IRC::Client::Channel::delUserPrefix(const Jupiter::ReadableString &in_nickname, char prefix)
{ {
Channel::User *user = m_users.get(in_nickname); Channel::User *user = getUser(in_nickname);
if (user != nullptr) if (user != nullptr)
user->m_prefixes.remove(prefix); user->m_prefixes.remove(prefix);
@ -1640,7 +1638,12 @@ const Jupiter::ReadableString &Jupiter::IRC::Client::Channel::getName() const
Jupiter::IRC::Client::Channel::User *Jupiter::IRC::Client::Channel::getUser(const Jupiter::ReadableString &in_nickname) const Jupiter::IRC::Client::Channel::User *Jupiter::IRC::Client::Channel::getUser(const Jupiter::ReadableString &in_nickname) const
{ {
return m_users.get(in_nickname); auto user = m_users.find(in_nickname);
if (user != m_users.end()) {
return const_cast<Channel::User*>(&user->second);
}
return nullptr;
} }
char Jupiter::IRC::Client::Channel::getUserPrefix(const Channel::User &in_user) const char Jupiter::IRC::Client::Channel::getUserPrefix(const Channel::User &in_user) const
@ -1656,7 +1659,7 @@ char Jupiter::IRC::Client::Channel::getUserPrefix(const Channel::User &in_user)
char Jupiter::IRC::Client::Channel::getUserPrefix(const Jupiter::ReadableString &in_nickname) const char Jupiter::IRC::Client::Channel::getUserPrefix(const Jupiter::ReadableString &in_nickname) const
{ {
Channel::User *user = m_users.get(in_nickname); Channel::User *user = getUser(in_nickname);
if (user != nullptr) if (user != nullptr)
return this->getUserPrefix(*user); return this->getUserPrefix(*user);

11
src/common/Plugin.cpp

@ -18,6 +18,7 @@
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <string_view>
#if defined _WIN32 #if defined _WIN32
#include <Windows.h> #include <Windows.h>
@ -28,10 +29,10 @@
#include "Plugin.h" #include "Plugin.h"
#include "Functions.h" #include "Functions.h"
#include "ArrayList.h" #include "ArrayList.h"
#include "CString.h"
#include "String.hpp" #include "String.hpp"
using namespace Jupiter::literals; using namespace Jupiter::literals;
using namespace std::literals;
#if defined _WIN32 #if defined _WIN32
constexpr char directory_character = '\\'; constexpr char directory_character = '\\';
@ -63,9 +64,9 @@ dlib::~dlib()
} }
#if defined _WIN32 #if defined _WIN32
const Jupiter::ReferenceString module_file_extension = ".dll"_jrs; const char module_file_extension[]{ ".dll" };
#else // _WIN32 #else // _WIN32
const Jupiter::ReferenceString module_file_extension = ".so"_jrs; const char module_file_extension[]{ ".so" };
#endif // _WIN32 #endif // _WIN32
const Jupiter::ReferenceString config_file_extension = ".ini"_jrs; const Jupiter::ReferenceString config_file_extension = ".ini"_jrs;
@ -147,14 +148,14 @@ const Jupiter::ReadableString &Jupiter::Plugin::getConfigDirectory()
Jupiter::Plugin *Jupiter::Plugin::load(const Jupiter::ReadableString &pluginName) Jupiter::Plugin *Jupiter::Plugin::load(const Jupiter::ReadableString &pluginName)
{ {
Jupiter::CStringS file = plugins_directory + pluginName + module_file_extension; std::string file = static_cast<std::string>(plugins_directory) + static_cast<std::string>(pluginName) + module_file_extension;
dlib *dPlug = new dlib(); dlib *dPlug = new dlib();
// Load the library // Load the library
#if defined _WIN32 #if defined _WIN32
dPlug->lib = LoadLibraryA(file.c_str()); dPlug->lib = LoadLibraryA(file.c_str());
#else // _WIN32 #else // _WIN32
dPlug->lib = dlopen(file.c_str(), RTLD_LAZY); dPlug->lib = dlopen(file.c_str(), RTLD_NOW);
#endif // _WIN32 #endif // _WIN32
if (dPlug->lib == nullptr) if (dPlug->lib == nullptr)
{ {

11
src/common/SecureSocket.cpp

@ -20,7 +20,6 @@
#include <openssl/ssl.h> // OpenSSL SSL functions #include <openssl/ssl.h> // OpenSSL SSL functions
#include <openssl/err.h> // OpenSSL SSL errors #include <openssl/err.h> // OpenSSL SSL errors
#include "SecureSocket.h" #include "SecureSocket.h"
#include "CString.h"
struct Jupiter::SecureSocket::SSLData struct Jupiter::SecureSocket::SSLData
{ {
@ -28,8 +27,8 @@ struct Jupiter::SecureSocket::SSLData
SSL_CTX *context = nullptr; SSL_CTX *context = nullptr;
const SSL_METHOD *method = nullptr; const SSL_METHOD *method = nullptr;
Jupiter::SecureSocket::EncryptionMethod eMethod = ANY; Jupiter::SecureSocket::EncryptionMethod eMethod = ANY;
Jupiter::CStringS cert; std::string cert;
Jupiter::CStringS key; std::string key;
~SSLData(); ~SSLData();
}; };
@ -178,8 +177,8 @@ bool loadCertificate(SSL_CTX *context, const char *cert, const char *key)
void Jupiter::SecureSocket::setCertificate(const Jupiter::ReadableString &cert, const Jupiter::ReadableString &key) void Jupiter::SecureSocket::setCertificate(const Jupiter::ReadableString &cert, const Jupiter::ReadableString &key)
{ {
Jupiter::SecureSocket::SSLdata_->cert = cert; Jupiter::SecureSocket::SSLdata_->cert = static_cast<std::string>(cert);
Jupiter::SecureSocket::SSLdata_->key = key; Jupiter::SecureSocket::SSLdata_->key = static_cast<std::string>(key);
} }
void Jupiter::SecureSocket::setCertificate(const Jupiter::ReadableString &pem) void Jupiter::SecureSocket::setCertificate(const Jupiter::ReadableString &pem)
@ -241,7 +240,7 @@ bool Jupiter::SecureSocket::initSSL()
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
return false; return false;
} }
if (Jupiter::SecureSocket::SSLdata_->cert.isNotEmpty()) if (!Jupiter::SecureSocket::SSLdata_->cert.empty())
loadCertificate(Jupiter::SecureSocket::SSLdata_->context, Jupiter::SecureSocket::SSLdata_->cert.c_str(), Jupiter::SecureSocket::SSLdata_->key.c_str()); loadCertificate(Jupiter::SecureSocket::SSLdata_->context, Jupiter::SecureSocket::SSLdata_->cert.c_str(), Jupiter::SecureSocket::SSLdata_->key.c_str());
} }

26
src/common/Socket.cpp

@ -38,7 +38,6 @@ bool socketInit = false;
#include "Socket.h" #include "Socket.h"
#include "Functions.h" #include "Functions.h"
#include "CString.h"
void Jupiter::Socket::Buffer::set_length(size_t in_length) void Jupiter::Socket::Buffer::set_length(size_t in_length)
{ {
@ -56,8 +55,8 @@ struct Jupiter::Socket::Data
SocketType rawSock = INVALID_SOCKET; SocketType rawSock = INVALID_SOCKET;
unsigned short remote_port = 0; unsigned short remote_port = 0;
unsigned short bound_port = 0; unsigned short bound_port = 0;
Jupiter::CStringS remote_host; std::string remote_host;
Jupiter::CStringS bound_host; std::string bound_host;
int sockType = SOCK_RAW; int sockType = SOCK_RAW;
int sockProto = IPPROTO_RAW; int sockProto = IPPROTO_RAW;
bool is_shutdown = false; bool is_shutdown = false;
@ -162,9 +161,9 @@ bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const
if (!socketInit && !Jupiter::Socket::init()) if (!socketInit && !Jupiter::Socket::init())
return false; return false;
#endif // _WIN32 #endif // _WIN32
Jupiter::Socket::data_->remote_host.set(hostname); Jupiter::Socket::data_->remote_host = hostname;
Jupiter::Socket::data_->remote_port = iPort; Jupiter::Socket::data_->remote_port = iPort;
addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->remote_host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::data_->remote_port).c_str()); addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->remote_host.c_str(), std::to_string(Jupiter::Socket::data_->remote_port).c_str());
if (info_head != nullptr) if (info_head != nullptr)
{ {
addrinfo *info = info_head; addrinfo *info = info_head;
@ -212,9 +211,9 @@ bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andL
if (!socketInit && !Jupiter::Socket::init()) if (!socketInit && !Jupiter::Socket::init())
return false; return false;
#endif // _WIN32 #endif // _WIN32
Jupiter::Socket::data_->bound_host.set(hostname); Jupiter::Socket::data_->bound_host = hostname;
Jupiter::Socket::data_->bound_port = iPort; Jupiter::Socket::data_->bound_port = iPort;
addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->bound_host.c_str(), Jupiter::CStringS::Format("%hu", Jupiter::Socket::data_->bound_port).c_str()); addrinfo *info_head = Jupiter::Socket::getAddrInfo(Jupiter::Socket::data_->bound_host.c_str(), std::to_string(Jupiter::Socket::data_->bound_port).c_str());
if (info_head != nullptr) if (info_head != nullptr)
{ {
addrinfo *info = info_head; addrinfo *info = info_head;
@ -427,7 +426,7 @@ Jupiter::Socket *Jupiter::Socket::accept()
r->data_->rawSock = tSock; r->data_->rawSock = tSock;
r->data_->sockType = Jupiter::Socket::data_->sockType; r->data_->sockType = Jupiter::Socket::data_->sockType;
r->data_->sockProto = Jupiter::Socket::data_->sockProto; r->data_->sockProto = Jupiter::Socket::data_->sockProto;
r->data_->remote_host.set(resolved); r->data_->remote_host = resolved;
r->data_->remote_port = static_cast<unsigned short>(Jupiter_strtoi(resolved_port, 10)); r->data_->remote_port = static_cast<unsigned short>(Jupiter_strtoi(resolved_port, 10));
return r; return r;
} }
@ -472,7 +471,12 @@ bool Jupiter::Socket::setBlocking(bool mode)
#else // _WIN32 #else // _WIN32
int flags = fcntl(Jupiter::Socket::data_->rawSock, F_GETFL, 0); int flags = fcntl(Jupiter::Socket::data_->rawSock, F_GETFL, 0);
if (flags < 0) return 0; if (flags < 0) return 0;
flags = mode ? (flags|O_NONBLOCK) : (flags&~O_NONBLOCK); if (mode) {
flags &= ~O_NONBLOCK;
}
else {
flags |= O_NONBLOCK;
}
return fcntl(Jupiter::Socket::data_->rawSock, F_SETFL, flags) == 0; return fcntl(Jupiter::Socket::data_->rawSock, F_SETFL, flags) == 0;
#endif // _WIN32 #endif // _WIN32
} }
@ -488,7 +492,7 @@ bool Jupiter::Socket::getBlockingMode() const
#endif #endif
} }
const Jupiter::ReadableString &Jupiter::Socket::getRemoteHostname() const const std::string &Jupiter::Socket::getRemoteHostname() const
{ {
return Jupiter::Socket::data_->remote_host; return Jupiter::Socket::data_->remote_host;
} }
@ -498,7 +502,7 @@ const char *Jupiter::Socket::getRemoteHostnameC() const
return Jupiter::Socket::data_->remote_host.c_str(); return Jupiter::Socket::data_->remote_host.c_str();
} }
const Jupiter::ReadableString &Jupiter::Socket::getBoundHostname() const const std::string &Jupiter::Socket::getBoundHostname() const
{ {
return Jupiter::Socket::data_->bound_host; return Jupiter::Socket::data_->bound_host;
} }

570
src/include/Jupiter/CString.h

@ -1,570 +0,0 @@
/**
* Copyright (C) 2013-2017 Jessica James.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Written by Jessica James <jessica.aj@outlook.com>
*/
#if !defined _CSTRING_H_HEADER
#define _CSTRING_H_HEADER
/**
* @file CString.h
* @brief Defines the base CString_Type, as well as a series of CString types.
* Note: Functions which take "case" or "wildcards" into consideration will only function
* for types char and wchar_t; inputs with other types will simply return false.
*/
#include "Shift_String.h"
/** Disable warning 4458 */
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4458) // declaration of 'length' hides class member
#endif
namespace Jupiter
{
/**
* @brief Provides the basis for CString classes by providing a minimalist implementation (i.e: no extra variables).
*
* @param T Element type which the CString will store. Defaults to char.
*/
template<typename T = char> class CString_Type : public Shift_String_Type<T>
{
public:
/**
* @brief Returns the C-Style string behind the CString.
*
* @return C-Style string that the CString represents.
*/
const T *c_str() const;
/**
* @brief Truncates the string by a specified number of elements.
*
* @param n Number of elements to remove from the tail.
* @return New size of the CString.
*/
size_t truncate(size_t n);
/**
* @brief Removes the first instance of an element from the string.
*
* @param value Value of the element to remove.
* @return True if an element was removed, false otherwise.
*/
bool remove(const T &value);
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param args Inputs to match the format specifiers.
* @return Number of characters written.
*/
size_t vformat(const T *format, va_list args);
/**
* @brief Appends to a CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param args Inputs to match the format specifiers.
* @return Number of characters written.
*/
size_t avformat(const T *format, va_list args);
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return String containing the new format.
*/
static CString_Type Format(const T *format, ...);
/**
* @brief Creates a partial copy of the string.
*
* @param pos Position in the string to start copying from.
* @return String containing a partial copy of the original string.
*/
CString_Type<T> substring(size_t pos) const;
/**
* @brief Creates a partial copy of the string.
*
* @param pos Position in the string to start copying from.
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
CString_Type<T> substring(size_t pos, size_t length) const;
/**
* @brief Creates a partial copy of the string.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @return String containing a partial copy of the original string.
*/
static CString_Type<T> substring(const Jupiter::Readable_String<T> &in, size_t pos);
static CString_Type<T> substring(const T *in, size_t pos);
/**
* @brief Creates a partial copy of the string.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
static CString_Type<T> substring(const Jupiter::Readable_String<T> &in, size_t pos, size_t length);
static CString_Type<T> substring(const T *in, size_t pos, size_t length);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Type<T> getWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
*
* @param in String to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Type<T> getWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
*
* @param in C-Style string to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Type<T> getWord(const T *in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Type<T> gotoWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Type<T> gotoWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace);
/**
* @brief Tokenizes a string, based on an input token separator
*
* @param separator Separator to split tokens by
* @return TokenizeResult containing the results of the tokenization process.
*/
typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> tokenize(const T &separator) const;
typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> tokenize(const Jupiter::Readable_String<T> &separator) const;
typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> tokenize(const T *separator, size_t separator_size) const;
/**
* @brief Tokenizes a string, based on an input token separator
*
* @param in String to split into tokens
* @param separator Separator to split tokens by
* @return TokenizeResult containing the results of the tokenization process.
*/
static typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> tokenize(const Jupiter::Readable_String<T> &in, const T &separator);
static typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> tokenize(const Jupiter::Readable_String<T> &in, const Jupiter::Readable_String<T> &separator);
static typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> tokenize(const Jupiter::Readable_String<T> &in, const T *separator, size_t separator_size);
/**
* @brief Copies the data from the input string to the CString.
*
* @param in String containing the data to be copied.
* @return New size of the CString.
*/
size_t set(const T *in, size_t inSize) override;
size_t set(const Jupiter::Readable_String<T> &in) override;
size_t set(const std::basic_string<T> &in) override;
size_t set(const T *in) override;
size_t set(const T &in) override;
/**
* @brief Copies the data from the input string and concatenates it to the end of CString.
*
* @param in String containing the data to be concatenated.
* @return New size of the CString.
*/
size_t concat(const T *in, size_t inSize) override;
size_t concat(const Readable_String<T> &in) override;
size_t concat(const std::basic_string<T> &in) override;
size_t concat(const T *in) override;
size_t concat(const T &in) override;
/**
* @brief Sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSize(size_t len) override;
/**
* @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSizeNoCopy(size_t len) override;
/** Default Constructor */
CString_Type();
/**
* @brief Size hint constructor.
* Note: For the CString_Type base class, this is only truly useful internally.
*
* @param size Minimum number of elements the string must be able to hold.
*/
CString_Type(size_t size);
/** Move Constructor */
CString_Type(CString_Type<T> &&source);
/** Copy Constructors */
CString_Type(const CString_Type<T> &in) : CString_Type((Readable_String<T> &)in) {}
CString_Type(const Readable_String<T> &in);
CString_Type(const std::basic_string<T> &in);
CString_Type(const T *in, size_t len);
CString_Type(const T *in);
/** Concatenation Constructors */
CString_Type(const Readable_String<T> &lhs, const T &rhs);
CString_Type(const Readable_String<T> &lhs, const Readable_String<T> &rhs);
CString_Type(const Readable_String<T> &lhs, const std::basic_string<T> &rhs);
CString_Type(const Readable_String<T> &lhs, const T *rhs);
CString_Type(const Readable_String<T> &lhs, const T *rhs, size_t rhs_size);
/** Addition Operators */
inline CString_Type<T> operator+(const T &rhs) const;
inline CString_Type<T> operator+(const CString_Type<T> &rhs) const;
inline CString_Type<T> operator+(const Readable_String<T> &rhs) const;
inline CString_Type<T> operator+(const std::basic_string<T> &rhs) const;
inline CString_Type<T> operator+(const T *rhs) const;
/** Assignment Operators */
inline CString_Type<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const Readable_String<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T right) { this->set(right); return *this; };
static const Jupiter::CString_Type<T> empty; /** Empty instantiation of CString_Type */
protected:
/** Dummy constructor to prevent string initialization */
CString_Type(Jupiter::String_Constructor_Base &) {};
};
template<typename T = char> using CString_Strict = CString_Type<T>;
#if defined JUPITER_CSTRING_TYPE_OPERATOR_PLUS
/** String_Loose<T> Addition Operator */
template<typename T> static inline Jupiter::CString_Type<T> operator+(const Jupiter::Readable_String<T> &lhs, const Jupiter::Readable_String<T> &rhs);
#endif // JUPITER_CSTRING_TYPE_OPERATOR_PLUS
/**
* @brief Provides a "loose" CString implementation that's more optimized for repeated concatenations.
* Note: The underlying C-style string will always have a size which is a power of 2, but no fewer than 8 elements.
*
* @param T Element type which the CString will store. Defaults to char.
*/
template<typename T = char> class CString_Loose : public CString_Type<T>
{
public:
/**
* @brief Returns the maximum number of elements the String can contain,
* without expanding the socket buffer. This is generally the size of the
* underlying memory buffer.
*
* @return Number of elements the string can contain without reallocation.
*/
virtual size_t capacity() const;
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return String containing the new format.
*/
static CString_Loose<T> Format(const T *format, ...);
/**
* @brief Creates a partial copy of the string.
*
* @param pos Position in the string to start copying from.
* @return String containing a partial copy of the original string.
*/
CString_Loose<T> substring(size_t pos) const;
/**
* @brief Creates a partial copy of the string.
*
* @param pos Position in the string to start copying from.
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
CString_Loose<T> substring(size_t pos, size_t length) const;
/**
* @brief Creates a partial copy of the string.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> substring(const Jupiter::Readable_String<T> &in, size_t pos);
static CString_Loose<T> substring(const T *in, size_t pos);
/**
* @brief Creates a partial copy of the string.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> substring(const Jupiter::Readable_String<T> &in, size_t pos, size_t length);
static CString_Loose<T> substring(const T *in, size_t pos, size_t length);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Loose<T> getWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
* Useful when the input string's type isn't known.
*
* @param in String to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> getWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
* Useful when the input string's type isn't known.
*
* @param in C-Style string to get a partial copy of.
* @param pos Position of word in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> getWord(const T *in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Loose<T> gotoWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
*
* @param in String to get a partial copy of.
* @param pos Position in the string to start copying from.
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> gotoWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace);
/**
* @brief Tokenizes a string, based on an input token separator
*
* @param separator Separator to split tokens by
* @return TokenizeResult containing the results of the tokenization process.
*/
typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> tokenize(const T &separator);
typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> tokenize(const Jupiter::Readable_String<T> &separator);
typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> tokenize(const T *separator, size_t separator_size);
/**
* @brief Tokenizes a string, based on an input token separator
*
* @param in String to split into tokens
* @param separator Separator to split tokens by
* @return TokenizeResult containing the results of the tokenization process.
*/
static typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> tokenize(const Jupiter::Readable_String<T> &in, const T &separator);
static typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> tokenize(const Jupiter::Readable_String<T> &in, const Jupiter::Readable_String<T> &separator);
static typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> tokenize(const Jupiter::Readable_String<T> &in, const T *separator, size_t separator_size);
/**
* @brief Sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSize(size_t len) override;
/**
* @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSizeNoCopy(size_t len) override;
/** Default constructor */
CString_Loose();
/**
* @brief Size hint constructor.
*
* @param size Minimum number of elements the string must be able to hold.
*/
CString_Loose(size_t size);
/** Move Constructor */
CString_Loose(CString_Loose<T> &&source);
/** Copy Constructors */
CString_Loose(const CString_Loose<T> &in);
CString_Loose(const Readable_String<T> &in);
CString_Loose(const std::basic_string<T> &in);
CString_Loose(const T *in, size_t len);
CString_Loose(const T *in);
/** Concatenation Constructors */
CString_Loose(const Readable_String<T> &lhs, const T &rhs);
CString_Loose(const Readable_String<T> &lhs, const Readable_String<T> &rhs);
CString_Loose(const Readable_String<T> &lhs, const std::basic_string<T> &rhs);
CString_Loose(const Readable_String<T> &lhs, const T *rhs);
CString_Loose(const Readable_String<T> &lhs, const T *rhs, size_t rhs_size);
/** Addition Operators */
inline CString_Loose<T> operator+(const T &rhs) const;
inline CString_Loose<T> operator+(const CString_Loose<T> &rhs) const;
inline CString_Loose<T> operator+(const Readable_String<T> &rhs) const;
inline CString_Loose<T> operator+(const std::basic_string<T> &rhs) const;
inline CString_Loose<T> operator+(const T *rhs) const;
/** Assignment Operators */
inline CString_Loose<T> &operator=(const CString_Loose<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const Readable_String<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Loose<T> &operator=(const T right) { this->set(right); return *this; };
static const Jupiter::CString_Loose<T> empty; /** Empty instantiation of CString_Loose */
static const size_t start_size = 8; /** Starting size for loose CStrings. */
protected:
/** Dummy constructor to prevent string initialization */
CString_Loose(Jupiter::String_Constructor_Base &) {};
size_t strSize; /** Size of underlying C-string buffer */
};
#if defined JUPITER_CSTRING_LOOSE_OPERATOR_PLUS
/** String_Loose<T> Addition Operator */
template<typename T> static inline Jupiter::CString_LOOSE<T> operator+(const Jupiter::Readable_String<T> &lhs, const Jupiter::Readable_String<T> &rhs);
#endif // JUPITER_CSTRING_LOOSE_OPERATOR_PLUS
/** Definition of a Loose CString. */
typedef CString_Loose<char> CStringL;
/** Definition of a Loose Wide CString */
typedef CString_Loose<wchar_t> WCStringL;
/** Definition of a CString. */
typedef CStringL CString;
/** Definition of a Wide CString */
typedef WCStringL WCString;
/** Generic CString Type */
typedef CString_Type<char> CStringType;
/** Generic Wide CString Type */
typedef CString_Type<wchar_t> WCStringType;
/** Definition of a Strict CString. */
typedef CStringType CStringS;
/** Definition of a Strict Wide CString */
typedef WCStringType WCStringS;
namespace literals
{
/** CString_Strict literals */
inline Jupiter::CStringType operator"" _jcst(const char *str, size_t len) { return Jupiter::CStringType(str, len); }
inline Jupiter::WCStringType operator"" _jwcst(const wchar_t *str, size_t len) { return Jupiter::WCStringType(str, len); }
/** CString_Strict literals */
inline Jupiter::CStringS operator"" _jcss(const char *str, size_t len) { return Jupiter::CStringS(str, len); }
inline Jupiter::WCStringS operator"" _jwcss(const wchar_t *str, size_t len) { return Jupiter::WCStringS(str, len); }
/** CString_Loose literals */
inline Jupiter::CStringL operator"" _jcsl(const char *str, size_t len) { return Jupiter::CStringL(str, len); }
inline Jupiter::WCStringL operator"" _jwcsl(const wchar_t *str, size_t len) { return Jupiter::WCStringL(str, len); }
/** CString literals */
inline Jupiter::CStringS operator"" _jcs(const char *str, size_t len) { return Jupiter::CString(str, len); }
inline Jupiter::WCStringS operator"" _jwcs(const wchar_t *str, size_t len) { return Jupiter::WCString(str, len); }
}
}
/** Re-enable warning */
#if defined _MSC_VER
#pragma warning(pop)
#endif
/** Implementation for CString_Type and CString_Loose. Very scary. */
#include "CString_Imp.h"
#endif // _CSTRING_H_HEADER

932
src/include/Jupiter/CString_Imp.h

@ -1,932 +0,0 @@
/**
* Copyright (C) 2013-2017 Jessica James.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Written by Jessica James <jessica.aj@outlook.com>
*/
#if !defined _CSTRING_IMP_H_HEADER
#define _CSTRING_IMP_H_HEADER
/**
* @file CString_Imp.h
* @brief Provides the implementations for CString_Type functions, as well as extending classes.
* Note: Modification of this file is not supported in any way.
*/
#include "Functions.h"
#include "CString.h"
#include "String.hpp"
#if !defined va_copy
#if defined __INTEL_COMPILER
#pragma message("Warning: va_copy not properly defined. Assuming common implementation.")
#define va_copy(dst, src) ((void)((dst) = (src)))
#else
#error "va_copy not defined."
#endif // __INTEL_COMPILER
#endif // va_copy
#if !defined JUPITER_VSCPRINTF
#if defined _WIN32
#define JUPITER_VSCPRINTF(format, format_args) _vscprintf(format, format_args)
#define JUPITER_VSCWPRINTF(format, format_args) _vscwprintf(format, format_args)
#else // _WIN32
#define JUPITER_VSCPRINTF(format, format_args) vsnprintf(nullptr, 0, format, format_args)
#define JUPITER_VSCWPRINTF(format, format_args) vswprintf(nullptr, 0, format, format_args)
#endif // _WIN32
#endif // JUPITER_VSCPRINTF
/**
* IMPLEMENTATION:
* CString_Type
*/
template<typename T> Jupiter::CString_Type<T>::CString_Type() : Jupiter::CString_Type<T>::CString_Type(size_t(0))
{
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(size_t len)
{
Jupiter::Shift_String_Type<T>::base = new T[len + 1];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0;
Jupiter::String_Type<T>::length = 0;
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(Jupiter::CString_Type<T> &&source) : Jupiter::Shift_String_Type<T>(std::move(source))
{
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const Jupiter::Readable_String<T> &in) : Jupiter::CString_Type<T>::CString_Type(in.ptr(), in.size())
{
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const std::basic_string<T> &in) : Jupiter::CString_Type<T>::CString_Type(in.data(), in.size())
{
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const T *in, size_t len) : Jupiter::CString_Type<T>::CString_Type(len)
{
while (Jupiter::String_Type<T>::length != len)
{
if ((Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = *in) == 0) return;
Jupiter::String_Type<T>::length++;
in++;
}
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = 0;
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const T *in)
{
if (in == nullptr)
{
Jupiter::String_Type<T>::length = 0;
Jupiter::Shift_String_Type<T>::base = new T[1];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0;
}
else
{
Jupiter::String_Type<T>::length = Jupiter::strlen<T>(in);
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::String_Type<T>::length + 1];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
Jupiter::strcpy<T>(Jupiter::String_Type<T>::str, in);
}
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const Jupiter::Readable_String<T> &lhs, const T &rhs) : CString_Type<T>(lhs.size() + 1)
{
const T *itr;
const T *end;
if (lhs.isNotEmpty())
{
itr = lhs.ptr();
end = itr + lhs.size();
*Jupiter::String_Type<T>::str = *itr;
while (++itr != end)
*++Jupiter::String_Type<T>::str = *itr;
++Jupiter::String_Type<T>::str;
}
*Jupiter::String_Type<T>::str = rhs;
*++Jupiter::String_Type<T>::str = 0;
Jupiter::String_Type<T>::length = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const Jupiter::Readable_String<T> &lhs, const Jupiter::Readable_String<T> &rhs) : CString_Type<T>(lhs, rhs.ptr(), rhs.size())
{
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const Jupiter::Readable_String<T> &lhs, const std::basic_string<T> &rhs) : CString_Type<T>(lhs, rhs.data(), rhs.size())
{
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const Jupiter::Readable_String<T> &lhs, const T *rhs) : CString_Type<T>(lhs, rhs, Jupiter::strlen<T>(rhs))
{
}
template<typename T> Jupiter::CString_Type<T>::CString_Type(const Jupiter::Readable_String<T> &lhs, const T *rhs, size_t rhs_size) : CString_Type<T>(lhs.size() + rhs_size)
{
const T *itr;
const T *end;
if (lhs.isNotEmpty())
{
itr = lhs.ptr();
end = itr + lhs.size();
*Jupiter::String_Type<T>::str = *itr;
while (++itr != end)
*++Jupiter::String_Type<T>::str = *itr;
++Jupiter::String_Type<T>::str;
}
if (rhs_size != 0)
{
itr = rhs;
end = itr + rhs_size;
*Jupiter::String_Type<T>::str = *itr;
while (++itr != end)
*++Jupiter::String_Type<T>::str = *itr;
++Jupiter::String_Type<T>::str;
}
*Jupiter::String_Type<T>::str = 0;
Jupiter::String_Type<T>::length = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
}
template<typename T> bool Jupiter::CString_Type<T>::setBufferSize(size_t len)
{
if (Jupiter::Shift_String_Type<T>::setBufferSize(len + 1))
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = 0;
return true;
}
return false;
}
template<typename T> bool Jupiter::CString_Type<T>::setBufferSizeNoCopy(size_t len)
{
bool r = Jupiter::Shift_String_Type<T>::setBufferSizeNoCopy(len + 1);
*Jupiter::String_Type<T>::str = 0;
return r;
}
template<typename T> const T *Jupiter::CString_Type<T>::c_str() const
{
return Jupiter::String_Type<T>::str;
}
template<typename T> size_t Jupiter::CString_Type<T>::truncate(size_t n)
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::truncate(n)] = 0;
return Jupiter::String_Type<T>::length;
}
template<typename T> bool Jupiter::CString_Type<T>::remove(const T &value)
{
if (Jupiter::Shift_String_Type<T>::remove(value))
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = 0;
return true;
}
return false;
}
// vformat()
template<> size_t inline Jupiter::CString_Type<char>::vformat(const char *format, va_list args)
{
int minLen;
va_list sargs;
va_copy(sargs, args);
minLen = JUPITER_VSCPRINTF(format, sargs);
va_end(sargs);
if (minLen < 0) return 0; // We simply can not work with this.
this->setBufferSizeNoCopy(minLen);
Jupiter::String_Type<char>::length = minLen;
vsnprintf(Jupiter::String_Type<char>::str, Jupiter::String_Type<char>::length + 1, format, args);
Jupiter::String_Type<char>::str[Jupiter::String_Type<char>::length] = 0;
return Jupiter::String_Type<char>::length;
}
template<> size_t inline Jupiter::CString_Type<wchar_t>::vformat(const wchar_t *format, va_list args)
{
int minLen;
va_list sargs;
va_copy(sargs, args);
minLen = JUPITER_VSCWPRINTF(format, sargs);
va_end(sargs);
if (minLen < 0) return 0; // We simply can not work with this.
this->setBufferSizeNoCopy(minLen);
Jupiter::String_Type<wchar_t>::length = minLen;
vswprintf(Jupiter::String_Type<wchar_t>::str, Jupiter::String_Type<wchar_t>::length, format, args);
Jupiter::String_Type<wchar_t>::str[Jupiter::String_Type<wchar_t>::length] = 0;
return Jupiter::String_Type<wchar_t>::length;
}
template<typename T> size_t Jupiter::CString_Type<T>::vformat(const T *format, va_list args)
{
return 0;
}
// avformat()
template<> size_t inline Jupiter::CString_Type<char>::avformat(const char *format, va_list args)
{
int minLen;
va_list sargs;
va_copy(sargs, args);
minLen = JUPITER_VSCPRINTF(format, sargs);
va_end(sargs);
if (minLen < 0) return 0; // We simply can not work with this.
this->setBufferSize(Jupiter::String_Type<char>::length + minLen);
minLen = vsnprintf(Jupiter::String_Type<char>::str + Jupiter::String_Type<char>::length, minLen + 1, format, args);
if (minLen <= 0) return 0;
Jupiter::String_Type<char>::length += minLen;
Jupiter::String_Type<char>::str[Jupiter::String_Type<char>::length] = 0;
return minLen;
}
template<> size_t inline Jupiter::CString_Type<wchar_t>::avformat(const wchar_t *format, va_list args)
{
int minLen;
va_list sargs;
va_copy(sargs, args);
minLen = JUPITER_VSCWPRINTF(format, sargs);
va_end(sargs);
if (minLen < 0) return 0; // We simply can not work with this.
this->setBufferSize(minLen + Jupiter::String_Type<wchar_t>::length);
minLen = vswprintf(Jupiter::String_Type<wchar_t>::str + Jupiter::String_Type<wchar_t>::length, minLen, format, args);
if (minLen <= 0) return 0;
Jupiter::String_Type<wchar_t>::length += minLen;
Jupiter::String_Type<wchar_t>::str[Jupiter::String_Type<wchar_t>::length] = 0;
return minLen;
}
template<typename T> size_t Jupiter::CString_Type<T>::avformat(const T *format, va_list args)
{
return 0;
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::Format(const T *format, ...)
{
CString_Type<T> r;
va_list args;
va_start(args, format);
r.vformat(format, args);
va_end(args);
return r;
}
// substring
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::substring(size_t pos) const
{
return Jupiter::CString_Type<T>::substring(*this, pos);
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::substring(size_t pos, size_t len) const
{
return Jupiter::CString_Type<T>::substring(*this, pos, len);
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::substring(const Jupiter::Readable_String<T> &in, size_t pos)
{
if (pos >= in.size()) return Jupiter::CString_Type<T>();
Jupiter::CString_Type<T> r = Jupiter::CString_Type<T>(in.size() - pos);
for (r.length = 0; pos + r.length != in.size() && in.get(pos + r.length) != 0; r.length++) r.str[r.length] = in.get(pos + r.length);
r.str[r.length] = 0;
return r;
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::substring(const T *in, size_t pos)
{
Jupiter::CString_Type<T> r = Jupiter::String_Type<T>::template substring<Jupiter::CString_Type>(in, pos);
r.str[r.length] = 0;
return r;
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::substring(const Jupiter::Readable_String<T> &in, size_t pos, size_t len)
{
if (pos + len >= in.size()) return Jupiter::CString_Type<T>::substring(in, pos);
Jupiter::CString_Type<T> r = Jupiter::CString_Type<T>(len);
for (r.length = 0; r.length != len && in.get(pos + r.length) != 0; r.length++) r.str[r.length] = in.get(pos + r.length);
r.str[r.length] = 0;
return r;
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::substring(const T *in, size_t pos, size_t len)
{
Jupiter::CString_Type<T> r = Jupiter::String_Type<T>::template substring<Jupiter::CString_Type>(in, pos, len);
r.str[r.length] = 0;
return r;
}
// getWord
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::getWord(size_t pos, const T *whitespace) const
{
return Jupiter::CString_Type<T>::getWord(*this, pos, whitespace);
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::getWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace)
{
return Jupiter::Readable_String<T>::template getWord<Jupiter::CString_Type>(in, pos, whitespace);
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::getWord(const T *in, size_t pos, const T *whitespace)
{
return Jupiter::Readable_String<T>::template getWord<Jupiter::CString_Type>(in, pos, whitespace);
}
// gotoWord
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::gotoWord(size_t pos, const T *whitespace) const
{
return Jupiter::CString_Type<T>::gotoWord(*this, pos, whitespace);
}
template<typename T> Jupiter::CString_Type<T> Jupiter::CString_Type<T>::gotoWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace)
{
return Jupiter::Readable_String<T>::template gotoWord<Jupiter::CString_Type>(in, pos, whitespace);
}
// tokenize
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> Jupiter::CString_Type<T>::tokenize(const T &separator) const
{
return Jupiter::CString_Type<T>::tokenize(*this, separator);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> Jupiter::CString_Type<T>::tokenize(const Jupiter::Readable_String<T> &separator) const
{
return Jupiter::CString_Type<T>::tokenize(*this, separator);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> Jupiter::CString_Type<T>::tokenize(const T *separator, size_t separator_size) const
{
return Jupiter::CString_Type<T>::tokenize(*this, separator, separator_size);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> Jupiter::CString_Type<T>::tokenize(const Jupiter::Readable_String<T> &in, const T &token)
{
return typename Jupiter::template Readable_String<T>::template tokenize<typename Jupiter::template CString_Type<T>>(in, token);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> Jupiter::CString_Type<T>::tokenize(const Jupiter::Readable_String<T> &in, const Jupiter::Readable_String<T> &separator)
{
return typename Jupiter::template Readable_String<T>::template tokenize<typename Jupiter::template CString_Type<T>>(in, separator);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Type> Jupiter::CString_Type<T>::tokenize(const Jupiter::Readable_String<T> &in, const T *separator, size_t separator_size)
{
return typename Jupiter::template Readable_String<T>::template tokenize<typename Jupiter::template CString_Type<T>>(in, separator, separator_size);
}
// set
template<typename T> size_t Jupiter::CString_Type<T>::set(const T *in, size_t in_size)
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::set(in, in_size)] = 0;
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::CString_Type<T>::set(const Jupiter::Readable_String<T> &in)
{
return this->set(in.ptr(), in.size());
}
template<typename T> size_t Jupiter::CString_Type<T>::set(const std::basic_string<T> &in)
{
return this->set(in.data(), in.size());
}
template<typename T> size_t Jupiter::CString_Type<T>::set(const T *in)
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::set(in)] = 0;
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::CString_Type<T>::set(const T &in)
{
if (in == 0)
{
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0;
return Jupiter::String_Type<T>::length = 0;
}
this->setBufferSizeNoCopy(1);
*Jupiter::String_Type<T>::str = in;
Jupiter::String_Type<T>::str[1] = 0;
return Jupiter::String_Type<T>::length = 1;
}
// concat
template<typename T> size_t Jupiter::CString_Type<T>::concat(const T *in, size_t in_size)
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::concat(in, in_size)] = 0;
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::CString_Type<T>::concat(const Jupiter::Readable_String<T> &in)
{
return this->concat(in.ptr(), in.size());
}
template<typename T> size_t Jupiter::CString_Type<T>::concat(const std::basic_string<T> &in)
{
return this->concat(in.data(), in.size());
}
template<typename T> size_t Jupiter::CString_Type<T>::concat(const T *in)
{
size_t nSize = Jupiter::String_Type<T>::length + Jupiter::strlen<T>(in);
this->setBufferSize(nSize);
Jupiter::strcpy<T>(Jupiter::String_Type<T>::str + Jupiter::String_Type<T>::length, in);
return Jupiter::String_Type<T>::length = nSize;
}
template<typename T> size_t Jupiter::CString_Type<T>::concat(const T &in)
{
this->setBufferSize(Jupiter::String_Type<T>::length + 1);
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = in;
Jupiter::String_Type<T>::str[++Jupiter::String_Type<T>::length] = 0;
return Jupiter::String_Type<T>::length;
}
// Operators
template<typename T> inline Jupiter::CString_Type<T> Jupiter::CString_Type<T>::operator+(const T &rhs) const
{
return Jupiter::template operator+<T>(*this, rhs);
}
template<typename T> inline Jupiter::CString_Type<T> Jupiter::CString_Type<T>::operator+(const Jupiter::CString_Type<T> &rhs) const
{
return Jupiter::CString_Type<T>::operator+(reinterpret_cast<const Jupiter::Readable_String<T> &>(rhs));
}
template<typename T> inline Jupiter::CString_Type<T> Jupiter::CString_Type<T>::operator+(const Jupiter::Readable_String<T> &rhs) const
{
return Jupiter::operator+(*this, rhs);
}
template<typename T> inline Jupiter::CString_Type<T> Jupiter::CString_Type<T>::operator+(const std::basic_string<T> &rhs) const
{
return Jupiter::operator+(*this, rhs);
}
template<typename T> inline Jupiter::CString_Type<T> Jupiter::CString_Type<T>::operator+(const T *rhs) const
{
return Jupiter::operator+(*this, rhs);
}
#if defined JUPITER_CSTRING_TYPE_OPERATOR_PLUS
template<typename T> static inline Jupiter::CString_Type<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const T &rhs)
{
return Jupiter::CString_Type<T>(lhs, rhs);
}
template<typename T> static inline Jupiter::CString_Type<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const Jupiter::Readable_String<T> &rhs)
{
return Jupiter::CString_Type<T>(lhs, rhs);
}
template<typename T> static inline Jupiter::CString_Type<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const std::basic_string<T> &rhs)
{
return Jupiter::CString_Type<T>(lhs, rhs);
}
template<typename T> static inline Jupiter::CString_Type<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const T *rhs)
{
return Jupiter::CString_Type<T>(lhs, rhs);
}
#endif // JUPITER_CSTRING_TYPE_OPERATOR_PLUS
template<typename T> const Jupiter::CString_Type<T> Jupiter::CString_Type<T>::empty = Jupiter::CString_Type<T>();
// Jupiter::DataBuffer specialization
template<> struct _Jupiter_DataBuffer_partial_specialization_impl<Jupiter::CString_Type>
{
template<typename Y> static void push(Jupiter::DataBuffer *buffer, const Jupiter::CString_Type<Y> *data)
{
_Jupiter_DataBuffer_partial_specialization_impl<Jupiter::Readable_String>::push<Y>(buffer, data);
};
template<typename Y> static Jupiter::CString_Type<Y> interpret(uint8_t *&head)
{
size_t size_ = *reinterpret_cast<size_t *>(head);
head += sizeof(size_t);
Jupiter::CString_Type<Y> r = Jupiter::CString_Type<Y>(reinterpret_cast<Y *>(head), size_);
head += size_;
return r;
}
};
/**
* IMPLEMENTATION:
* CString_Loose
*/
template<typename T> Jupiter::CString_Loose<T>::CString_Loose() : Jupiter::CString_Loose<T>::CString_Loose(Jupiter::CString_Loose<T>::start_size)
{
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(Jupiter::CString_Loose<T> &&source) : Jupiter::CString_Type<T>(std::move(source))
{
Jupiter::CString_Loose<T>::strSize = source.strSize;
source.strSize = 0;
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(size_t len) : Jupiter::CString_Type<T>::CString_Type(Jupiter::stringConstructorBase)
{
if (len < Jupiter::CString_Loose<T>::start_size) Jupiter::CString_Loose<T>::strSize = Jupiter::CString_Loose<T>::start_size;
else Jupiter::CString_Loose<T>::strSize = getPowerTwo(len + 1);
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0;
Jupiter::String_Type<T>::length = 0;
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::CString_Loose<T> &in) : Jupiter::CString_Type<T>::CString_Type(Jupiter::stringConstructorBase)
{
Jupiter::CString_Loose<T>::strSize = in.strSize;
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
Jupiter::strcpy<T>(Jupiter::String_Type<T>::str, in.str);
Jupiter::String_Type<T>::length = in.length;
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::Readable_String<T> &in) : Jupiter::CString_Loose<T>::CString_Loose(in.ptr(), in.size())
{
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const std::basic_string<T> &in) : Jupiter::CString_Loose<T>::CString_Loose(in.data(), in.size())
{
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const T *in, size_t len) : Jupiter::CString_Loose<T>::CString_Loose(len)
{
while (Jupiter::String_Type<T>::length != len)
{
if ((Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = *in) == 0) return;
Jupiter::String_Type<T>::length++;
}
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = 0;
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const T *in) : Jupiter::CString_Type<T>::CString_Type(Jupiter::stringConstructorBase)
{
if (in == nullptr)
{
Jupiter::CString_Loose<T>::strSize = Jupiter::CString_Loose<T>::start_size;
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0;
Jupiter::String_Type<T>::length = 0;
}
else
{
Jupiter::String_Type<T>::length = Jupiter::strlen<T>(in);
Jupiter::CString_Loose<T>::strSize = getPowerTwo(Jupiter::String_Type<T>::length + 1);
if (Jupiter::CString_Loose<T>::strSize < Jupiter::CString_Loose<T>::start_size) Jupiter::CString_Loose<T>::strSize = Jupiter::CString_Loose<T>::start_size;
Jupiter::Shift_String_Type<T>::base = new T[Jupiter::CString_Loose<T>::strSize];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
Jupiter::strcpy<T>(Jupiter::String_Type<T>::str, in);
}
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::Readable_String<T> &lhs, const T &rhs) : CString_Loose<T>(lhs.size() + 1)
{
const T *itr;
const T *end;
if (lhs.isNotEmpty())
{
itr = lhs.ptr();
end = itr + lhs.size();
*Jupiter::String_Type<T>::str = *itr;
while (++itr != end)
*++Jupiter::String_Type<T>::str = *itr;
++Jupiter::String_Type<T>::str;
}
*Jupiter::String_Type<T>::str = rhs;
*++Jupiter::String_Type<T>::str = 0;
Jupiter::String_Type<T>::length = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::Readable_String<T> &lhs, const Jupiter::Readable_String<T> &rhs) : CString_Loose<T>(lhs, rhs.ptr(), rhs.size())
{
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::Readable_String<T> &lhs, const std::basic_string<T> &rhs) : CString_Loose<T>(lhs, rhs.data(), rhs.size())
{
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::Readable_String<T> &lhs, const T *rhs) : CString_Loose<T>(lhs, rhs, Jupiter::strlen<T>(rhs))
{
}
template<typename T> Jupiter::CString_Loose<T>::CString_Loose(const Jupiter::Readable_String<T> &lhs, const T *rhs, size_t rhs_size) : CString_Loose<T>(lhs.size() + rhs_size)
{
const T *itr;
const T *end;
if (lhs.isNotEmpty())
{
itr = lhs.ptr();
end = itr + lhs.size();
*Jupiter::String_Type<T>::str = *itr;
while (++itr != end)
*++Jupiter::String_Type<T>::str = *itr;
++Jupiter::String_Type<T>::str;
}
if (rhs_size != 0)
{
itr = rhs;
end = itr + rhs_size;
*Jupiter::String_Type<T>::str = *itr;
while (++itr != end)
*++Jupiter::String_Type<T>::str = *itr;
++Jupiter::String_Type<T>::str;
}
*Jupiter::String_Type<T>::str = 0;
Jupiter::String_Type<T>::length = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
}
template<typename T> bool Jupiter::CString_Loose<T>::setBufferSize(size_t len)
{
size_t offset = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
++len; // null term
if (len + offset > Jupiter::CString_Loose<T>::strSize)
{
if (len > Jupiter::CString_Loose<T>::strSize)
{
// Buffer is not large enough; reallocate
Jupiter::CString_Loose<T>::strSize = getPowerTwo(len);
T *ptr = new T[Jupiter::CString_Loose<T>::strSize];
for (size_t i = 0; i < Jupiter::String_Type<T>::length; i++)
ptr[i] = Jupiter::String_Type<T>::str[i];
ptr[Jupiter::String_Type<T>::length] = 0;
delete[] Jupiter::Shift_String_Type<T>::base;
Jupiter::Shift_String_Type<T>::base = ptr;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return true;
}
// Buffer has enough space to accomodate; shift data to the left
T *read_itr = Jupiter::String_Type<T>::str;
T *read_end = read_itr + Jupiter::String_Type<T>::length;
T *write_itr = Jupiter::Shift_String_Type<T>::base;
while (read_itr != read_end)
{
*write_itr = *read_itr;
++read_itr;
++write_itr;
}
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
}
return false;
}
template<typename T> bool Jupiter::CString_Loose<T>::setBufferSizeNoCopy(size_t len)
{
len = getPowerTwo(len + 1);
if (len > Jupiter::CString_Loose<T>::strSize)
{
Jupiter::String_Type<T>::length = 0;
delete[] Jupiter::Shift_String_Type<T>::base;
Jupiter::Shift_String_Type<T>::base = new T[len];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0;
return true;
}
Jupiter::String_Type<T>::length = 0;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
*Jupiter::String_Type<T>::str = 0;
return false;
}
template<typename T> size_t Jupiter::CString_Loose<T>::capacity() const
{
return Jupiter::CString_Loose<T>::strSize - 1;
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::Format(const T *format, ...)
{
CString_Loose<T> r;
va_list args;
va_start(args, format);
r.vformat(format, args);
va_end(args);
return r;
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::substring(size_t pos) const
{
return Jupiter::CString_Loose<T>::substring(*this, pos);
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::substring(size_t pos, size_t length) const
{
return Jupiter::CString_Loose<T>::substring(*this, pos, length);
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::substring(const Jupiter::Readable_String<T> &in, size_t pos)
{
if (pos > in.size()) return Jupiter::CString_Loose<T>();
Jupiter::CString_Loose<T> r = Jupiter::CString_Loose<T>(in.size() - pos);
for (r.length = 0; pos + r.length != in.size() && in.get(r.length) != 0; r.length++) r.str[r.length] = in.get(pos + r.length);
r.str[r.length] = 0;
return r;
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::substring(const T *in, size_t pos)
{
Jupiter::CString_Loose<T> r = Jupiter::String_Type<T>::template substring<Jupiter::CString_Loose>(in, pos);
r.str[r.length] = 0;
return r;
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::substring(const Jupiter::Readable_String<T> &in, size_t pos, size_t len)
{
if (pos + len >= in.size()) return Jupiter::CString_Loose<T>::substring(in, pos);
Jupiter::CString_Loose<T> r = Jupiter::CString_Loose<T>(len);
for (r.length = 0; r.length != len && in.get(r.length + pos) != 0; r.length++) r.str[r.length] = in.get(r.length + pos);
r.str[r.length] = 0;
return r;
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::substring(const T *in, size_t pos, size_t len)
{
Jupiter::CString_Loose<T> r = Jupiter::String_Type<T>::template substring<Jupiter::CString_Loose>(in, pos, len);
r.str[r.length] = 0;
return r;
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::getWord(size_t pos, const T *whitespace) const
{
return Jupiter::CString_Loose<T>::getWord(*this, pos, whitespace);
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::getWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace)
{
return Jupiter::Readable_String<T>::template getWord<Jupiter::CString_Loose>(in, pos, whitespace);
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::getWord(const T *in, size_t pos, const T *whitespace)
{
return Jupiter::Readable_String<T>::template getWord<Jupiter::CString_Loose>(in, pos, whitespace);
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::gotoWord(size_t pos, const T *whitespace) const
{
return Jupiter::CString_Loose<T>::gotoWord(*this, pos, whitespace);
}
template<typename T> Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::gotoWord(const Jupiter::Readable_String<T> &in, size_t pos, const T *whitespace)
{
return Jupiter::Readable_String<T>::template gotoWord<Jupiter::CString_Loose>(in, pos, whitespace);
}
// tokenize
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> Jupiter::CString_Loose<T>::tokenize(const T &token)
{
return Jupiter::CString_Loose<T>::tokenize(*this, token);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> Jupiter::CString_Loose<T>::tokenize(const Jupiter::Readable_String<T> &separator)
{
return Jupiter::CString_Loose<T>::tokenize(*this, separator);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> Jupiter::CString_Loose<T>::tokenize(const T *separator, size_t separator_size)
{
return Jupiter::CString_Loose<T>::tokenize(*this, separator, separator_size);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> Jupiter::CString_Loose<T>::tokenize(const Jupiter::Readable_String<T> &in, const T &token)
{
return typename Jupiter::template Readable_String<T>::template tokenize<typename Jupiter::template CString_Loose<T>>(in, token);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> Jupiter::CString_Loose<T>::tokenize(const Jupiter::Readable_String<T> &in, const Jupiter::Readable_String<T> &separator)
{
return typename Jupiter::template Readable_String<T>::template tokenize<typename Jupiter::template CString_Loose<T>>(in, separator);
}
template<typename T> typename Jupiter::Readable_String<T>::template TokenizeResult<Jupiter::CString_Loose> Jupiter::CString_Loose<T>::tokenize(const Jupiter::Readable_String<T> &in, const T *separator, size_t separator_size)
{
return typename Jupiter::template Readable_String<T>::template tokenize<typename Jupiter::template CString_Loose<T>>(in, separator, separator_size);
}
// Operators
template<typename T> inline Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::operator+(const T &rhs) const
{
return Jupiter::operator+(*this, rhs);
}
template<typename T> inline Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::operator+(const Jupiter::CString_Loose<T> &rhs) const
{
return Jupiter::CString_Loose<T>::operator+(reinterpret_cast<const Jupiter::Readable_String<T> &>(rhs));
}
template<typename T> inline Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::operator+(const Jupiter::Readable_String<T> &rhs) const
{
return Jupiter::operator+(*this, rhs);
}
template<typename T> inline Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::operator+(const std::basic_string<T> &rhs) const
{
return Jupiter::operator+(*this, rhs);
}
template<typename T> inline Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::operator+(const T *rhs) const
{
return Jupiter::operator+(*this, rhs);
}
#if defined JUPITER_CSTRING_LOOSE_OPERATOR_PLUS
template<typename T> static inline Jupiter::CString_Loose<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const T &rhs)
{
return Jupiter::CString_Loose<T>(lhs, rhs);
}
template<typename T> static inline Jupiter::CString_Loose<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const Jupiter::Readable_String<T> &rhs)
{
return Jupiter::CString_Loose<T>(lhs, rhs);
}
template<typename T> static inline Jupiter::CString_Loose<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const std::basic_string<T> &rhs)
{
return Jupiter::CString_Loose<T>(lhs, rhs);
}
template<typename T> static inline Jupiter::CString_Loose<T> Jupiter::operator+(const Jupiter::Readable_String<T> &lhs, const T *rhs)
{
return Jupiter::CString_Loose<T>(lhs, rhs);
}
#endif // JUPITER_CSTRING_LOOSE_OPERATOR_PLUS
template<typename T> const Jupiter::CString_Loose<T> Jupiter::CString_Loose<T>::empty = Jupiter::CString_Loose<T>();
// Jupiter::DataBuffer specialization
template<> struct _Jupiter_DataBuffer_partial_specialization_impl<Jupiter::CString_Loose>
{
template<typename Y> static void push(Jupiter::DataBuffer *buffer, const Jupiter::CString_Loose<Y> *data)
{
_Jupiter_DataBuffer_partial_specialization_impl<Jupiter::Readable_String>::push<Y>(buffer, data);
};
template<typename Y> static Jupiter::CString_Loose<Y> interpret(uint8_t *&head)
{
size_t size_ = *reinterpret_cast<size_t *>(head);
head += sizeof(size_t);
Jupiter::CString_Loose<Y> r = Jupiter::CString_Loose<Y>(reinterpret_cast<Y *>(head), size_);
head += size_;
return r;
}
};
#endif // _CSTRING_IMP_H_HEADER

41
src/include/Jupiter/Config.h

@ -24,10 +24,12 @@
* @brief Defines the Config class, which provides common functionality for Config files in differing formats. * @brief Defines the Config class, which provides common functionality for Config files in differing formats.
*/ */
#include <unordered_map>
#include <memory>
#include "Jupiter.h" #include "Jupiter.h"
#include "Hash_Table.h" #include "Hash.h"
#include "Reference_String.h" #include "Reference_String.h"
#include "CString.h" #include "String.hpp"
/** DLL Linkage Nagging */ /** DLL Linkage Nagging */
#if defined _MSC_VER #if defined _MSC_VER
@ -44,7 +46,14 @@ namespace Jupiter
{ {
public: public:
/** Hash_Table type for sections */ /** Hash_Table type for sections */
typedef Hash_Table<StringS, Config, ReadableString> SectionHashTable; using SectionHashTable = std::unordered_map<StringS, Config, default_hash_function>;
using ValuesHashTable = std::unordered_map<StringS, StringS, default_hash_function>;
Config() = default;
Config(const Config& in_config);
Config(Config&& in_config) = default;
Config& operator=(const Config& in_config);
Config& operator=(Config&& in_config) = default;
/** /**
* @brief Fetches the value of an entry. * @brief Fetches the value of an entry.
@ -55,14 +64,6 @@ namespace Jupiter
*/ */
const Jupiter::ReadableString &get(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_default_value = Jupiter::ReferenceString::empty) const; const Jupiter::ReadableString &get(const Jupiter::ReadableString &in_key, const Jupiter::ReadableString &in_default_value = Jupiter::ReferenceString::empty) const;
/**
* @brief Fetches the value of an entry
*
* @param in_key Key of the entry to fetch
* @return Pointer to the value of the entry on success, nullptr otherwise
*/
const Jupiter::ReadableString *getValue(const Jupiter::ReadableString &in_key) const;
/** /**
* @brief Fetches the value of an entry and interprets it as another type. * @brief Fetches the value of an entry and interprets it as another type.
* *
@ -114,7 +115,7 @@ namespace Jupiter
* *
* @return Name of this section * @return Name of this section
*/ */
const Jupiter::ReadableString &getName() const; const std::string &getName() const;
/** /**
* @brief Erases all data from this section * @brief Erases all data from this section
@ -188,14 +189,14 @@ namespace Jupiter
* *
* @return Reference to m_table * @return Reference to m_table
*/ */
inline const HashTable &getTable() const { return m_table; } inline const ValuesHashTable &getTable() const { return m_table; }
/** /**
* @brief Fetches a reference to this config's subsections * @brief Fetches a reference to this config's subsections
* *
* @return Reference to m_sections * @return Reference to m_sections
*/ */
inline const SectionHashTable &getSections() const { return m_sections; } const SectionHashTable &getSections() const;
/** Subscript operator */ /** Subscript operator */
Config &operator[](const Jupiter::ReadableString &in_key); Config &operator[](const Jupiter::ReadableString &in_key);
@ -224,13 +225,13 @@ namespace Jupiter
virtual bool write_internal(const char *in_filename); virtual bool write_internal(const char *in_filename);
/** Name of this Config section. This is empty or the filename at the root level. */ /** Name of this Config section. This is empty or the filename at the root level. */
Jupiter::CStringS m_name; std::string m_name;
/** Table of entries within this section */ /** Table of entries within this section */
HashTable m_table; ValuesHashTable m_table;
/** Table of sections within this section */ /** Table of sections within this section */
SectionHashTable m_sections; std::unique_ptr<SectionHashTable> m_sections;
}; };
} }
@ -238,12 +239,12 @@ namespace Jupiter
template<typename T> inline T Jupiter::Config::get(const Jupiter::ReadableString &in_key, T in_default_value) const template<typename T> inline T Jupiter::Config::get(const Jupiter::ReadableString &in_key, T in_default_value) const
{ {
const Jupiter::ReadableString *result = m_table.get(in_key); auto result = m_table.find(in_key);
if (result == nullptr) if (result == m_table.end())
return in_default_value; return in_default_value;
return static_cast<T>(*result); return static_cast<T>(result->second);
} }
/** Re-enable warnings */ /** Re-enable warnings */

10
src/include/Jupiter/Database.h

@ -24,7 +24,7 @@
* @brief Defines a database file structure. * @brief Defines a database file structure.
*/ */
#include "CString.h" #include "String.hpp"
namespace Jupiter namespace Jupiter
{ {
@ -67,7 +67,7 @@ namespace Jupiter
* @return True on success, false otherwise * @return True on success, false otherwise
*/ */
bool process_file(const Jupiter::ReadableString &file); bool process_file(const Jupiter::ReadableString &file);
bool process_file(const Jupiter::CStringType &file); bool process_file(const std::string &file);
bool process_file(const char *file); bool process_file(const char *file);
bool process_file(FILE *file); bool process_file(FILE *file);
@ -83,7 +83,7 @@ namespace Jupiter
* *
* @return Name of the file on the file system. * @return Name of the file on the file system.
*/ */
const Jupiter::CStringType &getFilename() const; const std::string &getFilename() const;
/** /**
* @brief Appends a DataBuffer to the end of the Database. * @brief Appends a DataBuffer to the end of the Database.
@ -100,7 +100,7 @@ namespace Jupiter
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
static bool append(Jupiter::ReadableString &file, Jupiter::DataBuffer &data); static bool append(Jupiter::ReadableString &file, Jupiter::DataBuffer &data);
static bool append(Jupiter::CStringType &file, Jupiter::DataBuffer &data); static bool append(std::string &file, Jupiter::DataBuffer &data);
static bool append(const char *file, Jupiter::DataBuffer &data); static bool append(const char *file, Jupiter::DataBuffer &data);
static bool append(FILE *file, Jupiter::DataBuffer &data); static bool append(FILE *file, Jupiter::DataBuffer &data);
@ -112,7 +112,7 @@ namespace Jupiter
* @param header DataBuffer containing the header to write to the file * @param header DataBuffer containing the header to write to the file
*/ */
static bool create_database(const Jupiter::ReadableString &file, const Jupiter::DataBuffer *header = nullptr); static bool create_database(const Jupiter::ReadableString &file, const Jupiter::DataBuffer *header = nullptr);
static bool create_database(const Jupiter::CStringType &file, const Jupiter::DataBuffer *header = nullptr); static bool create_database(const std::string &file, const Jupiter::DataBuffer *header = nullptr);
static bool create_database(const char *file, const Jupiter::DataBuffer *header = nullptr); static bool create_database(const char *file, const Jupiter::DataBuffer *header = nullptr);
/** /**

2
src/include/Jupiter/File.h

@ -55,7 +55,7 @@ namespace Jupiter
* *
* @return String containing the name of the first file loaded into this file. * @return String containing the name of the first file loaded into this file.
*/ */
const Jupiter::ReadableString &getFileName() const; const std::string &getFileName() const;
/** /**
* @brief Adds data to a file, which may consist of one or more lines. * @brief Adds data to a file, which may consist of one or more lines.

31
src/include/Jupiter/HTTP_QueryString.h

@ -19,8 +19,8 @@
#if !defined _HTTP_QUERYSTRING_H_HEADER #if !defined _HTTP_QUERYSTRING_H_HEADER
#define _HTTP_QUERYSTRING_H_HEADER #define _HTTP_QUERYSTRING_H_HEADER
#include <unordered_map>
#include "String.hpp" #include "String.hpp"
#include "Hash_Table.h"
/** /**
* @file HTTP_QueryString.h * @file HTTP_QueryString.h
@ -52,7 +52,28 @@ namespace Jupiter
HTMLFormResponse() = delete; HTMLFormResponse() = delete;
inline HTMLFormResponse(const Jupiter::ReadableString &query_string) : HTMLFormResponse(query_string.ptr(), query_string.size()) {} inline HTMLFormResponse(const Jupiter::ReadableString &query_string) : HTMLFormResponse(query_string.ptr(), query_string.size()) {}
inline HTMLFormResponse(const char *ptr, size_t str_size); inline HTMLFormResponse(const char *ptr, size_t str_size);
Jupiter::HashTable table; using TableType = std::unordered_map<Jupiter::StringS, Jupiter::StringS, Jupiter::default_hash_function>;
template<typename CastT>
CastT tableGetCast(const Jupiter::StringS &in_key, const CastT &in_value) const {
auto item = table.find(in_key);
if (item != table.end()) {
return static_cast<CastT>(item->second);
}
return in_value;
}
const Jupiter::ReadableString& tableGet(const Jupiter::StringS& in_key, const Jupiter::ReadableString& in_value) {
auto item = table.find(in_key);
if (item != table.end()) {
return item->second;
}
return in_value;
}
TableType table;
}; };
} }
} }
@ -164,7 +185,7 @@ inline Jupiter::HTTP::HTMLFormResponse::HTMLFormResponse(const char *ptr, size_t
else if (*ptr == '&') // End of key/value, start of key else if (*ptr == '&') // End of key/value, start of key
{ {
if (key.isNotEmpty()) // A key was already set; end of value if (key.isNotEmpty()) // A key was already set; end of value
Jupiter::HTTP::HTMLFormResponse::table.set(key, Jupiter::ReferenceString(token_start, buf - token_start)); Jupiter::HTTP::HTMLFormResponse::table[key] = Jupiter::ReferenceString(token_start, buf - token_start);
key.erase(); key.erase();
++buf, ++ptr; ++buf, ++ptr;
@ -190,13 +211,13 @@ inline Jupiter::HTTP::HTMLFormResponse::HTMLFormResponse(const char *ptr, size_t
{ {
key.set(token_start, ++buf - token_start); key.set(token_start, ++buf - token_start);
*buf = *++ptr; *buf = *++ptr;
Jupiter::HTTP::HTMLFormResponse::table.set(key, Jupiter::ReferenceString(ptr, 1)); Jupiter::HTTP::HTMLFormResponse::table[key] = Jupiter::ReferenceString(ptr, 1);
} }
else else
*++buf = *++ptr; *++buf = *++ptr;
if (key.isNotEmpty()) // A key was already set; end of value if (key.isNotEmpty()) // A key was already set; end of value
Jupiter::HTTP::HTMLFormResponse::table.set(key, Jupiter::ReferenceString(token_start, buf - token_start + 1)); Jupiter::HTTP::HTMLFormResponse::table[key] = Jupiter::ReferenceString(token_start, buf - token_start + 1);
Jupiter::StringType::length = buf + 1 - str; Jupiter::StringType::length = buf + 1 - str;
} }

285
src/include/Jupiter/Hash_Table.h

@ -1,285 +0,0 @@
/**
* Copyright (C) 2016-2017 Jessica James.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Written by Jessica James <jessica.aj@outlook.com>
*/
#if !defined _HASH_TABLE_H_HEADER
#define _HASH_TABLE_H_HEADER
/**
* @file Hash_Table.h
* @brief Defines a generic hash table structure
*/
#include <forward_list>
#include "String.hpp"
namespace Jupiter
{
template<typename T> inline size_t default_hash_function(const T &in);
/**
* @brief Provides a generic hash table structure
*
* @param KeyT Type the table will use for keys; must implement following: operator==, move constructor
* @param ValueT Type the table will use for values
* @param InKeyT Type the table will accept for keys (Default: KeyT)
* @param InValueT Type the table will accept for values (Default: ValueT)
* @param HashF Function to be used for generating hashes (Default: Fowler-Noll-Vo 1a)
*/
template<typename KeyT, typename ValueT, typename InKeyT = KeyT, typename InValueT = ValueT, size_t(*HashF)(const InKeyT &) = Jupiter::default_hash_function<InKeyT>> class Hash_Table
{
public:
/** Initial number of buckets to allocate; m_buckets_size is never less than INIT_SIZE. */
static constexpr const size_t INIT_SIZE = 8;
/**
* @brief Container for table entries
*/
struct Bucket
{
/**
* @brief An individual entry within the table, including its normal key and value.
*/
struct Entry
{
KeyT key;
ValueT value;
Entry(const InKeyT &in_key);
Entry(const InKeyT &in_key, const InValueT &in_value);
};
/**
* @brief Searches for an entry in the bucket and returns its value if it exists.
*
* @param in_key Key of the entry to search for
* @return Pointer to the value of the entry if it exists, nullptr otherwise
*/
const ValueT *get(const InKeyT &in_key) const;
ValueT *get(const InKeyT &in_key);
const InValueT &get(const InKeyT &in_key, const InValueT &in_value) const;
template<typename CastT> CastT getCast(const InKeyT &in_key, const CastT &in_value) const;
/**
* @brief Sets the value for an entry in the bucket
*
* @param in_key Key of the entry to set
* @param in_value Value to set in the entry
* @return True if a new entry was added, false if an entry was overwritten
*/
bool set(const InKeyT &in_key, const InValueT &in_value);
bool set(const InKeyT &in_key);
/**
* @brief Removes an entry from the table
*
* @param in_key Key of the entry to remove
* @return True if an entry was removed, false otherwise
*/
bool remove(const InKeyT &in_key);
/**
* @brief Calls a function for each Entry in the table, passing each Entry as a parameter
*
* @param CallT Function type to call
*
* @param in_callback Function to callback
*/
template<typename CallT> void callback(CallT &in_callback) const;
template<typename CallT> void callback(CallT &in_callback);
/**
* @brief Copy assignment operator
*
* @param in_bucket Bucket to copy entries from
* @return Reference to this bucket
*/
Bucket &operator=(const Bucket &in_bucket);
/**
* @brief Move assignment operator
*
* @param in_bucket Bucket to move entries from
* @return Reference to this bucket
*/
Bucket &operator=(Bucket &&in_bucket);
/**
* @brief Default constructor for the Bucket class
*/
Bucket() = default;
/**
* @brief Copy constructor for the Bucket class
*/
Bucket(const Bucket &in_bucket);
/**
* @brief Move constructor for the Bucket class
*/
Bucket(Bucket &&in_bucket);
/**
* @brief Destructor for the Bucket class
*/
~Bucket();
/** List of entries in the bucket */
std::forward_list<Entry> m_entries;
};
/**
* @brief Returns an iterator positioned at the beginning of the table
*
* @brief Iterator at beginning of m_buckets
*/
Bucket *begin() const;
/**
* @brief Returns an iterator positioned at the end of the table
*
* @return Iterator at end of m_buckets
*/
Bucket *end() const;
/**
* @brief Fetches the value of an entry based on its key
*
* @param in_key Key of the entry to search for
* @return Value of the entry if it exists, nullptr otherwise
*/
ValueT *get(const InKeyT &in_key) const;
const InValueT &get(const InKeyT &in_key, const InValueT &in_value) const;
template<typename CastT> CastT getCast(const InKeyT &in_key, const CastT &in_value) const;
/**
* @brief Sets the value for an entry in the table
*
* @param in_key Key of the entry to set
* @param in_value Value of the entry to set
* @return True if a new entry was added, false if an entry was overwritten
*/
bool set(const InKeyT &in_key, const InValueT &in_value);
bool set(const InKeyT &in_key);
/**
* @brief Removes an entry from the table
*
* @param in_key Key of the entry to remove
* @return True if an entry was removed, false otherwise
*/
bool remove(const InKeyT &in_key);
/**
* @brief Calls a function for each Entry in the table, passing each Entry as a parameter
*
* @param CallT Function type to call
*
* @param in_callback Function to callback
*/
template<typename CallT> void callback(CallT &in_callback) const;
template<typename CallT> void callback(CallT &in_callback);
/**
* @brief Returns the number of entries in the table
*
* @return Number of entries in the table
*/
size_t size() const;
/**
* @brief Erases the table's contents
*/
void erase();
/**
* @brief Shrinks the table's internal bucket pool to the current number of entries, not to be less than INIT_SIZE.
*/
void shrink();
/**
* @brief Copy assignment operator
*
* @param in_table Table to copy entries from
* @return Reference to this table
*/
Hash_Table &operator=(const Hash_Table &in_table);
/**
* @brief Move assignment operator
*
* @param in_table Table to move entries from
* @return Reference to this table
*/
Hash_Table &operator=(Hash_Table &&in_table);
/**
* @brief Default constructor for the Hash_Table class
*/
Hash_Table();
/**
* @brief Allocation constructor for the Hash_Table class
*
* @param in_buckets_size Number of buckets to initialize to
*/
Hash_Table(size_t in_buckets_size);
/**
* @brief Copy constructor for the Hash_Table class
*
* @param in_table Table to copy entries from
*/
Hash_Table(const Hash_Table &in_table);
/**
* @brief Move constructor for the Hash_Table class
*
* @param in_table Table to move entries from
*/
Hash_Table(Hash_Table &&in_table);
/**
* @brief Destructor for the Hash_Table class
*/
~Hash_Table();
private:
/**
* @brief Doubles the size of m_buckets
*/
void expand();
/**
* @brief Copies entries from m_buckets to in_buckets; used when expanding or shrinking m_buckets.
*
* @param in_buckets Array of buckets to copy entries into
* @param in_buckets_size Number of buckets in in_buckets
*/
void copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size) const;
Bucket *m_buckets; /** Array of Buckets */
size_t m_buckets_size; /** Number of buckets */
size_t m_length = 0; /** Number of entries */
};
typedef Hash_Table<Jupiter::StringS, Jupiter::StringS, Jupiter::ReadableString, Jupiter::ReadableString, Jupiter::default_hash_function<Jupiter::ReadableString>> HashTable;
}
#include "Hash_Table_Imp.h"
#endif // _HASH_TABLE_H_HEADER

503
src/include/Jupiter/Hash_Table_Imp.h

@ -1,503 +0,0 @@
/**
* Copyright (C) 2016-2017 Jessica James.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Written by Jessica James <jessica.aj@outlook.com>
*/
#if !defined _HASH_TABLE_IMP_H_HEADER
#define _HASH_TABLE_IMP_H_HEADER
/**
* @file Hash_Table_Imp.h
* @brief Provides the implementation for Hash_Table.
*/
#include "Hash_Table.h"
#include "Hash.h"
/**
* IMPLEMENTATION:
* Hash_Table
*/
/** Conditional is constant; can probably be removed when 'if constexpr' support is added to MSVC */
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4127)
#endif
template<typename T> inline size_t Jupiter::default_hash_function(const T &in)
{
if (sizeof(size_t) >= sizeof(uint64_t))
return static_cast<size_t>(Jupiter::fnv1a(in));
return static_cast<size_t>(Jupiter::fnv1a_32(in));
}
/** Re-enable warnings */
#if defined _MSC_VER
#pragma warning(pop)
#endif
/** Hash_Table::Bucket::Entry */
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Entry::Entry(const InKeyT &in_key)
: key{ in_key }
{
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Entry::Entry(const InKeyT &in_key, const InValueT &in_value)
: key{ in_key }, value{ in_value }
{
}
/** Hash_Table::Bucket */
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
const ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key) const
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->key == in_key)
return &node->value;
return nullptr;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key)
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->key == in_key)
return &node->value;
return nullptr;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
const InValueT &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key, const InValueT &in_value) const
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->key == in_key)
return node->value;
return in_value;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CastT>
CastT Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::getCast(const InKeyT &in_key, const CastT &in_value) const
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->key == in_key)
return static_cast<CastT>(node->value);
return in_value;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::set(const InKeyT &in_key, const InValueT &in_value)
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->key == in_key)
{
node->value = in_value;
return false;
}
m_entries.emplace_front(in_key, in_value);
return true;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::set(const InKeyT &in_key)
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->key == in_key)
return false;
m_entries.emplace_front(in_key);
return true;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::remove(const InKeyT &in_key)
{
auto node = m_entries.begin();
auto end = m_entries.end();
// No nodes in the bucket
if (node == end)
return false;
// Check if the head is the desired node
if (node->key == in_key)
{
m_entries.pop_front();
return true;
}
auto next_node = node;
++next_node;
// iterate through list
while (next_node != end)
{
if (next_node->key == in_key)
{
// The next node is the desired node
m_entries.erase_after(node);
return true;
}
node = next_node;
++next_node;
}
return false;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CallT>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::callback(CallT &in_callback) const
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
in_callback(*node);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CallT>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::callback(CallT &in_callback)
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
in_callback(*node);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::operator=(const Bucket &in_bucket)
{
m_entries.clear();
for (auto node = in_bucket.m_entries.begin(); node != m_entries.end(); ++node)
m_entries.emplace_front(node->key, node->value);
return *this;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::operator=(Bucket &&in_bucket)
{
m_entries = std::move(in_bucket.m_entries);
return *this;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Bucket(const Bucket &in_bucket)
{
for (auto node = in_bucket.m_entries.getHead(); node != in_bucket.m_entries.end(); ++node)
m_entries.emplace_front(node->key, node->value);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Bucket(Bucket &&in_bucket)
{
m_entries = std::move(in_bucket.m_entries);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::~Bucket()
{
m_entries.clear();
}
/** Hash_Table */
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::begin() const
{
return m_buckets;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::end() const
{
return m_buckets + m_buckets_size;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::get(const InKeyT &in_key) const
{
return m_buckets[HashF(in_key) % m_buckets_size].get(in_key);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
const InValueT &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::get(const InKeyT &in_key, const InValueT &in_value) const
{
return m_buckets[HashF(in_key) % m_buckets_size].get(in_key, in_value);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CastT>
CastT Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::getCast(const InKeyT &in_key, const CastT &in_value) const
{
return m_buckets[HashF(in_key) % m_buckets_size].getCast(in_key, in_value);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::set(const InKeyT &in_key, const InValueT &in_value)
{
if (m_buckets[HashF(in_key) % m_buckets_size].set(in_key, in_value))
{
if (++m_length == m_buckets_size)
expand();
return true;
}
return false;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::set(const InKeyT &in_key)
{
if (m_buckets[HashF(in_key) % m_buckets_size].set(in_key))
{
if (++m_length == m_buckets_size)
expand();
return true;
}
return false;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::remove(const InKeyT &in_key)
{
if (m_buckets[HashF(in_key) % m_buckets_size].remove(in_key))
{
--m_length;
return true;
}
return false;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CallT>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::callback(CallT &in_callback) const
{
Bucket *itr = m_buckets;
Bucket *end = m_buckets + m_buckets_size;
while (itr != end)
{
itr->template callback<CallT>(in_callback);
++itr;
}
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CallT>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::callback(CallT &in_callback)
{
Bucket *itr = m_buckets;
Bucket *end = m_buckets + m_buckets_size;
while (itr != end)
{
itr->template callback<CallT>(in_callback);
++itr;
}
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
size_t Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::size() const
{
return m_length;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::erase()
{
m_length = 0;
delete[] m_buckets;
m_buckets_size = INIT_SIZE;
m_buckets = new Bucket[m_buckets_size];
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::shrink()
{
size_t buckets_size = m_length < INIT_SIZE ? INIT_SIZE : m_length;
Bucket *buckets = new Bucket[buckets_size];
copy_to_buckets(buckets, buckets_size);
delete[] m_buckets;
m_buckets = buckets;
m_buckets_size = buckets_size;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF> &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::operator=(const Hash_Table &in_table)
{
if (m_buckets_size >= in_table.m_buckets_size && m_buckets_size <= in_table.m_buckets_size * 2)
{
// We're larger than what we're copying, but not drastically (2x) larger. Just erase our current data and copy their entries.
if (m_length == 0) // we don't need to erase any data
in_table.copy_to_buckets(m_buckets, m_buckets_size);
else
{
// we need to erase data; slightly modified version of copy_to_buckets()
size_t index = 0;
while (index != in_table.m_buckets_size)
{
in_table.m_buckets[index].m_entries.clear();
for (auto node = in_table.m_buckets[index].m_entries.begin(); node != in_table.m_buckets[index].m_entries.end(); ++node)
m_buckets[HashF(node->key) % m_buckets_size].set(node->key, node->value);
++index;
}
while (index != m_buckets_size)
{
in_table.m_buckets[index].m_entries.clear();
++index;
}
}
}
else
{
// m_buckets is either too small to copy the data, or it'd be too wasteful
delete[] m_buckets;
m_buckets_size = in_table.m_buckets_size;
m_buckets = new Bucket[m_buckets_size];
for (size_t index = 0; index != m_buckets_size; ++index)
m_buckets[index] = in_table.m_buckets[index];
}
m_length = in_table.m_length;
return *this;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF> &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::operator=(Hash_Table &&in_table)
{
if (m_length == 0)
{
Bucket *old_buckets = m_buckets;
size_t old_buckets_size = m_buckets_size;
m_buckets = in_table.m_buckets;
m_buckets_size = in_table.m_buckets_size;
m_length = in_table.m_length;
in_table.m_buckets = old_buckets;
in_table.m_buckets_size = old_buckets_size;
}
else
{
delete[] m_buckets;
m_buckets = in_table.m_buckets;
m_buckets_size = in_table.m_buckets_size;
m_length = in_table.m_length;
in_table.m_buckets = new Bucket[1];
in_table.m_buckets_size = 1;
}
in_table.m_length = 0;
return *this;
}
/** Constructors */
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Hash_Table()
{
m_buckets_size = INIT_SIZE;
m_buckets = new Bucket[m_buckets_size];
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Hash_Table(size_t in_buckets_size)
{
m_buckets_size = in_buckets_size;
m_buckets = new Bucket[m_buckets_size];
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Hash_Table(const Hash_Table &in_table)
{
m_length = in_table.m_length;
m_buckets_size = in_table.m_buckets_size;
m_buckets = new Bucket[m_buckets_size];
for (size_t index = 0; index != m_buckets_size; ++index)
m_buckets[index] = in_table.m_buckets[index];
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Hash_Table(Hash_Table &&in_table)
{
m_buckets = in_table.m_buckets;
m_buckets_size = in_table.m_buckets_size;
m_length = in_table.m_length;
in_table.m_buckets = new Bucket[1];
in_table.m_buckets_size = 1;
in_table.m_length = 0;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::~Hash_Table()
{
delete[] m_buckets;
}
/** Hash_Table/private */
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::expand()
{
size_t buckets_size = m_buckets_size * 2;
Bucket *buckets = new Bucket[buckets_size];
copy_to_buckets(buckets, buckets_size);
delete[] m_buckets;
m_buckets = buckets;
m_buckets_size = buckets_size;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size) const
{
for (size_t index = 0; index != m_buckets_size; ++index)
for (auto node = m_buckets[index].m_entries.begin(); node != m_buckets[index].m_entries.end(); ++node)
in_buckets[HashF(node->key) % in_buckets_size].set(node->key, node->value);
}
#endif // _HASH_TABLE_IMP_H_HEADER

14
src/include/Jupiter/IRC_Client.h

@ -314,7 +314,7 @@ namespace Jupiter
Jupiter::StringS m_prefixes; Jupiter::StringS m_prefixes;
}; };
typedef Jupiter::Hash_Table<Jupiter::StringS, Channel::User, Jupiter::ReadableString> UserTableType; using UserTableType = std::unordered_map<Jupiter::StringS, Channel::User, default_hash_function>;
/** /**
* @brief Returns the name of the channel. * @brief Returns the name of the channel.
@ -428,8 +428,8 @@ namespace Jupiter
bool m_adding_names; bool m_adding_names;
}; // Jupiter::IRC::Client::Channel class }; // Jupiter::IRC::Client::Channel class
typedef Jupiter::Hash_Table<Jupiter::StringS, Client::Channel, Jupiter::ReadableString> ChannelTableType; using ChannelTableType = std::unordered_map<Jupiter::StringS, Client::Channel, default_hash_function>;
typedef Jupiter::Hash_Table<Jupiter::StringS, Client::User, Jupiter::ReadableString> UserTableType; using UserTableType = std::unordered_map<Jupiter::StringS, Client::User, default_hash_function>;
/** /**
* @brief Returns the name of the primary config section this client reads from. * @brief Returns the name of the primary config section this client reads from.
@ -473,7 +473,7 @@ namespace Jupiter
* *
* @return String containing a log file's name. * @return String containing a log file's name.
*/ */
const Jupiter::ReadableString &getLogFile() const; const std::string &getLogFile() const;
/** /**
* @brief Returns the nickname prefixes supported by the connected server. * @brief Returns the nickname prefixes supported by the connected server.
@ -516,7 +516,7 @@ namespace Jupiter
* *
* @return String containing a hostname. * @return String containing a hostname.
*/ */
const Jupiter::ReadableString &getServerHostname() const; const std::string &getServerHostname() const;
/** /**
* @brief Returns the server's port. * @brief Returns the server's port.
@ -829,7 +829,7 @@ namespace Jupiter
private: private:
Jupiter::Socket *m_socket; Jupiter::Socket *m_socket;
uint16_t m_server_port; uint16_t m_server_port;
Jupiter::CStringS m_server_hostname; std::string m_server_hostname;
bool m_ssl; bool m_ssl;
Jupiter::StringS m_ssl_certificate; Jupiter::StringS m_ssl_certificate;
@ -842,7 +842,7 @@ namespace Jupiter
Jupiter::StringS m_primary_section_name; Jupiter::StringS m_primary_section_name;
Jupiter::Config *m_primary_section; Jupiter::Config *m_primary_section;
Jupiter::Config *m_secondary_section; Jupiter::Config *m_secondary_section;
Jupiter::CStringS m_log_file_name; std::string m_log_file_name;
Jupiter::StringS m_last_line; Jupiter::StringS m_last_line;
Jupiter::StringS m_server_name; Jupiter::StringS m_server_name;
Jupiter::StringS m_nickname; Jupiter::StringS m_nickname;

2
src/include/Jupiter/Shift_String.h

@ -125,7 +125,7 @@ namespace Jupiter
virtual ~Shift_String_Type(); virtual ~Shift_String_Type();
protected: protected:
T *base; /** Base pointer for the underlying String's memory allocation */ T *base{ nullptr }; /** Base pointer for the underlying String's memory allocation */
}; };
} }

6
src/include/Jupiter/Socket.h

@ -32,8 +32,10 @@
struct addrinfo; struct addrinfo;
#ifdef _WIN32 #ifdef _WIN32
#define JUPITER_SOCK_EWOULDBLOCK 10035
struct in_addr6; struct in_addr6;
#else #else
#define JUPITER_SOCK_EWOULDBLOCK EWOULDBLOCK
#define in_addr6 in6_addr #define in_addr6 in6_addr
struct in6_addr; struct in6_addr;
#endif #endif
@ -294,7 +296,7 @@ namespace Jupiter
* *
* @return String containing the hostname. * @return String containing the hostname.
*/ */
const Jupiter::ReadableString &getRemoteHostname() const; const std::string &getRemoteHostname() const;
const char *getRemoteHostnameC() const; const char *getRemoteHostnameC() const;
/** /**
@ -302,7 +304,7 @@ namespace Jupiter
* *
* @return String containing the hostname. * @return String containing the hostname.
*/ */
const Jupiter::ReadableString &getBoundHostname() const; const std::string &getBoundHostname() const;
const char *getBoundHostnameC() const; const char *getBoundHostnameC() const;
/** /**

19
src/include/Jupiter/String.hpp

@ -27,6 +27,7 @@
*/ */
#include "Shift_String.h" #include "Shift_String.h"
#include "Hash.h"
/** Disable warning 4458 */ /** Disable warning 4458 */
#if defined _MSC_VER #if defined _MSC_VER
@ -269,11 +270,6 @@ namespace Jupiter
inline String_Strict<T> &operator=(const T right) { this->set(right); return *this; }; inline String_Strict<T> &operator=(const T right) { this->set(right); return *this; };
static const Jupiter::String_Strict<T> empty; /** Empty instantiation of String_Strict */ static const Jupiter::String_Strict<T> empty; /** Empty instantiation of String_Strict */
protected:
/** Dummy constructor to prevent string initialization */
String_Strict(Jupiter::String_Constructor_Base &) {};
}; };
#if defined JUPITER_STRING_STRICT_OPERATOR_PLUS #if defined JUPITER_STRING_STRICT_OPERATOR_PLUS
@ -549,9 +545,6 @@ namespace Jupiter
static const size_t start_size = 8; /** Starting size for loose Strings. */ static const size_t start_size = 8; /** Starting size for loose Strings. */
protected: protected:
/** Dummy constructor to prevent string initialization */
String_Loose(Jupiter::String_Constructor_Base &) {};
size_t strSize; /** Size of underlying string buffer */ size_t strSize; /** Size of underlying string buffer */
}; };
@ -597,6 +590,16 @@ namespace Jupiter
inline Jupiter::StringS operator""_js(const char *str, size_t len) { return Jupiter::String(str, len); } inline Jupiter::StringS operator""_js(const char *str, size_t len) { return Jupiter::String(str, len); }
inline Jupiter::WStringS operator""_jws(const wchar_t *str, size_t len) { return Jupiter::WString(str, len); } inline Jupiter::WStringS operator""_jws(const wchar_t *str, size_t len) { return Jupiter::WString(str, len); }
} }
// Carried over from Hash_Table.h for compatibility
struct default_hash_function {
size_t operator()(const Jupiter::ReadableString& in) const {
if constexpr (sizeof(size_t) >= sizeof(uint64_t))
return static_cast<size_t>(Jupiter::fnv1a<char>(in));
return static_cast<size_t>(Jupiter::fnv1a_32<char>(in));
}
};
} }
/** Re-enable warning */ /** Re-enable warning */

2
src/include/Jupiter/String_Imp.h

@ -54,7 +54,7 @@
* String_Strict * String_Strict
*/ */
template<typename T> Jupiter::String_Strict<T>::String_Strict() : Jupiter::String_Strict<T>::String_Strict(size_t(0)) template<typename T> Jupiter::String_Strict<T>::String_Strict()
{ {
} }

4
src/include/Jupiter/String_Type.h

@ -307,8 +307,8 @@ namespace Jupiter
virtual ~String_Type() = default; virtual ~String_Type() = default;
protected: protected:
T *str; /** Pointer for the underlying string of elements */ T *str{}; /** Pointer for the underlying string of elements */
size_t length; /** Number of representable elements in the string */ size_t length{}; /** Number of representable elements in the string */
}; };
/** Generic String Type */ /** Generic String Type */

5
src/include/Jupiter/String_Type_Imp.h

@ -796,11 +796,6 @@ template<typename T> template<template<typename> class R> R<T> Jupiter::String_T
return r; return r;
} }
namespace Jupiter
{
static struct String_Constructor_Base {} stringConstructorBase;
}
// Jupiter::DataBuffer specialization // Jupiter::DataBuffer specialization
template<> struct _Jupiter_DataBuffer_partial_specialization_impl<Jupiter::String_Type> template<> struct _Jupiter_DataBuffer_partial_specialization_impl<Jupiter::String_Type>

Loading…
Cancel
Save