[librsvg: 46/48] Hook up the C code to handle XML xi:include into the Rust code



commit 9d31692fbd36e78dbf63458cb1201906c65d2498
Author: Federico Mena Quintero <federico gnome org>
Date:   Sat Nov 17 03:53:06 2018 -0600

    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!

 librsvg/rsvg-load.c          | 117 ++++++++-----------------------------------
 librsvg/rsvg-load.h          |   3 ++
 rsvg_internals/src/handle.rs |   9 ++++
 rsvg_internals/src/xml.rs    |   6 ++-
 4 files changed, 38 insertions(+), 97 deletions(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index b5300562..1a05bd5e 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -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 */
 
diff --git a/librsvg/rsvg-load.h b/librsvg/rsvg-load.h
index 24d6ba38..6cfcace9 100644
--- a/librsvg/rsvg-load.h
+++ b/librsvg/rsvg-load.h
@@ -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;
 
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index b202e7ee..a081734d 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -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)) }
+}
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 992e13e4..c7729123 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -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 {


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