[librsvg: 15/48] Port characters_impl() to Rust; it's now add_characters()



commit 9e20b1cef52662d9866c2d52f6824773361a231b
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Sep 7 08:12:53 2018 -0500

    Port characters_impl() to Rust; it's now add_characters()
    
    This lets us remove boxed_node_new() and node_ptr_to_weak(), woohoo!

 librsvg/rsvg-load.c        | 57 ++++++++--------------------------------------
 rsvg_internals/src/lib.rs  |  3 +--
 rsvg_internals/src/text.rs | 44 +++--------------------------------
 rsvg_internals/src/xml.rs  | 52 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 64 insertions(+), 92 deletions(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index d36d7598..89ea13fc 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -61,6 +61,8 @@ extern gboolean rsvg_xml_state_topmost_element_name_is(RsvgXmlState *xml, const
 extern void rsvg_xml_state_free_element_name_stack(RsvgXmlState *xml);
 extern void rsvg_xml_state_standard_element_start(RsvgXmlState *xml, RsvgHandle *handle, const char *name, 
RsvgPropertyBag atts);
 extern void rsvg_xml_state_standard_element_end(RsvgXmlState *xml, RsvgHandle *handle, const char *name);
+extern void rsvg_xml_state_add_characters(RsvgXmlState *xml, const char *characters, gsize len);
+
 
 /* Holds the XML parsing state */
 typedef struct {
@@ -97,7 +99,7 @@ struct RsvgSaxHandler {
     void (*free) (RsvgSaxHandler * self);
     void (*start_element) (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts);
     void (*end_element) (RsvgSaxHandler * self, const char *name);
-    void (*characters) (RsvgSaxHandler * self, const char *ch, gssize len);
+    void (*characters) (RsvgSaxHandler * self, const char *ch, gsize len);
 };
 
 typedef struct _RsvgSaxHandlerStyle {
@@ -188,7 +190,7 @@ style_handler_free (RsvgSaxHandler * self)
 }
 
 static void
-style_handler_characters (RsvgSaxHandler * self, const char *ch, gssize len)
+style_handler_characters (RsvgSaxHandler * self, const char *ch, gsize len)
 {
     RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
     g_string_append_len (z->style, ch, len);
@@ -271,7 +273,6 @@ typedef struct _RsvgSaxHandlerXinclude {
 } RsvgSaxHandlerXinclude;
 
 static void start_xinclude (RsvgLoad *load, RsvgPropertyBag *atts);
-static void characters_impl (RsvgLoad *load, const char *ch, gssize len);
 
 static void
 xinclude_handler_free (RsvgSaxHandler * self)
@@ -280,12 +281,12 @@ xinclude_handler_free (RsvgSaxHandler * self)
 }
 
 static void
-xinclude_handler_characters (RsvgSaxHandler * self, const char *ch, gssize len)
+xinclude_handler_characters (RsvgSaxHandler * self, const char *ch, gsize len)
 {
     RsvgSaxHandlerXinclude *z = (RsvgSaxHandlerXinclude *) self;
 
     if (z->in_fallback) {
-        characters_impl (z->load, ch, len);
+        rsvg_xml_state_add_characters (z->load->xml.rust_state, ch, len);
     }
 }
 
@@ -501,7 +502,7 @@ start_xinclude (RsvgLoad *load, RsvgPropertyBag * atts)
                     data_len = text_data_len;
                 }
 
-                characters_impl (load, data, data_len);
+                rsvg_xml_state_add_characters (load->xml.rust_state, data, data_len);
 
                 g_free (data);
 
@@ -608,57 +609,17 @@ sax_end_element_cb (void *data, const xmlChar * xmlname)
     }
 }
 
