90#include <unordered_map>
99 namespace INIStringUtil
102 inline void trim(std::string& str)
107#ifndef MINI_CASE_SENSITIVE
110 std::transform(str.begin(), str.end(), str.begin(), [](
const char c) {
111 return static_cast<char>(std::tolower(c));
115 inline void replace(std::string& str, std::string
const&
a, std::string
const&
b)
120 while ((pos = str.find(
a, pos)) != std::string::npos)
122 str.replace(pos,
a.size(),
b);
128 const char*
const endl =
"\r\n";
141 using T_MultiArgs =
typename std::vector<std::pair<std::string, T>>;
150 data.emplace_back(key, T());
161 std::size_t data_size = other.
data.size();
162 for (std::size_t
i = 0;
i < data_size; ++
i)
164 auto const& key = other.
data[
i].first;
165 auto const& obj = other.
data[
i].second;
166 data.emplace_back(key, obj);
174#ifndef MINI_CASE_SENSITIVE
182 T
get(std::string key)
const
185#ifndef MINI_CASE_SENSITIVE
193 return T(
data[it->second].second);
195 bool has(std::string key)
const
198#ifndef MINI_CASE_SENSITIVE
203 void set(std::string key, T obj)
206#ifndef MINI_CASE_SENSITIVE
212 data[it->second].second = obj;
217 data.emplace_back(key, obj);
222 for (
auto const& it : multiArgs)
224 auto const& key = it.first;
225 auto const& obj = it.second;
232#ifndef MINI_CASE_SENSITIVE
238 std::size_t
index = it->second;
243 auto& vi = it2.second;
283 parseData.first.
clear();
284 parseData.second.clear();
290 char firstCharacter = line[0];
291 if (firstCharacter ==
';')
295 if (firstCharacter ==
'[')
297 auto commentAt = line.find_first_of(
';');
298 if (commentAt != std::string::npos)
300 line = line.substr(0, commentAt);
302 auto closingBracketAt = line.find_last_of(
']');
303 if (closingBracketAt != std::string::npos)
305 auto section = line.substr(1, closingBracketAt - 1);
311 auto lineNorm = line;
313 auto equalsAt = lineNorm.find_first_of(
'=');
314 if (equalsAt != std::string::npos)
316 auto key = line.substr(0, equalsAt);
319 auto value = line.substr(equalsAt + 1);
321 parseData.first = key;
322 parseData.second =
value;
344 const std::size_t fileSize =
static_cast<std::size_t
>(
fileReadStream.tellg());
353 header[0] ==
static_cast<char>(0xEF) &&
354 header[1] ==
static_cast<char>(0xBB) &&
355 header[2] ==
static_cast<char>(0xBF)
361 std::string fileContents;
362 fileContents.resize(fileSize);
373 for (std::size_t
i = 0;
i < fileSize; ++
i)
375 char& c = fileContents[
i];
382 if (c !=
'\0' && c !=
'\r')
392 INIReader(std::string
const& filename,
bool keepLineData =
false)
397 lineData = std::make_shared<T_LineData>();
410 bool inSection =
false;
412 for (
auto const& line : fileLines)
422 auto const& key = parseData.first;
423 auto const&
value = parseData.second;
467 auto it =
data.begin();
470 auto const&
section = it->first;
471 auto const& collection = it->second;
476 if (collection.size())
479 auto it2 = collection.begin();
482 auto key = it2->first;
484 auto value = it2->second;
490 if (++it2 == collection.end())
497 if (++it ==
data.end())
523 std::string sectionCurrent;
524 bool parsingSection =
false;
525 bool continueToNextSection =
false;
526 bool discardNextEmpty =
false;
527 bool writeNewKeys =
false;
528 std::size_t lastKeyLine = 0;
529 for (
auto line = lineData->begin(); line != lineData->end(); ++line)
539 parsingSection =
false;
543 sectionCurrent = parseData.first;
544 if (
data.has(sectionCurrent))
546 parsingSection =
true;
547 continueToNextSection =
false;
548 discardNextEmpty =
false;
549 output.emplace_back(*line);
550 lastKeyLine =
output.size();
554 continueToNextSection =
true;
555 discardNextEmpty =
true;
561 if (continueToNextSection)
565 if (
data.has(sectionCurrent))
567 auto& collection =
data[sectionCurrent];
568 auto const& key = parseData.first;
569 auto const&
value = parseData.second;
570 if (collection.has(key))
572 auto outputValue = collection[key];
573 if (
value == outputValue)
575 output.emplace_back(*line);
580 auto lineNorm = *line;
582 auto equalsAt = lineNorm.find_first_of(
'=');
583 auto valueAt = lineNorm.find_first_not_of(
587 std::string outputLine = line->substr(0, valueAt);
592 outputLine += outputValue;
593 output.emplace_back(outputLine);
595 lastKeyLine =
output.size();
601 if (discardNextEmpty && line->empty())
603 discardNextEmpty =
false;
607 output.emplace_back(*line);
611 if (writeNewKeys || std::next(line) == lineData->end())
614 if (
data.has(sectionCurrent) && original.has(sectionCurrent))
616 auto const& collection =
data[sectionCurrent];
617 auto const& collectionOriginal = original[sectionCurrent];
618 for (
auto const& it : collection)
621 if (collectionOriginal.has(key))
625 auto value = it.second;
628 linesToAdd.emplace_back(
633 if (!linesToAdd.empty())
636 output.begin() + lastKeyLine,
643 writeNewKeys =
false;
648 for (
auto const& it :
data)
650 auto const&
section = it.first;
660 auto const& collection = it.second;
661 for (
auto const& it2 : collection)
663 auto key = it2.first;
664 auto value = it2.second;
687 bool fileExists = (stat(
filename.c_str(), &buf) == 0);
692 return generator <<
data;
696 bool readSuccess =
false;
697 bool fileIsBOM =
false;
700 if ((readSuccess = reader >> originalData))
703 fileIsBOM = reader.
isBOM;
711 std::ofstream fileWriteStream(
filename, std::ios::out | std::ios::binary);
712 if (fileWriteStream.is_open())
715 const char utf8_BOM[3] = {
716 static_cast<char>(0xEF),
717 static_cast<char>(0xBB),
718 static_cast<char>(0xBF)
720 fileWriteStream.write(utf8_BOM, 3);
724 auto line =
output.begin();
727 fileWriteStream << *line;
728 if (++line ==
output.end())
764 return reader >>
data;
774 return generator <<
data;
784 return writer <<
data;
void clear()
Definition core.h:1114
bool read(INIStructure &data) const
Definition ini.h:753
std::string filename
Definition ini.h:744
bool generate(INIStructure const &data, bool pretty=false) const
Definition ini.h:766
~INIFile()
Definition ini.h:751
INIFile(std::string const &filename)
Definition ini.h:747
bool write(INIStructure &data, bool pretty=false) const
Definition ini.h:776
bool prettyPrint
Definition ini.h:449
bool operator<<(INIStructure const &data)
Definition ini.h:457
INIGenerator(std::string const &filename)
Definition ini.h:451
std::ofstream fileWriteStream
Definition ini.h:446
~INIGenerator()
Definition ini.h:455
T get(std::string key) const
Definition ini.h:182
typename T_DataContainer::const_iterator const_iterator
Definition ini.h:155
T_DataIndexMap dataIndexMap
Definition ini.h:143
void set(T_MultiArgs const &multiArgs)
Definition ini.h:220
const_iterator end() const
Definition ini.h:263
std::pair< std::string, T > T_DataItem
Definition ini.h:139
const_iterator begin() const
Definition ini.h:262
std::unordered_map< std::string, std::size_t > T_DataIndexMap
Definition ini.h:138
bool has(std::string key) const
Definition ini.h:195
std::vector< T_DataItem > T_DataContainer
Definition ini.h:140
T_DataContainer data
Definition ini.h:144
INIMap()
Definition ini.h:157
bool remove(std::string key)
Definition ini.h:229
T & operator[](std::string key)
Definition ini.h:171
void set(std::string key, T obj)
Definition ini.h:203
typename std::vector< std::pair< std::string, T > > T_MultiArgs
Definition ini.h:141
std::size_t setEmpty(std::string &key)
Definition ini.h:146
void clear()
Definition ini.h:253
INIMap(INIMap const &other)
Definition ini.h:159
std::size_t size() const
Definition ini.h:258
T_LineDataPtr lineData
Definition ini.h:339
~INIReader()
Definition ini.h:400
bool operator>>(INIStructure &data)
Definition ini.h:402
T_LineDataPtr getLines()
Definition ini.h:437
T_LineData readFile()
Definition ini.h:341
INIReader(std::string const &filename, bool keepLineData=false)
Definition ini.h:392
bool isBOM
Definition ini.h:335
std::vector< std::string > T_LineData
Definition ini.h:332
std::shared_ptr< T_LineData > T_LineDataPtr
Definition ini.h:333
std::ifstream fileReadStream
Definition ini.h:338
bool prettyPrint
Definition ini.h:676
std::vector< std::string > T_LineData
Definition ini.h:514
std::string filename
Definition ini.h:517
std::shared_ptr< T_LineData > T_LineDataPtr
Definition ini.h:515
bool operator<<(INIStructure &data)
Definition ini.h:684
INIWriter(std::string const &filename)
Definition ini.h:678
~INIWriter()
Definition ini.h:682
T_LineData getLazyOutput(T_LineDataPtr const &lineData, INIStructure &data, INIStructure &original)
Definition ini.h:519
PDataType parseLine(std::string line, T_ParseValues &parseData)
Definition ini.h:281
std::pair< std::string, std::string > T_ParseValues
Definition ini.h:270
PDataType
Definition ini.h:273
const char *const endl
Definition ini.h:130
const char *const whitespaceDelimiters
Definition ini.h:101
void replace(std::string &str, std::string const &a, std::string const &b)
Definition ini.h:115
void toLower(std::string &str)
Definition ini.h:108
void trim(std::string &str)
Definition ini.h:102
INIMap< INIMap< std::string > > INIStructure
Definition ini.h:266
section
Definition tag_strings.h:16
b
Definition tag_strings.h:61
a
Definition tag_strings.h:43
annotation output
Definition tag_strings.h:122
i
Definition tag_strings.h:60
header
Definition tag_strings.h:26