Browse Source

Removed shiftLeft/shiftRight; Fixed a bug in parsing IRC modes; refactored INI file parsing slightly

master
Jessica James 3 years ago
parent
commit
273bb80abf
  1. 46
      src/common/Config.cpp
  2. 87
      src/common/INIConfig.cpp
  3. 9
      src/common/IRC_Client.cpp
  4. 4
      src/common/Socket.cpp
  5. 19
      src/include/Jupiter/Config.h
  6. 1
      src/include/Jupiter/Readable_String.h
  7. 16
      src/include/Jupiter/Shift_String.h
  8. 25
      src/include/Jupiter/Shift_String_Imp.h
  9. 32
      src/include/Jupiter/Socket.h

46
src/common/Config.cpp

@ -29,8 +29,7 @@ Jupiter::Config& Jupiter::Config::operator=(const Config& in_config) {
return *this; return *this;
} }
std::string_view Jupiter::Config::get(std::string_view in_key, std::string_view in_default_value) const std::string_view Jupiter::Config::get(std::string_view in_key, std::string_view in_default_value) const {
{
auto value = m_table.find(JUPITER_WRAP_CONFIG_KEY(in_key)); auto value = m_table.find(JUPITER_WRAP_CONFIG_KEY(in_key));
if (value != m_table.end()) { if (value != m_table.end()) {
return value->second; return value->second;
@ -39,8 +38,7 @@ std::string_view Jupiter::Config::get(std::string_view in_key, std::string_view
return in_default_value; return in_default_value;
} }
Jupiter::Config *Jupiter::Config::getSection(std::string_view in_key) const Jupiter::Config *Jupiter::Config::getSection(std::string_view in_key) const {
{
if (m_sections != nullptr) { if (m_sections != nullptr) {
auto section = m_sections->find(JUPITER_WRAP_CONFIG_KEY(in_key)); auto section = m_sections->find(JUPITER_WRAP_CONFIG_KEY(in_key));
if (section != m_sections->end()) { if (section != m_sections->end()) {
@ -51,8 +49,7 @@ Jupiter::Config *Jupiter::Config::getSection(std::string_view in_key) const
return nullptr; return nullptr;
} }
Jupiter::Config &Jupiter::Config::getSectionReference(std::string_view in_key) Jupiter::Config &Jupiter::Config::getSectionReference(std::string_view in_key) {
{
if (m_sections == nullptr) { if (m_sections == nullptr) {
m_sections = std::make_unique<SectionHashTable>(); m_sections = std::make_unique<SectionHashTable>();
} }
@ -117,35 +114,29 @@ bool Jupiter::Config::read(std::string_view in_filename) {
return this->read_internal(m_name.c_str()); return this->read_internal(m_name.c_str());
} }
bool Jupiter::Config::write() bool Jupiter::Config::write() {
{
return this->write(m_name.c_str()); return this->write(m_name.c_str());
} }
bool Jupiter::Config::write(const char *in_filename) bool Jupiter::Config::write(const char *in_filename) {
{
return this->write_internal(in_filename); return this->write_internal(in_filename);
} }
bool Jupiter::Config::write(std::string_view in_filename) bool Jupiter::Config::write(std::string_view in_filename) {
{
return this->write(static_cast<std::string>(in_filename).c_str()); return this->write(static_cast<std::string>(in_filename).c_str());
} }
bool Jupiter::Config::reload() bool Jupiter::Config::reload() {
{
this->erase(); this->erase();
return this->read_internal(m_name.c_str()); return this->read_internal(m_name.c_str());
} }
bool Jupiter::Config::reload(const char *in_filename) bool Jupiter::Config::reload(const char *in_filename) {
{
this->erase(); this->erase();
return this->read(in_filename); return this->read(in_filename);
} }
bool Jupiter::Config::reload(std::string_view in_filename) bool Jupiter::Config::reload(std::string_view in_filename) {
{
this->erase(); this->erase();
return this->read(in_filename); return this->read(in_filename);
} }
@ -159,29 +150,16 @@ const Jupiter::Config::SectionHashTable &Jupiter::Config::getSections() const {
} }
/** Operators */ /** Operators */
Jupiter::Config &Jupiter::Config::operator[](std::string_view in_key) Jupiter::Config &Jupiter::Config::operator[](std::string_view in_key) {
{
return this->getSectionReference(in_key); return this->getSectionReference(in_key);
} }
/** Private functions */ /** Private functions */
bool Jupiter::Config::read_internal(const char *) bool Jupiter::Config::read_internal(const char *) {
{
return false; return false;
} }
bool Jupiter::Config::write_internal(const char *) bool Jupiter::Config::write_internal(const char *) {
{
return false; return false;
} }
void Jupiter::Config::Buffer::set_length(size_t in_length)
{
this->length = in_length;
}
char *Jupiter::Config::Buffer::get_str() const
{
return this->str;
}

87
src/common/INIConfig.cpp

@ -82,13 +82,10 @@ bool Jupiter::INIConfig::write_internal(const char *in_filename)
} }
bool Jupiter::INIConfig::read_internal(const char *in_filename) { bool Jupiter::INIConfig::read_internal(const char *in_filename) {
std::string_view line;
std::stack<Jupiter::Config *> section_stack; std::stack<Jupiter::Config *> section_stack;
section_stack.push(this); section_stack.push(this);
auto process_line = [&line, &section_stack]() auto process_line = [&section_stack](std::string_view line) {
{
const char *itr = line.data(); const char *itr = line.data();
const char *end = itr + line.size(); // guaranteed to be greater than itr const char *end = itr + line.size(); // guaranteed to be greater than itr
@ -189,9 +186,9 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) {
constexpr size_t READ_CHUNK_SIZE = 1024; constexpr size_t READ_CHUNK_SIZE = 1024;
size_t read_count = READ_CHUNK_SIZE; size_t read_count = READ_CHUNK_SIZE;
Buffer buffer; char* line_head;
char *itr; char* read_head;
char *end; char* read_end;
// Open file // Open file
FILE *file = fopen(in_filename, "rb"); FILE *file = fopen(in_filename, "rb");
@ -199,63 +196,57 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) {
if (file == nullptr) if (file == nullptr)
return false; return false;
buffer.setBufferSize(READ_CHUNK_SIZE * 2);
// Parse file contents // Parse file contents
while (read_count == READ_CHUNK_SIZE) char buffer[READ_CHUNK_SIZE];
{ std::string line;
// Ensure the buffer has at least READ_CHUNK_SIZE space remaining do {
buffer.setBufferSize(buffer.size() + READ_CHUNK_SIZE);
// Read data from file to end of buffer // Read data from file to end of buffer
itr = buffer.get_str(); read_head = buffer;
read_count = fread(itr + buffer.size(), sizeof(char), READ_CHUNK_SIZE, file); read_count = fread(buffer, sizeof(char), READ_CHUNK_SIZE, file);
buffer.set_length(buffer.size() + read_count); read_end = read_head + read_count;
end = itr + buffer.size(); line_head = nullptr;
// Reset line
line = std::string_view(buffer.data(), 0);
// Parse buffer for lines // Parse buffer for lines
while (itr != end) while (read_head != read_end) {
{
// Check if the line is over // Check if the line is over
if (*itr == '\n' || *itr == '\r') if (*read_head == '\n' || *read_head == '\r') {
{ if (line_head == nullptr) {
// Process line // There's not any pending data; process a view from the line_head to here
line = std::string_view(buffer.data(), itr - buffer.data()); process_line({ buffer, static_cast<size_t>(read_head - buffer) });
if (!line.empty()) }
process_line(); else {
// There's pending data; join these together and process it
// Keep iterating until next non-newline character line.append(line_head, read_head);
while (true) process_line(line);
{ line.clear();
++itr;
if (itr == end)
{
// No data remains to be parsed in buffer; erase buffer and break
buffer.clear();
break;
} }
if (*itr != '\n' && *itr != '\r') // Keep iterating until next non-newline character
{ for (++read_head; read_head != read_end; ++read_head) {
if (*read_head != '\n' && *read_head != '\r') {
// Shift buffer and break // Shift buffer and break
buffer.shiftRight(itr - buffer.data()); line_head = read_head;
break; break;
} }
} }
} }
else else {
++itr; ++read_head;
} }
} }
// We've processed the read buffer; push any pending line data to the line buffer
if (line_head == nullptr) {
// No newlines in the entire buffer; should be rare
line_head = buffer;
}
line.append(line_head, read_head);
} while (read_count == READ_CHUNK_SIZE);
// Process data remaining in buffer as a line // Process data remaining in buffer as a line
line = std::string_view(buffer.data(), buffer.size()); if (!line.empty()) {
if (!line.empty()) process_line(line);
process_line(); }
// File has been successfully read, or an error occurred. // File has been successfully read, or an error occurred.
fclose(file); fclose(file);

9
src/common/IRC_Client.cpp

@ -789,7 +789,7 @@ int Jupiter::IRC::Client::process_line(std::string_view line) {
else if (jessilib::equalsi(command_token, "NOTICE"sv)) { else if (jessilib::equalsi(command_token, "NOTICE"sv)) {
std::string_view channel_name = getLineToken(2); std::string_view channel_name = getLineToken(2);
if (!channel_name.empty()) { if (!channel_name.empty()) {
size_t pos = line.find('!', 0); size_t pos = line.find('!');
auto message = jessilib::split_once_view(line, ':').second; auto message = jessilib::split_once_view(line, ':').second;
if (pos < line.find(' ')) { if (pos < line.find(' ')) {
auto nick = line.substr(1, pos); auto nick = line.substr(1, pos);
@ -964,11 +964,8 @@ int Jupiter::IRC::Client::process_line(std::string_view line) {
if (!channel_name.empty()) { if (!channel_name.empty()) {
if (m_chan_types.find(channel_name[0]) != std::string::npos) { if (m_chan_types.find(channel_name[0]) != std::string::npos) {
auto nick = getSender(line); auto nick = getSender(line);
if (!nick.empty()) { if (!nick.empty() && line_split.size() >= 4) {
std::string_view mode_line = line.substr(std::min(line.find(' ', 2), line.size())); std::string_view mode_line = line.substr(line_split[3].data() - line.data());
if (!mode_line.empty()) {
mode_line.remove_prefix(1);
}
auto split_mode_line = jessilib::word_split_once_view(mode_line, ' '); auto split_mode_line = jessilib::word_split_once_view(mode_line, ' ');
std::string_view modes = split_mode_line.first; std::string_view modes = split_mode_line.first;

4
src/common/Socket.cpp

@ -65,6 +65,10 @@ size_t Jupiter::Socket::Buffer::capacity() const {
return m_buffer_capacity; return m_buffer_capacity;
} }
size_t Jupiter::Socket::Buffer::size() const {
return m_buffer_size;
}
void Jupiter::Socket::Buffer::reserve(size_t new_capacity) { void Jupiter::Socket::Buffer::reserve(size_t new_capacity) {
if (capacity() == new_capacity // Skip when already this size if (capacity() == new_capacity // Skip when already this size
|| new_capacity == 0 // Don't allow empty buffers, results in 0 from recv || new_capacity == 0 // Don't allow empty buffers, results in 0 from recv

19
src/include/Jupiter/Config.h

@ -217,25 +217,6 @@ namespace Jupiter
/** Subscript operator */ /** Subscript operator */
Config &operator[](std::string_view in_key); Config &operator[](std::string_view in_key);
/** Used for low-level string operations */
class Buffer : public Jupiter::StringL
{
public:
/**
* @brief Sets the length of the string
*
* @param in_length Length of the string
*/
void set_length(size_t in_length);
/**
* @brief Returns a pointer to the underlying string
*
* @return Pointer to an array of characters
*/
char *get_str() const;
};
protected: protected:
virtual bool read_internal(const char *in_filename); virtual bool read_internal(const char *in_filename);
virtual bool write_internal(const char *in_filename); virtual bool write_internal(const char *in_filename);

1
src/include/Jupiter/Readable_String.h

@ -163,6 +163,7 @@ namespace Jupiter {
inline std::string vstring_printf(const char* format, va_list args) { inline std::string vstring_printf(const char* format, va_list args) {
std::string result; std::string result;
// Calculate size needed for formatted string
va_list args_copy; va_list args_copy;
va_copy(args_copy, args); va_copy(args_copy, args);
int min_length = std::vsnprintf(nullptr, 0, format, args_copy); int min_length = std::vsnprintf(nullptr, 0, format, args_copy);

16
src/include/Jupiter/Shift_String.h

@ -45,22 +45,6 @@ namespace Jupiter
{ {
public: public:
/**
* @brief Shifts the string pointer to the left.
*
* @param length Number of elements to shift
* @return Number of elements shifted to the left.
*/
size_t shiftLeft(size_t length);
/**
* @brief Shifts the string pointer to the right.
*
* @param length Number of elements to shift
* @return Number of elements shifted.
*/
size_t shiftRight(size_t length);
/** /**
* @brief Removes the first instance of an element from the string. * @brief Removes the first instance of an element from the string.
* *

25
src/include/Jupiter/Shift_String_Imp.h

@ -36,30 +36,16 @@ template<typename T> Jupiter::Shift_String_Type<T>::~Shift_String_Type()
if (Jupiter::Shift_String_Type<T>::base != nullptr) delete[] Jupiter::Shift_String_Type<T>::base; if (Jupiter::Shift_String_Type<T>::base != nullptr) delete[] Jupiter::Shift_String_Type<T>::base;
} }
template<typename T> size_t Jupiter::Shift_String_Type<T>::shiftLeft(size_t len)
{
size_t offset = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
if (len > offset) len = offset;
Jupiter::String_Type<T>::str -= len;
Jupiter::String_Type<T>::length += len;
return len;
}
template<typename T> size_t Jupiter::Shift_String_Type<T>::shiftRight(size_t len)
{
if (len > Jupiter::String_Type<T>::length) len = Jupiter::String_Type<T>::length;
Jupiter::String_Type<T>::str += len;
Jupiter::String_Type<T>::length -= len;
return len;
}
template<typename T> bool Jupiter::Shift_String_Type<T>::remove(const T &value) template<typename T> bool Jupiter::Shift_String_Type<T>::remove(const T &value)
{ {
if (Jupiter::String_Type<T>::length == 0) return false; if (Jupiter::String_Type<T>::length == 0) return false;
if (*Jupiter::String_Type<T>::str == value) if (*Jupiter::String_Type<T>::str == value)
{ {
if (Jupiter::String_Type<T>::length == 1) this->truncate(1); if (Jupiter::String_Type<T>::length == 1) this->truncate(1);
else this->shiftRight(1); else {
++Jupiter::String_Type<T>::str;
--Jupiter::String_Type<T>::length;
}
return true; return true;
} }
return Jupiter::String_Type<T>::remove(value); return Jupiter::String_Type<T>::remove(value);
@ -67,9 +53,6 @@ template<typename T> bool Jupiter::Shift_String_Type<T>::remove(const T &value)
template<typename T> void Jupiter::Shift_String_Type<T>::remove(size_t index, size_t len) template<typename T> void Jupiter::Shift_String_Type<T>::remove(size_t index, size_t len)
{ {
if (index == 0)
this->shiftRight(len);
else
Jupiter::String_Type<T>::remove(index, len); Jupiter::String_Type<T>::remove(index, len);
} }

32
src/include/Jupiter/Socket.h

@ -518,30 +518,21 @@ namespace Jupiter
*/ */
virtual ~Socket(); virtual ~Socket();
/** Protected functions and members*/
protected:
#if defined _WIN32
typedef uintptr_t SocketType;
#else
typedef int SocketType;
#endif
/** /**
* @brief An extended verison of the string class, which allows for low-level length and string modification. * @brief An extremely basic data buffer
*/ */
class Buffer class Buffer {
{
public: public:
Buffer(); Buffer();
~Buffer(); ~Buffer();
void set_length(size_t in_length); void set_length(size_t in_length);
size_t capacity() const; [[nodiscard]] size_t capacity() const;
[[nodiscard]] size_t size() const;
void reserve(size_t new_capacity); void reserve(size_t new_capacity);
void clear(); void clear();
std::string_view view() const; [[nodiscard]] std::string_view view() const;
void* data() const; [[nodiscard]] void* data() const;
char* chr_data() const; [[nodiscard]] char* chr_data() const;
private: private:
void* m_buffer; void* m_buffer;
@ -549,6 +540,15 @@ namespace Jupiter
size_t m_buffer_size; size_t m_buffer_size;
}; };
/** Protected functions and members*/
protected:
#if defined _WIN32
typedef uintptr_t SocketType;
#else
typedef int SocketType;
#endif
/** /**
* @brief Fetches the buffer where data is stored * @brief Fetches the buffer where data is stored
* *

Loading…
Cancel
Save