-/* Implemented in rust/src/node.rs */
-extern RsvgNode *rsvg_node_find_last_chars_child(RsvgNode *node, gboolean *accept_chars);
-
-/* Implemented in rust/src/text.rs */
-extern RsvgNode *rsvg_node_chars_new(RsvgNode *parent);
-
-/* Implemented in rust/src/text.rs */
-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;
-
-    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 (current_node, &accept_chars);
-    if (!accept_chars) {
-        goto out;
-    }
-
-    if (!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
 sax_characters_cb (void *data, const xmlChar * ch, int len)
 {
     RsvgLoad *load = data;
 
     if (load->xml.handler) {
-        load->xml.handler->characters (load->xml.handler, (const char *) ch, len);
+        load->xml.handler->characters (load->xml.handler, (const char *) ch, (gsize) len);
         return;
     }
 
-    characters_impl (load, (const char *) ch, len);
+    rsvg_xml_state_add_characters (load->xml.rust_state, (const char *) ch, (gsize) len);
 }
 
 static xmlEntityPtr
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index a7f8649a..57144121 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -73,9 +73,8 @@ pub use property_bag::{
 
 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_add_characters,
     rsvg_xml_state_free,
     rsvg_xml_state_free_element_name_stack,
     rsvg_xml_state_get_current_node,
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 3fa42ec3..326ca1f7 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -1,8 +1,5 @@
-use libc;
 use pango::{self, ContextExt, LayoutExt};
-use std;
 use std::cell::{Cell, RefCell};
-use std::str;
 
 use attributes::Attribute;
 use drawing_ctx::DrawingCtx;
@@ -10,7 +7,7 @@ use error::RenderingError;
 use font_props::FontWeightSpec;
 use handle::RsvgHandle;
 use length::*;
-use node::{boxed_node_new, CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
+use node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
 use parsers::parse;
 use property_bag::PropertyBag;
 use space::xml_space_normalize;
@@ -53,13 +50,13 @@ pub struct NodeChars {
 }
 
 impl NodeChars {
-    fn new() -> NodeChars {
+    pub fn new() -> NodeChars {
         NodeChars {
             string: RefCell::new(String::new()),
         }
     }
 
-    fn append(&self, s: &str) {
+    pub fn append(&self, s: &str) {
         self.string.borrow_mut().push_str(s);
     }
 
@@ -750,38 +747,3 @@ fn render_child(
 
     res
 }
-
-#[no_mangle]
-pub extern "C" fn rsvg_node_chars_new(raw_parent: *const RsvgNode) -> *const RsvgNode {
-    boxed_node_new(
-        NodeType::Chars,
-        raw_parent,
-        "rsvg_chars",
-        None,
-        None,
-        Box::new(NodeChars::new()),
-    )
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_node_chars_append(
-    raw_node: *const RsvgNode,
-    text: *const libc::c_char,
-    len: isize,
-) {
-    assert!(!raw_node.is_null());
-    let node: &RsvgNode = unsafe { &*raw_node };
-
-    assert!(node.get_type() == NodeType::Chars);
-    assert!(!text.is_null());
-    assert!(len >= 0);
-
-    // libxml2 already validated the incoming string as UTF-8.  Note that
-    // it is *not* nul-terminated; this is why we create a byte slice first.
-    let bytes = unsafe { std::slice::from_raw_parts(text as *const u8, len as usize) };
-    let utf8 = unsafe { str::from_utf8_unchecked(bytes) };
-
-    node.with_impl(|chars: &NodeChars| {
-        chars.append(utf8);
-    });
-}
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 7576cee5..5e7a7715 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -1,15 +1,18 @@
 use libc;
+use std;
 use std::ptr;
 use std::rc::Rc;
+use std::str;
 
 use glib::translate::*;
 use glib_sys;
 
 use handle::{self, RsvgHandle};
 use load::rsvg_load_new_node;
-use node::{box_node, Node, NodeType, RsvgNode};
+use node::{box_node, node_new, Node, NodeType, RsvgNode};
 use property_bag::PropertyBag;
 use structure::NodeSvg;
+use text::NodeChars;
 use tree::{RsvgTree, Tree};
 use util::utf8_cstr;
 
@@ -137,6 +140,34 @@ impl XmlState {
             }
         }
     }
+
+    pub fn add_characters(&mut self, text: &str) {
+        if text.len() == 0 {
+            return;
+        }
+
+        if let Some(ref current_node) = self.current_node {
+            if current_node.accept_chars() {
+                let chars_node = if let Some(child) = current_node.find_last_chars_child() {
+                    child
+                } else {
+                    let child = node_new(
+                        NodeType::Chars,
+                        self.current_node.as_ref(),
+                        None,
+                        None,
+                        Box::new(NodeChars::new()),
+                    );
+                    current_node.add_child(&child);
+                    child
+                };
+
+                chars_node.with_impl(|chars: &NodeChars| {
+                    chars.append(text);
+                });
+            }
+        }
+    }
 }
 
 #[no_mangle]
@@ -283,3 +314,22 @@ pub extern "C" fn rsvg_xml_state_standard_element_end(
 
     xml.standard_element_end(handle, name);
 }
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_add_characters(
+    xml: *mut RsvgXmlState,
+    unterminated_text: *const libc::c_char,
+    len: usize,
+) {
+    assert!(!xml.is_null());
+    let xml = unsafe { &mut *(xml as *mut XmlState) };
+
+    assert!(!unterminated_text.is_null());
+
+    // libxml2 already validated the incoming string as UTF-8.  Note that
+    // it is *not* nul-terminated; this is why we create a byte slice first.
+    let bytes = unsafe { std::slice::from_raw_parts(unterminated_text as *const u8, len) };
+    let utf8 = unsafe { str::from_utf8_unchecked(bytes) };
+
+    xml.add_characters(utf8);
+}


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