[librsvg] Xml2Parser: Move the parse-from-stream machinery to a struct
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Xml2Parser: Move the parse-from-stream machinery to a struct
- Date: Fri, 7 Dec 2018 17:29:20 +0000 (UTC)
commit 7aa53b5173420b0331ee7cdc58b9a34b4bf35847
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Dec 7 09:27:32 2018 -0600
Xml2Parser: Move the parse-from-stream machinery to a struct
At least this way we can avoid freeing things by hand in the caller.
rsvg_internals/src/xml2_load.rs | 121 ++++++++++++++++++++++------------------
1 file changed, 66 insertions(+), 55 deletions(-)
---
diff --git a/rsvg_internals/src/xml2_load.rs b/rsvg_internals/src/xml2_load.rs
index 23b1aa20..8e6b25fd 100644
--- a/rsvg_internals/src/xml2_load.rs
+++ b/rsvg_internals/src/xml2_load.rs
@@ -270,42 +270,77 @@ unsafe extern "C" fn stream_ctx_close(context: *mut libc::c_void) -> libc::c_int
ret
}
-fn create_xml_stream_parser(
- xml: &mut XmlState,
- unlimited_size: bool,
- stream: gio::InputStream,
- cancellable: Option<gio::Cancellable>,
+struct Xml2Parser {
+ parser: xmlParserCtxtPtr,
gio_error: *mut *mut glib_sys::GError,
-) -> Result<xmlParserCtxtPtr, ParseFromStreamError> {
- let ctx = Box::new(StreamCtx {
- stream,
- cancellable,
- gio_error,
- });
+}
- let mut sax_handler = get_xml2_sax_handler();
+impl Xml2Parser {
+ fn from_stream(
+ xml: &mut XmlState,
+ unlimited_size: bool,
+ stream: gio::InputStream,
+ cancellable: Option<gio::Cancellable>,
+ gio_error: *mut *mut glib_sys::GError,
+ ) -> Result<Xml2Parser, ParseFromStreamError> {
+ let ctx = Box::new(StreamCtx {
+ stream,
+ cancellable,
+ gio_error,
+ });
+
+ let mut sax_handler = get_xml2_sax_handler();
+
+ unsafe {
+ let parser = xmlCreateIOParserCtxt(
+ &mut sax_handler,
+ xml as *mut _ as *mut _,
+ Some(stream_ctx_read),
+ Some(stream_ctx_close),
+ Box::into_raw(ctx) as *mut _,
+ XML_CHAR_ENCODING_NONE,
+ );
+
+ if parser.is_null() {
+ // on error, xmlCreateIOParserCtxt() frees our ctx via the
+ // stream_ctx_close function
+ Err(ParseFromStreamError::CouldNotCreateParser)
+ } else {
+ set_xml_parse_options(parser, unlimited_size);
+ Ok(Xml2Parser { parser, gio_error })
+ }
+ }
+ }
- unsafe {
- let parser = xmlCreateIOParserCtxt(
- &mut sax_handler,
- xml as *mut _ as *mut _,
- Some(stream_ctx_read),
- Some(stream_ctx_close),
- Box::into_raw(ctx) as *mut _,
- XML_CHAR_ENCODING_NONE,
- );
-
- if parser.is_null() {
- // on error, xmlCreateIOParserCtxt() frees our ctx via the
- // stream_ctx_close function
- Err(ParseFromStreamError::CouldNotCreateParser)
- } else {
- set_xml_parse_options(parser, unlimited_size);
- Ok(parser)
+ fn parse(&self) -> Result<(), ParseFromStreamError> {
+ unsafe {
+ let xml_parse_success = xmlParseDocument(self.parser) == 0;
+
+ let io_success = (*self.gio_error).is_null();
+
+ if !io_success {
+ Err(ParseFromStreamError::IoError(from_glib_full(
+ *self.gio_error,
+ )))
+ } else if !xml_parse_success {
+ let xerr = xmlCtxtGetLastError(self.parser as *mut _);
+ Err(ParseFromStreamError::XmlParseError(xml2_error_to_string(
+ xerr,
+ )))
+ } else {
+ Ok(())
+ }
}
}
}
+impl Drop for Xml2Parser {
+ fn drop(&mut self) {
+ free_xml_parser_and_doc(self.parser);
+ self.parser = ptr::null_mut();
+ }
+}
+
#[no_mangle]
pub unsafe extern "C" fn rsvg_create_xml_push_parser(
xml: *mut XmlState,
@@ -388,32 +423,8 @@ pub fn xml_state_parse_from_stream(
) -> Result<(), ParseFromStreamError> {
let mut gio_err: *mut glib_sys::GError = ptr::null_mut();
- match create_xml_stream_parser(xml, unlimited_size, stream, cancellable, &mut gio_err) {
- Ok(parser) => unsafe {
- let xml_parse_success = xmlParseDocument(parser) == 0;
-
- let io_success = gio_err.is_null();
-
- let res;
-
- if !io_success {
- res = Err(ParseFromStreamError::IoError(from_glib_full(gio_err)));
- } else if !xml_parse_success {
- let xerr = xmlCtxtGetLastError(parser as *mut _);
- res = Err(ParseFromStreamError::XmlParseError(xml2_error_to_string(
- xerr,
- )));
- } else {
- res = Ok(());
- }
-
- free_xml_parser_and_doc(parser);
-
- res
- },
-
- Err(e) => Err(e),
- }
+ Xml2Parser::from_stream(xml, unlimited_size, stream, cancellable, &mut gio_err)
+ .and_then(|parser| parser.parse())
}
#[no_mangle]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]