Move the "currentnode" to XmlState in Rust

parent 8b934ba7
......@@ -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
......
......@@ -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,
};
......
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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment