WoW Model Viewer
Your premiere tool for viewing, equipping and animating World of Warcraft models.
Loading...
Searching...
No Matches
IniFile.h
Go to the documentation of this file.
1#pragma once
2
3#include <fstream>
4#include <map>
5#include <string>
6
7namespace core
8{
14 class IniFile
15 {
16 public:
17 explicit IniFile(const std::string& path) : m_path(path)
18 {
19 load();
20 }
21
22 explicit IniFile(const std::wstring& path) : m_wpath(path)
23 {
24 load();
25 }
26
27 std::string getString(const std::string& key, const std::string& defaultValue = "") const
28 {
29 const auto it = m_data.find(key);
30 if (it == m_data.end())
31 return defaultValue;
32
33 // Strip surrounding double quotes (QSettings backward compatibility)
34 std::string val = it->second;
35 if (val.size() >= 2 && val.front() == '"' && val.back() == '"')
36 val = val.substr(1, val.size() - 2);
37 return val;
38 }
39
40 int getInt(const std::string& key, int defaultValue = 0) const
41 {
42 const auto it = m_data.find(key);
43 if (it == m_data.end())
44 return defaultValue;
45 try { return std::stoi(it->second); }
46 catch (...) { return defaultValue; }
47 }
48
49 double getDouble(const std::string& key, double defaultValue = 0.0) const
50 {
51 const auto it = m_data.find(key);
52 if (it == m_data.end())
53 return defaultValue;
54 try { return std::stod(it->second); }
55 catch (...) { return defaultValue; }
56 }
57
58 bool getBool(const std::string& key, bool defaultValue = false) const
59 {
60 const auto it = m_data.find(key);
61 if (it == m_data.end())
62 return defaultValue;
63 const std::string& v = it->second;
64 if (v == "true" || v == "1") return true;
65 if (v == "false" || v == "0") return false;
66 return defaultValue;
67 }
68
69 std::wstring getWString(const std::string& key, const std::wstring& defaultValue = L"") const
70 {
71 const std::string s = getString(key);
72 if (s.empty())
73 return defaultValue;
74 // Convert UTF-8 string to wide string
75 const int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), static_cast<int>(s.size()), nullptr, 0);
76 if (len == 0)
77 return defaultValue;
78 std::wstring result(len, L'\0');
79 MultiByteToWideChar(CP_UTF8, 0, s.c_str(), static_cast<int>(s.size()), result.data(), len);
80 return result;
81 }
82
83 void setValue(const std::string& key, int value)
84 {
85 m_data[key] = std::to_string(value);
86 }
87
88 void setValue(const std::string& key, double value)
89 {
90 m_data[key] = std::to_string(value);
91 }
92
93 void setValue(const std::string& key, bool value)
94 {
95 m_data[key] = value ? "true" : "false";
96 }
97
98 void setValue(const std::string& key, const std::string& value)
99 {
100 m_data[key] = value;
101 }
102
103 void setValue(const std::string& key, const std::wstring& value)
104 {
105 // Convert wide string to UTF-8
106 if (value.empty())
107 {
108 m_data[key] = "";
109 return;
110 }
111 const int len = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), static_cast<int>(value.size()),
112 nullptr, 0, nullptr, nullptr);
113 std::string result(len, '\0');
114 WideCharToMultiByte(CP_UTF8, 0, value.c_str(), static_cast<int>(value.size()),
115 result.data(), len, nullptr, nullptr);
116 m_data[key] = result;
117 }
118
119 void sync() const
120 {
121 std::ofstream file;
122 if (!m_wpath.empty())
123 file.open(m_wpath);
124 else
125 file.open(m_path);
126
127 if (!file.is_open())
128 return;
129
130 // Group keys by section and write in order
131 std::map<std::string, std::map<std::string, std::string>> sections;
132 for (const auto& [fullKey, value] : m_data)
133 {
134 const auto pos = fullKey.find('/');
135 if (pos != std::string::npos)
136 sections[fullKey.substr(0, pos)][fullKey.substr(pos + 1)] = value;
137 else
138 sections["General"][fullKey] = value;
139 }
140
141 bool first = true;
142 for (const auto& [section, keys] : sections)
143 {
144 if (!first)
145 file << '\n';
146 first = false;
147 file << '[' << section << "]\n";
148 for (const auto& [key, value] : keys)
149 file << key << '=' << value << '\n';
150 }
151 }
152
153 private:
154 void load()
155 {
156 std::ifstream file;
157 if (!m_wpath.empty())
158 file.open(m_wpath);
159 else
160 file.open(m_path);
161
162 if (!file.is_open())
163 return;
164
165 std::string currentSection;
166 std::string line;
167 while (std::getline(file, line))
168 {
169 // Trim trailing \r for Windows line endings
170 if (!line.empty() && line.back() == '\r')
171 line.pop_back();
172
173 // Skip empty lines and comments
174 if (line.empty() || line[0] == ';' || line[0] == '#')
175 continue;
176
177 // Section header
178 if (line.front() == '[' && line.back() == ']')
179 {
180 currentSection = line.substr(1, line.size() - 2);
181 continue;
182 }
183
184 // Key=Value
185 const auto eq = line.find('=');
186 if (eq == std::string::npos)
187 continue;
188
189 std::string key = line.substr(0, eq);
190 std::string value = line.substr(eq + 1);
191
192 // Skip QSettings @variant entries (binary blobs we can't parse)
193 if (!value.empty() && value[0] == '@')
194 continue;
195
196 if (!currentSection.empty())
197 key = currentSection + "/" + key;
198
199 m_data[key] = value;
200 }
201 }
202
203 std::string m_path;
204 std::wstring m_wpath;
205 std::map<std::string, std::string> m_data;
206 };
207}
Simple INI file reader/writer with section/key support.
Definition IniFile.h:15
void setValue(const std::string &key, const std::string &value)
Definition IniFile.h:98
IniFile(const std::string &path)
Definition IniFile.h:17
bool getBool(const std::string &key, bool defaultValue=false) const
Definition IniFile.h:58
std::string m_path
Definition IniFile.h:203
int getInt(const std::string &key, int defaultValue=0) const
Definition IniFile.h:40
void setValue(const std::string &key, int value)
Definition IniFile.h:83
void load()
Definition IniFile.h:154
void setValue(const std::string &key, const std::wstring &value)
Definition IniFile.h:103
std::map< std::string, std::string > m_data
Definition IniFile.h:205
void setValue(const std::string &key, bool value)
Definition IniFile.h:93
IniFile(const std::wstring &path)
Definition IniFile.h:22
void setValue(const std::string &key, double value)
Definition IniFile.h:88
std::wstring m_wpath
Definition IniFile.h:204
std::wstring getWString(const std::string &key, const std::wstring &defaultValue=L"") const
Definition IniFile.h:69
std::string getString(const std::string &key, const std::string &defaultValue="") const
Definition IniFile.h:27
double getDouble(const std::string &key, double defaultValue=0.0) const
Definition IniFile.h:49
void sync() const
Definition IniFile.h:119
Common string utility functions (split, case-insensitive search, etc.).
Definition GameLoader.h:11