summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2022-09-23 11:43:06 -0500
committerFederico Mena Quintero <federico@gnome.org>2022-09-23 11:43:06 -0500
commit13b952615d3cfbc2ee7373dd66b7e31274e61078 (patch)
treea80cbc9f355862b0d897aa379f81bb4031fa636e
parent6a42a6fa94d7957b08d8f25c8a046f92a878ea73 (diff)
downloadlibrsvg-13b952615d3cfbc2ee7373dd66b7e31274e61078.tar.gz
Xml2Parser: store a plain reference to XmlState, not an Rc<XmlState>
Now that I know how to use structs with reference fields and lifetimes... The lifetime of the Xml2Parser is basically the duration of XmlState::parse_from_stream(), and it just calls the XmlState to add elements and such. Let's encode that into the Xml2Parser struct. Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/752>
-rw-r--r--src/xml/mod.rs25
-rw-r--r--src/xml/xml2_load.rs28
2 files changed, 18 insertions, 35 deletions
diff --git a/src/xml/mod.rs b/src/xml/mod.rs
index f7c5f86e..5e9015b8 100644
--- a/src/xml/mod.rs
+++ b/src/xml/mod.rs
@@ -13,7 +13,7 @@ use markup5ever::{
};
use std::cell::RefCell;
use std::collections::HashMap;
-use std::rc::{Rc, Weak};
+use std::rc::Rc;
use std::str;
use std::string::ToString;
use std::sync::Arc;
@@ -104,7 +104,6 @@ macro_rules! xinclude_name {
/// trait objects. Normally the context refers to a `NodeCreationContext` implementation which is
/// what creates normal graphical elements.
struct XmlStateInner {
- weak: Option<Weak<XmlState>>,
document_builder: Option<DocumentBuilder>,
num_loaded_elements: usize,
context_stack: Vec<Context>,
@@ -147,7 +146,6 @@ impl XmlState {
) -> XmlState {
XmlState {
inner: RefCell::new(XmlStateInner {
- weak: None,
document_builder: Some(document_builder),
num_loaded_elements: 0,
context_stack: vec![Context::Start],
@@ -610,22 +608,9 @@ impl XmlState {
stream: &gio::InputStream,
cancellable: Option<&gio::Cancellable>,
) -> Result<(), LoadingError> {
- let strong = self
- .inner
- .borrow()
- .weak
- .as_ref()
- .unwrap()
- .upgrade()
- .unwrap();
- Xml2Parser::from_stream(
- strong,
- self.load_options.unlimited_size,
- stream,
- cancellable,
- )
- .and_then(|parser| parser.parse())
- .and_then(|_: ()| self.check_last_error())
+ Xml2Parser::from_stream(self, self.load_options.unlimited_size, stream, cancellable)
+ .and_then(|parser| parser.parse())
+ .and_then(|_: ()| self.check_last_error())
}
fn unsupported_xinclude_start_element(&self, _name: &QualName) -> Context {
@@ -732,8 +717,6 @@ pub fn xml_load_from_possibly_compressed_stream(
) -> Result<Document, LoadingError> {
let state = Rc::new(XmlState::new(session, document_builder, load_options));
- state.inner.borrow_mut().weak = Some(Rc::downgrade(&state));
-
let stream = get_input_stream_for_loading(stream, cancellable)?;
state.build_document(&stream, cancellable)
diff --git a/src/xml/xml2_load.rs b/src/xml/xml2_load.rs
index cb21123d..c916c4f7 100644
--- a/src/xml/xml2_load.rs
+++ b/src/xml/xml2_load.rs
@@ -66,7 +66,7 @@ fn get_xml2_sax_handler() -> xmlSAXHandler {
}
unsafe extern "C" fn rsvg_sax_serror_cb(user_data: *mut libc::c_void, error: xmlErrorPtr) {
- let xml2_parser = &*(user_data as *mut Xml2Parser);
+ let xml2_parser = &*(user_data as *mut Xml2Parser<'_>);
let error = error.as_ref().unwrap();
let level_name = match error.level {
@@ -119,7 +119,7 @@ unsafe extern "C" fn sax_get_entity_cb(
user_data: *mut libc::c_void,
name: *const libc::c_char,
) -> xmlEntityPtr {
- let xml2_parser = &*(user_data as *mut Xml2Parser);
+ let xml2_parser = &*(user_data as *mut Xml2Parser<'_>);
assert!(!name.is_null());
let name = utf8_cstr(name);
@@ -138,7 +138,7 @@ unsafe extern "C" fn sax_entity_decl_cb(
_system_id: *const libc::c_char,
content: *const libc::c_char,
) {
- let xml2_parser = &*(user_data as *mut Xml2Parser);
+ let xml2_parser = &*(user_data as *mut Xml2Parser<'_>);
assert!(!name.is_null());
@@ -204,7 +204,7 @@ unsafe extern "C" fn sax_start_element_ns_cb(
_nb_defaulted: libc::c_int,
attributes: *mut *mut libc::c_char,
) {
- let xml2_parser = &*(user_data as *mut Xml2Parser);
+ let xml2_parser = &*(user_data as *mut Xml2Parser<'_>);
assert!(!localname.is_null());
@@ -242,7 +242,7 @@ unsafe extern "C" fn sax_end_element_ns_cb(
prefix: *mut libc::c_char,
uri: *mut libc::c_char,
) {
- let xml2_parser = &*(user_data as *mut Xml2Parser);
+ let xml2_parser = &*(user_data as *mut Xml2Parser<'_>);
assert!(!localname.is_null());
@@ -260,7 +260,7 @@ unsafe extern "C" fn sax_characters_cb(
unterminated_text: *const libc::c_char,
len: libc::c_int,
) {
- let xml2_parser = &*(user_data as *mut Xml2Parser);
+ let xml2_parser = &*(user_data as *mut Xml2Parser<'_>);
assert!(!unterminated_text.is_null());
assert!(len >= 0);
@@ -278,7 +278,7 @@ unsafe extern "C" fn sax_processing_instruction_cb(
target: *const libc::c_char,
data: *const libc::c_char,
) {
- let xml2_parser = &*(user_data as *mut Xml2Parser);
+ let xml2_parser = &*(user_data as *mut Xml2Parser<'_>);
assert!(!target.is_null());
let target = utf8_cstr(target);
@@ -392,19 +392,19 @@ fn init_libxml2() {
});
}
-pub struct Xml2Parser {
+pub struct Xml2Parser<'a> {
parser: Cell<xmlParserCtxtPtr>,
- state: Rc<XmlState>,
+ state: &'a XmlState,
gio_error: Rc<RefCell<Option<glib::Error>>>,
}
-impl Xml2Parser {
+impl<'a> Xml2Parser<'a> {
pub fn from_stream(
- state: Rc<XmlState>,
+ state: &'a XmlState,
unlimited_size: bool,
stream: &gio::InputStream,
cancellable: Option<&gio::Cancellable>,
- ) -> Result<Box<Xml2Parser>, LoadingError> {
+ ) -> Result<Box<Xml2Parser<'a>>, LoadingError> {
init_libxml2();
// The Xml2Parser we end up creating, if
@@ -431,7 +431,7 @@ impl Xml2Parser {
});
unsafe {
- let xml2_parser_ptr: *mut Xml2Parser = xml2_parser.as_mut();
+ let xml2_parser_ptr: *mut Xml2Parser<'a> = xml2_parser.as_mut();
let parser = xmlCreateIOParserCtxt(
&mut sax_handler,
xml2_parser_ptr as *mut _,
@@ -480,7 +480,7 @@ impl Xml2Parser {
}
}
-impl Drop for Xml2Parser {
+impl<'a> Drop for Xml2Parser<'a> {
fn drop(&mut self) {
let parser = self.parser.get();
free_xml_parser_and_doc(parser);