[librsvg] rsvg_handle_acquire_data(): Move to Rust



commit 7542a94560e125b867b9584f85ea57580dcfcf58
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Nov 26 17:18:18 2018 -0600

    rsvg_handle_acquire_data(): Move to Rust

 librsvg/rsvg-handle.c             | 34 ++-------------
 librsvg/rsvg-load.c               | 18 ++++----
 librsvg/rsvg-private.h            | 14 ++++---
 rsvg_internals/src/allowed_url.rs | 20 +++++----
 rsvg_internals/src/handle.rs      | 88 +++++++++++++++++++++------------------
 rsvg_internals/src/io.rs          | 41 ++++--------------
 rsvg_internals/src/lib.rs         |  8 +---
 7 files changed, 91 insertions(+), 132 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 9bbca717..b10fec49 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -1692,38 +1692,10 @@ allow_load (RsvgHandle *handle, const char *uri, GError **error)
     return FALSE;
 }
 
-/* Implemented in rsvg_internals/src/io.rs */
-G_GNUC_INTERNAL
-char * rsvg_io_acquire_data (const char *uri,
-                             char **out_mime_type,
-                             gsize *out_len,
-                             GCancellable *cancellable,
-                             GError **error);
-
-char *
-_rsvg_handle_acquire_data (RsvgHandle *handle,
-                           const char *href,
-                           char **content_type,
-                           gsize *len,
-                           GError **error)
+GCancellable *
+rsvg_handle_get_cancellable (RsvgHandle *handle)
 {
-    char *uri;
-    char *data;
-
-    uri = rsvg_handle_resolve_uri (handle, href);
-
-    if (allow_load (handle, uri, error)) {
-        data = rsvg_io_acquire_data (uri,
-                                     content_type,
-                                     len,
-                                     handle->priv->cancellable,
-                                     error);
-    } else {
-        data = NULL;
-    }
-
-    g_free (uri);
-    return data;
+    return handle->priv->cancellable;
 }
 
 /* Implemented in rsvg_internals/src/io.rs */
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index eeaa2130..85f057f6 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -377,17 +377,15 @@ sax_entity_decl_cb (void *data, const xmlChar * name, int type,
         gsize entity_data_len;
 
         if (systemId)
-            entity_data = _rsvg_handle_acquire_data (load->handle,
-                                                     (const char *) systemId,
-                                                     NULL,
-                                                     &entity_data_len,
-                                                     NULL);
+            entity_data = rsvg_handle_acquire_data (load->handle,
+                                                    (const char *) systemId,
+                                                    &entity_data_len,
+                                                    NULL);
         else if (publicId)
-            entity_data = _rsvg_handle_acquire_data (load->handle,
-                                                     (const char *) publicId,
-                                                     NULL,
-                                                     &entity_data_len,
-                                                     NULL);
+            entity_data = rsvg_handle_acquire_data (load->handle,
+                                                    (const char *) publicId,
+                                                    &entity_data_len,
+                                                    NULL);
         else
             entity_data = NULL;
 
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index f9a5b337..11b42403 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -287,12 +287,16 @@ RsvgHandle *rsvg_handle_load_extern (RsvgHandle *handle,
 G_GNUC_INTERNAL
 gboolean rsvg_handle_keep_image_data (RsvgHandle *handle);
 
+/* Implemented in rsvg_internals/src/handle.rs */
+G_GNUC_INTERNAL
+char *rsvg_handle_acquire_data (RsvgHandle *handle,
+                                const char *href,
+                                gsize *len,
+                                GError **error);
+
 G_GNUC_INTERNAL
-char *_rsvg_handle_acquire_data (RsvgHandle *handle,
-                                 const char *href,
-                                 char **content_type,
-                                 gsize *len,
-                                 GError **error);
+GCancellable *rsvg_handle_get_cancellable (RsvgHandle *handle);
+
 G_GNUC_INTERNAL
 GInputStream *_rsvg_handle_acquire_stream (RsvgHandle *handle,
                                            const char *href,
diff --git a/rsvg_internals/src/allowed_url.rs b/rsvg_internals/src/allowed_url.rs
index bc997c3f..d6b69692 100644
--- a/rsvg_internals/src/allowed_url.rs
+++ b/rsvg_internals/src/allowed_url.rs
@@ -102,6 +102,10 @@ impl AllowedUrl {
             Err(AllowedUrlError::NotSiblingOrChildOfBaseFile)
         }
     }
+
+    pub fn url(&self) -> &Url {
+        &self.0
+    }
 }
 
 // For tests, we don't want to touch the filesystem.  In that case,
@@ -164,8 +168,8 @@ mod tests {
         assert_eq!(
             AllowedUrl::from_href("data:image/jpeg;base64,xxyyzz", None)
                 .unwrap()
-                .0,
-            Url::parse("data:image/jpeg;base64,xxyyzz").unwrap(),
+                .url(),
+            &Url::parse("data:image/jpeg;base64,xxyyzz").unwrap(),
         );
     }
 
@@ -177,8 +181,8 @@ mod tests {
                 Some(Url::parse("file:///example/bar.svg").unwrap()).as_ref()
             )
             .unwrap()
-            .0,
-            Url::parse("file:///example/foo.svg").unwrap(),
+            .url(),
+            &Url::parse("file:///example/foo.svg").unwrap(),
         );
     }
 
