[librsvg: 7/48] xml.rs: New file; start moving the XML parsing state to Rust



commit 8b934ba7f02bd4715742a7804a92b9b41767a40b
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Sep 6 18:09:02 2018 -0500

    xml.rs: New file; start moving the XML parsing state to Rust

 Makefile.am                |  3 ++-
 librsvg/rsvg-load.c        | 22 ++++++++++-----
 librsvg/rsvg-private.h     |  4 ---
 rsvg_internals/src/lib.rs  |  9 ++++++-
 rsvg_internals/src/tree.rs |  8 ------
 rsvg_internals/src/xml.rs  | 67 ++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 93 insertions(+), 20 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 1963570f..edfe723d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -116,7 +116,8 @@ RUST_SRC =                                                  \
        rsvg_internals/src/unitinterval.rs                      \
        rsvg_internals/src/util.rs                              \
        rsvg_internals/src/viewbox.rs                           \
-       rsvg_internals/src/viewport.rs
+       rsvg_internals/src/viewport.rs                          \
+       rsvg_internals/src/xml.rs
 
 RUST_EXTRA =                                           \
        Cargo.lock                                      \
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 4d62d3f9..511678df 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -53,6 +53,15 @@ void rsvg_load_set_svg_node_atts (RsvgHandle *handle, RsvgNode *node);
 G_GNUC_INTERNAL
 void rsvg_node_register_in_defs(RsvgNode *node, RsvgDefs *defs);
 
+/* Implemented in rsvg_internals/src/xml.rs */
+typedef struct RsvgXmlState RsvgXmlState;
+
+/* Implemented in rsvg_internals/src/xml.rs */
+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);
+
 /* Holds the XML parsing state */
 typedef struct {
     /* not a handler stack. each nested handler keeps
@@ -70,8 +79,9 @@ typedef struct {
      */
     GSList *element_name_stack;
 
-    RsvgTree *tree;
     RsvgNode *currentnode;
+
+    RsvgXmlState *rust_state;
 } XmlState;
 
 /* Holds the GIO and loading state for compressed data */
@@ -127,8 +137,8 @@ rsvg_load_new (RsvgHandle *handle, gboolean unlimited_size)
                                                 (GDestroyNotify) xmlFreeNode);
     load->xml.ctxt = NULL;
     load->xml.element_name_stack = NULL;
-    load->xml.tree = NULL;
     load->xml.currentnode = NULL;
+    load->xml.rust_state = rsvg_xml_state_new ();
 
     return load;
 }
@@ -165,14 +175,14 @@ rsvg_load_free (RsvgLoad *load)
 
     g_clear_object (&load->compressed_input_stream);
     g_clear_pointer (&load->xml.currentnode, rsvg_node_unref);
-    g_clear_pointer (&load->xml.tree, rsvg_tree_free);
+    g_clear_pointer (&load->xml.rust_state, rsvg_xml_state_free);
     g_free (load);
 }
 
 RsvgTree *
 rsvg_load_steal_tree (RsvgLoad *load)
 {
-    return g_steal_pointer (&load->xml.tree);
+    return rsvg_xml_state_steal_tree (load->xml.rust_state);
 }
 
 static void
@@ -307,7 +317,7 @@ standard_element_start (RsvgLoad *load, const char *name, RsvgPropertyBag * atts
         rsvg_node_add_child (load->xml.currentnode, newnode);
         load->xml.currentnode = rsvg_node_unref (load->xml.currentnode);
     } else if (is_svg) {
-        load->xml.tree = rsvg_tree_new (newnode);
+        rsvg_xml_state_set_root (load->xml.rust_state, newnode);
     }
 
     load->xml.currentnode = rsvg_node_ref (newnode);
@@ -1194,7 +1204,7 @@ rsvg_load_close (RsvgLoad *load, GError **error)
     }
 
     if (!res) {
-        g_clear_pointer (&load->xml.tree, rsvg_tree_free);
+        g_clear_pointer (&load->xml.rust_state, rsvg_xml_state_free);
     }
 
     load->state = LOAD_STATE_CLOSED;
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index e5c94c4d..f31f8d72 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -166,10 +166,6 @@ gboolean rsvg_node_children_iter_next_back (RsvgNodeChildrenIter *iter,
 G_GNUC_INTERNAL
 void rsvg_node_children_iter_end (RsvgNodeChildrenIter *iter);
 
-/* Implemented in rsvg_internals/src/tree.rs */
-G_GNUC_INTERNAL
-RsvgTree *rsvg_tree_new (RsvgNode *root);
-
 /* Implemented in rsvg_internals/src/tree.rs */
 G_GNUC_INTERNAL
 void rsvg_tree_free (RsvgTree *tree);
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index c0147338..a5a0ec6d 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -62,7 +62,6 @@ pub use tree::{
     rsvg_tree_free,
     rsvg_tree_get_root,
     rsvg_tree_is_root,
-    rsvg_tree_new,
     rsvg_tree_root_is_svg,
 };
 
@@ -78,6 +77,13 @@ pub use structure::rsvg_node_svg_get_size;
 
 pub use text::{rsvg_node_chars_append, rsvg_node_chars_new};
 
+pub use xml::{
+    rsvg_xml_state_free,
+    rsvg_xml_state_new,
+    rsvg_xml_state_set_root,
+    rsvg_xml_state_steal_tree,
+};
+
 #[macro_use]
 mod log;
 
@@ -134,3 +140,4 @@ mod unitinterval;
 mod util;
 mod viewbox;
 mod viewport;
+mod xml;
diff --git a/rsvg_internals/src/tree.rs b/rsvg_internals/src/tree.rs
index 4345cc5d..ad35d089 100644
--- a/rsvg_internals/src/tree.rs
+++ b/rsvg_internals/src/tree.rs
@@ -35,14 +35,6 @@ impl Tree {
     }
 }
 
-#[no_mangle]
-pub extern "C" fn rsvg_tree_new(root: *const RsvgNode) -> *mut RsvgTree {
-    assert!(!root.is_null());
-    let root: &RsvgNode = unsafe { &*root };
-
-    Box::into_raw(Box::new(Tree::new(root))) as *mut RsvgTree
-}
-
 #[no_mangle]
 pub extern "C" fn rsvg_tree_free(tree: *mut RsvgTree) {
     if !tree.is_null() {
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
new file mode 100644
index 00000000..34986e06
--- /dev/null
+++ b/rsvg_internals/src/xml.rs
@@ -0,0 +1,67 @@
+use std::ptr;
+use std::rc::Rc;
+
+use node::{Node, RsvgNode};
+use tree::{RsvgTree, Tree};
+
+// A *const RsvgXmlState is just the type that we export to C
+pub enum RsvgXmlState {}
+
+struct XmlState {
+    tree: Option<Box<Tree>>,
+}
+
+impl XmlState {
+    fn new() -> XmlState {
+        XmlState { tree: None }
+    }
+
+    pub fn set_root(&mut self, root: &Rc<Node>) {
+        if self.tree.is_some() {
+            panic!("The tree root has already been set");
+        }
+
+        self.tree = Some(Box::new(Tree::new(root)));
+    }
+
+    pub fn steal_tree(&mut self) -> Option<Box<Tree>> {
+        self.tree.take()
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_new() -> *mut RsvgXmlState {
+    Box::into_raw(Box::new(XmlState::new())) as *mut RsvgXmlState
+}
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_free(xml: *mut RsvgXmlState) {
+    assert!(!xml.is_null());
+    let xml = unsafe { &mut *(xml as *mut XmlState) };
+    unsafe {
+        Box::from_raw(xml);
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_set_root(xml: *mut RsvgXmlState, root: *const RsvgNode) {
+    assert!(!xml.is_null());
+    let xml = unsafe { &mut *(xml as *mut XmlState) };
+
+    assert!(!root.is_null());
+    let root = unsafe { &*root };
+
+    xml.set_root(root);
+}
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_steal_tree(xml: *mut RsvgXmlState) -> *mut RsvgTree {
+    assert!(!xml.is_null());
+    let xml = unsafe { &mut *(xml as *mut XmlState) };
+
+    if let Some(tree) = xml.steal_tree() {
+        Box::into_raw(tree) as *mut RsvgTree
+    } else {
+        ptr::null_mut()
+    }
+}


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