[librsvg: 8/48] Move the "currentnode" to XmlState in Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 8/48] Move the "currentnode" to XmlState in Rust
- Date: Sat, 17 Nov 2018 10:20:42 +0000 (UTC)
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]