Browse Source

Implement igeom file parser for all tradition igeom properties

Lucas de Souza 5 years ago
parent
commit
4fe4c07a1c
1 changed files with 84 additions and 73 deletions
  1. 84 73
      src/app/core/parser/file-parser.js

+ 84 - 73
src/app/core/parser/file-parser.js

@@ -14,112 +14,123 @@ const FONT     =  9; // 'Arial' T Tam: T = FONT.PLAIN, FONT.BOLD, FONT.ITALIC; T
                     //           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 OBJECT_LINE_REGEX = /^\{\w*(?:(?:\d+:@\|[^@]+@\|)|(?:\d+:[^,@|]+))\w(?:,\w*(?:(?:\d+:@\|[^@]+@\|)|(?:\d+:[^,@\|]+)))+\w*\}!?$/.compile();
+const ALPHA_MASK = 255 << 24;
 
 export class FileParser {
 
   /**
-   * 
-   * @param {string} content 
+   *
+   * @param {string} content
    */
   constructor(content) {
     this.content = content;
   }
 
   parse () {
-    const objects_list = []
-    this.content.split('\n')
+    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);
-        } else {
-          const object = this.parseObjectLine(str.trim());
-          objects_list.push(object);
+          return undefined;
         }
+        return this.parseObjectLine(str.trim());
       });
-    return objects_list;
   }
 
   /**
-   * 
-   * @param {string} object_line 
+   *
+   * @param {string} object_line
    */
   parseObjectLine (object_line) {
-    let current_char = '';
-    let current_pos = 0;
     const map = new Map();
-    while(1==1) {
-      current_char = object_line[current_pos];
-      if(current_char == '}') {
-        current_pos += 1;
-        if(current_pos == object_line.length)
-          break;
-        current_char = object_line[current_pos]
-        current_pos += 1;
-        if(current_char != '!') {
-          console.warn("Malformed object string: ",object_line);
-        }
-        break;
-      }
+    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 prop in properties) {
+      const prop_info = prop.trim().split(':');
+      const key = parseInt(prop_info[0]);
 
-      if(current_char == TYPE) {
-        current_pos += 2;
-        let type = '';
-        while(object_line[current_pos] != ',') {
-          type += object_line[current_pos];
-          current_pos += 1;
-        }
+      if(key == TYPE) {
+        const type = prop_info[1];
         map.set("type", ObjectClass.fromCodeToClass(parseInt(type)));
-      } else if(current_char == ID) {
-        current_pos += 2;
-        let id = '';
-        while(object_line[current_pos] != ',') {
-          id += object_line[current_pos];
-          current_pos += 1;
-        }
+      } else if(key == ID) {
+        const id = prop_info[1];
         map.set("id", parseInt(id));
-      } else if(current_char == DEFINITION) {
-        current_pos += 2;
+      } else if(key == DEFINITION) {
         const param_list = [];
-        let word = '';
-        while(object_line[current_pos] != ',') {
-          if(object_line[current_pos] == ' ') {
-            param_list.push(Number(word));
-            word = '';
-          } else if(object_line[current_pos] == '@') {
-            current_pos += 2
-            while(1==1) {
-              const char = object_line[current_pos];
-              if(char == '@' && bject_line[current_pos + 1] == '|') {
-                current_pos += 1;
-                break;
-              } else {
-                word += object_line[current_pos];
-              }
-              current_pos += 1;
-            }
+        const list = prop_info[1].trim().split(' ');
+        for(const param in list) {
+          const maybe_number = Number(param);
+          if(Number.isNaN((maybe_number))) {
+            param_list.push(param);
           } else {
-            word += object_line[current_pos];
+            param_list.push(maybe_number);
           }
-          current_pos += 1;
         }
-        param_list.push(word);
         map.set("param", param_list);
-      }
-      if(current_char == '{' || current_char == ' ') {
-        current_pos += 1;
-        continue;
-      } else {
-        console.warn("Malformed object string: ",object_line);
-        break;
+      } else if (key == LIST) {
+        const id_list = [];
+        const list = prop_info[1].trim().split(' ');
+        for(const id in list) {
+           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 param in list) {
+          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 i in list) {
+          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});
       }
     }
 
-    if(current_pos != object_line.length) {
-      console.warn("Object string ",object_line, " parsing did not match its size: Processed: ",current_pos," Length: ", object_line.length);
-    }
     return map;
   }
 
-}
+}