blob: ff4a1a6dea859f7977770f7c28cdbfa2d25bcef6 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include <stdlib.h>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include "heading.h"
Heading::Heading(std::string_view line) {
std::string original_line(line);
if (line[0] != '[') {
std::ostringstream errormsg;
errormsg << "Heading must start with [." << std::endl
<< "Bad heading: " << original_line;
throw std::invalid_argument(errormsg.str());
}
line.remove_prefix(1);
int divider = line.find_first_of(" ]");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
type_ = line.substr(0, divider);
line.remove_prefix(divider + 1);
while (!line.empty()) {
divider = line.find_first_of("=");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
std::string key(line.substr(0, divider));
line.remove_prefix(divider + 1);
if (line[0] == '"') {
line.remove_prefix(1);
divider = line.find_first_of("\"");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
std::string strval(line.substr(0, divider));
line.remove_prefix(divider + 2);
keyvals_[key] = strval;
} else if (line[0] == 'S' || line[0] == 'E') {
ResourceRef rrval;
rrval.internal = (line[0] == 'S');
line.remove_prefix(13); // SubResource(#
divider = line.find_first_of(" ");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
rrval.id = std::atoi(line.substr(0, divider).data());
line.remove_prefix(divider + 3);
keyvals_[key] = rrval;
} else {
divider = line.find_first_of(" ]");
if (divider == std::string_view::npos) {
std::ostringstream errormsg;
errormsg << "Malformatted heading: " << line << std::endl
<< "Original line: " << original_line;
throw std::invalid_argument(errormsg.str());
}
int numval = std::atoi(line.substr(0, divider).data());
line.remove_prefix(divider + 1);
keyvals_[key] = numval;
}
}
}
std::string Heading::ToString() const {
std::ostringstream output;
output << "[";
output << type_;
for (const auto& [key, value] : keyvals_) {
output << " " << key << "=";
if (std::holds_alternative<int>(value)) {
output << std::get<int>(value);
} else if (std::holds_alternative<ResourceRef>(value)) {
const auto& rrval = std::get<ResourceRef>(value);
if (rrval.internal) {
output << "Sub";
} else {
output << "Ext";
}
output << "Resource( " << rrval.id << " )";
} else {
output << "\"" << std::get<std::string>(value) << "\"";
}
}
output << "]" << std::endl;
return output.str();
}
|