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.
parent 6e1b205d
......@@ -318,44 +318,6 @@ rsvg_css_parse_list (const char *in_str, guint * out_list_len)
return string_array;
}
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)
{
......
......@@ -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
......
......@@ -79,6 +79,7 @@ pub use opacity::{
};
pub use parsers::{
rsvg_css_parse_number_list,
rsvg_css_parse_number_optional_number
};
......
......@@ -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::*;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment