diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9da8cb6..269da2c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,6 +20,7 @@ add_executable(${PROJECT_NAME}
curl_wrapper.cpp
index_response.cpp
pastie_response.cpp
+ ini_file.cpp
)
target_include_directories(${PROJECT_NAME} SYSTEM
diff --git a/src/ini_file.cpp b/src/ini_file.cpp
new file mode 100644
index 0000000..77d4874
--- /dev/null
+++ b/src/ini_file.cpp
@@ -0,0 +1,139 @@
+/* Copyright 2017, Michele Santullo
+ * This file is part of "tawashi".
+ *
+ * "tawashi" is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * "tawashi" is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with "tawashi". If not, see .
+ */
+
+#include "ini_file.hpp"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace tawashi {
+ namespace {
+ typedef std::string string_type;
+
+ template
+ struct IniGrammar : boost::spirit::qi::grammar {
+ explicit IniGrammar (const std::string* parString);
+ boost::spirit::qi::rule start;
+ boost::spirit::qi::rule section_head;
+ boost::spirit::qi::rule key;
+ boost::spirit::qi::rule key_value;
+ boost::spirit::qi::rule key_values;
+ const std::string* m_master_string;
+ Iterator m_begin;
+ };
+
+ template
+ IniGrammar::IniGrammar (const std::string* parString) :
+ IniGrammar::base_type(start),
+ m_master_string(parString),
+ m_begin(m_master_string->cbegin())
+ {
+ assert(m_master_string);
+ namespace px = boost::phoenix;
+ using boost::spirit::ascii::space;
+ using boost::spirit::qi::_val;
+ using boost::spirit::_1;
+ using boost::spirit::qi::char_;
+ using boost::spirit::qi::eol;
+ typedef IniFile::KeyValueMapType refpair;
+
+ section_head = '[' >> +(char_ - ']') >> ']' >> eol;
+ key = +(char_ - '=');
+ key_value = key >> '=' >> *(char_ - eol) >> eol;
+ key_values = *key_value;
+ start = *(section_head >> key_values);
+
+ //start %= *(section_head >> key_values);
+ //key_values %= *key_value;
+ //key_value = key[px::bind(&refpair::first, _val) = _1] >> '=' >>
+ // raw[*char_][px::bind(&refpair::second, _val) = px::bind(
+ // &string_ref::substr,
+ // px::construct(px::ref(*m_master_string)),
+ // px::begin(_1) - px::ref(m_begin), px::size(_1)
+ //)];
+ //key = as_string[+(char_ - '=')][_val = px::bind(
+ // &string_ref::substr,
+ // px::construct(px::ref(*m_master_string)),
+ // px::begin(_1) - px::ref(m_begin), px::size(_1)
+ //)];
+ //section_head = '[' >> as_string[(+char_ - ']')][_val = px::bind(
+ // &string_ref::substr,
+ // px::construct(px::ref(*m_master_string)),
+ // px::begin(_1) - px::ref(m_begin), px::size(_1)
+ //)] >> ']';
+ }
+
+ IniFile::IniMapType parse_ini (const std::string* parIni) {
+ using boost::spirit::qi::blank;
+ using boost::spirit::qi::blank_type;
+
+ IniGrammar gramm(parIni);
+ IniFile::IniMapType result;
+
+ std::string::const_iterator start_it = parIni->cbegin();
+ /*const bool parse_ok =*/ boost::spirit::qi::phrase_parse(
+ start_it,
+ parIni->cend(),
+ gramm,
+ blank,
+ result
+ );
+
+ //assert(parse_ok and (parIni->cend() == start_it));
+ return result;
+ }
+ } //unnamed namespace
+
+ IniFile::IniFile (std::istream_iterator parInputFrom, std::istream_iterator parInputEnd) :
+ IniFile(std::string(parInputFrom, parInputEnd))
+ {
+ }
+
+ IniFile::IniFile (std::string&& parIniData) :
+ m_raw_ini(std::move(parIniData)),
+ m_map(parse_ini(&m_raw_ini))
+ {
+ }
+
+ IniFile::IniFile (IniFile&& parOther) {
+ auto* const old_data_ptr = parOther.m_raw_ini.data();
+ m_raw_ini = std::move(parOther.m_raw_ini);
+ if (m_raw_ini.data() == old_data_ptr)
+ m_map = std::move(parOther.m_map);
+ else
+ m_map = parse_ini(&m_raw_ini);
+ }
+
+ IniFile::~IniFile() noexcept {
+ }
+} //namespace tawashi
diff --git a/src/ini_file.hpp b/src/ini_file.hpp
new file mode 100644
index 0000000..004fbf9
--- /dev/null
+++ b/src/ini_file.hpp
@@ -0,0 +1,45 @@
+/* Copyright 2017, Michele Santullo
+ * This file is part of "tawashi".
+ *
+ * "tawashi" is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * "tawashi" is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with "tawashi". If not, see .
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace tawashi {
+ class IniFile {
+ public:
+ typedef boost::container::flat_map KeyValueMapType;
+ typedef boost::container::flat_map IniMapType;
+
+ IniFile (std::istream_iterator parInputFrom, std::istream_iterator parInputEnd);
+ explicit IniFile (std::string&& parIniData);
+ IniFile (IniFile&& parOther);
+ IniFile (const IniFile& parOther) = delete;
+ ~IniFile() noexcept;
+
+ IniFile& operator== (IniFile&&) = delete;
+ IniFile& operator== (const IniFile&) = delete;
+
+ const IniMapType& parsed() const { return m_map; }
+
+ private:
+ std::string m_raw_ini;
+ IniMapType m_map;
+ };
+} //namespace tawashi