diff options
author | Federico Mena Quintero <federico@gnome.org> | 2022-09-23 11:43:06 -0500 |
---|---|---|
committer | Federico Mena Quintero <federico@gnome.org> | 2022-09-23 11:43:06 -0500 |
commit | 13b952615d3cfbc2ee7373dd66b7e31274e61078 (patch) | |
tree | a80cbc9f355862b0d897aa379f81bb4031fa636e | |
parent | 6a42a6fa94d7957b08d8f25c8a046f92a878ea73 (diff) | |
download | librsvg-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.rs | 25 | ||||
-rw-r--r-- | src/xml/xml2_load.rs | 28 |
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); |