Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : /**
3 : * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
4 : *
5 : * @file ini_wrapper.cpp
6 : * @date 08 April 2021
7 : * @brief NNTrainer Ini Wrapper helps to save ini
8 : * @note this is to be used with ini_interpreter
9 : * @see https://github.com/nnstreamer/nntrainer
10 : * @author Jihoon Lee <jhoon.it.lee@samsung.com>
11 : * @bug No known bugs except for NYI items
12 : */
13 : #include <ini_wrapper.h>
14 :
15 : #include <regex>
16 :
17 : #include <iostream>
18 : #include <nntrainer_error.h>
19 : #include <util_func.h>
20 :
21 : namespace nntrainer {
22 :
23 2721 : IniSection::IniSection(const std::string &name) : section_name(name), entry{} {}
24 :
25 110 : IniSection::IniSection(const std::string §ion_name,
26 110 : const std::string &entry_str) :
27 110 : IniSection(section_name) {
28 110 : setEntry(entry_str);
29 110 : }
30 :
31 10 : IniSection::IniSection(IniSection &from, const std::string §ion_name,
32 10 : const std::string &entry_str) :
33 10 : IniSection(from) {
34 10 : if (!section_name.empty()) {
35 10 : this->section_name = section_name;
36 : }
37 10 : if (!entry_str.empty()) {
38 0 : setEntry(entry_str);
39 : }
40 10 : }
41 :
42 4368 : void IniSection::print(std::ostream &out) const {
43 8736 : out << '[' << section_name << ']' << std::endl;
44 34762 : for (auto &it : entry)
45 : out << it.first << " = " << it.second << std::endl;
46 4368 : }
47 :
48 78 : void IniSection::setEntry(const std::map<std::string, std::string> &entry) {
49 240 : for (auto &it : entry) {
50 162 : this->entry[it.first] = it.second;
51 : }
52 78 : }
53 :
54 24737 : void IniSection::setEntry(const std::string &key, const std::string &value) {
55 24737 : entry[key] = value;
56 24737 : }
57 :
58 1329 : void IniSection::setEntry(const std::string &entry_str) {
59 : // setting property separated by "|"
60 1329 : std::regex words_regex("[^|]+");
61 :
62 : auto words_begin =
63 1329 : std::sregex_iterator(entry_str.begin(), entry_str.end(), words_regex);
64 1329 : auto words_end = std::sregex_iterator();
65 :
66 : std::string key, value;
67 3050 : for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
68 1721 : std::string cur = (*i).str();
69 :
70 1721 : if (cur[0] == '-') {
71 328 : entry.erase(cur.substr(1));
72 : continue;
73 : }
74 :
75 1557 : int status = getKeyValue(cur, key, value);
76 1557 : NNTR_THROW_IF(status != ML_ERROR_NONE, std::invalid_argument)
77 : << "getKeyValue Failed";
78 :
79 1557 : setEntry(key, value);
80 : }
81 1329 : }
82 :
83 6 : void IniWrapper::updateSection(const std::string &s) {
84 :
85 6 : auto seperator_pos = s.find('/');
86 :
87 6 : NNTR_THROW_IF(seperator_pos == std::string::npos, std::invalid_argument)
88 : << "invalid string format is given, please "
89 : "pass format of sectionKey/properties format";
90 :
91 6 : auto section_key = s.substr(0, seperator_pos);
92 6 : auto properties = s.substr(seperator_pos + 1);
93 :
94 6 : IniSection target(section_key, properties);
95 :
96 6 : updateSection(target);
97 6 : }
98 :
99 6 : void IniWrapper::updateSection(const IniSection &s) {
100 :
101 6 : auto section = std::find_if(sections.begin(), sections.end(),
102 10 : [&](const IniSection §ion) {
103 20 : return section.getName() == s.getName();
104 : });
105 :
106 6 : NNTR_THROW_IF(section == sections.end(), std::invalid_argument)
107 0 : << "section key is not found key: " << s.getName();
108 :
109 : (*section) += s;
110 6 : }
111 :
112 0 : void IniWrapper::updateSections(const Sections §ions_) {
113 0 : for (auto §ion : sections_) {
114 0 : updateSection(section);
115 : }
116 0 : }
117 :
118 828 : void IniWrapper::save_ini() const { save_ini(getIniName()); }
119 :
120 896 : void IniWrapper::save_ini(const std::string &ini_name) const {
121 896 : auto out = checkedOpenStream<std::ofstream>(ini_name, std::ios_base::app);
122 :
123 5264 : for (auto &it : sections) {
124 4368 : it.print(out);
125 : out << std::endl;
126 : }
127 896 : }
128 :
129 414 : void IniWrapper::erase_ini() const noexcept {
130 828 : if (remove(getIniName().c_str())) {
131 : const size_t error_buflen = 100;
132 : char error_buf[error_buflen];
133 0 : std::cerr << "remove ini " << getIniName() << "failed, reason: "
134 0 : << SAFE_STRERROR(errno, error_buf, error_buflen);
135 : }
136 414 : }
137 :
138 : } // namespace nntrainer
|