diff --git a/settings.cpp b/settings.cpp index 55cb1ff..a226226 100644 --- a/settings.cpp +++ b/settings.cpp @@ -25,7 +25,7 @@ Settings::~Settings() { } -void Settings::add_line(String const& section, String const& key, String const& val) +void Settings::add_line(char const* section, char const* key, char const* val) { //TODO: do something with the line Serial.print("Section: \""); @@ -35,6 +35,10 @@ void Settings::add_line(String const& section, String const& key, String const& Serial.print("\", Val: \""); Serial.print(val); Serial.println("\""); + + delete[] section; + delete[] key; + delete[] val; } Settings const* Settings::load(char const* settings_filename) @@ -62,9 +66,9 @@ Settings const* Settings::load(char const* settings_filename) bool is_section_line = false; unsigned int nb_whitespace = 0; //used for trimming the end of lines - String current_section = ""; - String current_key = ""; - String current_val = ""; + StringBuilder current_section; + StringBuilder current_key; + StringBuilder current_val; bool write_to_key = true; @@ -89,7 +93,7 @@ Settings const* Settings::load(char const* settings_filename) else if (c == '[') { is_section_line = true; - current_section = ""; + current_section.clear(); continue; } } @@ -100,10 +104,12 @@ Settings const* Settings::load(char const* settings_filename) is_comment_line = false; is_section_line = false; - settings->add_line(current_section, current_key, current_val); + settings->add_line(current_section.to_string(), + current_key.to_string(), + current_val.to_string()); - current_key = ""; - current_val = ""; + current_key.clear(); + current_val.clear(); write_to_key = true; } else if(is_comment_line) @@ -142,7 +148,9 @@ Settings const* Settings::load(char const* settings_filename) } } if(!first_char_of_line && !is_comment_line && !is_section_line) - settings->add_line(current_section, current_key, current_val); + settings->add_line(current_section.to_string(), + current_key.to_string(), + current_val.to_string()); file.close(); diff --git a/settings.h b/settings.h index fc54e26..3419271 100644 --- a/settings.h +++ b/settings.h @@ -1,7 +1,7 @@ #ifndef SETTINGS_H #define SETTINGS_H -#include "Arduino.h" +#include "string_builder.h" #include "wifi_settings.h" #include "clock_settings.h" @@ -11,7 +11,9 @@ class Settings Settings(); ~Settings(); - void add_line(String const& section, String const& key, String const& val); + void add_line(char const* section, + char const* key, + char const* val); public: static Settings const* load(char const* settings_filename); diff --git a/string_builder.cpp b/string_builder.cpp new file mode 100644 index 0000000..c81b7ad --- /dev/null +++ b/string_builder.cpp @@ -0,0 +1,62 @@ +#include "string_builder.h" + +StringBuilder::StringBuilder(): + m_size(0), + m_front(nullptr) +{ +} + +StringBuilder::~StringBuilder() +{ + if(m_front != nullptr) + delete m_front; +} + +void StringBuilder::clear() +{ + if(m_front != nullptr) + delete m_front; + m_front = nullptr; + + m_size = 0; +} + +bool StringBuilder::empty() const +{ + return m_size == 0; +} + +void StringBuilder::append(char const c) +{ + ++m_size; + Node* new_front = new Node(m_front, c); + m_front = new_front; +} + +char* StringBuilder::to_string() const +{ + char* ret = new char[m_size + 1]; + if(ret == nullptr) + return ret; + + //populating the string in reverse + //because m_front is the last char of the string + ret[m_size] = '\0'; + unsigned int i = m_size - 1; + for(Node const* it = m_front; it != nullptr; it = it->next()) + ret[i--] = it->getChar(); + + return ret; +} + +StringBuilder::Node::Node(Node* next, char c): + m_next(next), + m_c(c) +{ +} + +StringBuilder::Node::~Node() +{ + if(m_next != nullptr) + delete m_next; +} diff --git a/string_builder.h b/string_builder.h new file mode 100644 index 0000000..0aa8138 --- /dev/null +++ b/string_builder.h @@ -0,0 +1,63 @@ +/** + * @file string_builder.h + * @author n0m1s + */ +#ifndef STRING_BUILDER_H +#define STRING_BUILDER_H + +/** + * @brief Object used to create string by appending chars without re-allocations + */ +class StringBuilder +{ + public: + StringBuilder(); + ~StringBuilder(); + + /** + * @brief empties everything and go back to an empty string + */ + void clear(); + + /** + * @return true if this is empty + */ + bool empty() const; + + /** + * @brief appends a character + */ + void append(char const c); + inline void operator += (char const c) {this-> append(c);} + + /** + * @brief get the string + * + * @return a dynamically allocated string (be sure to delete it afterwards) + */ + char* to_string() const; + + protected: + /** + * @brief Class used to simulate a std::forward_list + */ + class Node + { + public: + Node(Node* next, char c); + ~Node(); + + inline char getChar() const {return m_c;} + inline Node const* next() const {return m_next;} + + protected: + Node* m_next; + char m_c; + }; + + protected: + unsigned int m_size; + Node * m_front; +}; + +#endif //STRING_BUILDER_H