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;
}
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));
if (value != m_table.end()) {
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;
}
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) {
auto section = m_sections->find(JUPITER_WRAP_CONFIG_KEY(in_key));
if (section != m_sections->end()) {
@ -51,8 +49,7 @@ Jupiter::Config *Jupiter::Config::getSection(std::string_view in_key) const
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) {
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());
}
bool Jupiter::Config::write()
{
bool Jupiter::Config::write() {
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);
}
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());
}
bool Jupiter::Config::reload()
{
bool Jupiter::Config::reload() {
this->erase();
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();
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();
return this->read(in_filename);
}
@ -159,29 +150,16 @@ const Jupiter::Config::SectionHashTable &Jupiter::Config::getSections() const {
}
/** 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);
}
/** Private functions */
bool Jupiter::Config::read_internal(const char *)
{
bool Jupiter::Config::read_internal(const char *) {
return false;
}
bool Jupiter::Config::write_internal(const char *)
{
bool Jupiter::Config::write_internal(const char *) {
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) {
std::string_view line;
std::stack<Jupiter::Config *> section_stack;
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 *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;
size_t read_count = READ_CHUNK_SIZE;
Buffer buffer;
char *itr;
char *end;
char* line_head;
char* read_head;
char* read_end;
// Open file
FILE *file = fopen(in_filename, "rb");
@ -199,63 +196,57 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) {
if (file == nullptr)
return false;
buffer.setBufferSize(READ_CHUNK_SIZE * 2);
// Parse file contents
while (read_count == READ_CHUNK_SIZE)
{
// Ensure the buffer has at least READ_CHUNK_SIZE space remaining
buffer.setBufferSize(buffer.size() + READ_CHUNK_SIZE);
char buffer[READ_CHUNK_SIZE];
std::string line;
do {
// Read data from file to end of buffer
itr = buffer.get_str();
read_count = fread(itr + buffer.size(), sizeof(char), READ_CHUNK_SIZE, file);
buffer.set_length(buffer.size() + read_count);
end = itr + buffer.size();
// Reset line
line = std::string_view(buffer.data(), 0);
read_head = buffer;
read_count = fread(buffer, sizeof(char), READ_CHUNK_SIZE, file);
read_end = read_head + read_count;
line_head = nullptr;
// Parse buffer for lines
while (itr != end)
{
while (read_head != read_end) {
// Check if the line is over
if (*itr == '\n' || *itr == '\r')
{
// Process line
line = std::string_view(buffer.data(), itr - buffer.data());
if (!line.empty())
process_line();
// Keep iterating until next non-newline character
while (true)
{
++itr;
if (itr == end)
{
// No data remains to be parsed in buffer; erase buffer and break
buffer.clear();
break;
if (*read_head == '\n' || *read_head == '\r') {
if (line_head == nullptr) {
// There's not any pending data; process a view from the line_head to here
process_line({ buffer, static_cast<size_t>(read_head - buffer) });
}
else {
// There's pending data; join these together and process it
line.append(line_head, read_head);
process_line(line);
line.clear();
}
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
buffer.shiftRight(itr - buffer.data());
line_head = read_head;
break;
}
}
}
else
++itr;
else {
++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
line = std::string_view(buffer.data(), buffer.size());
if (!line.empty())
process_line();
if (!line.empty()) {
process_line(line);
}
// File has been successfully read, or an error occurred.
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)) {
std::string_view channel_name = getLineToken(2);
if (!channel_name.empty()) {
size_t pos = line.find('!', 0);
size_t pos = line.find('!');
auto message = jessilib::split_once_view(line, ':').second;
if (pos < line.find(' ')) {
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 (m_chan_types.find(channel_name[0]) != std::string::npos) {
auto nick = getSender(line);
if (!nick.empty()) {
std::string_view mode_line = line.substr(std::min(line.find(' ', 2), line.size()));
if (!mode_line.empty()) {
mode_line.remove_prefix(1);
}
if (!nick.empty() && line_split.size() >= 4) {
std::string_view mode_line = line.substr(line_split[3].data() - line.data());
auto split_mode_line = jessilib::word_split_once_view(mode_line, ' ');
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;
}
size_t Jupiter::Socket::Buffer::size() const {
return m_buffer_size;
}
void Jupiter::Socket::Buffer::reserve(size_t new_capacity) {
if (capacity() == new_capacity // Skip when already this size
|| 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 */
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:
virtual bool read_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) {
std::string result;
// Calculate size needed for formatted string
va_list args_copy;
va_copy(args_copy, args);
int min_length = std::vsnprintf(nullptr, 0, format, args_copy);

16
src/include/Jupiter/Shift_String.h

@ -45,22 +45,6 @@ namespace Jupiter
{
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.
*

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;
}
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)
{
if (Jupiter::String_Type<T>::length == 0) return false;
if (*Jupiter::String_Type<T>::str == value)
{
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 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)
{
if (index == 0)
this->shiftRight(len);
else
Jupiter::String_Type<T>::remove(index, len);
}

32
src/include/Jupiter/Socket.h

@ -518,30 +518,21 @@ namespace Jupiter
*/
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:
Buffer();
~Buffer();
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 clear();
std::string_view view() const;
void* data() const;
char* chr_data() const;
[[nodiscard]] std::string_view view() const;
[[nodiscard]] void* data() const;
[[nodiscard]] char* chr_data() const;
private:
void* m_buffer;
@ -549,6 +540,15 @@ namespace Jupiter
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
*

Loading…
Cancel
Save