@@ -190,8 +194,8 @@ mod tests {
                 Some(Url::parse("file:///example/bar.svg").unwrap()).as_ref()
             )
             .unwrap()
-            .0,
-            Url::parse("file:///example/foo.svg").unwrap(),
+            .url(),
+            &Url::parse("file:///example/foo.svg").unwrap(),
         );
     }
 
@@ -203,8 +207,8 @@ mod tests {
                 Some(Url::parse("file:///example/bar.svg").unwrap()).as_ref()
             )
             .unwrap()
-            .0,
-            Url::parse("file:///example/subdir/foo.svg").unwrap(),
+            .url(),
+            &Url::parse("file:///example/subdir/foo.svg").unwrap(),
         );
     }
 
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 19de2795..d26891ef 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -4,7 +4,7 @@ use std::ptr;
 use cairo::{ImageSurface, Status};
 use cairo_sys;
 use gdk_pixbuf::{PixbufLoader, PixbufLoaderExt};
-use gio::{File as GFile, InputStream};
+use gio::{Cancellable, File as GFile, InputStream};
 use gio_sys;
 use glib;
 use glib::translate::*;
@@ -12,9 +12,11 @@ use glib_sys;
 use libc;
 use url::Url;
 
+use allowed_url::AllowedUrl;
 use css::{self, CssStyles, RsvgCssStyles};
 use defs::{Defs, RsvgDefs};
-use error::LoadingError;
+use error::{set_gerror, LoadingError, RsvgError};
+use io;
 use surface_utils::shared_surface::SharedImageSurface;
 use util::utf8_cstr;
 
