[librsvg] LoadOptions: new struct to represent RsvgHandleFlags in the Rust code
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] LoadOptions: new struct to represent RsvgHandleFlags in the Rust code
- Date: Tue, 18 Dec 2018 00:32:29 +0000 (UTC)
commit cda7477f1358a54fc7704e80612a5b99bc945245
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Dec 17 15:57:19 2018 -0600
LoadOptions: new struct to represent RsvgHandleFlags in the Rust code
librsvg/rsvg-handle.c | 25 ++++--------
librsvg/rsvg-private.h | 10 +----
rsvg_internals/src/handle.rs | 87 ++++++++++++++++++++++++++++++++---------
rsvg_internals/src/lib.rs | 2 +
rsvg_internals/src/load.rs | 15 +++----
rsvg_internals/src/xml.rs | 4 +-
rsvg_internals/src/xml2_load.rs | 23 +++++------
7 files changed, 101 insertions(+), 65 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 3762bc63..1832c131 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -141,13 +141,15 @@ extern GFile *rsvg_handle_rust_get_base_gfile (RsvgHandleRust *raw_handle);
extern RsvgNode *rsvg_handle_defs_lookup (RsvgHandle *handle, const char *name);
extern gboolean rsvg_handle_rust_node_is_root(RsvgHandleRust *raw_handle, RsvgNode *node);
extern void rsvg_handle_rust_steal_result (RsvgHandleRust *raw_handle, RsvgXmlState *xml);
+extern guint rsvg_handle_rust_get_flags (RsvgHandleRust *raw_handle);
+extern void rsvg_handle_rust_set_flags (RsvgHandleRust *raw_handle, guint flags);
/* Implemented in rsvg_internals/src/xml.rs */
extern void rsvg_xml_state_free (RsvgXmlState *xml);
extern gboolean rsvg_xml_state_tree_is_valid(RsvgXmlState *xml, GError **error);
/* Implemented in rsvg_internals/src/load.rs */
-extern RsvgLoad *rsvg_load_new (RsvgXmlState *xml, gboolean unlimited_size) G_GNUC_WARN_UNUSED_RESULT;
+extern RsvgLoad *rsvg_load_new (RsvgXmlState *xml, guint flags) G_GNUC_WARN_UNUSED_RESULT;
extern RsvgXmlState *rsvg_load_free (RsvgLoad *load) G_GNUC_WARN_UNUSED_RESULT;
extern void rsvg_load_write (RsvgLoad *load, const guchar *buf, gsize count);
extern gboolean rsvg_load_close (RsvgLoad *load, GError **error) G_GNUC_WARN_UNUSED_RESULT;
@@ -201,7 +203,6 @@ rsvg_handle_init (RsvgHandle * self)
{
self->priv = rsvg_handle_get_instance_private (self);
- self->priv->flags = RSVG_HANDLE_FLAGS_NONE;
self->priv->hstate = RSVG_HANDLE_STATE_START;
self->priv->in_loop = FALSE;
@@ -252,7 +253,7 @@ rsvg_handle_set_property (GObject * instance, guint prop_id, GValue const *value
switch (prop_id) {
case PROP_FLAGS:
- self->priv->flags = g_value_get_flags (value);
+ rsvg_handle_rust_set_flags (self->priv->rust_handle, g_value_get_flags (value));
break;
case PROP_DPI_X:
rsvg_handle_rust_set_dpi_x (self->priv->rust_handle, g_value_get_double (value));
@@ -276,7 +277,7 @@ rsvg_handle_get_property (GObject * instance, guint prop_id, GValue * value, GPa
switch (prop_id) {
case PROP_FLAGS:
- g_value_set_flags (value, self->priv->flags);
+ g_value_set_flags (value, rsvg_handle_rust_get_flags (self->priv->rust_handle));
break;
case PROP_DPI_X:
g_value_set_double (value, rsvg_handle_rust_get_dpi_x (self->priv->rust_handle));
@@ -686,7 +687,7 @@ rsvg_handle_write (RsvgHandle *handle, const guchar *buf, gsize count, GError **
if (priv->hstate == RSVG_HANDLE_STATE_START) {
priv->hstate = RSVG_HANDLE_STATE_LOADING;
priv->load = rsvg_load_new (rsvg_xml_state_new (handle),
- (priv->flags && RSVG_HANDLE_FLAG_UNLIMITED) != 0);
+ rsvg_handle_rust_get_flags (priv->rust_handle));
}
g_assert (priv->hstate == RSVG_HANDLE_STATE_LOADING);
@@ -822,7 +823,7 @@ rsvg_handle_read_stream_sync (RsvgHandle *handle,
xml = rsvg_xml_state_new (handle);
read_successfully = rsvg_xml_state_load_from_possibly_compressed_stream (
xml,
- (priv->flags && RSVG_HANDLE_FLAG_UNLIMITED) != 0,
+ rsvg_handle_rust_get_flags (priv->rust_handle),
stream,
cancellable,
error
@@ -1048,24 +1049,12 @@ rsvg_handle_get_desc (RsvgHandle * handle)
return NULL;
}
-guint
-rsvg_handle_get_flags (RsvgHandle *handle)
-{
- return (guint) handle->priv->flags;
-}
-
RsvgHandleRust *
rsvg_handle_get_rust (RsvgHandle *handle)
{
return handle->priv->rust_handle;
}
-gboolean
-rsvg_handle_keep_image_data (RsvgHandle *handle)
-{
- return (handle->priv->flags & RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA) != 0;
-}
-
static RsvgDrawingCtx *
rsvg_handle_create_drawing_ctx(RsvgHandle *handle,
cairo_t *cr,
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 3d4afc40..57046e1e 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -89,8 +89,6 @@ typedef struct RsvgLoad RsvgLoad;
typedef struct RsvgHandleRust RsvgHandleRust;
struct RsvgHandlePrivate {
- RsvgHandleFlags flags;
-
RsvgHandleState hstate;
RsvgLoad *load;
@@ -126,7 +124,7 @@ void rsvg_xml_state_error(RsvgXmlState *xml, const char *msg);
/* Implemented in rsvg_internals/src/xml2_load.rs */
G_GNUC_INTERNAL
gboolean rsvg_xml_state_load_from_possibly_compressed_stream (RsvgXmlState *xml,
- gboolean unlimited_size,
+ guint flags,
GInputStream *stream,
GCancellable *cancellable,
GError **error);
@@ -138,15 +136,9 @@ G_GNUC_INTERNAL
void rsvg_return_if_fail_warning (const char *pretty_function,
const char *expression, GError ** error);
-G_GNUC_INTERNAL
-guint rsvg_handle_get_flags (RsvgHandle *handle);
-
G_GNUC_INTERNAL
RsvgHandleRust *rsvg_handle_get_rust (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,
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 24eeac4d..a14dfdfa 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -1,4 +1,4 @@
-use std::cell::{Ref, RefCell};
+use std::cell::{Cell, Ref, RefCell};
use std::error::Error;
use std::ptr;
use std::rc::Rc;
@@ -31,10 +31,24 @@ pub struct RsvgHandle {
_private: [u8; 0],
}
+/// Flags used during loading
+///
+/// We communicate these to/from the C code with a guint <-> u32,
+/// and this struct provides to_flags() and from_flags() methods.
+#[derive(Default, Copy, Clone)]
+pub struct LoadOptions {
+ /// Whether to turn off size limits in libxml2
+ pub unlimited_size: bool,
+
+ /// Whether to keep original (undecoded) image data to embed in Cairo PDF surfaces
+ pub keep_image_data: bool,
+}
+
pub struct Handle {
dpi: Dpi,
base_url: RefCell<Option<Url>>,
svg: RefCell<Option<Svg>>,
+ load_options: Cell<LoadOptions>,
}
impl Handle {
@@ -43,14 +57,45 @@ impl Handle {
dpi: Dpi::default(),
base_url: RefCell::new(None),
svg: RefCell::new(None),
+ load_options: Cell::new(LoadOptions::default()),
+ }
+ }
+}
+
+// Keep these in sync with rsvg.h:RsvgHandleFlags
+const RSVG_HANDLE_FLAG_UNLIMITED: u32 = 1 << 0;
+const RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA: u32 = 1 << 1;
+
+pub fn get_load_options(handle: *const RsvgHandle) -> LoadOptions {
+ let rhandle = get_rust_handle(handle);
+ rhandle.load_options.get()
+}
+
+impl LoadOptions {
+ pub fn from_flags(flags: u32) -> Self {
+ LoadOptions {
+ unlimited_size: (flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0,
+ keep_image_data: (flags & RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA) != 0,
+ }
+ }
+
+ fn to_flags(&self) -> u32 {
+ let mut flags = 0;
+
+ if self.unlimited_size {
+ flags |= RSVG_HANDLE_FLAG_UNLIMITED;
+ }
+
+ if self.keep_image_data {
+ flags |= RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA;
}
+
+ flags
}
}
#[allow(improper_ctypes)]
extern "C" {
- fn rsvg_handle_get_flags(handle: *const RsvgHandle) -> u32;
-
fn rsvg_handle_new_from_gfile_sync(
file: *const gio_sys::GFile,
flags: u32,
@@ -58,8 +103,6 @@ extern "C" {
error: *mut *mut glib_sys::GError,
) -> *mut RsvgHandle;
- fn rsvg_handle_keep_image_data(handle: *const RsvgHandle) -> glib_sys::gboolean;
-
fn rsvg_handle_get_rust(handle: *const RsvgHandle) -> *mut Handle;
}
@@ -88,11 +131,13 @@ pub fn lookup_fragment_id(handle: *const RsvgHandle, fragment: &Fragment) -> Opt
pub fn load_extern(handle: *const RsvgHandle, aurl: &AllowedUrl) -> Result<*const RsvgHandle, ()> {
unsafe {
+ let rhandle = get_rust_handle(handle);
+
let file = GFile::new_for_uri(aurl.url().as_str());
let res = rsvg_handle_new_from_gfile_sync(
file.to_glib_none().0,
- rsvg_handle_get_flags(handle),
+ rhandle.load_options.get().to_flags(),
ptr::null(),
ptr::null_mut(),
);
@@ -112,12 +157,6 @@ pub fn load_extern(handle: *const RsvgHandle, aurl: &AllowedUrl) -> Result<*cons
}
}
-const RSVG_HANDLE_FLAG_UNLIMITED: u32 = 1 << 0;
-
-pub fn get_unlimited_size(handle: *const RsvgHandle) -> bool {
- unsafe { (rsvg_handle_get_flags(handle) & RSVG_HANDLE_FLAG_UNLIMITED) != 0 }
-}
-
pub fn get_dpi<'a>(handle: *const RsvgHandle) -> &'a Dpi {
let rhandle = get_rust_handle(handle);
@@ -149,14 +188,12 @@ pub fn acquire_stream(
io::acquire_stream(&aurl, None)
}
-fn keep_image_data(handle: *const RsvgHandle) -> bool {
- unsafe { from_glib(rsvg_handle_keep_image_data(handle)) }
-}
-
pub fn load_image_to_surface(
handle: *mut RsvgHandle,
aurl: &AllowedUrl,
) -> Result<ImageSurface, LoadingError> {
+ let rhandle = get_rust_handle(handle);
+
let data = acquire_data(handle, aurl)?;
if data.data.len() == 0 {
@@ -176,7 +213,7 @@ pub fn load_image_to_surface(
let surface = SharedImageSurface::from_pixbuf(&pixbuf)?.into_image_surface()?;
- if keep_image_data(handle) {
+ if rhandle.load_options.get().keep_image_data {
if let Some(mime_type) = data.content_type {
extern "C" {
fn cairo_surface_set_mime_data(
@@ -270,7 +307,7 @@ pub unsafe extern "C" fn rsvg_handle_rust_free(raw_handle: *mut Handle) {
Box::from_raw(raw_handle);
}
-fn get_rust_handle<'a>(handle: *const RsvgHandle) -> &'a mut Handle {
+pub fn get_rust_handle<'a>(handle: *const RsvgHandle) -> &'a mut Handle {
unsafe { &mut *(rsvg_handle_get_rust(handle) as *mut Handle) }
}
@@ -519,3 +556,17 @@ pub unsafe extern "C" fn rsvg_handle_rust_node_is_root(
Rc::ptr_eq(&svg.tree.root(), node).to_glib()
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_get_flags(raw_handle: *const Handle) -> u32 {
+ let rhandle = &*raw_handle;
+
+ rhandle.load_options.get().to_flags()
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_set_flags(raw_handle: *const Handle, flags: u32) {
+ let rhandle = &*raw_handle;
+
+ rhandle.load_options.set(LoadOptions::from_flags(flags));
+}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 6fd85a12..a7950025 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -52,12 +52,14 @@ pub use handle::{
rsvg_handle_rust_get_base_gfile,
rsvg_handle_rust_get_dpi_x,
rsvg_handle_rust_get_dpi_y,
+ rsvg_handle_rust_get_flags,
rsvg_handle_rust_get_root,
rsvg_handle_rust_new,
rsvg_handle_rust_node_is_root,
rsvg_handle_rust_set_base_url,
rsvg_handle_rust_set_dpi_x,
rsvg_handle_rust_set_dpi_y,
+ rsvg_handle_rust_set_flags,
rsvg_handle_rust_steal_result,
};
diff --git a/rsvg_internals/src/load.rs b/rsvg_internals/src/load.rs
index 69a318a4..a112b02b 100644
--- a/rsvg_internals/src/load.rs
+++ b/rsvg_internals/src/load.rs
@@ -6,6 +6,7 @@ use glib_sys;
use std::slice;
use error::set_gerror;
+use handle::LoadOptions;
use xml::XmlState;
use xml2_load::{xml_state_load_from_possibly_compressed_stream, ParseFromStreamError};
@@ -18,7 +19,7 @@ use xml2_load::{xml_state_load_from_possibly_compressed_stream, ParseFromStreamE
// This struct maintains the loading context while an RsvgHandle is being
// populated with data, in case the caller is using write()/close().
pub struct LoadContext<'a> {
- unlimited_size: bool,
+ load_options: LoadOptions,
state: LoadState,
@@ -35,9 +36,9 @@ enum LoadState {
}
impl<'a> LoadContext<'a> {
- pub fn new(xml: &mut XmlState, unlimited_size: bool) -> LoadContext {
+ pub fn new(xml: &mut XmlState, load_options: LoadOptions) -> LoadContext {
LoadContext {
- unlimited_size,
+ load_options,
state: LoadState::Start,
buffer: Vec::new(),
xml,
@@ -74,7 +75,7 @@ impl<'a> LoadContext<'a> {
xml_state_load_from_possibly_compressed_stream(
&mut self.xml,
- self.unlimited_size,
+ &self.load_options,
stream.upcast(),
None,
)
@@ -86,14 +87,14 @@ impl<'a> LoadContext<'a> {
#[no_mangle]
pub unsafe extern "C" fn rsvg_load_new<'a>(
raw_xml: *mut XmlState,
- unlimited_size: glib_sys::gboolean,
+ flags: u32,
) -> *mut LoadContext<'a> {
assert!(!raw_xml.is_null());
let xml = &mut *raw_xml;
- let unlimited_size = from_glib(unlimited_size);
+ let load_options = LoadOptions::from_flags(flags);
- Box::into_raw(Box::new(LoadContext::new(xml, unlimited_size)))
+ Box::into_raw(Box::new(LoadContext::new(xml, load_options)))
}
#[no_mangle]
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 1eeb8c82..af4e5133 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -516,10 +516,10 @@ impl XmlState {
_ => AcquireError::ResourceError,
})?;
- let unlimited_size = handle::get_unlimited_size(self.handle);
+ let load_options = handle::get_load_options(self.handle);
// FIXME: pass a cancellable
- xml_state_parse_from_stream(self, unlimited_size, stream, None).map_err(|e| match e {
+ xml_state_parse_from_stream(self, &load_options, stream, None).map_err(|e| match e {
ParseFromStreamError::CouldNotCreateParser => AcquireError::FatalError,
ParseFromStreamError::IoError(_) => AcquireError::ResourceError,
ParseFromStreamError::XmlParseError(_) => AcquireError::FatalError,
diff --git a/rsvg_internals/src/xml2_load.rs b/rsvg_internals/src/xml2_load.rs
index 63eb61a0..cfb59df1 100644
--- a/rsvg_internals/src/xml2_load.rs
+++ b/rsvg_internals/src/xml2_load.rs
@@ -15,6 +15,7 @@ use std::str;
use glib::translate::*;
use error::set_gerror;
+use handle::LoadOptions;
use io::get_input_stream_for_loading;
use property_bag::PropertyBag;
use util::utf8_cstr;
@@ -189,10 +190,10 @@ unsafe extern "C" fn sax_get_parameter_entity_cb(
sax_get_entity_cb(ctx, name)
}
-fn set_xml_parse_options(parser: xmlParserCtxtPtr, unlimited_size: bool) {
+fn set_xml_parse_options(parser: xmlParserCtxtPtr, load_options: &LoadOptions) {
let mut options: libc::c_int = XML_PARSE_NONET | XML_PARSE_BIG_LINES;
- if unlimited_size {
+ if load_options.unlimited_size {
options |= XML_PARSE_HUGE;
}
@@ -286,7 +287,7 @@ struct Xml2Parser {
impl Xml2Parser {
fn from_stream(
xml: &mut XmlState,
- unlimited_size: bool,
+ load_options: &LoadOptions,
stream: gio::InputStream,
cancellable: Option<&gio::Cancellable>,
) -> Result<Xml2Parser, ParseFromStreamError> {
@@ -322,7 +323,7 @@ impl Xml2Parser {
// stream_ctx_close function
Err(ParseFromStreamError::CouldNotCreateParser)
} else {
- set_xml_parse_options(parser, unlimited_size);
+ set_xml_parse_options(parser, load_options);
Ok(Xml2Parser { parser, gio_error })
}
}
@@ -402,30 +403,30 @@ pub enum ParseFromStreamError {
// for example, when including another XML file via xi:include.
pub fn xml_state_parse_from_stream(
xml: &mut XmlState,
- unlimited_size: bool,
+ load_options: &LoadOptions,
stream: gio::InputStream,
cancellable: Option<&gio::Cancellable>,
) -> Result<(), ParseFromStreamError> {
- Xml2Parser::from_stream(xml, unlimited_size, stream, cancellable)
+ Xml2Parser::from_stream(xml, load_options, stream, cancellable)
.and_then(|parser| parser.parse())
}
pub fn xml_state_load_from_possibly_compressed_stream(
xml: &mut XmlState,
- unlimited_size: bool,
+ load_options: &LoadOptions,
stream: gio::InputStream,
cancellable: Option<gio::Cancellable>,
) -> Result<(), ParseFromStreamError> {
let stream = get_input_stream_for_loading(stream, cancellable.as_ref())
.map_err(|e| ParseFromStreamError::IoError(e))?;
- xml_state_parse_from_stream(xml, unlimited_size, stream, cancellable.as_ref())
+ xml_state_parse_from_stream(xml, load_options, stream, cancellable.as_ref())
}
#[no_mangle]
pub unsafe extern "C" fn rsvg_xml_state_load_from_possibly_compressed_stream(
xml: *mut XmlState,
- unlimited_size: glib_sys::gboolean,
+ flags: u32,
stream: *mut gio_sys::GInputStream,
cancellable: *mut gio_sys::GCancellable,
error: *mut *mut glib_sys::GError,
@@ -433,12 +434,12 @@ pub unsafe extern "C" fn rsvg_xml_state_load_from_possibly_compressed_stream(
assert!(!xml.is_null());
let xml = &mut *xml;
- let unlimited_size = from_glib(unlimited_size);
+ let load_options = LoadOptions::from_flags(flags);
let stream = from_glib_none(stream);
let cancellable = from_glib_none(cancellable);
- match xml_state_load_from_possibly_compressed_stream(xml, unlimited_size, stream, cancellable) {
+ match xml_state_load_from_possibly_compressed_stream(xml, &load_options, stream, cancellable) {
Ok(()) => true.to_glib(),
Err(e) => {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]