[librsvg: 10/18] rsvg_get_input_stream_for_loading(): Port to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 10/18] rsvg_get_input_stream_for_loading(): Port to Rust
- Date: Fri, 23 Nov 2018 22:32:20 +0000 (UTC)
commit a688447c0b2d91c9f085973aac87f401ee2cf2b8
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Nov 23 12:07:49 2018 -0600
rsvg_get_input_stream_for_loading(): Port to Rust
Cargo.lock | 2 ++
librsvg/rsvg-load.c | 39 +++--------------------------
rsvg_internals/Cargo.toml | 2 ++
rsvg_internals/src/io.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++-
rsvg_internals/src/lib.rs | 4 ++-
5 files changed, 72 insertions(+), 38 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index 37be5da3..d8410398 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -942,6 +942,8 @@ dependencies = [
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 27b9fe30..45a33d35 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -641,44 +641,11 @@ close_impl (RsvgLoad *load, GError ** error)
#define GZ_MAGIC_0 ((guchar) 0x1f)
#define GZ_MAGIC_1 ((guchar) 0x8b)
-static GInputStream *
+/* Implemented in rsvg_internals/src/io.rs */
+extern GInputStream *
rsvg_get_input_stream_for_loading (GInputStream *stream,
GCancellable *cancellable,
- GError **error)
-{
- gssize num_read;
- const guchar *buf;
-
- /* detect zipped streams */
- stream = g_buffered_input_stream_new (stream);
- num_read = g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (stream), 2, cancellable, error);
- if (num_read < 2) {
- g_object_unref (stream);
- if (num_read < 0) {
- g_assert (error == NULL || *error != NULL);
- } else {
- g_set_error (error, rsvg_error_quark (), RSVG_ERROR_FAILED,
- _("Input file is too short"));
- }
-
- return NULL;
- }
-
- buf = g_buffered_input_stream_peek_buffer (G_BUFFERED_INPUT_STREAM (stream), NULL);
- if ((buf[0] == GZ_MAGIC_0) && (buf[1] == GZ_MAGIC_1)) {
- GConverter *converter;
- GInputStream *conv_stream;
-
- converter = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));
- conv_stream = g_converter_input_stream_new (stream, converter);
- g_object_unref (converter);
- g_object_unref (stream);
-
- stream = conv_stream;
- }
-
- return stream;
-}
+ GError **error);
gboolean
rsvg_load_read_stream_sync (RsvgLoad *load,
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index b6e8d44f..02257492 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -28,6 +28,8 @@ downcast-rs = "^1.0.0"
encoding = "0.2.33"
float-cmp = "0.4.0"
gdk-pixbuf = "0.5.0"
+gio = "0.5.1"
+gio-sys = "0.7.0"
glib = "0.6.0"
glib-sys = "0.7.0"
itertools = "0.7.4"
diff --git a/rsvg_internals/src/io.rs b/rsvg_internals/src/io.rs
index 3997fc98..a3e6b700 100644
--- a/rsvg_internals/src/io.rs
+++ b/rsvg_internals/src/io.rs
@@ -1,11 +1,22 @@
use data_url;
+use gio_sys;
use glib_sys;
use libc;
+use gio::{
+ BufferedInputStream,
+ BufferedInputStreamExt,
+ Cancellable,
+ ConverterInputStream,
+ InputStream,
+ ZlibCompressorFormat,
+ ZlibDecompressor,
+};
use glib::translate::*;
+use glib::Cast;
use std::ptr;
-use error::{set_gerror, LoadingError};
+use error::{set_gerror, LoadingError, RsvgError};
use handle::BinaryData;
use util::utf8_cstr;
@@ -75,3 +86,53 @@ pub fn rsvg_decode_data_uri(
}
}
}
+
+// Header of a gzip data stream
+const GZ_MAGIC_0: u8 = 0x1f;
+const GZ_MAGIC_1: u8 = 0x8b;
+
+fn get_input_stream_for_loading(
+ stream: InputStream,
+ cancellable: Option<Cancellable>,
+) -> Result<InputStream, glib::Error> {
+ // detect gzipped streams (svgz)
+
+ let buffered = BufferedInputStream::new(&stream);
+ let num_read = buffered.fill(2, cancellable.as_ref())?;
+ if num_read < 2 {
+ // FIXME: this string was localized in the original; localize it
+ return Err(glib::Error::new(RsvgError, "Input file is too short"));
+ }
+
+ let buf = buffered.peek_buffer();
+ assert!(buf.len() >= 2);
+ if buf[0] == GZ_MAGIC_0 && buf[1] == GZ_MAGIC_1 {
+ let decomp = ZlibDecompressor::new(ZlibCompressorFormat::Gzip);
+ let converter = ConverterInputStream::new(&buffered, &decomp);
+ Ok(converter.upcast::<InputStream>())
+ } else {
+ Ok(buffered.upcast::<InputStream>())
+ }
+}
+
+#[no_mangle]
+pub unsafe fn rsvg_get_input_stream_for_loading(
+ stream: *mut gio_sys::GInputStream,
+ cancellable: *mut gio_sys::GCancellable,
+ error: *mut *mut glib_sys::GError,
+) -> *mut gio_sys::GInputStream {
+ let stream = from_glib_borrow(stream);
+ let cancellable = from_glib_borrow(cancellable);
+
+ match get_input_stream_for_loading(stream, cancellable) {
+ Ok(stream) => stream.to_glib_full(),
+
+ Err(e) => {
+ if !error.is_null() {
+ *error = e.to_glib_full() as *mut _;
+ }
+
+ ptr::null_mut()
+ }
+ }
+}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 34bde426..bde0ed33 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -10,6 +10,8 @@ extern crate downcast_rs;
extern crate encoding;
extern crate float_cmp;
extern crate gdk_pixbuf;
+extern crate gio;
+extern crate gio_sys;
extern crate glib;
extern crate glib_sys;
extern crate itertools;
@@ -45,7 +47,7 @@ pub use drawing_ctx::{
pub use handle::rsvg_handle_load_css;
-pub use io::rsvg_decode_data_uri;
+pub use io::{rsvg_decode_data_uri, rsvg_get_input_stream_for_loading};
pub use node::rsvg_node_unref;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]