[librsvg: 8/48] Move the "currentnode" to XmlState in Rust



commit 2ca3daf72cec7af47e1c4ff3a67edbdd812205ed
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Sep 6 19:22:16 2018 -0500

    Move the "currentnode" to XmlState in Rust

 librsvg/rsvg-load.c       | 56 +++++++++++++++++++++++++++++------------------
 rsvg_internals/src/lib.rs |  2 ++
 rsvg_internals/src/xml.rs | 46 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 81 insertions(+), 23 deletions(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 511678df..6a4c6cd9 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -61,6 +61,8 @@ extern RsvgXmlState *rsvg_xml_state_new ();
 extern void rsvg_xml_state_free (RsvgXmlState *xml);
 extern void rsvg_xml_state_set_root (RsvgXmlState *xml, RsvgNode *root);
 extern RsvgTree *rsvg_xml_state_steal_tree(RsvgXmlState *xml);
+extern RsvgNode *rsvg_xml_state_get_current_node(RsvgXmlState *xml);
+extern void rsvg_xml_state_set_current_node(RsvgXmlState *xml, RsvgNode *node);
 
 /* Holds the XML parsing state */
 typedef struct {
@@ -79,8 +81,6 @@ typedef struct {
      */
     GSList *element_name_stack;
 
-    RsvgNode *currentnode;
-
     RsvgXmlState *rust_state;
 } XmlState;
 
@@ -137,7 +137,6 @@ rsvg_load_new (RsvgHandle *handle, gboolean unlimited_size)
                                                 (GDestroyNotify) xmlFreeNode);
     load->xml.ctxt = NULL;
     load->xml.element_name_stack = NULL;
-    load->xml.currentnode = NULL;
     load->xml.rust_state = rsvg_xml_state_new ();
 
     return load;
@@ -174,7 +173,6 @@ rsvg_load_free (RsvgLoad *load)
     load->xml.ctxt = free_xml_parser_and_doc (load->xml.ctxt);
 
     g_clear_object (&load->compressed_input_stream);
-    g_clear_pointer (&load->xml.currentnode, rsvg_node_unref);
     g_clear_pointer (&load->xml.rust_state, rsvg_xml_state_free);
     g_free (load);
 }
