[librsvg: 3/7] Xml2Parser: store a plain reference to XmlState, not an Rc<XmlState>




commit 13b952615d3cfbc2ee7373dd66b7e31274e61078
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Sep 23 11:43:06 2022 -0500

    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>

 src/xml/mod.rs       | 25 ++++---------------------
 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 f7c5f86e1..5e9015b86 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 cb21123d1..c916c4f78 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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]