Hook up the C code to handle XML xi:include into the Rust code

The C code creates a secondary XML parser context and re-runs the
loading machinery, which will call back into the Rust code.

Porting the XML stream handling to Rust is the next task.

All the tests pass again!
parent f5e43888
......@@ -278,112 +278,37 @@ create_xml_stream_parser (RsvgLoad *load,
return parser;
}
#if 0
/* http://www.w3.org/TR/xinclude/ */
static void
start_xinclude (RsvgLoad *load, RsvgPropertyBag * atts)
gboolean
rsvg_load_handle_xml_xinclude (RsvgHandle *handle, const char *url)
{
RsvgSaxHandlerXinclude *handler;
const char *href = NULL;
const char *parse = NULL;
const char *encoding = NULL;
gboolean success = FALSE;
RsvgPropertyBagIter *iter;
const char *key;
RsvgAttribute attr;
const char *value;
iter = rsvg_property_bag_iter_begin (atts);
while (rsvg_property_bag_iter_next (iter, &key, &attr, &value)) {
switch (attr) {
case RSVG_ATTRIBUTE_HREF:
href = value;
break;
case RSVG_ATTRIBUTE_PARSE:
parse = value;
break;
case RSVG_ATTRIBUTE_ENCODING:
encoding = value;
break;
default:
break;
}
}
rsvg_property_bag_iter_end (iter);
if (href) {
if (parse && !strcmp (parse, "text")) {
char *data;
gsize data_len;
data = _rsvg_handle_acquire_data (load->handle, href, NULL, &data_len, NULL);
if (data) {
if (encoding && g_ascii_strcasecmp (encoding, "UTF-8") != 0) {
char *text_data;
gsize text_data_len;
text_data = g_convert (data, data_len, "utf-8", encoding, NULL,
&text_data_len, NULL);
g_free (data);
data = text_data;
data_len = text_data_len;
}
rsvg_xml_state_characters (load->xml.rust_state, data, data_len);
g_free (data);
success = TRUE;
}
} else {
/* xml */
GInputStream *stream;
GError *err = NULL;
xmlParserCtxtPtr xml_parser;
stream = _rsvg_handle_acquire_stream (load->handle, href, NULL, NULL);
if (stream) {
xml_parser = create_xml_stream_parser (load,
stream,
NULL, /* cancellable */
&err);
GInputStream *stream;
GError *err = NULL;
xmlParserCtxtPtr xml_parser;
g_object_unref (stream);
g_assert (handle->priv->load != NULL);
if (xml_parser) {
(void) xmlParseDocument (xml_parser);
stream = _rsvg_handle_acquire_stream (handle, url, NULL, NULL);
if (stream) {
xml_parser = create_xml_stream_parser (handle->priv->load,
stream,
NULL, /* cancellable */
&err);
xml_parser = free_xml_parser_and_doc (xml_parser);
}
g_object_unref (stream);
g_clear_error (&err);
if (xml_parser) {
(void) xmlParseDocument (xml_parser);
success = TRUE;
}
xml_parser = free_xml_parser_and_doc (xml_parser);
}
}
/* needed to handle xi:fallback */
handler = g_new0 (RsvgSaxHandlerXinclude, 1);
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;
handler->load = load;
handler->success = success;
g_clear_error (&err);
load->xml.handler = &handler->super;
return TRUE;
} else {
return FALSE;
}
}
#endif
/* end xinclude */
......
......@@ -31,6 +31,9 @@ RsvgLoad *rsvg_load_new (RsvgHandle *handle, gboolean unlimited_size) G_GNUC_WAR
G_GNUC_INTERNAL
void rsvg_load_free (RsvgLoad *load);
G_GNUC_INTERNAL
gboolean rsvg_load_handle_xml_xinclude (RsvgHandle *handle, const char *url);
G_GNUC_INTERNAL
RsvgTree *rsvg_load_steal_tree (RsvgLoad *load) G_GNUC_WARN_UNUSED_RESULT;
......
......@@ -33,6 +33,11 @@ extern "C" {
out_len: *mut usize,
error: *mut *mut glib_sys::GError,
) -> *mut u8;
fn rsvg_load_handle_xml_xinclude(
handle: *mut RsvgHandle,
url: *const libc::c_char,
) -> glib_sys::gboolean;
}
pub fn get_defs<'a>(handle: *const RsvgHandle) -> &'a mut Defs {
......@@ -94,3 +99,7 @@ pub fn acquire_data(handle: *mut RsvgHandle, url: &str) -> Result<BinaryData, gl
}
}
}
pub fn load_xml_xinclude(handle: *mut RsvgHandle, url: &str) -> bool {
unsafe { from_glib(rsvg_load_handle_xml_xinclude(handle, url.to_glib_none().0)) }
}
......@@ -368,7 +368,11 @@ impl XmlState {
}
fn acquire_xml(&self, handle: *mut RsvgHandle, href: &str) -> Result<(), ()> {
unimplemented!()
if handle::load_xml_xinclude(handle, href) {
Ok(())
} else {
Err(())
}
}
fn unsupported_xinclude_start_element(&self, name: &str) -> Context {
......
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