rsvg_get_input_stream_for_loading(): Port to Rust

parent 1a249da8
......@@ -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)",
......
......@@ -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,
......
......@@ -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"
......
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()
}
}
}
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment