src/app/core/parser/file-parser.js
import * as ObjectClass from "./../enums/elements-class-enum";
const TYPE = 0; // identifica se Ponto, Texto, Reta...
const ID = 1; // identificador unico do objeto
const DEFINITION = 2; // parametros dos quais o objeto depende (exemplo Reta depende de Ponto e Ponto => "2:IDPONTO1 IDPONTO2")
const LIST = 3; // lista de identificadores de objetos dependentes do atual
const LABEL = 4; // definicao do rotulo (valor/nome e se escondido ou nao)
const DEFINED = 6; // 0 ou 1 (???)
const COLOR = 5; // cor usando valor inteiro
const HIDDEN = 7; // 0 (visivel) ou 1 (escondido)
const PIXEL = 8; // LeScript usa (coordenada X e Y - inteiros)
const FONT = 9; // 'Arial' T Tam: T = FONT.PLAIN, FONT.BOLD, FONT.ITALIC; Tam = 8, 9,...
// PROIBIDO: "Arial" T Tam, pois em caso contrario nao sera lido como parametro
// usa MARCAFNT = "\'" nao pode ser "\"" <[28/09/2006] agora vazio "">
const LABEL_COLOR = 10; // cor de rotulo (tambem um inteiro) - inserido apos iGeom versao >= 2.9.9.31
const OBJECT_LINE_REGEX = /^\{\w*(?:(?:\d+:@\|[^@]+@\|)|(?:\d+:[^,@|]+))\w(?:,\w*(?:(?:\d+:@\|[^@]+@\|)|(?:\d+:[^,@\|]+)))+\w*\}!?$/.compile();
const ALPHA_MASK = 255 << 24;
export class FileParser {
/**
*
* @param {string} content
*/
constructor(content) {
this.content = content;
}
parse() {
return this.content
.split("\n")
.filter(str => !str.match(/^[#\[]/))
.map(str => {
if (!OBJECT_LINE_REGEX.test(str.trim())) {
console.error("Malformed object string in igeom file: ", str);
return undefined;
}
return this.parseObjectLine(str.trim());
});
}
/**
*
* @param {string} object_line
*/
parseObjectLine(object_line) {
const map = new Map();
object_line = object_line.substring(1);
if (object_line.endsWith("}!")) {
object_line = object_line.substring(0, object_line.length - 2);
} else {
object_line = object_line.substring(0, object_line.length - 1);
}
const properties = object_line.split(",");
for (const index in properties) {
const prop = properties[index];
const prop_info = prop.trim().split(":");
const key = parseInt(prop_info[0]);
if (prop_info[1] == undefined) continue;
if (key == TYPE) {
const type = prop_info[1];
map.set("type", ObjectClass.fromCodeToClass(parseInt(type)));
} else if (key == ID) {
const id = prop_info[1];
map.set("id", parseInt(id));
} else if (key == DEFINITION) {
const param_list = [];
const list = prop_info[1].trim().split(" ");
for (const i in list) {
const param = list[i];
const maybe_number = Number(param);
if (Number.isNaN(maybe_number)) {
param_list.push(param);
} else {
param_list.push(maybe_number);
}
}
map.set("param", param_list);
} else if (key == LIST) {
const id_list = [];
const list = prop_info[1].trim().split(" ");
for (const i in list) {
const id = list[i];
id_list.push(id);
}
map.set("deps", id_list);
} else if (key == LABEL) {
const param_list = [];
const list = prop_info[1].trim().split(" ");
for (const i in list) {
const param = list[i];
const maybe_number = Number(param);
if (Number.isNaN(maybe_number)) {
param_list.push(param);
} else {
param_list.push(maybe_number);
}
}
map.set("label", param_list);
} else if (key == DEFINED) {
const value = prop_info[1];
map.set("defined", parseInt(value));
} else if (key == COLOR) {
const value = prop_info[1];
let number = Number(value);
const alpha = ((number & ALPHA_MASK) >>> 24) / 255;
number = number ^ ALPHA_MASK;
const r = (number >> 16) & 0xff;
const g = (number >> 8) & 0xff;
const b = number & 0xff;
map.set("color", { alpha: alpha, r: r, g: g, b: b });
} else if (key == HIDDEN) {
const value = prop_info[1];
map.set("hidden", parseInt(value));
} else if (key == PIXEL) {
const position = [];
const list = prop_info[1].trim().split(" ");
for (const index in list) {
const i = list[index];
position.push(parseInt(i));
}
map.set("position", position);
} else if (key == FONT) {
const param_list = prop_info[1].trim().split(" ");
map.set("font", param_list);
} else if (key == LABEL_COLOR) {
const value = prop_info[1];
let number = Number(value);
const alpha = ((number & ALPHA_MASK) >>> 24) / 255;
number = number ^ ALPHA_MASK;
const r = (number >> 16) & 0xff;
const g = (number >> 8) & 0xff;
const b = number & 0xff;
map.set("label_color", { alpha: alpha, r: r, g: g, b: b });
}
}
return map;
}
}