[librsvg] rsvg_handle_new_from_data(): Port the implementation to Rust



commit 7e34060f35ca5c449793ed3c2d0db0ef1832d21e
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Jan 9 16:56:44 2019 -0600

    rsvg_handle_new_from_data(): Port the implementation to Rust

 librsvg/rsvg-handle.c        | 14 +++++---------
 rsvg_internals/src/handle.rs | 34 ++++++++++++++++++++++++++++++++++
 rsvg_internals/src/lib.rs    |  1 +
 3 files changed, 40 insertions(+), 9 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index a1e46a30..3e903573 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -190,6 +190,9 @@ extern RsvgHandle *rsvg_handle_rust_new_from_stream_sync (GInputStream *input_st
                                                           RsvgHandleFlags flags,
                                                           GCancellable *cancellable,
                                                           GError **error);
+extern RsvgHandle *rsvg_handle_rust_new_from_data (const guint8 *data,
+                                                   gsize data_len,
+                                                   GError **error);
 
 struct RsvgHandlePrivate {
     RsvgHandleRust *rust_handle;
@@ -476,18 +479,11 @@ rsvg_handle_new (void)
 RsvgHandle *
 rsvg_handle_new_from_data (const guint8 *data, gsize data_len, GError **error)
 {
-    GInputStream *stream;
-    RsvgHandle *handle;
-
-    g_return_val_if_fail (data != NULL, NULL);
+    g_return_val_if_fail ((data != NULL && data_len != 0) || (data_len == 0), NULL);
     g_return_val_if_fail (data_len <= G_MAXSSIZE, NULL);
     g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-    stream = g_memory_input_stream_new_from_data (data, data_len, NULL);
-    handle = rsvg_handle_new_from_stream_sync (stream, NULL, RSVG_HANDLE_FLAGS_NONE, NULL, error);
-    g_object_unref (stream);
-
-    return handle;
+    return rsvg_handle_rust_new_from_data (data, data_len, error);
 }
 
 /**
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 900645f7..6a053f25 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -1,3 +1,4 @@
+use std;
 use std::cell::{Cell, Ref, RefCell};
 use std::ffi::CString;
 use std::mem;
@@ -1239,3 +1240,36 @@ pub unsafe extern "C" fn rsvg_handle_rust_new_from_stream_sync(
         }
     }
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_new_from_data(
+    data: *mut u8,
+    len: usize,
+    error: *mut *mut glib_sys::GError,
+) -> *mut RsvgHandle {
+    // We create the MemoryInputStream without the gtk-rs binding because of this:
+    //
+    // - The binding doesn't provide _new_from_data().  All of the binding's ways to
+    // put data into a MemoryInputStream involve copying the data buffer.
+    //
+    // - We can't use glib::Bytes from the binding either, for the same reason.
+    //
+    // - For now, we are using the other C-visible constructor, so we need a raw pointer to the
+    //   stream, anyway.
+
+    assert!(len <= std::isize::MAX as usize);
+    let len = len as isize;
+
+    let raw_stream = gio_sys::g_memory_input_stream_new_from_data(data, len, None);
+
+    let ret = rsvg_handle_rust_new_from_stream_sync(
+        raw_stream as *mut _,
+        ptr::null_mut(), // base_file
+        0,               // flags
+        ptr::null_mut(), // cancellable
+        error,
+    );
+
+    gobject_sys::g_object_unref(raw_stream as *mut _);
+    ret
+}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index e2ccf936..c1c2ff44 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -54,6 +54,7 @@ pub use handle::{
     rsvg_handle_rust_get_position_sub,
     rsvg_handle_rust_has_sub,
     rsvg_handle_rust_new,
+    rsvg_handle_rust_new_from_data,
     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]