1 | //============================================================================ |
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #include "KeyValueRepositoryConfigfile.hxx" |
19 | #include "Logger.hxx" |
20 | |
21 | namespace { |
22 | string trim(const string& str) |
23 | { |
24 | string::size_type first = str.find_first_not_of(' '); |
25 | return (first == string::npos) ? EmptyString : |
26 | str.substr(first, str.find_last_not_of(' ')-first+1); |
27 | } |
28 | } |
29 | |
30 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
31 | KeyValueRepositoryConfigfile::KeyValueRepositoryConfigfile(const string& filename) |
32 | : myFilename(filename) |
33 | {} |
34 | |
35 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
36 | std::map<string, Variant> KeyValueRepositoryConfigfile::load() |
37 | { |
38 | std::map<string, Variant> values; |
39 | |
40 | string line, key, value; |
41 | string::size_type equalPos, garbage; |
42 | |
43 | ifstream in(myFilename); |
44 | if(!in || !in.is_open()) { |
45 | Logger::error("ERROR: Couldn't load from settings file " + myFilename); |
46 | |
47 | return values; |
48 | } |
49 | |
50 | while(getline(in, line)) |
51 | { |
52 | // Strip all whitespace and tabs from the line |
53 | while((garbage = line.find("\t" )) != string::npos) |
54 | line.erase(garbage, 1); |
55 | |
56 | // Ignore commented and empty lines |
57 | if((line.length() == 0) || (line[0] == ';')) |
58 | continue; |
59 | |
60 | // Search for the equal sign and discard the line if its not found |
61 | if((equalPos = line.find("=" )) == string::npos) |
62 | continue; |
63 | |
64 | // Split the line into key/value pairs and trim any whitespace |
65 | key = trim(line.substr(0, equalPos)); |
66 | value = trim(line.substr(equalPos + 1, line.length() - key.length() - 1)); |
67 | |
68 | // Skip absent key |
69 | if(key.length() == 0) |
70 | continue; |
71 | |
72 | values[key] = value; |
73 | } |
74 | |
75 | return values; |
76 | } |
77 | |
78 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
79 | void KeyValueRepositoryConfigfile::save(const std::map<string, Variant>& values) |
80 | { |
81 | ofstream out(myFilename); |
82 | if(!out || !out.is_open()) { |
83 | Logger::error("ERROR: Couldn't save to settings file " + myFilename); |
84 | |
85 | return; |
86 | } |
87 | |
88 | out << "; Stella configuration file" << endl |
89 | << ";" << endl |
90 | << "; Lines starting with ';' are comments and are ignored." << endl |
91 | << "; Spaces and tabs are ignored." << endl |
92 | << ";" << endl |
93 | << "; Format MUST be as follows:" << endl |
94 | << "; command = value" << endl |
95 | << ";" << endl |
96 | << "; Commands are the same as those specified on the commandline," << endl |
97 | << "; without the '-' character." << endl |
98 | << ";" << endl |
99 | << "; Values are the same as those allowed on the commandline." << endl |
100 | << "; Boolean values are specified as 1 (or true) and 0 (or false)" << endl |
101 | << ";" << endl; |
102 | |
103 | // Write out each of the key and value pairs |
104 | for(const auto& pair: values) |
105 | out << pair.first << " = " << pair.second << endl; |
106 | } |
107 | |