Port characters_impl() to Rust; it's now add_characters()

This lets us remove boxed_node_new() and node_ptr_to_weak(), woohoo!
parent 890b43c5
......@@ -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
......
......@@ -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,
......
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);
});
}
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);
}
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