#include #include #include #include #include #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(value)) { output << std::get(value); } else if (std::holds_alternative(value)) { const auto& rrval = std::get(value); if (rrval.internal) { output << "Sub"; } else { output << "Ext"; } output << "Resource( " << rrval.id << " )"; } else { output << "\"" << std::get(value) << "\""; } } output << "]" << std::endl; return output.str(); }