[librsvg: 49/95] PropertyBag: Export rsvg_property_bag_iter_*() for use from C
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 49/95] PropertyBag: Export rsvg_property_bag_iter_*() for use from C
- Date: Thu, 22 Feb 2018 03:17:15 +0000 (UTC)
commit 1b9946f6a0f847698067c124fefa7c6dab965e3f
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Feb 20 19:03:55 2018 -0600
PropertyBag: Export rsvg_property_bag_iter_*() for use from C
rsvg-private.h | 17 +++++++++
rust/src/lib.rs | 3 ++
rust/src/property_bag.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 114 insertions(+), 1 deletion(-)
---
diff --git a/rsvg-private.h b/rsvg-private.h
index 995ad8b9..15d8e6d2 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -451,6 +451,23 @@ G_GNUC_INTERNAL
void rsvg_property_bag_enumerate (RsvgPropertyBag bag,
RsvgPropertyBagEnumFunc func,
gpointer user_data);
+
+typedef struct RsvgPropertyBagIter *RsvgPropertyBagIter;
+
+/* Implemented in rust/src/property_bag.rs */
+G_GNUC_INTERNAL
+RsvgPropertyBagIter *rsvg_property_bag_iter_begin (RsvgPropertyBag bag);
+
+/* Implemented in rust/src/property_bag.rs */
+G_GNUC_INTERNAL
+gboolean rsvg_property_bag_iter_next (RsvgPropertyBagIter *iter,
+ const char **out_key,
+ const char **out_value);
+
+/* Implemented in rust/src/property_bag.rs */
+G_GNUC_INTERNAL
+void rsvg_property_bag_iter_end (RsvgPropertyBagIter *iter);
+
/* for some reason this one's public... */
GdkPixbuf *rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
size_t len,
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index e49dd2f2..77ed6cd6 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -131,6 +131,9 @@ pub use pattern::{
pub use property_bag::{
rsvg_property_bag_enumerate,
rsvg_property_bag_free,
+ rsvg_property_bag_iter_begin,
+ rsvg_property_bag_iter_end,
+ rsvg_property_bag_iter_next,
rsvg_property_bag_lookup,
rsvg_property_bag_new,
rsvg_property_bag_size,
diff --git a/rust/src/property_bag.rs b/rust/src/property_bag.rs
index 4335222a..635b1267 100644
--- a/rust/src/property_bag.rs
+++ b/rust/src/property_bag.rs
@@ -1,5 +1,8 @@
use libc;
+use glib_sys;
+use glib::translate::*;
+
use std::collections::HashMap;
use std::collections::hash_map;
use std::ffi::{CStr, CString};
@@ -157,10 +160,50 @@ pub extern fn rsvg_property_bag_lookup(pbag: *const PropertyBag,
}
}
+#[no_mangle]
+pub extern fn rsvg_property_bag_iter_begin(pbag: *const PropertyBag) -> *mut PropertyBagCStrIter {
+ assert!(!pbag.is_null());
+ let pbag = unsafe { &*pbag };
+
+ Box::into_raw(Box::new(pbag.cstr_iter()))
+}
+
+#[no_mangle]
+pub extern fn rsvg_property_bag_iter_next(iter: *mut PropertyBagCStrIter,
+ out_key: *mut *const libc::c_char,
+ out_value: *mut *const libc::c_char)
+ -> glib_sys::gboolean
+{
+ assert!(!iter.is_null());
+ let iter = unsafe { &mut *iter };
+
+ if let Some((key, val)) = iter.next() {
+ unsafe {
+ *out_key = key.as_ptr();
+ *out_value = val.as_ptr();
+ }
+ true.to_glib()
+ } else {
+ unsafe {
+ *out_key = ptr::null();
+ *out_value = ptr::null();
+ }
+ false.to_glib()
+ }
+}
+
+#[no_mangle]
+pub extern fn rsvg_property_bag_iter_end(iter: *mut PropertyBagCStrIter) {
+ assert!(!iter.is_null());
+
+ unsafe { Box::from_raw(iter) };
+}
+
#[cfg(test)]
mod tests {
use super::*;
use std::ffi::CString;
+ use std::mem;
#[test]
fn empty_property_bag() {
@@ -194,10 +237,12 @@ mod tests {
let mut had_alpha: bool = false;
let mut had_beta: bool = false;
- for (k, _) in pbag.iter() {
+ for (k, v) in pbag.iter() {
if k == "alpha" {
+ assert!(v == "1");
had_alpha = true;
} else if k == "beta" {
+ assert!(v == "2");
had_beta = true;
}
}
@@ -205,4 +250,52 @@ mod tests {
assert!(had_alpha);
assert!(had_beta);
}
+
+ #[test]
+ fn property_bag_can_iterate_from_c() {
+ let pairs = [
+ CString::new("alpha").unwrap(),
+ CString::new("1").unwrap(),
+ CString::new("beta").unwrap(),
+ CString::new("2").unwrap(),
+ ];
+
+ let mut v = Vec::new();
+
+ for x in &pairs {
+ v.push(x.as_ptr() as *const libc::c_char);
+ }
+
+ v.push(ptr::null());
+
+ let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };
+
+ let mut had_alpha: bool = false;
+ let mut had_beta: bool = false;
+
+ let iter = rsvg_property_bag_iter_begin(&pbag as *const PropertyBag);
+
+ let mut key = unsafe { mem::uninitialized() };
+ let mut val = unsafe { mem::uninitialized() };
+
+ while from_glib(rsvg_property_bag_iter_next(iter,
+ &mut key as *mut _,
+ &mut val as *mut _)) {
+ let k = unsafe { CStr::from_ptr(key).to_str().unwrap() };
+ let v = unsafe { CStr::from_ptr(val).to_str().unwrap() };
+
+ if k == "alpha" {
+ assert!(v == "1");
+ had_alpha = true;
+ } else if k == "beta" {
+ assert!(v == "2");
+ had_beta = true;
+ }
+ }
+
+ rsvg_property_bag_iter_end(iter);
+
+ assert!(had_alpha);
+ assert!(had_beta);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]