igir
Version:
🕹 A zero-setup ROM collection manager that sorts, filters, extracts or archives, patches, and reports on collections of any size on any OS.
112 lines (111 loc) • 2.99 kB
JavaScript
import IgirException from "../../../exceptions/igirException.js";
class CMProParser {
static WHITESPACE_CHARS = /* @__PURE__ */ new Set([" ", " ", "\n", "\r", "\v"]);
contents;
pos = 0;
constructor(contents) {
this.contents = contents;
}
/**
* Parse the CMPro DAT's file contents.
*/
parse() {
this.pos = 0;
const result = {};
while (this.pos < this.contents.length) {
const tag = this.parseTag();
const value = this.parseValue();
const existing = result[tag];
if (existing === void 0) {
result[tag] = value;
} else {
if (Array.isArray(existing)) {
result[tag] = [...existing, value];
} else {
result[tag] = [existing, value];
}
}
this.skipWhitespace();
}
return result;
}
skipWhitespace() {
while (CMProParser.WHITESPACE_CHARS.has(this.contents.charAt(this.pos))) {
this.pos += 1;
}
}
parseObject() {
if (this.contents.charAt(this.pos) === "(") {
this.pos += 1;
}
this.skipWhitespace();
const result = {};
while (this.contents.charAt(this.pos) !== ")") {
const tag = this.parseTag();
const value = this.parseValue();
const existing = result[tag];
if (existing === void 0) {
result[tag] = value;
} else {
if (Array.isArray(existing)) {
result[tag] = [...existing, value];
} else {
result[tag] = [existing, value];
}
}
this.skipWhitespace();
}
this.pos += 1;
return result;
}
parseTag() {
this.skipWhitespace();
const initialPos = this.pos;
while (!CMProParser.WHITESPACE_CHARS.has(this.contents.charAt(this.pos))) {
this.pos += 1;
}
return this.contents.slice(initialPos, this.pos);
}
parseValue() {
this.skipWhitespace();
if (this.contents.charAt(this.pos) === "(") {
this.pos += 1;
return this.parseObject();
}
if (this.contents.charAt(this.pos) === '"') {
return this.parseQuotedString();
}
return this.parseUnquotedString();
}
parseQuotedString() {
if (this.contents.charAt(this.pos) !== '"') {
throw new IgirException("invalid quoted string");
}
this.pos += 1;
const initialPos = this.pos;
while (this.pos < this.contents.length) {
if (this.contents.charAt(this.pos) === '"') {
const value = this.contents.slice(initialPos, this.pos);
this.pos += 1;
return value;
}
if (this.contents.charAt(this.pos) === "\\") {
this.pos += 2;
} else {
this.pos += 1;
}
}
throw new IgirException("invalid quoted string");
}
parseUnquotedString() {
const initialPos = this.pos;
while (!CMProParser.WHITESPACE_CHARS.has(this.contents.charAt(this.pos))) {
this.pos += 1;
}
return this.contents.slice(initialPos, this.pos);
}
}
export {
CMProParser as default
};
//# sourceMappingURL=cmProParser.js.map