Commit 18ec089
Use foreach iterator in libbirdxml
Changed files (7)
modifiedlibbirdfont/BirdFontFile.valamodifiedlibbirdfont/SvgFont.valamodifiedlibbirdfont/SvgParser.valaaddedlibbirdxml/Attribute.valamodifiedlibbirdxml/Attributes.valamodifiedlibbirdxml/Tag.valamodifiedlibbirdxml/Xml.vala
Diff
@@ -83,10 +83,8 @@ class BirdFontFile : GLib.Object { private bool load_xml (XmlParser parser) { bool ok = true; - create_background_files (parser.get_next_tag ());- - parser.reparse ();- ok = parse_file (parser.get_next_tag ());+ create_background_files (parser.get_root_tag ());+ ok = parse_file (parser.get_root_tag ()); return ok; }@@ -593,12 +591,7 @@ class BirdFontFile : GLib.Object { } private bool parse_file (Tag tag) {- Tag t;- - tag.reparse ();- while (tag.has_more_tags ()) {- t = tag.get_next_tag ();-+ foreach (Tag t in tag) { // this is a backup file, but path pointing to the original file if (t.get_name () == "backup") { font.font_file = t.get_content ();@@ -679,10 +672,7 @@ class BirdFontFile : GLib.Object { } private void create_background_files (Tag root) {- Tag child;- while (root.has_more_tags ()) {- child = root.get_next_tag ();- + foreach (Tag child in root) { if (child.get_name () == "name") { font.set_name (child.get_content ()); }@@ -715,15 +705,11 @@ class BirdFontFile : GLib.Object { private void parse_spacing_class (Tag tag) { string first, next; SpacingClassTab spacing_class_tab = MainWindow.get_spacing_class_tab ();- Attribute attr; first = ""; next = ""; - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "first") { first = (!) Font.to_unichar (attr.get_content ()).to_string (); }@@ -740,16 +726,12 @@ class BirdFontFile : GLib.Object { GlyphRange range_left, range_right; double hadjustment = 0; KerningRange kerning_range;- Attribute attr; try { range_left = new GlyphRange (); range_right = new GlyphRange (); - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();-+ foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "left") { range_left.parse_ranges (unserialize (attr.get_content ())); }@@ -783,8 +765,6 @@ class BirdFontFile : GLib.Object { } private void parse_background_image (Tag tag) {- Attribute attr;- string file = ""; string data = ""; @@ -794,9 +774,7 @@ class BirdFontFile : GLib.Object { DataOutputStream png_stream; tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "sha1") { file = attr.get_content (); }@@ -834,12 +812,7 @@ class BirdFontFile : GLib.Object { } private void parse_background (Tag tag) {- Attribute attr;- - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "scale") { font.background_scale = attr.get_content (); }@@ -847,12 +820,7 @@ class BirdFontFile : GLib.Object { } private void parse_grid (Tag tag) {- Attribute attr;- - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "width") { font.grid_width.add (attr.get_content ()); }@@ -860,11 +828,7 @@ class BirdFontFile : GLib.Object { } private void parse_horizontal_lines (Tag tag) {- Tag t;- - tag.reparse ();- while (tag.has_more_tags ()) {- t = tag.get_next_tag ();+ foreach (Tag t in tag) { if (t.get_name () == "top_limit" && t.get_content () != "") { font.top_limit = parse_double_from_node (t); }@@ -917,14 +881,9 @@ class BirdFontFile : GLib.Object { StringBuilder b; string name = ""; int selected_id = -1;- Attribute attribute;- Tag t; bool unassigned = false; - tag.reparse ();- while (tag.has_more_attributes ()) {- attribute = tag.get_next_attribute ();- + foreach (Attribute attribute in tag.get_attributes ()) { if (attribute.get_name () == "unicode") { unicode = Font.to_unichar (attribute.get_content ()); b = new StringBuilder ();@@ -949,20 +908,14 @@ class BirdFontFile : GLib.Object { new_glyph_collection = (current_gc == null); gc = (!new_glyph_collection) ? (!) current_gc : new GlyphCollection (unicode, name); - tag.reparse ();- while (tag.has_more_tags ()) {- t = tag.get_next_tag ();- + foreach (Tag t in tag) { if (t.get_name () == "selected") { selected_id = parse_selected (t); gc.set_selected_version (selected_id); } }- - tag.reparse (); - while (tag.has_more_tags ()) {- t = tag.get_next_tag (); + foreach (Tag t in tag) { if (t.get_name () == "glyph") { parse_glyph (t, gc, name, unicode, selected_id, unassigned); }@@ -976,12 +929,8 @@ class BirdFontFile : GLib.Object { private int parse_selected (Tag tag) { int id = 1; bool has_selected_tag = false;- Attribute attribute;-- tag.reparse ();- while (tag.has_more_attributes ()) {- attribute = tag.get_next_attribute ();-+ + foreach (Attribute attribute in tag.get_attributes ()) { if (attribute.get_name () == "id") { id = int.parse (attribute.get_content ()); has_selected_tag = true;@@ -1003,13 +952,8 @@ class BirdFontFile : GLib.Object { bool selected = false; bool has_id = false; int id = 1;- Attribute attr;- Tag t; - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "left") { glyph.left_limit = double.parse (attr.get_content ()); }@@ -1030,9 +974,7 @@ class BirdFontFile : GLib.Object { } } - tag.reparse ();- while (tag.has_more_tags ()) {- t = tag.get_next_tag ();+ foreach (Tag t in tag) { if (t.get_name () == "path") { path = parse_path (t); glyph.add_path (path);@@ -1050,21 +992,14 @@ class BirdFontFile : GLib.Object { private Path parse_path (Tag tag) { Path path = new Path ();- Attribute attr; - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "data") { path = parse_path_data (attr.get_content ()); } } - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();-+ foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "stroke") { path.set_stroke (double.parse (attr.get_content ())); }@@ -1366,14 +1301,10 @@ class BirdFontFile : GLib.Object { private void parse_background_scale (Glyph g, Tag tag) { BackgroundImage img; BackgroundImage? new_img = null;- Attribute attr; File img_file = font.get_backgrounds_folder ().get_child ("parts"); - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "sha1") { img_file = img_file.get_child (attr.get_content () + ".png"); @@ -1393,10 +1324,7 @@ class BirdFontFile : GLib.Object { img = (!) new_img; - tag.reparse (); - while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "x") { img.img_x = double.parse (attr.get_content ()); }@@ -1,5 +1,5 @@ /*- Copyright (C) 2013 Johan Mattsson+ Copyright (C) 2013 2014 Johan Mattsson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -18,7 +18,7 @@ namespace BirdFont { class SvgFont : GLib.Object { Font font;- double units = 1; // 1000 is default in svg spec.+ double units = 1; double font_advance = 0; public SvgFont (Font f) {@@ -32,19 +32,14 @@ class SvgFont : GLib.Object { try { FileUtils.get_contents (path, out data); xml_parser = new XmlParser (data);- parse_svg_font (xml_parser.get_next_tag ());+ parse_svg_font (xml_parser.get_root_tag ()); } catch (GLib.Error e) { warning (e.message); } } void parse_svg_font (Tag tag) {- Tag t;- - tag.reparse ();- while (tag.has_more_tags ()) {- t = tag.get_next_tag ();- + foreach (Tag t in tag) { if (t.get_name () == "defs") { parse_svg_font (t); }@@ -77,12 +72,8 @@ class SvgFont : GLib.Object { unichar l, r; StringBuilder sl, sr; GlyphRange grr, grl;- Attribute attr; - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { // left if (attr.get_name () == "u1") { left = attr.get_content ();@@ -137,21 +128,14 @@ class SvgFont : GLib.Object { void parse_font_limits (Tag tag) { double top_limit = 0; double bottom_limit = 0;- Attribute attr; - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "units-per-em") { units = 100.0 / double.parse (attr.get_content ()); } } - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "ascent") { top_limit = double.parse (attr.get_content ()); }@@ -169,12 +153,7 @@ class SvgFont : GLib.Object { } void parse_font_tag (Tag tag) {- Attribute attr;- - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "horiz-adv-x") { font_advance = double.parse (attr.get_content ()); }@@ -234,15 +213,11 @@ class SvgFont : GLib.Object { double advance = font_advance; string ligature = ""; SvgParser parser = new SvgParser ();- Attribute attr; StringBuilder unicode_name; parser.set_format (SvgFormat.INKSCAPE); - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();-+ foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "unicode") { unicode_value = get_unichar (attr.get_content ()); @@ -57,8 +57,7 @@ public class SvgParser { bool has_format = false; SvgParser parser = new SvgParser (); XmlParser xmlparser;- Tag root;- + foreach (string l in lines) { if (l.index_of ("Illustrator") > -1 || l.index_of ("illustrator") > -1) { parser.set_format (SvgFormat.ILLUSTRATOR);@@ -81,11 +80,8 @@ public class SvgParser { } xmlparser = new XmlParser (xml_data);- - xmlparser.reparse ();- root = xmlparser.get_next_tag (); - path_list = parser.parse_svg_file (root);+ path_list = parser.parse_svg_file (xmlparser.get_root_tag ()); glyph = MainWindow.get_current_glyph (); foreach (Path p in path_list.paths) {@@ -127,13 +123,9 @@ public class SvgParser { } private PathList parse_svg_file (Tag tag) {- Tag t; PathList pl = new PathList ();- - tag.reparse ();- while (tag.has_more_tags ()) {- t = tag.get_next_tag ();- + + foreach (Tag t in tag) { if (t.get_name () == "g") { parse_layer (t, pl); }@@ -156,13 +148,8 @@ public class SvgParser { private void parse_layer (Tag tag, PathList pl) { PathList layer = new PathList ();- Tag t;- Attribute attr; - tag.reparse ();- while (tag.has_more_tags ()) {- t = tag.get_next_tag ();- + foreach (Tag t in tag) { if (t.get_name () == "path") { parse_path (t, layer); }@@ -176,10 +163,7 @@ public class SvgParser { } } - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "transform") { transform (attr.get_content (), layer); }@@ -346,12 +330,8 @@ public class SvgParser { private void parse_polygon (Tag tag, PathList pl) { Glyph glyph = MainWindow.get_current_glyph (); Path p;- Attribute attr; - tag.reparse ();- while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "points") { p = parse_polygon_data (attr.get_content (), glyph); pl.add (p);@@ -362,22 +342,15 @@ public class SvgParser { private void parse_path (Tag tag, PathList pl) { Glyph glyph = MainWindow.get_current_glyph (); PathList path_list = new PathList ();- Attribute attr; - tag.reparse (); - while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "d") { path_list = parse_svg_data (attr.get_content (), glyph); pl.append (path_list); } } - tag.reparse (); - while (tag.has_more_attributes ()) {- attr = tag.get_next_attribute ();- + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "transform") { transform (attr.get_content (), path_list); }new file mode 100644@@ -0,0 +1,51 @@+/*+ Copyright (C) 2014 Johan Mattsson++ This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version.++ This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details.+*/+namespace Bird {++/** Representation of one XML attribute. */+public class Attribute : GLib.Object {+ + public string ns;+ public string name;+ public string content;+ + internal Attribute (string ns, string name, string content) {+ this.ns = ns;+ this.name = name;+ this.content = content;+ }++ internal Attribute.empty () {+ this.ns = "";+ this.name = "";+ this.content = "";+ }+ + /** @return name space part for this attribute. */+ public string get_namespace () {+ return ns;+ }+ + /** @return the name of this attribute. */+ public string get_name () {+ return name;+ }++ /** @return the value of this attribute. */+ public string get_content () {+ return content;+ }+}++}@@ -13,34 +13,47 @@ */ namespace Bird { -public class Attribute : GLib.Object {+/** Iterator for XML attributes. */+public class Attributes : GLib.Object { - public string ns;- public string name;- public string content;- - internal Attribute (string ns, string name, string content) {- this.ns = ns;- this.name = name;- this.content = content;- }-- internal Attribute.empty () {- this.ns = "";- this.name = "";- this.content = "";+ Tag tag;+ + internal Attributes (Tag t) {+ tag = t; } - public string get_namespace () {- return ns;+ public Iterator iterator () {+ return new Iterator (tag); } - public string get_name () {- return name;- }+ public class Iterator {+ Tag tag;+ Attribute? next_attribute;+ + internal Iterator (Tag t) {+ tag = t;+ next_attribute = null;+ tag.reparse_attributes ();+ }++ public bool next () {+ if (tag.has_more_attributes ()) {+ next_attribute = tag.get_next_attribute ();+ } else {+ next_attribute = null;+ }+ + return next_attribute != null;+ } - public string get_content () {- return content;+ public Attribute get () {+ if (unlikely (next_attribute == null)) {+ warning ("No attribute is parsed yet.");+ return new Attribute.empty ();+ }+ + return (!) next_attribute;+ } } } @@ -34,6 +34,7 @@ public class Tag : GLib.Object { this.data = content; this.attributes = attributes; reparse ();+ reparse_attributes (); } internal Tag.empty () {@@ -42,14 +43,27 @@ public class Tag : GLib.Object { name = ""; } + /** Get tag attributes for this tag. */+ public Attributes get_attributes () {+ return new Attributes (this);+ }++ /** Iterate over all tags inside of this tag. */+ public Iterator iterator () {+ return new Iterator(this);+ }+ /** Reset the parser and start from the beginning XML tag. */ public void reparse () { tag_index = 0;- attribute_index = 0; next_tag = obtain_next_tag ();- next_attribute = obtain_next_attribute (); } + internal void reparse_attributes () {+ attribute_index = 0;+ next_attribute = obtain_next_attribute ();+ }+ /** @return the name of this tag. */ public string get_name () { return name;@@ -61,24 +75,24 @@ public class Tag : GLib.Object { } /** @return true if there is one more tags left */- public bool has_more_tags () {+ internal bool has_more_tags () { return has_tags; } /** @return the next tag. **/- public Tag get_next_tag () {+ internal Tag get_next_tag () { Tag r = next_tag == null ? new Tag.empty () : (!) next_tag; next_tag = obtain_next_tag (); return r; } /** @return true is there is one or more attributes to obtain with get_next_attribute */- public bool has_more_attributes () {+ internal bool has_more_attributes () { return has_attributes; } /** @return next attribute. */- public Attribute get_next_attribute () {+ internal Attribute get_next_attribute () { Attribute r = next_attribute == null ? new Attribute.empty () : (!) next_attribute; next_attribute = obtain_next_attribute (); return r;@@ -228,7 +242,7 @@ public class Tag : GLib.Object { return false; } - Attribute obtain_next_attribute () {+ internal Attribute obtain_next_attribute () { int previous_index; int index = attribute_index; int name_start;@@ -328,6 +342,34 @@ public class Tag : GLib.Object { attribute_index = content_stop + 1; return new Attribute (ns, attribute_name, content); }++ public class Iterator {+ Tag tag;+ Tag? next_tag = null;+ + internal Iterator (Tag t) {+ tag = t;+ tag.reparse ();+ }++ public bool next () {+ if (tag.has_more_tags ()) {+ next_tag = tag.get_next_tag ();+ } else {+ next_tag = null;+ }+ + return next_tag != null;+ }++ public Tag get () {+ if (unlikely (next_tag == null)) {+ warning ("No tag is parsed yet.");+ return new Tag.empty ();+ }+ return (!) next_tag;+ }+ } } }@@ -19,31 +19,40 @@ public class XmlParser : GLib.Object { Tag root; string data; + /** Create a new xml parser. */ public XmlParser (string data) { this.data = data; reparse (); } + /** @return the root tag. */+ public Tag get_root_tag () {+ reparse ();+ return root;+ }+ /** Reset the parser and start from the beginning of the XML document. */- public void reparse () {+ internal void reparse () { int root_index;+ Tag container; root_index = find_root_tag (); if (root_index == -1) { warning ("No root tag found."); root = new Tag.empty (); } else {- root = new Tag ("", "", data.substring (root_index));+ container = new Tag ("", "", data.substring (root_index));+ root = container.get_next_tag (); } } /** @return the root tag. **/- public Tag get_next_tag () {+ internal Tag get_next_tag () { return root.get_next_tag (); } /** @return true if there is one more tags left */- public bool has_more_tags () {+ internal bool has_more_tags () { return root.has_more_tags (); } @@ -69,7 +78,7 @@ public class XmlParser : GLib.Object { } return -1;- } + } } }