aboutsummaryrefslogtreecommitdiff
path: root/TXTParser.cpp
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-22 15:51:40 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-22 15:51:40 +0200
commit2de024ba832eecca59a512e9f8e3e1f6e8a0d8a3 (patch)
tree7547c5e7f0466ed85d239d742846c45b7f1a63b5 /TXTParser.cpp
parent8c0562c8ef37cd5e80c58609f7bc7ae352365f65 (diff)
WIP (broken) TXT parser
Diffstat (limited to 'TXTParser.cpp')
-rw-r--r--TXTParser.cpp165
1 files changed, 163 insertions, 2 deletions
diff --git a/TXTParser.cpp b/TXTParser.cpp
index 17890e0..5d0820f 100644
--- a/TXTParser.cpp
+++ b/TXTParser.cpp
@@ -1,10 +1,171 @@
+#include <sstream>
+
#include "TXTParser.h"
+#include "Color.h"
+#include "Exception.h"
+
+using namespace std;
unsigned int TXTParser::heuristic() {
- return 0;
+ bool grid = false;
+ int columns = 0;
+ int rows = 0;
+ int penalty = 1;
+
+ istringstream lines(this->get_file().read());
+ string line;
+ while (getline(lines, line)) {
+ if (line.back() == '\r') line.pop_back();
+
+ if (line.size() == 0) {
+ grid = true;
+ continue;
+ }
+ if (!grid) continue;
+
+ rows++;
+ if (columns == 0) columns = line.size();
+ penalty += abs(columns - static_cast<int>(line.size()));
+ }
+
+ if (grid == false) return 0;
+
+ if (columns == 1) penalty += 1000;
+ return (rows + columns) / penalty;
+}
+
+
+static void parse_header_def(MuseumDeserializer & d, const std::string & line) {
+ CanvasData data;
+
+ istringstream defs(line);
+ string def;
+ while (getline(defs, def, ',')) {
+ size_t equals = def.find("=");
+ if (equals == string::npos)
+ throw Exception("TXTParser: invalid def \"%s\"", def.c_str());
+
+ string key = def.substr(0, equals);
+
+ if (key == "rows") {
+ data.rows = stoi(def.substr(equals + 1));
+ continue;
+ }
+
+ if (key == "cols") {
+ data.columns = stoi(def.substr(equals + 1));
+ continue;
+ }
+
+ throw Exception("TXTParser: invalid key \"%s\"", key.c_str());
+ }
+
+ d.set_canvas(data);
+}
+
+static size_t header_idx(vector<string> header, string field) {
+ auto iter = find(header.begin(), header.end(), field);
+ if (iter == header.end())
+ throw Exception("header table is missing \"%s\" column", field.c_str());
+ return iter - header.begin();
+}
+
+static Color stocolor(const string & str) {
+ istringstream ss(str);
+ string red, green, blue;
+ getline(ss, red, ',');
+ getline(ss, green, ',');
+ getline(ss, blue, ',');
+ return {
+ .red = static_cast<unsigned int>(stoi(red)),
+ .green = static_cast<unsigned int>(stoi(green)),
+ .blue = static_cast<unsigned int>(stoi(blue)),
+ };
+}
+
+static void parse_header_table(MuseumDeserializer & d, const std::string & header, std::istringstream & rows) {
+ vector<string> table_header;
+ istringstream header_row(header);
+ string column;
+ while (getline(header_row, column, ','))
+ table_header.push_back(column);
+
+ size_t type_idx = header_idx(table_header, "letter");
+ size_t color_idx = header_idx(table_header, "rgb");
+ size_t weight_idx = header_idx(table_header, "weight");
+
+ string row;
+ while (getline(rows, row)) {
+ if (row.back() == '\r') row.pop_back();
+ if (row.size() == 0) break;
+
+ unsigned int col_idx = 0;
+ string col = "";
+ string stack = "";
+ vector<string> cols = {};
+
+ for (char c : row) {
+ if (c == stack.back()) {
+ stack.pop_back();
+ continue;
+ }
+ if (c == '[') {
+ stack.push_back(']');
+ continue;
+ }
+ if (stack.size() == 0 && c == ',') {
+ cols.push_back(col);
+ col.clear();
+ continue;
+ }
+ col.push_back(c);
+ }
+ if (col.size() > 0) cols.push_back(col);
+
+ if (cols.size() != 3)
+ throw Exception("invalid header table row");
+
+ d.add_type(
+ cols[type_idx],
+ stocolor(cols[color_idx]),
+ stoi(cols[weight_idx])
+ );
+ }
+}
+
+static void parse_header(MuseumDeserializer & d, istringstream & input) {
+ string line;
+ while (getline(input, line)) {
+ if (line.back() == '\r') line.pop_back();
+ if (line.size() == 0) break;
+
+ if (line.find("=") != string::npos) {
+ parse_header_def(d, line);
+ } else {
+ parse_header_table(d, line, input);
+ break;
+ }
+ }
+}
+
+static void parse_canvas(MuseumDeserializer & d, istringstream & input) {
+ unsigned int x = 0, y = 0;
+ char c;
+ while (input >> c) {
+ if (c == '\r') continue;
+ if (c == '\n') {
+ x = 0;
+ y += 1;
+ }
+ d.set_tile({ .x = x, .y = y, .type = string(1, c), });
+ x += 1;
+ }
}
void TXTParser::parse(MuseumDeserializer & d) {
- printf("%s\n", __PRETTY_FUNCTION__);
+ istringstream input(this->get_file().read());
+
+ parse_header(d, input);
+ parse_canvas(d, input);
}