@@ -305,22 +303,25 @@ static void
 standard_element_start (RsvgLoad *load, const char *name, RsvgPropertyBag * atts)
 {
     RsvgDefs *defs;
+    RsvgNode *current_node;
     RsvgNode *newnode;
 
     defs = rsvg_handle_get_defs(load->handle);
 
-    newnode = rsvg_load_new_node(name, load->xml.currentnode, atts, defs);
+    current_node = rsvg_xml_state_get_current_node (load->xml.rust_state);
+
+    newnode = rsvg_load_new_node (name, current_node, atts, defs);
 
     push_element_name (load, name);
 
-    if (load->xml.currentnode) {
-        rsvg_node_add_child (load->xml.currentnode, newnode);
-        load->xml.currentnode = rsvg_node_unref (load->xml.currentnode);
+    if (current_node) {
+        rsvg_node_add_child (current_node, newnode);
     } else if (is_svg) {
         rsvg_xml_state_set_root (load->xml.rust_state, newnode);
     }
 
-    load->xml.currentnode = rsvg_node_ref (newnode);
+    rsvg_xml_state_set_current_node (load->xml.rust_state, newnode);
+    current_node = rsvg_node_unref (current_node);
 
     rsvg_load_set_node_atts (load->handle, newnode, atts);
 
@@ -654,6 +655,8 @@ sax_end_element_cb (void *data, const xmlChar * xmlname)
         load->xml.handler_nest--;
     } else {
         const char *tempname;
+        RsvgNode *current_node;
+
         for (tempname = name; *tempname != '\0'; tempname++)
             if (*tempname == ':')
                 name = tempname + 1;
@@ -663,18 +666,23 @@ sax_end_element_cb (void *data, const xmlChar * xmlname)
             load->xml.handler = NULL;
         }
 
-        if (load->xml.currentnode) {
-            rsvg_load_set_svg_node_atts (load->handle, load->xml.currentnode);
+        current_node = rsvg_xml_state_get_current_node (load->xml.rust_state);
+
+        if (current_node) {
+            rsvg_load_set_svg_node_atts (load->handle, current_node);
         }
 
-        if (load->xml.currentnode && topmost_element_name_is (load, name)) {
+        if (current_node && topmost_element_name_is (load, name)) {
             RsvgNode *parent;
 
-            parent = rsvg_node_get_parent (load->xml.currentnode);
-            load->xml.currentnode = rsvg_node_unref (load->xml.currentnode);
-            load->xml.currentnode = parent;
+            parent = rsvg_node_get_parent (current_node);
+            rsvg_xml_state_set_current_node (load->xml.rust_state, parent);
+            parent = rsvg_node_unref (parent);
+
             pop_element_name (load);
         }
+
+        current_node = rsvg_node_unref (current_node);
     }
 }
 
@@ -690,26 +698,32 @@ extern void rsvg_node_chars_append (RsvgNode *node, const char *text, gssize len
 static void
 characters_impl (RsvgLoad *load, const char *ch, gssize len)
 {
+    RsvgNode *current_node;
     RsvgNode *node;
     gboolean accept_chars = FALSE;
 
-    if (!ch || !len || !load->xml.currentnode) {
-        return;
+    current_node = rsvg_xml_state_get_current_node (load->xml.rust_state);
+
+    if (!ch || !len || !current_node) {
+        goto out;
     }
 
-    node = rsvg_node_find_last_chars_child (load->xml.currentnode, &accept_chars);
+    node = rsvg_node_find_last_chars_child (current_node, &accept_chars);
     if (!accept_chars) {
-        return;
+        goto out;
     }
 
     if (!node) {
-        node = rsvg_node_chars_new (load->xml.currentnode);
-        rsvg_node_add_child (load->xml.currentnode, node);
+        node = rsvg_node_chars_new (current_node);
+        rsvg_node_add_child (current_node, node);
     }
 
     rsvg_node_chars_append (node, ch, len);
 
     node = rsvg_node_unref (node);
+
+out:
+    current_node = rsvg_node_unref (current_node);
 }
 
 static void
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index a5a0ec6d..bb89a22b 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -79,7 +79,9 @@ pub use text::{rsvg_node_chars_append, rsvg_node_chars_new};
 
 pub use xml::{
     rsvg_xml_state_free,
+    rsvg_xml_state_get_current_node,
     rsvg_xml_state_new,
+    rsvg_xml_state_set_current_node,
     rsvg_xml_state_set_root,
     rsvg_xml_state_steal_tree,
 };
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 34986e06..e279eb5e 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -1,7 +1,7 @@
 use std::ptr;
 use std::rc::Rc;
 
-use node::{Node, RsvgNode};
+use node::{box_node, Node, RsvgNode};
 use tree::{RsvgTree, Tree};
 
 // A *const RsvgXmlState is just the type that we export to C
@@ -9,11 +9,15 @@ pub enum RsvgXmlState {}
 
 struct XmlState {
     tree: Option<Box<Tree>>,
+    current_node: Option<Rc<Node>>,
 }
 
 impl XmlState {
     fn new() -> XmlState {
-        XmlState { tree: None }
+        XmlState {
+            tree: None,
+            current_node: None,
+        }
     }
 
     pub fn set_root(&mut self, root: &Rc<Node>) {
@@ -27,6 +31,14 @@ impl XmlState {
     pub fn steal_tree(&mut self) -> Option<Box<Tree>> {
         self.tree.take()
     }
+
+    pub fn get_current_node(&self) -> Option<Rc<Node>> {
+        self.current_node.clone()
+    }
+
+    pub fn set_current_node(&mut self, node: Option<Rc<Node>>) {
+        self.current_node = node;
+    }
 }
 
 #[no_mangle]
@@ -65,3 +77,33 @@ pub extern "C" fn rsvg_xml_state_steal_tree(xml: *mut RsvgXmlState) -> *mut Rsvg
         ptr::null_mut()
     }
 }
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_get_current_node(xml: *const RsvgXmlState) -> *mut RsvgNode {
+    assert!(!xml.is_null());
+    let xml = unsafe { &*(xml as *const XmlState) };
+
+    if let Some(ref node) = xml.get_current_node() {
+        box_node(node.clone())
+    } else {
+        ptr::null_mut()
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_set_current_node(
+    xml: *mut RsvgXmlState,
+    raw_node: *const RsvgNode,
+) {
+    assert!(!xml.is_null());
+    let xml = unsafe { &mut *(xml as *mut XmlState) };
+
+    let node = if raw_node.is_null() {
+        None
+    } else {
+        let n = unsafe { &*raw_node };
+        Some(n.clone())
+    };
+
+    xml.set_current_node(node);
+}


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