@@ -50,14 +52,6 @@ extern "C" {
 
     fn rsvg_handle_get_css_styles(handle: *const RsvgHandle) -> *mut RsvgCssStyles;
 
-    fn _rsvg_handle_acquire_data(
-        handle: *mut RsvgHandle,
-        href: *const libc::c_char,
-        out_content_type: *mut *mut libc::c_char,
-        out_len: *mut usize,
-        error: *mut *mut glib_sys::GError,
-    ) -> *mut u8;
-
     fn _rsvg_handle_acquire_stream(
         handle: *mut RsvgHandle,
         href: *const libc::c_char,
@@ -72,6 +66,8 @@ extern "C" {
     ) -> glib_sys::gboolean;
 
     fn rsvg_handle_get_rust(handle: *const RsvgHandle) -> *mut RsvgHandleRust;
+
+    fn rsvg_handle_get_cancellable(handle: *const RsvgHandle) -> *mut gio_sys::GCancellable;
 }
 
 pub fn get_defs<'a>(handle: *const RsvgHandle) -> &'a mut Defs {
@@ -112,41 +108,23 @@ pub fn get_css_styles_mut<'a>(handle: *const RsvgHandle) -> &'a mut CssStyles {
     unsafe { &mut *(rsvg_handle_get_css_styles(handle) as *mut CssStyles) }
 }
 
+fn get_cancellable<'a>(handle: *const RsvgHandle) -> Option<Cancellable> {
+    unsafe { from_glib_borrow(rsvg_handle_get_cancellable(handle)) }
+}
+
 pub struct BinaryData {
     pub data: Vec<u8>,
     pub content_type: Option<String>,
 }
 
 pub fn acquire_data(handle: *mut RsvgHandle, href: &str) -> Result<BinaryData, glib::Error> {
-    unsafe {
-        let mut content_type: *mut libc::c_char = ptr::null_mut();
-        let mut len = 0;
-        let mut error = ptr::null_mut();
+    let rhandle = get_rust_handle(handle);
 
-        let buf = _rsvg_handle_acquire_data(
-            handle,
-            href.to_glib_none().0,
-            &mut content_type as *mut *mut _,
-            &mut len,
-            &mut error,
-        );
-
-        if buf.is_null() {
-            if error.is_null() && len == 0 {
-                Ok(BinaryData {
-                    data: Vec::new(),
-                    content_type: None,
-                })
-            } else {
-                Err(from_glib_full(error))
-            }
-        } else {
-            Ok(BinaryData {
-                data: FromGlibContainer::from_glib_full_num(buf as *mut u8, len),
-                content_type: from_glib_full(content_type),
-            })
-        }
-    }
+    let aurl = AllowedUrl::from_href(href, rhandle.base_url.borrow().as_ref())
+        .map_err(|_| glib::Error::new(RsvgError, "FIXME"))?;
+
+    io::acquire_data(&aurl, get_cancellable(handle).as_ref())
+        .map_err(|_| glib::Error::new(RsvgError, "FIXME"))
 }
 
 pub fn acquire_stream(handle: *mut RsvgHandle, href: &str) -> Result<InputStream, glib::Error> {
@@ -282,8 +260,8 @@ pub unsafe extern "C" fn rsvg_handle_rust_free(raw_handle: *mut RsvgHandleRust)
     Box::from_raw(raw_handle as *mut Handle);
 }
 
-fn get_rust_handle(handle: *const RsvgHandle) -> *mut Handle {
-    unsafe { rsvg_handle_get_rust(handle) as *mut Handle }
+fn get_rust_handle<'a>(handle: *const RsvgHandle) -> &'a mut Handle {
+    unsafe { &mut *(rsvg_handle_get_rust(handle) as *mut Handle) }
 }
 
 #[no_mangle]
@@ -325,3 +303,33 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_base_gfile(
         Some(ref url) => GFile::new_for_uri(url.as_str()).to_glib_full(),
     }
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_acquire_data(
+    handle: *mut RsvgHandle,
+    href: *const libc::c_char,
+    out_len: *mut usize,
+    error: *mut *mut glib_sys::GError,
+) -> *mut libc::c_char {
+    assert!(!href.is_null());
+    assert!(!out_len.is_null());
+
+    let href: String = from_glib_none(href);
+
+    match acquire_data(handle, &href) {
+        Ok(binary) => {
+            if !error.is_null() {
+                *error = ptr::null_mut();
+            }
+
+            *out_len = binary.data.len();
+            io::binary_data_to_glib(&binary, ptr::null_mut(), out_len)
+        }
+
+        Err(_) => {
+            set_gerror(error, 0, "Could not acquire data");
+            *out_len = 0;
+            ptr::null_mut()
+        }
+    }
+}
diff --git a/rsvg_internals/src/io.rs b/rsvg_internals/src/io.rs
index f2c4a9a6..4ac24ce1 100644
--- a/rsvg_internals/src/io.rs
+++ b/rsvg_internals/src/io.rs
@@ -19,6 +19,7 @@ use gio::{
 use glib::{self, translate::*, Bytes as GBytes, Cast};
 use std::ptr;
 
+use allowed_url::AllowedUrl;
 use error::{set_gerror, LoadingError, RsvgError};
 use handle::BinaryData;
 use util::utf8_cstr;
@@ -47,7 +48,7 @@ fn decode_data_uri(uri: &str) -> Result<BinaryData, LoadingError> {
     })
 }
 
-fn binary_data_to_glib(
+pub fn binary_data_to_glib(
     binary_data: &BinaryData,
     out_mime_type: *mut *mut libc::c_char,
     out_size: *mut usize,
@@ -189,12 +190,17 @@ pub unsafe fn rsvg_io_acquire_stream(
     }
 }
 
-fn acquire_data(uri: &str, cancellable: Option<Cancellable>) -> Result<BinaryData, LoadingError> {
+pub fn acquire_data(
+    aurl: &AllowedUrl,
+    cancellable: Option<&Cancellable>,
+) -> Result<BinaryData, LoadingError> {
+    let uri = aurl.url().as_str();
+
     if uri.starts_with("data:") {
         Ok(decode_data_uri(uri)?)
     } else {
         let file = GFile::new_for_uri(uri);
-        let (contents, _etag) = file.load_contents(cancellable.as_ref())?;
+        let (contents, _etag) = file.load_contents(cancellable)?;
 
         let (content_type, _uncertain) = gio::content_type_guess(uri, &contents);
         let mime_type = gio::content_type_get_mime_type(&content_type);
@@ -205,32 +211,3 @@ fn acquire_data(uri: &str, cancellable: Option<Cancellable>) -> Result<BinaryDat
         })
     }
 }
-
-#[no_mangle]
-pub unsafe fn rsvg_io_acquire_data(
-    uri: *const libc::c_char,
-    out_mime_type: *mut *mut libc::c_char,
-    out_size: *mut usize,
-    cancellable: *mut gio_sys::GCancellable,
-    error: *mut *mut glib_sys::GError,
-) -> *mut libc::c_char {
-    assert!(!uri.is_null());
-
-    let uri: String = from_glib_none(uri);
-    let cancellable = from_glib_borrow(cancellable);
-
-    match acquire_data(&uri, cancellable) {
-        Ok(binary_data) => {
-            if !error.is_null() {
-                *error = ptr::null_mut();
-            }
-
-            binary_data_to_glib(&binary_data, out_mime_type, out_size)
-        }
-
-        Err(_e) => {
-            set_gerror(error, 0, "Could not acquire data");
-            ptr::null_mut()
-        }
-    }
-}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 1ffa5919..d0eafd58 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -47,6 +47,7 @@ pub use drawing_ctx::{
 };
 
 pub use handle::{
+    rsvg_handle_acquire_data,
     rsvg_handle_load_css,
     rsvg_handle_rust_free,
     rsvg_handle_rust_get_base_gfile,
@@ -54,12 +55,7 @@ pub use handle::{
     rsvg_handle_rust_set_base_url,
 };
 
-pub use io::{
-    rsvg_decode_data_uri,
-    rsvg_get_input_stream_for_loading,
-    rsvg_io_acquire_data,
-    rsvg_io_acquire_stream,
-};
+pub use io::{rsvg_decode_data_uri, rsvg_get_input_stream_for_loading, rsvg_io_acquire_stream};
 
 pub use node::rsvg_node_unref;
 


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