[librsvg: 4/8] Move CSS importing to Rust



commit 3af8281e6fdcf7f8b1c387074a710e9b67612aaa
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Sep 26 18:12:26 2018 -0500

    Move CSS importing to Rust
    
    This moves all the libcroco-related calls to Rust.  Yay!

 librsvg/rsvg-styles.c        | 33 ---------------------------------
 rsvg_internals/src/croco.rs  |  1 -
 rsvg_internals/src/css.rs    | 30 +++++++++++++++++++++---------
 rsvg_internals/src/handle.rs | 42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 63 insertions(+), 43 deletions(-)
---
diff --git a/librsvg/rsvg-styles.c b/librsvg/rsvg-styles.c
index c009ce95..7b8bce1d 100644
--- a/librsvg/rsvg-styles.c
+++ b/librsvg/rsvg-styles.c
@@ -35,39 +35,6 @@
 
 #include <libcroco/libcroco.h>
 
-#if 0
-static void
-ccss_import_style (CRDocHandler * a_this,
-                   GList * a_media_list,
-                   CRString * a_uri, CRString * a_uri_default_ns, CRParsingLocation * a_location)
-{
-    CSSUserData *user_data = (CSSUserData *) a_this->app_data;
-    char *stylesheet_data;
-    gsize stylesheet_data_len;
-    char *mime_type = NULL;
-
-    if (a_uri == NULL)
-        return;
-
-    stylesheet_data = _rsvg_handle_acquire_data (user_data->handle,
-                                                 cr_string_peek_raw_str (a_uri),
-                                                 &mime_type,
-                                                 &stylesheet_data_len,
-                                                 NULL);
-    if (stylesheet_data == NULL || 
-        mime_type == NULL || 
-        strcmp (mime_type, "text/css") != 0) {
-        g_free (stylesheet_data);
-        g_free (mime_type);
-        return;
-    }
-
-    rsvg_parse_cssbuffer (user_data->handle, stylesheet_data, stylesheet_data_len);
-    g_free (stylesheet_data);
-    g_free (mime_type);
-}
-#endif
-
 /* This is defined like this so that we can export the Rust function... just for
  * the benefit of rsvg-convert.c
  */
diff --git a/rsvg_internals/src/croco.rs b/rsvg_internals/src/croco.rs
index 3d551398..892aca9b 100644
--- a/rsvg_internals/src/croco.rs
+++ b/rsvg_internals/src/croco.rs
@@ -94,7 +94,6 @@ extern "C" {
     pub fn cr_simple_sel_to_string(a_this: CRSimpleSel) -> *mut libc::c_char;
 
     pub fn cr_string_peek_raw_str(a_this: CRString) -> *const libc::c_char;
-    pub fn cr_string_peek_raw_str_len(a_this: CRString) -> libc::c_int;
 
     pub fn cr_term_to_string(a_this: CRTerm) -> *mut libc::c_char;
 
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index 991c3788..d4ef1df1 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -127,13 +127,29 @@ fn init_cr_doc_handler(handler: &mut CRDocHandler) {
 }
 
 unsafe extern "C" fn css_import_style(
-    _a_this: *mut CRDocHandler,
+    a_this: *mut CRDocHandler,
     _a_media_list: *mut GList,
-    _a_uri: CRString,
+    a_uri: CRString,
     _a_uri_default_ns: CRString,
     _a_location: CRParsingLocation,
 ) {
-    unimplemented!();
+    let handler_data = get_doc_handler_data(a_this);
+
+    if a_uri.is_null() {
+        return;
+    }
+
+    let raw_uri = cr_string_peek_raw_str(a_uri);
+    let uri = utf8_cstr(raw_uri);
+
+    if let Ok(binary_data) = handle::acquire_data(handler_data.handle, uri) {
+        if binary_data.content_type.as_ref().map(String::as_ref) == Some("text/css") {
+            parse_into_handle(
+                handler_data.handle,
+                str::from_utf8_unchecked(&binary_data.data),
+            );
+        }
+    }
 }
 
 unsafe fn get_doc_handler_data<'a>(doc_handler: *mut CRDocHandler) -> &'a mut DocHandlerData {
@@ -180,12 +196,8 @@ unsafe extern "C" fn css_property(
             let raw_selector_name = cr_simple_sel_to_string(simple_sel) as *mut libc::c_char;
 
             if !raw_selector_name.is_null() {
-                let prop_name_ptr = cr_string_peek_raw_str(a_name);
-                let prop_name_len = cr_string_peek_raw_str_len(a_name) as usize;
-
-                let prop_name_bytes =
-                    slice::from_raw_parts(prop_name_ptr as *const u8, prop_name_len);
-                let prop_name = str::from_utf8_unchecked(prop_name_bytes);
+                let raw_prop_name = cr_string_peek_raw_str(a_name);
+                let prop_name = utf8_cstr(raw_prop_name);
 
                 let prop_value =
                     <String as FromGlibPtrFull<_>>::from_glib_full(cr_term_to_string(a_expression));
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index f77a4d9f..f75492e5 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -1,4 +1,8 @@
+use std::ptr;
+
+use glib;
 use glib::translate::*;
+use glib_sys;
 use libc;
 
 use css::{CssStyles, RsvgCssStyles};
@@ -21,6 +25,14 @@ extern "C" {
     ) -> *const RsvgHandle;
 
     fn rsvg_handle_get_css_styles(handle: *const RsvgHandle) -> *mut RsvgCssStyles;
+
+    fn _rsvg_handle_acquire_data(
+        handle: *mut RsvgHandle,
+        url: *const libc::c_char,
+        out_content_type: *mut *mut libc::c_char,
+        out_len: *mut usize,
+        error: *mut *mut glib_sys::GError,
+    ) -> *mut u8;
 }
 
 pub fn get_defs<'a>(handle: *const RsvgHandle) -> &'a Defs {
@@ -52,3 +64,33 @@ pub fn get_css_styles<'a>(handle: *const RsvgHandle) -> &'a CssStyles {
 pub fn get_css_styles_mut<'a>(handle: *const RsvgHandle) -> &'a mut CssStyles {
     unsafe { &mut *(rsvg_handle_get_css_styles(handle) as *mut CssStyles) }
 }
+
+pub struct BinaryData {
+    pub data: Vec<u8>,
+    pub content_type: Option<String>,
+}
+
+pub fn acquire_data(handle: *mut RsvgHandle, url: &str) -> Result<BinaryData, glib::Error> {
+    unsafe {
+        let mut content_type: *mut libc::c_char = ptr::null_mut();
+        let mut len = 0;
+        let mut error = ptr::null_mut();
+
+        let buf = _rsvg_handle_acquire_data(
+            handle,
+            url.to_glib_none().0,
+            &mut content_type as *mut *mut _,
+            &mut len,
+            &mut error,
+        );
+
+        if buf.is_null() {
+            Err(from_glib_full(error))
+        } else {
+            Ok(BinaryData {
+                data: FromGlibContainer::from_glib_full_num(buf as *mut u8, len),
+                content_type: from_glib_full(content_type),
+            })
+        }
+    }
+}


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