[librsvg: 5/7] Move rsvg_css_parse_number_list() completely to Rust. Yay!
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 5/7] Move rsvg_css_parse_number_list() completely to Rust. Yay!
- Date: Thu, 22 Jun 2017 18:25:50 +0000 (UTC)
commit dc4756378535d5db3b9c0a07deb607b0f71bcd70
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Jun 20 11:02:08 2017 -0500
Move rsvg_css_parse_number_list() completely to Rust. Yay!
Unfortunately there is no to_glib_full() for arrays of doubles. We call
g_malloc_n() by hand to create an array that C can consume, and fill it
with the values that we parsed.
rsvg-css.c | 38 -----------------------------
rsvg-css.h | 3 +-
rust/src/lib.rs | 1 +
rust/src/parsers.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 67 insertions(+), 40 deletions(-)
---
diff --git a/rsvg-css.c b/rsvg-css.c
index a75bfa7..6ca0656 100644
--- a/rsvg-css.c
+++ b/rsvg-css.c
@@ -319,44 +319,6 @@ rsvg_css_parse_list (const char *in_str, guint * out_list_len)
}
gboolean
-rsvg_css_parse_number_list (const char *in_str,
- NumberListLength nlength,
- gsize size,
- gdouble **out_list,
- gsize *out_list_len)
-{
- gchar **string_array;
- gdouble *output;
- guint len, i;
-
- *out_list = NULL;
- *out_list_len = 0;
-
- string_array = rsvg_css_parse_list (in_str, &len);
-
- if (!(string_array && len))
- return FALSE;
-
- if ((nlength == NUMBER_LIST_LENGTH_EXACT && (gsize) len != size)
- || (nlength == NUMBER_LIST_LENGTH_MAXIMUM && (gsize) len > size))
- return FALSE;
-
- output = g_new0 (gdouble, len);
-
- /* TODO: some error checking */
- for (i = 0; i < len; i++)
- output[i] = g_ascii_strtod (string_array[i], NULL);
-
- g_strfreev (string_array);
-
- *out_list_len = len;
-
- *out_list = output;
-
- return TRUE;
-}
-
-gboolean
rsvg_css_parse_overflow (const char *str, gboolean * inherit)
{
SETINHERIT ();
diff --git a/rsvg-css.h b/rsvg-css.h
index 4efbde6..74c3220 100644
--- a/rsvg-css.h
+++ b/rsvg-css.h
@@ -140,11 +140,12 @@ typedef enum {
NUMBER_LIST_LENGTH_MAXIMUM
} NumberListLength;
+/* Implemented in rust/src/parsers.rs */
G_GNUC_INTERNAL
gboolean rsvg_css_parse_number_list (const char *in_str,
NumberListLength nlength,
gsize size,
- gdouble **out_list,
+ gdouble **out_list,
gsize *out_list_len);
G_GNUC_INTERNAL
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 1323d1e..fe7f2a0 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -79,6 +79,7 @@ pub use opacity::{
};
pub use parsers::{
+ rsvg_css_parse_number_list,
rsvg_css_parse_number_optional_number
};
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index 948f5c5..548936e 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -4,8 +4,11 @@ use ::glib::translate::*;
use ::glib_sys;
use ::nom::{IResult, double, is_alphabetic};
-use std::str;
use std::f64::consts::*;
+use std::mem;
+use std::ptr;
+use std::slice;
+use std::str;
// I don't know how to copy a nom::IError for long-term storage
// (i.e. when it can no longer reference the &[u8]). So, we explode a
@@ -245,6 +248,66 @@ fn number_list (s: &str, length: ListLength) -> Result <Vec<f64>, NumberListErro
Ok(v)
}
+#[repr(C)]
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum NumberListLength {
+ Exact,
+ Maximum
+}
+
+#[no_mangle]
+pub extern fn rsvg_css_parse_number_list (in_str: *const libc::c_char,
+ nlength: NumberListLength,
+ size: libc::size_t,
+ out_list: *mut *const libc::c_double,
+ out_list_length: *mut libc::size_t) -> glib_sys::gboolean {
+ assert! (!in_str.is_null ());
+ assert! (!out_list.is_null ());
+ assert! (!out_list_length.is_null ());
+
+ let length = match nlength {
+ NumberListLength::Exact => ListLength::Exact (size),
+ NumberListLength::Maximum => ListLength::Maximum (size)
+ };
+
+ let s = unsafe { String::from_glib_none (in_str) };
+
+ let result = number_list (&s, length);
+
+ match result {
+ Ok (number_list) => {
+ let num_elems = number_list.len ();
+
+ let c_array = unsafe {
+ glib_sys::g_malloc_n (num_elems,
+ mem::size_of::<libc::c_double> ())
+ as *mut libc::c_double
+ };
+
+ let mut array = unsafe { slice::from_raw_parts_mut (c_array, num_elems) };
+
+ for (i, v) in number_list.into_iter ().enumerate () {
+ array[i] = v;
+ }
+
+ unsafe {
+ *out_list = c_array;
+ *out_list_length = num_elems;
+ }
+
+ true
+ },
+
+ Err (_) => {
+ unsafe {
+ *out_list = ptr::null ();
+ *out_list_length = 0;
+ }
+ false
+ }
+ }.to_glib ()
+}
+
#[cfg(test)]
mod tests {
use super::*;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]