[librsvg] rsvg_handle_new_from_file(): Port the implementation to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] rsvg_handle_new_from_file(): Port the implementation to Rust
- Date: Wed, 16 Jan 2019 20:13:05 +0000 (UTC)
commit 169bf43e3cd8dc64ba420415c53365c45e9dcf51
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Jan 16 13:51:45 2019 -0600
rsvg_handle_new_from_file(): Port the implementation to Rust
The C code had an additional check for the resulting GFile to actually
be able to produce a URI. I think this is how it intended to catch
invalid URIs being passed to g_file_new_for_uri().
The code now uses Rust constructs to decide whether to call
g_file_new_for_uri() or g_file_new_for_path(), so I've removed that
check. In any case, an invalid GFile should only produce I/O errors,
which will get caught during the loading stage.
librsvg/rsvg-handle.c | 37 ++++++-------------------------------
rsvg_internals/src/handle.rs | 24 +++++++++++++++++++++++-
rsvg_internals/src/lib.rs | 1 +
3 files changed, 30 insertions(+), 32 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 3e903573..88621087 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -181,6 +181,8 @@ extern void rsvg_handle_rust_set_size_callback (RsvgHandleRust *raw_handle,
RsvgSizeFunc size_func,
gpointer user_data,
GDestroyNotify destroy_notify);
+extern RsvgHandle *rsvg_handle_rust_new_from_file (const char *filename,
+ GError **error);
extern RsvgHandle *rsvg_handle_rust_new_from_gfile_sync (GFile *file,
RsvgHandleFlags flags,
GCancellable *cancellable,
@@ -488,7 +490,7 @@ rsvg_handle_new_from_data (const guint8 *data, gsize data_len, GError **error)
/**
* rsvg_handle_new_from_file:
- * @file_name: The file name to load. If built with gnome-vfs, can be a URI.
+ * @filename: The file name to load, or a URI.
* @error: return location for errors
*
* Loads the SVG specified by @file_name.
@@ -497,39 +499,12 @@ rsvg_handle_new_from_data (const guint8 *data, gsize data_len, GError **error)
* Since: 2.14
*/
RsvgHandle *
-rsvg_handle_new_from_file (const gchar *file_name, GError **error)
+rsvg_handle_new_from_file (const gchar *filename, GError **error)
{
- gchar *base_uri;
- RsvgHandle *handle;
- GFile *file;
- char *scheme;
-
- g_return_val_if_fail (file_name != NULL, NULL);
+ g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- scheme = g_uri_parse_scheme (file_name);
- if (scheme) {
- file = g_file_new_for_uri (file_name);
- g_free (scheme);
- } else {
- file = g_file_new_for_path (file_name);
- }
-
- base_uri = g_file_get_uri (file);
- if (!base_uri) {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Cannot obtain URI from '%s'"), file_name);
- g_object_unref (file);
- return NULL;
- }
- g_free (base_uri);
-
- handle = rsvg_handle_new_from_gfile_sync (file, 0, NULL, error);
- g_object_unref (file);
-
- return handle;
+ return rsvg_handle_rust_new_from_file (filename, error);
}
/**
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index cfe8994e..c7516f21 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -1,7 +1,8 @@
use std;
use std::cell::{Cell, RefCell};
-use std::ffi::CString;
+use std::ffi::{CStr, CString};
use std::mem;
+use std::path::PathBuf;
use std::ptr;
use std::rc::Rc;
use std::slice;
@@ -1011,6 +1012,27 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_position_sub(
}
}
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_new_from_file(
+ filename: *const libc::c_char,
+ error: *mut *mut glib_sys::GError,
+) -> *mut RsvgHandle {
+ // This API lets the caller pass a URI, or a file name in the operating system's
+ // encoding. So, first we'll see if it's UTF-8, and in that case, try the URL version.
+ // Otherwise, we'll try building a path name.
+
+ let cstr = CStr::from_ptr(filename);
+
+ let file = cstr
+ .to_str()
+ .map_err(|_| ())
+ .and_then(|utf8| Url::parse(utf8).map_err(|_| ()))
+ .and_then(|url| Ok(gio::File::new_for_uri(url.as_str())))
+ .unwrap_or_else(|_| gio::File::new_for_path(PathBuf::from_glib_none(filename)));
+
+ rsvg_handle_rust_new_from_gfile_sync(file.to_glib_none().0, 0, ptr::null_mut(), error)
+}
+
#[no_mangle]
pub unsafe extern "C" fn rsvg_handle_rust_new_from_gfile_sync(
file: *mut gio_sys::GFile,
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 5ad608b6..72e7d572 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -55,6 +55,7 @@ pub use handle::{
rsvg_handle_rust_has_sub,
rsvg_handle_rust_new,
rsvg_handle_rust_new_from_data,
+ rsvg_handle_rust_new_from_file,
rsvg_handle_rust_new_from_gfile_sync,
rsvg_handle_rust_new_from_stream_sync,
rsvg_handle_rust_read_stream_sync,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]