[librsvg] rsvg_handle_acquire_data(): Move to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] rsvg_handle_acquire_data(): Move to Rust
- Date: Tue, 27 Nov 2018 00:24:33 +0000 (UTC)
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]