MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / LoadFromDisk

Method LoadFromDisk

src/ini_load.cpp:185–266  ·  view source on GitHub ↗

* Load the Ini file's data from the disk. * @param filename the file to load. * @param subdir the sub directory to load the file from. * @pre nothing has been loaded yet. */

Source from the content-addressed store, hash-verified

183 * @pre nothing has been loaded yet.
184 */
185void IniLoadFile::LoadFromDisk(std::string_view filename, Subdirectory subdir)
186{
187 assert(this->groups.empty());
188
189 char buffer[1024];
190 IniGroup *group = nullptr;
191
192 std::string comment;
193
194 size_t end;
195 auto in = this->OpenFile(filename, subdir, &end);
196 if (!in.has_value()) return;
197
198 end += ftell(*in);
199
200 size_t line = 0;
201 /* for each line in the file */
202 while (static_cast<size_t>(ftell(*in)) < end && fgets(buffer, sizeof(buffer), *in)) {
203 ++line;
204 StringConsumer consumer{StrTrimView(buffer, StringConsumer::WHITESPACE_OR_NEWLINE)};
205
206 /* Skip comments and empty lines outside IGT_SEQUENCE groups. */
207 if ((group == nullptr || group->type != IGT_SEQUENCE) && (!consumer.AnyBytesLeft() || consumer.PeekCharIfIn("#;"))) {
208 comment += consumer.GetOrigData();
209 comment += "\n";
210 continue;
211 }
212
213 /* it's a group? */
214 if (consumer.ReadCharIf('[')) {
215 std::string_view group_name = consumer.ReadUntilChar(']', StringConsumer::KEEP_SEPARATOR);
216 if (!consumer.ReadCharIf(']') || consumer.AnyBytesLeft()) {
217 this->ReportFileError(fmt::format("ini [{}]: invalid group name '{}'", line, consumer.GetOrigData()));
218 }
219 group = &this->CreateGroup(group_name);
220 group->comment = std::move(comment);
221 comment.clear(); // std::move leaves comment in a "valid but unspecified state" according to the specification.
222 } else if (group != nullptr) {
223 if (group->type == IGT_SEQUENCE) {
224 /* A sequence group, use the line as item name without further interpretation. */
225 IniItem &item = group->CreateItem(consumer.GetOrigData());
226 item.comment = std::move(comment);
227 comment.clear(); // std::move leaves comment in a "valid but unspecified state" according to the specification.
228 continue;
229 }
230
231 static const std::string_view key_parameter_separators = "=\t ";
232 std::string_view key;
233 /* find end of keyname */
234 if (consumer.ReadCharIf('\"')) {
235 key = consumer.ReadUntilChar('\"', StringConsumer::SKIP_ONE_SEPARATOR);
236 } else {
237 key = consumer.ReadUntilCharIn(key_parameter_separators);
238 }
239
240 /* it's an item in an existing group */
241 IniItem &item = group->CreateItem(key);
242 item.comment = std::move(comment);

Callers 6

ConfigIniFileMethod · 0.80
LoadFromConfigMethod · 0.80
SaveToConfigMethod · 0.80
AddFileMethod · 0.80
SaveLoadHotkeysFunction · 0.80
ProcessIniFileFunction · 0.80

Calls 15

StrTrimViewFunction · 0.85
AnyBytesLeftMethod · 0.80
PeekCharIfInMethod · 0.80
GetOrigDataMethod · 0.80
ReadCharIfMethod · 0.80
ReadUntilCharMethod · 0.80
CreateGroupMethod · 0.80
ReadUntilCharInMethod · 0.80
SkipUntilCharNotInMethod · 0.80
GetLeftDataMethod · 0.80
StrMakeValidFunction · 0.70
formatFunction · 0.50

Tested by

no test coverage detected