[gxml] XParser: reset TextReader/Writer once finished



commit c0ae501f50350917bea9ef95093037d53fe8798e
Author: Daniel Espinosa <esodan gmail com>
Date:   Mon Mar 6 12:09:14 2017 -0600

    XParser: reset TextReader/Writer once finished
    
    XParser holds a pointer to a Xml.TextReader and
    Xml.TextWriter, used internally by some methods,
    they are initialized more than twice then some
    issues arise. This patch just set them to null
    once they are finished to be usedful in context
    in order to free memory resources.

 gxml/XParser.vala    |   31 ++++++++++++++++++++++++++++++-
 test/tests-runner.py |   26 ++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletions(-)
---
diff --git a/gxml/XParser.vala b/gxml/XParser.vala
index ed71295..466751a 100644
--- a/gxml/XParser.vala
+++ b/gxml/XParser.vala
@@ -12,7 +12,7 @@
  * 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.
-
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
@@ -80,6 +80,7 @@ public class GXml.XParser : Object, GXml.Parser {
     var b = new GLib.MemoryInputStream.from_data (s.data, null);
     stream.splice (b, GLib.OutputStreamSpliceFlags.NONE);
     stream.close ();
+    tw = null;
   }
 
   public string write_string () throws GLib.Error  {
@@ -102,11 +103,14 @@ public class GXml.XParser : Object, GXml.Parser {
 #endif
     tr = new TextReader.for_memory ((char[]) b.data, (int) b.get_data_size (), "/gxml_memory");
     read_node (_node);
+    tr = null;
   }
   /**
    * Reads a node using current parser.
    */
   public void read_node (DomNode node) throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     move_next_node ();
     if (node is DomElement) {
       while (true) {
@@ -142,6 +146,8 @@ public class GXml.XParser : Object, GXml.Parser {
    * Use parser to go to next parsed node.
    */
   public bool move_next_node () throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     int res = tr.read ();
     if (res == -1)
       throw new ParserError.INVALID_DATA_ERROR (_("Can't read node data"));
@@ -157,30 +163,40 @@ public class GXml.XParser : Object, GXml.Parser {
    * Check if current node has childs.
    */
   public bool current_is_empty_element () {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     return tr.is_empty_element () == 1;
   }
   /**
    * Check if current node found by parser, is a {@link DomElement}
    */
   public bool current_is_element () {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     return (tr.node_type () == Xml.ReaderType.ELEMENT);
   }
   /**
    * Check if current node found by parser, is a {@link DomDocument}
    */
   public bool current_is_document() {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     return (tr.node_type () == Xml.ReaderType.DOCUMENT);
   }
   /**
    * Returns current node's local name, found by parser.
    */
   public string current_node_name () {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     return tr.const_local_name ();
   }
   /**
    * Creates a new {@link DomElement} and append it as a child of parent.
    */
   public DomElement? create_element (DomNode parent) throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     DomElement n = null;
 #if DEBUG
     GLib.message ("Creating a standard element: "
@@ -203,6 +219,8 @@ public class GXml.XParser : Object, GXml.Parser {
    * Reads a {@link DomElement}
    */
   public void read_element (DomElement element) throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     var nattr = tr.attribute_count ();
 #if DEBUG
     GLib.message ("Current reading Element:"+element.local_name);
@@ -275,6 +293,8 @@ public class GXml.XParser : Object, GXml.Parser {
    * Iterates in all child nodes and append them to node.
    */
   public void read_child_nodes (DomNode parent) throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     bool cont = true;
     while (cont) {
 #if DEBUG
@@ -300,6 +320,8 @@ public class GXml.XParser : Object, GXml.Parser {
    * Returns: true if node has been created and appended to parent.
    */
   public bool read_child_node (DomNode parent) throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     DomNode n = null;
     bool ret = true;
     var t = tr.node_type ();
@@ -424,6 +446,8 @@ public class GXml.XParser : Object, GXml.Parser {
    * Reads current found element
    */
   public bool read_child_element (DomNode parent) throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     if (!current_is_element ())
       throw new DomError.INVALID_NODE_TYPE_ERROR
         (_("Invalid attempt to parse an element node, when current found node is not"));
@@ -453,6 +477,8 @@ public class GXml.XParser : Object, GXml.Parser {
    */
   public bool read_element_property (DomNode parent,
                                     out DomNode element) throws GLib.Error {
+    if (tr == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextReader was set"));
     if (!(parent is GomObject)) return false;
 #if DEBUG
     GLib.message ("Searching for Properties Nodes for:"+
@@ -578,11 +604,14 @@ public class GXml.XParser : Object, GXml.Parser {
     if (str != null)
       GLib.message ("STR: "+str);
 #endif
+    tw = null;
     return str;
   }
   private void start_node (GXml.DomNode node)
     throws GLib.Error
   {
+    if (tw == null)
+      throw new ParserError.INVALID_DATA_ERROR (_("Internal Error: No TextWriter initialized"));
 #if DEBUG
     GLib.message ("Starting node..."+node.node_name);
 #endif
diff --git a/test/tests-runner.py b/test/tests-runner.py
new file mode 100755
index 0000000..c7e6715
--- /dev/null
+++ b/test/tests-runner.py
@@ -0,0 +1,26 @@
+# TestRunner.py
+#
+# Copyright (C) 2017  Daniel Espinosa <esodan gmail com>
+#
+# 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 2.1 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.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+#      Daniel Espinosa <esodan gmail com>
+#/
+
+import subprocess
+print('Initalizing GXml TestRunner')
+for n in range(20):
+       subprocess.run('./gxml_test', shell=True, universal_newlines=True, check=False)
+print ('Finished multitesting')


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]