[librsvg: 39/48] wip: xinclude fallback
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 39/48] wip: xinclude fallback
- Date: Sat, 17 Nov 2018 10:23:18 +0000 (UTC)
commit fe276c0b14b03205979235f6d67dd8a441622626
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Nov 16 07:20:22 2018 -0600
wip: xinclude fallback
librsvg/rsvg-load.c | 74 +-------------
rsvg_internals/src/xml.rs | 247 +++++++++++++++++++++++++---------------------
2 files changed, 141 insertions(+), 180 deletions(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 06c5e916..b5300562 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -162,74 +162,6 @@ rsvg_load_steal_tree (RsvgLoad *load)
return rsvg_xml_state_steal_tree (load->xml.rust_state);
}
-/* start xinclude */
-
-typedef struct _RsvgSaxHandlerXinclude {
- RsvgSaxHandler super;
-
- RsvgSaxHandler *prev_handler;
- RsvgLoad *load;
- gboolean success;
- gboolean in_fallback;
-} RsvgSaxHandlerXinclude;
-
-static void start_xinclude (RsvgLoad *load, RsvgPropertyBag *atts);
-
-static void
-xinclude_handler_free (RsvgSaxHandler * self)
-{
- g_free (self);
-}
-
-static void
-xinclude_handler_characters (RsvgSaxHandler * self, const char *ch, gsize len)
-{
- RsvgSaxHandlerXinclude *z = (RsvgSaxHandlerXinclude *) self;
-
- if (z->in_fallback) {
- rsvg_xml_state_characters (z->load->xml.rust_state, ch, len);
- }
-}
-
-static void
-xinclude_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts)
-{
- RsvgSaxHandlerXinclude *z = (RsvgSaxHandlerXinclude *) self;
-
- if (!z->success) {
- if (z->in_fallback) {
- if (!strcmp (name, "xi:include"))
- start_xinclude (z->load, atts);
- else {
- rsvg_xml_state_start_element (z->load->xml.rust_state,
- z->load->handle,
- (const char *) name,
- atts);
- }
- } else if (!strcmp (name, "xi:fallback")) {
- z->in_fallback = TRUE;
- }
- }
-}
-
-static void
-xinclude_handler_end (RsvgSaxHandler * self, const char *name)
-{
- RsvgSaxHandlerXinclude *z = (RsvgSaxHandlerXinclude *) self;
- RsvgSaxHandler *previous = z->prev_handler;
- RsvgLoad *load = z->load;
-
- if (!strcmp (name, "include") || !strcmp (name, "xi:include")) {
- if (load->xml.handler != NULL) {
- load->xml.handler->free (load->xml.handler);
- load->xml.handler = previous;
- }
- } else if (z->in_fallback) {
- if (!strcmp (name, "xi:fallback"))
- z->in_fallback = FALSE;
- }
-}
-
static void
set_xml_parse_options(xmlParserCtxtPtr xml_parser,
gboolean unlimited_size)
@@ -346,6 +278,7 @@ create_xml_stream_parser (RsvgLoad *load,
return parser;
}
+#if 0
/* http://www.w3.org/TR/xinclude/ */
static void
start_xinclude (RsvgLoad *load, RsvgPropertyBag * atts)
@@ -440,8 +373,8 @@ start_xinclude (RsvgLoad *load, RsvgPropertyBag * atts)
/* needed to handle xi:fallback */
handler = g_new0 (RsvgSaxHandlerXinclude, 1);
- handler->super.free = xinclude_handler_free;
- handler->super.characters = xinclude_handler_characters;
+ handler->super.free = NULL;
+ handler->super.characters = NULL;
handler->super.start_element = xinclude_handler_start;
handler->super.end_element = xinclude_handler_end;
handler->prev_handler = load->xml.handler;
@@ -450,6 +383,7 @@ start_xinclude (RsvgLoad *load, RsvgPropertyBag * atts)
load->xml.handler = &handler->super;
}
+#endif
/* end xinclude */
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 400a5f7c..0bcabc08 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -18,107 +18,7 @@ use structure::NodeSvg;
use text::NodeChars;
use tree::{RsvgTree, Tree};
use util::utf8_cstr;
-// struct XIncludeContext {
-// needs_fallback: bool,
-// }
-//
-// impl XmlHandler for XIncludeContext {
-// fn start_element(
-// &self,
-// _previous_handler: Option<&XmlHandler>,
-// _parent: Option<&Rc<Node>>,
-// handle: *mut RsvgHandle,
-// _name: &str,
-// pbag: &PropertyBag,
-// ) -> Box<XmlHandler> {
-// let mut href = None;
-// let mut parse = None;
-// let mut encoding = None;
-//
-// for (_key, attr, value) in pbag.iter() {
-// match attr {
-// Attribute::Href => href = Some(value),
-// Attribute::Parse => parse = Some(value),
-// Attribute::Encoding => encoding = Some(value),
-// _ => (),
-// }
-// }
-//
-// self.acquire(handle, href, parse, encoding);
-//
-// unimplemented!("finish start_xinclude() here");
-//
-// Box::new(XIncludeContext::empty())
-// }
-//
-// fn end_element(&self, handle: *mut RsvgHandle, _name: &str) -> Option<Rc<Node>> {
-// unimplemented!();
-// }
-//
-// fn characters(&self, text: &str) {
-// unimplemented!();
-// }
-// }
-//
-// impl XIncludeContext {
-// fn empty() -> XIncludeContext {
-// XIncludeContext {
-// needs_fallback: true,
-// }
-// }
-//
-// fn acquire(
-// &self,
-// handle: *mut RsvgHandle,
-// href: Option<&str>,
-// parse: Option<&str>,
-// encoding: Option<&str>,
-// ) {
-// if let Some(href) = href {
-// if parse == Some("text") {
-// self.acquire_text(handle, href, encoding);
-// } else {
-// unimplemented!("finish the xml case here");
-// }
-// }
-// }
-//
-// fn acquire_text(&self, handle: *mut RsvgHandle, href: &str, encoding: Option<&str>) {
-// let binary = match handle::acquire_data(handle, href) {
-// Ok(b) => b,
-// Err(e) => {
-// rsvg_log!("could not acquire \"{}\": {}", href, e);
-// return;
-// }
-// };
-//
-// let encoding = encoding.unwrap_or("utf-8");
-//
-// let encoder = match encoding_from_whatwg_label(encoding) {
-// Some(enc) => enc,
-// None => {
-// rsvg_log!("unknown encoding \"{}\" for \"{}\"", encoding, href);
-// return;
-// }
-// };
-//
-// let utf8_data = match encoder.decode(&binary.data, DecoderTrap::Strict) {
-// Ok(data) => data,
-//
-// Err(e) => {
-// rsvg_log!(
-// "could not convert contents of \"{}\" from character encoding \"{}\": {}",
-// href,
-// encoding,
-// e
-// );
-// return;
-// }
-// };
-//
-// unimplemented!("rsvg_xml_state_characters(utf8_data)");
-// }
-// }
+
enum ContextKind {
// Starting state
Start,
@@ -133,7 +33,13 @@ enum ContextKind {
UnsupportedStyleChild,
// Inside <xi:include>
- XInclude,
+ XInclude(XIncludeContext),
+
+ // An unsupported element inside a <xi:include> context, to be ignored
+ UnsupportedXIncludeChild,
+
+ // Insie <xi::fallback>
+ XIncludeFallback,
}
/// Handles the `<style>` element by parsing its character contents as CSS
@@ -142,6 +48,10 @@ struct StyleContext {
text: String,
}
+struct XIncludeContext {
+ needs_fallback: bool,
+}
+
/// A concrete parsing context for a surrounding `element_name` and its XML event handlers
struct Context {
element_name: String,
@@ -217,7 +127,11 @@ impl XmlState {
}
ContextKind::Style(_) => self.inside_style_start_element(name),
ContextKind::UnsupportedStyleChild => self.inside_style_start_element(name),
- ContextKind::XInclude => self.xinclude_start_element(handle, name, pbag),
+ ContextKind::XInclude(ref ctx) => {
+ self.inside_xinclude_start_element(ctx, handle, name, pbag)
+ }
+ ContextKind::UnsupportedXIncludeChild => self.unsupported_xinclude_start_element(name),
+ ContextKind::XIncludeFallback => self.xinclude_fallback_start_element(ctx, handle, name, pbag),
};
self.push_context(new_ctx);
@@ -244,7 +158,8 @@ impl XmlState {
}
ContextKind::Style(style_ctx) => self.style_end_element(style_ctx, handle),
ContextKind::UnsupportedStyleChild => (),
- ContextKind::XInclude => self.xinclude_end_element(handle, name),
+ ContextKind::XInclude(_) => self.xinclude_end_element(handle, name),
+ ContextKind::UnsupportedXIncludeChild => (),
}
}
@@ -256,7 +171,9 @@ impl XmlState {
}
ContextKind::Style(ref mut style_ctx) => style_characters(style_ctx, text),
ContextKind::UnsupportedStyleChild => (),
- ContextKind::XInclude => self.xinclude_characters(text),
+ ContextKind::XInclude(ref ctx) => (),
+ ContextKind::UnsupportedXIncludeChild => (),
+ ContextKind::XIncludeFallback => self.xinclude_fallback_characters(ctx, text),
}
}
@@ -268,7 +185,7 @@ impl XmlState {
pbag: &PropertyBag,
) -> Context {
match name {
- "include" => unimplemented!(),
+ "include" => self.xinclude_start_element(handle, name, pbag),
"style" => self.style_start_element(name, pbag),
_ => {
let node = self.create_node(parent, handle, name, pbag);
@@ -399,19 +316,129 @@ impl XmlState {
fn xinclude_start_element(
&mut self,
+ ctx: &XIncludeContext,
handle: *mut RsvgHandle,
name: &str,
pbag: &PropertyBag,
) -> Context {
- unimplemented!();
+ let mut href = None;
+ let mut parse = None;
+ let mut encoding = None;
+
+ for (_key, attr, value) in pbag.iter() {
+ match attr {
+ Attribute::Href => href = Some(value),
+ Attribute::Parse => parse = Some(value),
+ Attribute::Encoding => encoding = Some(value),
+ _ => (),
+ }
+ }
+
+ let needs_fallback = self.acquire(handle, href, parse, encoding).is_ok();
+
+ Context {
+ element_name: name.to_string(),
+ kind: ContextKind::XInclude(XIncludeContext { needs_fallback }),
+ }
}
fn xinclude_end_element(&mut self, handle: *mut RsvgHandle, name: &str) {
- unimplemented!();
}
- fn xinclude_characters(&mut self, text: &str) {
- unimplemented!();
+ fn inside_xinclude_start_element(
+ &self,
+ ctx: &XIncludeContext,
+ handle: *mut RsvgHandle,
+ name: &str,
+ pbag: &PropertyBag,
+ ) -> Context {
+ if name == "xi:fallback" {
+ Context {
+ element_name: name.to_string(),
+ kind: ContextKind::XIncludeFallback,
+ }
+ }
+ }
+
+ fn xinclude_fallback_characters(&mut self, ctx: &XIncludeContext, text: &str) {
+ self.characters(text);
+ }
+
+ fn xinclude_fallback_start_element(
+ &self,
+ ctx: &XIncludeContext,
+ handle: *mut RsvgHandle,
+ name: &str,
+ pbag: &PropertyBag,
+ ) -> Context {
+ if name == "xi:include" {
+ self.xinclude_start_element(handle, name, pbag)
+ } else {
+ let parent = parent.clone();
+ self.element_creation_start_element(Some(&parent), handle, name, pbag)
+ }
+ }
+
+ fn acquire(
+ &self,
+ handle: *mut RsvgHandle,
+ href: Option<&str>,
+ parse: Option<&str>,
+ encoding: Option<&str>,
+ ) -> Result<(), ()> {
+ if let Some(href) = href {
+ if parse == Some("text") {
+ self.acquire_text(handle, href, encoding)
+ } else {
+ self.acquire_xml(handle, href)
+ }
+ }
+ }
+
+ fn acquire_text(
+ &mut self,
+ handle: *mut RsvgHandle,
+ href: &str,
+ encoding: Option<&str>,
+ ) -> Result<(), ()> {
+ let binary = handle::acquire_data(handle, href).map_err(|e| {
+ rsvg_log!("could not acquire \"{}\": {}", href, e);
+ ()
+ })?;
+
+ let encoding = encoding.unwrap_or("utf-8");
+
+ let encoder = encoding_from_whatwg_label(encoding)
+ .ok_or_else(|| {
+ rsvg_log!("unknown encoding \"{}\" for \"{}\"", encoding, href);
+ ()
+ })?;
+
+ let utf8_data = encoder
+ .decode(&binary.data, DecoderTrap::Strict)
+ .map_err(|e| {
+ rsvg_log!(
+ "could not convert contents of \"{}\" from character encoding \"{}\": {}",
+ href,
+ encoding,
+ e
+ );
+ ()
+ })?;
+
+ self.characters(utf8_data);
+ Ok(())
+ }
+
+ fn acquire_xml(&self, handle: *mut RsvgHandle, href: &str) -> Result<(), ()> {
+ unimplemented!()
+ }
+
+ fn unsupported_xinclude_start_element(&self, name: &str) -> Context {
+ Context {
+ element_name: name.to_string(),
+ kind: ContextKind::UnsupportedXIncludeChild,
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]