[librsvg: 14/95] Port PropertyBag to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 14/95] Port PropertyBag to Rust
- Date: Thu, 22 Feb 2018 03:14:19 +0000 (UTC)
commit 22281aa8ee30a00b8de165f7f227f3b6e035662e
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Feb 12 14:55:31 2018 -0600
Port PropertyBag to Rust
This is a HashMap for now, to match the C version which used a
GHashTable. Eventually its implementation will only be a wrapper for
the (char **) from libxml2, plus an iterator over the key/value pairs
in such an array. For now, we do need lookup() semantics. We will be
moving the set_atts() methods to iteration instead of lookups one by
one.
rsvg-base.c | 12 ++--
rsvg-filter.c | 40 +++++------
rsvg-private.h | 30 +++++---
rsvg-styles.c | 77 --------------------
rsvg-text.c | 6 +-
rust/src/cnode.rs | 4 +-
rust/src/lib.rs | 8 +++
rust/src/node.rs | 13 ++--
rust/src/property_bag.rs | 180 +++++++++++++++++++++++++++++++++++++----------
rust/src/stop.rs | 4 +-
rust/src/structure.rs | 14 ++--
11 files changed, 219 insertions(+), 169 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index c8da9c26..3fe71f01 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -145,7 +145,7 @@ rsvg_style_handler_characters (RsvgSaxHandler * self, const char *ch, gssize len
}
static void
-rsvg_style_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag * atts)
+rsvg_style_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts)
{
}
@@ -388,7 +388,7 @@ get_node_creator_for_element_name (const char *name)
}
static void
-node_set_atts (RsvgNode * node, RsvgHandle *handle, const NodeCreator *creator, RsvgPropertyBag * atts)
+node_set_atts (RsvgNode * node, RsvgHandle *handle, const NodeCreator *creator, RsvgPropertyBag atts)
{
if (rsvg_property_bag_size (atts) > 0) {
const char *id;
@@ -482,7 +482,7 @@ rsvg_extra_handler_characters (RsvgSaxHandler * self, const char *ch, gssize len
}
static void
-rsvg_extra_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag * atts)
+rsvg_extra_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts)
{
}
@@ -560,7 +560,7 @@ rsvg_metadata_props_enumerate (const char *key, const char *value, gpointer user
}
static void
-rsvg_metadata_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag * atts)
+rsvg_metadata_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts)
{
RsvgSaxHandlerMetadata *z = (RsvgSaxHandlerMetadata *) self;
@@ -629,7 +629,7 @@ rsvg_xinclude_handler_characters (RsvgSaxHandler * self, const char *ch, gssize
}
static void
-rsvg_xinclude_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag * atts)
+rsvg_xinclude_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts)
{
RsvgSaxHandlerXinclude *z = (RsvgSaxHandlerXinclude *) self;
@@ -805,7 +805,7 @@ rsvg_start_xinclude (RsvgHandle *handle, RsvgPropertyBag * atts)
static void
rsvg_start_element (void *data, const xmlChar * name, const xmlChar ** atts)
{
- RsvgPropertyBag *bag;
+ RsvgPropertyBag bag;
RsvgHandle *handle = (RsvgHandle *) data;
bag = rsvg_property_bag_new ((const char **) atts);
diff --git a/rsvg-filter.c b/rsvg-filter.c
index 0a6e0f89..8421a8bc 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -790,7 +790,7 @@ rsvg_filter_get_in (GString * name, RsvgFilterContext * ctx)
}
static void
-rsvg_filter_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
+rsvg_filter_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag atts)
{
RsvgFilter *filter = impl;
const char *value;
@@ -1041,7 +1041,7 @@ rsvg_filter_primitive_blend_free (gpointer impl)
}
static void
-rsvg_filter_primitive_blend_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
*atts)
+rsvg_filter_primitive_blend_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
atts)
{
RsvgFilterPrimitiveBlend *filter = impl;
const char *value;
@@ -1255,7 +1255,7 @@ rsvg_filter_primitive_convolve_matrix_free (gpointer impl)
}
static void
-rsvg_filter_primitive_convolve_matrix_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_convolve_matrix_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveConvolveMatrix *filter = impl;
gint i, j;
@@ -2009,7 +2009,7 @@ rsvg_filter_primitive_gaussian_blur_render (RsvgNode *node, RsvgFilterPrimitive
}
static void
-rsvg_filter_primitive_gaussian_blur_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_gaussian_blur_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveGaussianBlur *filter = impl;
const char *value;
@@ -2134,7 +2134,7 @@ rsvg_filter_primitive_offset_render (RsvgNode *node, RsvgFilterPrimitive *primit
}
static void
-rsvg_filter_primitive_offset_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *
atts)
+rsvg_filter_primitive_offset_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
atts)
{
RsvgFilterPrimitiveOffset *filter = impl;
const char *value;
@@ -2240,7 +2240,7 @@ rsvg_filter_primitive_merge_render (RsvgNode *node, RsvgFilterPrimitive *primiti
}
static void
-rsvg_filter_primitive_merge_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
*atts)
+rsvg_filter_primitive_merge_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
atts)
{
RsvgFilterPrimitiveMerge *filter = impl;
const char *value;
@@ -2270,7 +2270,7 @@ rsvg_new_filter_primitive_merge (const char *element_name, RsvgNode *parent)
}
static void
-rsvg_filter_primitive_merge_node_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_merge_node_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitive *primitive = impl;
const char *value;
@@ -2419,7 +2419,7 @@ rsvg_filter_primitive_color_matrix_free (gpointer impl)
}
static void
-rsvg_filter_primitive_color_matrix_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_color_matrix_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveColorMatrix *filter = impl;
gint type;
@@ -2755,7 +2755,7 @@ rsvg_filter_primitive_component_transfer_render (RsvgNode *node, RsvgFilterPrimi
}
static void
-rsvg_filter_primitive_component_transfer_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_component_transfer_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveComponentTransfer *filter = impl;
const char *value;
@@ -2788,7 +2788,7 @@ rsvg_new_filter_primitive_component_transfer (const char *element_name, RsvgNode
}
static void
-rsvg_node_component_transfer_function_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_node_component_transfer_function_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgNodeComponentTransferFunc *data = impl;
const char *value;
@@ -2979,7 +2979,7 @@ rsvg_filter_primitive_erode_render (RsvgNode *node, RsvgFilterPrimitive *primiti
}
static void
-rsvg_filter_primitive_erode_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
*atts)
+rsvg_filter_primitive_erode_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
atts)
{
RsvgFilterPrimitiveErode *filter = impl;
const char *value;
@@ -3184,7 +3184,7 @@ rsvg_filter_primitive_composite_free (gpointer impl)
}
static void
-rsvg_filter_primitive_composite_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
*atts)
+rsvg_filter_primitive_composite_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
atts)
{
RsvgFilterPrimitiveComposite *filter = impl;
const char *value;
@@ -3301,7 +3301,7 @@ rsvg_filter_primitive_flood_render (RsvgNode *node, RsvgFilterPrimitive *primiti
}
static void
-rsvg_filter_primitive_flood_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
*atts)
+rsvg_filter_primitive_flood_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
atts)
{
RsvgFilterPrimitive *filter = impl;
const char *value;
@@ -3472,7 +3472,7 @@ rsvg_filter_primitive_displacement_map_free (gpointer impl)
}
static void
-rsvg_filter_primitive_displacement_map_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_displacement_map_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveDisplacementMap *filter = impl;
const char *value;
@@ -3834,7 +3834,7 @@ rsvg_filter_primitive_turbulence_render (RsvgNode *node, RsvgFilterPrimitive *pr
}
static void
-rsvg_filter_primitive_turbulence_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_turbulence_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveTurbulence *filter = impl;
const char *value;
@@ -4055,7 +4055,7 @@ rsvg_filter_primitive_image_free (gpointer impl)
}
static void
-rsvg_filter_primitive_image_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
*atts)
+rsvg_filter_primitive_image_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
atts)
{
RsvgFilterPrimitiveImage *filter = impl;
const char *value;
@@ -4443,7 +4443,7 @@ get_light_color (RsvgNodeLightSource * source, vector3 color,
static void
-rsvg_node_light_source_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
+rsvg_node_light_source_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag atts)
{
RsvgNodeLightSource *data = impl;
const char *value;
@@ -4645,7 +4645,7 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgNode *node, RsvgFilterPrimiti
}
static void
-rsvg_filter_primitive_diffuse_lighting_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_diffuse_lighting_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveDiffuseLighting *filter = impl;
const char *value;
@@ -4835,7 +4835,7 @@ rsvg_filter_primitive_specular_lighting_render (RsvgNode *node, RsvgFilterPrimit
}
static void
-rsvg_filter_primitive_specular_lighting_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag *atts)
+rsvg_filter_primitive_specular_lighting_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle,
RsvgPropertyBag atts)
{
RsvgFilterPrimitiveSpecularLighting *filter = impl;
const char *value;
@@ -4987,7 +4987,7 @@ rsvg_filter_primitive_tile_render (RsvgNode *node, RsvgFilterPrimitive *primitiv
}
static void
-rsvg_filter_primitive_tile_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag
*atts)
+rsvg_filter_primitive_tile_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag atts)
{
RsvgFilterPrimitiveTile *filter = impl;
const char *value;
diff --git a/rsvg-private.h b/rsvg-private.h
index cc2c700f..995ad8b9 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -48,7 +48,7 @@ G_BEGIN_DECLS
typedef struct RsvgSaxHandler RsvgSaxHandler;
typedef struct RsvgDrawingCtx RsvgDrawingCtx;
typedef struct RsvgRender RsvgRender;
-typedef GHashTable RsvgPropertyBag;
+typedef void *RsvgPropertyBag;
typedef struct _RsvgState RsvgState;
typedef struct _RsvgDefs RsvgDefs;
typedef struct _RsvgNode RsvgNode;
@@ -117,7 +117,7 @@ typedef struct _RsvgFilter RsvgFilter;
struct RsvgSaxHandler {
void (*free) (RsvgSaxHandler * self);
- void (*start_element) (RsvgSaxHandler * self, const char *name, RsvgPropertyBag * atts);
+ void (*start_element) (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts);
void (*end_element) (RsvgSaxHandler * self, const char *name);
void (*characters) (RsvgSaxHandler * self, const char *ch, gssize len);
};
@@ -342,7 +342,7 @@ typedef enum {
RSVG_NODE_TYPE_FILTER_PRIMITIVE_LAST /* just a marker; not a valid type */
} RsvgNodeType;
-typedef void (* CNodeSetAtts) (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *pbag);
+typedef void (* CNodeSetAtts) (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag pbag);
typedef void (* CNodeDraw) (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate);
typedef void (* CNodeFree) (gpointer impl);
@@ -397,7 +397,7 @@ void rsvg_node_add_child (RsvgNode *node, RsvgNode *child);
/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
-void rsvg_node_set_atts (RsvgNode *node, RsvgHandle *handle, RsvgPropertyBag *atts);
+void rsvg_node_set_atts (RsvgNode *node, RsvgHandle *handle, RsvgPropertyBag atts);
/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
@@ -430,18 +430,26 @@ void rsvg_node_chars_get_string (RsvgNode *node, const char **out_str, gsize *ou
typedef void (*RsvgPropertyBagEnumFunc) (const char *key, const char *value, gpointer user_data);
+/* Implemented in rust/src/property_bag.rs */
G_GNUC_INTERNAL
-RsvgPropertyBag *rsvg_property_bag_new (const char **atts);
-G_GNUC_INTERNAL
-RsvgPropertyBag *rsvg_property_bag_dup (RsvgPropertyBag * bag);
+RsvgPropertyBag rsvg_property_bag_new (const char **atts);
+
+/* Implemented in rust/src/property_bag.rs */
G_GNUC_INTERNAL
-void rsvg_property_bag_free (RsvgPropertyBag * bag);
+void rsvg_property_bag_free (RsvgPropertyBag bag);
+
+/* Implemented in rust/src/property_bag.rs */
G_GNUC_INTERNAL
-const char *rsvg_property_bag_lookup (RsvgPropertyBag * bag, const char *key);
+const char *rsvg_property_bag_lookup (RsvgPropertyBag bag, const char *key);
+
+/* Implemented in rust/src/property_bag.rs */
G_GNUC_INTERNAL
-guint rsvg_property_bag_size (RsvgPropertyBag * bag);
+guint rsvg_property_bag_size (RsvgPropertyBag bag);
+
+/* Implemented in rust/src/property_bag.rs */
G_GNUC_INTERNAL
-void rsvg_property_bag_enumerate (RsvgPropertyBag * bag, RsvgPropertyBagEnumFunc func,
+void rsvg_property_bag_enumerate (RsvgPropertyBag bag,
+ RsvgPropertyBagEnumFunc func,
gpointer user_data);
/* for some reason this one's public... */
GdkPixbuf *rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
diff --git a/rsvg-styles.c b/rsvg-styles.c
index a16c789e..cec664c1 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -1676,83 +1676,6 @@ rsvg_state_free_all (RsvgState * state)
}
}
-/**
- * rsvg_property_bag_new:
- * @atts: (array zero-terminated=1): list of alternating attributes
- * and values
- *
- * The property bag will NOT copy the attributes and values. If you need
- * to store them for later, use rsvg_property_bag_dup().
- *
- * Returns: (transfer full): a new property bag
- */
-RsvgPropertyBag *
-rsvg_property_bag_new (const char **atts)
-{
- RsvgPropertyBag *bag;
- int i;
-
- bag = g_hash_table_new (g_str_hash, g_str_equal);
-
- if (atts != NULL) {
- for (i = 0; atts[i] != NULL; i += 2)
- g_hash_table_insert (bag, (gpointer) atts[i], (gpointer) atts[i + 1]);
- }
-
- return bag;
-}
-
-/**
- * rsvg_property_bag_dup:
- * @bag: property bag to duplicate
- *
- * Returns a copy of @bag that owns the attributes and values.
- *
- * Returns: (transfer full): a new property bag
- */
-RsvgPropertyBag *
-rsvg_property_bag_dup (RsvgPropertyBag * bag)
-{
- RsvgPropertyBag *dup;
- GHashTableIter iter;
- gpointer key, value;
-
- dup = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- g_hash_table_iter_init (&iter, bag);
- while (g_hash_table_iter_next (&iter, &key, &value))
- g_hash_table_insert (dup,
- (gpointer) g_strdup ((char *) key),
- (gpointer) g_strdup ((char *) value));
-
- return dup;
-}
-
-void
-rsvg_property_bag_free (RsvgPropertyBag * bag)
-{
- g_hash_table_unref (bag);
-}
-
-const char *
-rsvg_property_bag_lookup (RsvgPropertyBag * bag, const char *key)
-{
- return (const char *) g_hash_table_lookup (bag, (gconstpointer) key);
-}
-
-guint
-rsvg_property_bag_size (RsvgPropertyBag * bag)
-{
- return g_hash_table_size (bag);
-}
-
-void
-rsvg_property_bag_enumerate (RsvgPropertyBag * bag, RsvgPropertyBagEnumFunc func,
- gpointer user_data)
-{
- g_hash_table_foreach (bag, (GHFunc) func, user_data);
-}
-
void
rsvg_state_push (RsvgDrawingCtx * ctx)
{
diff --git a/rsvg-text.c b/rsvg-text.c
index 3c69cd9d..e17dab38 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -81,7 +81,7 @@ set_text_common_atts (RsvgNodeText *text, RsvgPropertyBag *atts)
static void
-rsvg_node_text_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
+rsvg_node_text_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag atts)
{
RsvgNodeText *text = impl;
@@ -433,7 +433,7 @@ length_from_tspan (RsvgNode *node,
}
static void
-rsvg_node_tspan_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
+rsvg_node_tspan_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag atts)
{
RsvgNodeText *text = impl;
@@ -515,7 +515,7 @@ rsvg_node_tref_free (gpointer impl)
}
static void
-rsvg_node_tref_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
+rsvg_node_tref_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag atts)
{
RsvgNodeTref *text = impl;
const char *value;
diff --git a/rust/src/cnode.rs b/rust/src/cnode.rs
index b8afecef..3b6be21a 100644
--- a/rust/src/cnode.rs
+++ b/rust/src/cnode.rs
@@ -1,12 +1,12 @@
use drawing_ctx::RsvgDrawingCtx;
use handle::*;
use node::*;
-use property_bag::{FfiRsvgPropertyBag, PropertyBag};
+use property_bag::PropertyBag;
use state::RsvgState;
use std::rc::*;
-type CNodeSetAtts = unsafe extern "C" fn (node: *const RsvgNode, node_impl: *const RsvgCNodeImpl, handle:
*const RsvgHandle, pbag: FfiRsvgPropertyBag);
+type CNodeSetAtts = unsafe extern "C" fn (node: *const RsvgNode, node_impl: *const RsvgCNodeImpl, handle:
*const RsvgHandle, pbag: *const PropertyBag);
type CNodeDraw = unsafe extern "C" fn (node: *const RsvgNode, node_impl: *const RsvgCNodeImpl, draw_ctx:
*const RsvgDrawingCtx, dominate: i32);
type CNodeFree = unsafe extern "C" fn (node_impl: *const RsvgCNodeImpl);
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index d5b5bcd8..0179834a 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -130,6 +130,14 @@ pub use pattern::{
pattern_resolve_fallbacks_and_set_pattern,
};
+pub use property_bag::{
+ rsvg_property_bag_enumerate,
+ rsvg_property_bag_free,
+ rsvg_property_bag_lookup,
+ rsvg_property_bag_new,
+ rsvg_property_bag_size,
+};
+
pub use shapes::{
rsvg_node_circle_new,
rsvg_node_ellipse_new,
diff --git a/rust/src/node.rs b/rust/src/node.rs
index 443dc808..d3058c12 100644
--- a/rust/src/node.rs
+++ b/rust/src/node.rs
@@ -12,7 +12,7 @@ use drawing_ctx;
use error::*;
use handle::RsvgHandle;
use parsers::ParseError;
-use property_bag::{FfiRsvgPropertyBag, PropertyBag};
+use property_bag::PropertyBag;
use state::RsvgState;
/* A *const RsvgNode is just a pointer for the C code's benefit: it
@@ -361,13 +361,14 @@ pub extern fn rsvg_node_add_child (raw_node: *mut RsvgNode, raw_child: *const Rs
#[no_mangle]
pub extern fn rsvg_node_set_atts (raw_node: *mut RsvgNode,
handle: *const RsvgHandle,
- ffi_pbag: FfiRsvgPropertyBag) {
- assert! (!raw_node.is_null ());
- let node: &RsvgNode = unsafe { & *raw_node };
+ pbag: *const PropertyBag) {
+ assert!(!raw_node.is_null());
+ assert!(!pbag.is_null());
- let pbag = PropertyBag::new(ffi_pbag);
+ let node: &RsvgNode = unsafe { & *raw_node };
+ let pbag = unsafe { &*pbag };
- node.set_atts (node, handle, &pbag);
+ node.set_atts(node, handle, &pbag);
}
#[no_mangle]
diff --git a/rust/src/property_bag.rs b/rust/src/property_bag.rs
index 8671dec7..de509f1b 100644
--- a/rust/src/property_bag.rs
+++ b/rust/src/property_bag.rs
@@ -1,60 +1,132 @@
-use glib::translate::*;
use libc;
+use std::collections::HashMap;
+use std::ffi::{CStr, CString};
+use std::ops::Deref;
+use std::ptr;
+
use error::*;
use parsers::Parse;
-use util::utf8_cstr;
-pub type FfiRsvgPropertyBag = *mut libc::c_void;
+pub struct PropertyBag<'a>(HashMap<&'a CStr, &'a CStr>);
-pub enum PropertyBag {
- Borrowed(FfiRsvgPropertyBag),
- Owned(FfiRsvgPropertyBag)
-}
+pub struct OwnedPropertyBag(HashMap<CString, CString>);
-extern "C" {
- fn rsvg_property_bag_lookup (pbag: FfiRsvgPropertyBag, key: *const libc::c_char) -> *const libc::c_char;
- fn rsvg_property_bag_dup (pbag: FfiRsvgPropertyBag) -> FfiRsvgPropertyBag;
- fn rsvg_property_bag_free (pbag: FfiRsvgPropertyBag);
-}
+impl<'a> PropertyBag<'a> {
+ pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
+ let mut map = HashMap::new();
+
+ if !pairs.is_null() {
+ let mut i = 0;
+ loop {
+ let key = *pairs.offset(i);
+ if !key.is_null() {
+ let val = *pairs.offset(i + 1);
+ assert!(!val.is_null());
+
+ let key_str = CStr::from_ptr(key);
+ let val_str = CStr::from_ptr(val);
+
+ map.insert(key_str, val_str);
+ } else {
+ break;
+ }
-impl PropertyBag {
- pub fn new(ffi: FfiRsvgPropertyBag) -> PropertyBag {
- PropertyBag::Borrowed(ffi)
+ i += 2;
+ }
+ }
+
+ PropertyBag(map)
}
- pub fn ffi(&self) -> FfiRsvgPropertyBag {
- match self {
- &PropertyBag::Borrowed(ffi) => ffi,
- &PropertyBag::Owned(ffi) => ffi
+ pub fn from_owned(owned: &OwnedPropertyBag) -> PropertyBag {
+ let mut map = HashMap::new();
+
+ for (k, v) in &owned.0 {
+ map.insert(k.deref(), v.deref());
}
+
+ PropertyBag(map)
}
- pub fn dup(&self) -> PropertyBag {
- unsafe {
- PropertyBag::Owned(rsvg_property_bag_dup(self.ffi()))
+ pub fn to_owned(&self) -> OwnedPropertyBag {
+ let mut map = HashMap::<CString, CString>::new();
+
+ for (k, v) in &self.0 {
+ map.insert((*k).to_owned(), (*v).to_owned());
}
+
+ OwnedPropertyBag(map)
+ }
+
+ pub fn ffi(&self) -> *const PropertyBag {
+ self as *const PropertyBag
+ }
+
+ pub fn len(&self) -> usize {
+ self.0.len()
+ }
+
+ pub fn lookup_cstr(&self, key: &CStr) -> Option<&CStr> {
+ self.0.get(key).map(|v| *v)
}
pub fn lookup(&self, key: &str) -> Option<&str> {
- let ffi = self.ffi();
-
- unsafe {
- let c_value = rsvg_property_bag_lookup (ffi, key.to_glib_none ().0);
- if c_value.is_null() {
- None
- } else {
- Some(utf8_cstr(c_value))
- }
+ let k = CString::new(key).unwrap();
+ self.lookup_cstr(&k).map(|v| v.to_str().unwrap())
+ }
+
+ pub fn enumerate(&self,
+ enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char, data: *const libc::c_void),
+ data: *const libc::c_void) {
+ for (k, v) in &self.0 {
+ enum_fn(k.as_ptr(), v.as_ptr(), data);
}
}
}
-impl Drop for PropertyBag {
- fn drop(&mut self) {
- match *self {
- PropertyBag::Borrowed(_) => (),
- PropertyBag::Owned(ffi) => unsafe { rsvg_property_bag_free(ffi) }
+#[no_mangle]
+pub extern fn rsvg_property_bag_new<'a>(atts: *const *const libc::c_char) -> *const PropertyBag<'a> {
+ let pbag = unsafe { PropertyBag::new_from_key_value_pairs(atts) };
+ Box::into_raw(Box::new(pbag))
+}
+
+#[no_mangle]
+pub extern fn rsvg_property_bag_free(pbag: *mut PropertyBag) {
+ unsafe {
+ let _ = Box::from_raw(pbag);
+ }
+}
+
+#[no_mangle]
+pub extern fn rsvg_property_bag_size(pbag: *const PropertyBag) -> libc::c_uint {
+ unsafe {
+ let pbag = &*pbag;
+
+ pbag.len() as libc::c_uint
+ }
+}
+
+#[no_mangle]
+pub extern fn rsvg_property_bag_enumerate(pbag: *const PropertyBag,
+ enum_fn: fn (key: *const libc::c_char, val: *const libc::c_char,
data: *const libc::c_void),
+ data: *const libc::c_void) {
+ unsafe {
+ let pbag = &*pbag;
+
+ pbag.enumerate(enum_fn, data);
+ }
+}
+
+#[no_mangle]
+pub extern fn rsvg_property_bag_lookup(pbag: *const PropertyBag,
+ raw_key: *const libc::c_char) -> *const libc::c_char {
+ unsafe {
+ let pbag = &*pbag;
+ let key = CStr::from_ptr(raw_key);
+ match pbag.lookup_cstr(key) {
+ Some(v) => v.as_ptr(),
+ None => ptr::null()
}
}
}
@@ -102,3 +174,39 @@ pub fn parse_or_value<T> (pbag: &PropertyBag,
{
Ok (parse_or_none (pbag, key, data, validate)?.unwrap_or (value))
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::ffi::CString;
+
+ #[test]
+ fn empty_property_bag() {
+ let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
+ assert_eq!(map.len(), 0);
+ }
+
+ #[test]
+ fn property_bag_lookups() {
+ 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 map = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };
+
+ assert_eq!(map.lookup("alpha"), Some("1"));
+ assert_eq!(map.lookup("beta"), Some("2"));
+ assert_eq!(map.lookup("gamma"), None);
+ }
+}
diff --git a/rust/src/stop.rs b/rust/src/stop.rs
index 7e29ede0..1091a643 100644
--- a/rust/src/stop.rs
+++ b/rust/src/stop.rs
@@ -12,7 +12,7 @@ use handle::RsvgHandle;
use length::*;
use node::*;
use opacity::*;
-use property_bag::{self, FfiRsvgPropertyBag, PropertyBag};
+use property_bag::{self, PropertyBag};
use state::RsvgState;
pub struct NodeStop {
@@ -172,7 +172,7 @@ fn u32_from_rgba (rgba: cssparser::RGBA) -> u32 {
}
extern "C" {
- fn rsvg_parse_presentation_attributes (state: *mut RsvgState, pbag: FfiRsvgPropertyBag);
+ fn rsvg_parse_presentation_attributes (state: *mut RsvgState, pbag: *const PropertyBag);
fn rsvg_parse_style (state: *mut RsvgState, string: *const libc::c_char);
}
diff --git a/rust/src/structure.rs b/rust/src/structure.rs
index 841b6170..bceb8833 100644
--- a/rust/src/structure.rs
+++ b/rust/src/structure.rs
@@ -13,7 +13,7 @@ use handle::RsvgHandle;
use length::*;
use node::*;
use parsers::Parse;
-use property_bag::{self, FfiRsvgPropertyBag, PropertyBag};
+use property_bag::{self, OwnedPropertyBag, PropertyBag};
use util::*;
use viewbox::*;
use viewport::{ClipMode,draw_in_viewport};
@@ -117,7 +117,7 @@ struct NodeSvg {
w: Cell<RsvgLength>,
h: Cell<RsvgLength>,
vbox: Cell<Option<ViewBox>>,
- atts: RefCell<Option<PropertyBag>>
+ pbag: RefCell<Option<OwnedPropertyBag>>
}
impl NodeSvg {
@@ -129,7 +129,7 @@ impl NodeSvg {
w: Cell::new (RsvgLength::parse ("100%", LengthDir::Horizontal).unwrap ()),
h: Cell::new (RsvgLength::parse ("100%", LengthDir::Vertical).unwrap ()),
vbox: Cell::new (None),
- atts: RefCell::new(None)
+ pbag: RefCell::new(None)
}
}
}
@@ -161,7 +161,7 @@ impl NodeTrait for NodeSvg {
// The "style" sub-element is not loaded yet here, so we need
// to store other attributes to be applied later.
- *self.atts.borrow_mut() = Some(pbag.dup());
+ *self.pbag.borrow_mut() = Some(pbag.to_owned());
Ok (())
}
@@ -432,7 +432,7 @@ extern "C" {
tag: *const libc::c_char,
class: *const libc::c_char,
id: *const libc::c_char,
- pbag: FfiRsvgPropertyBag);
+ pbag: *const PropertyBag);
}
#[no_mangle]
@@ -441,7 +441,9 @@ pub extern fn rsvg_node_svg_apply_atts (raw_node: *const RsvgNode, handle: *cons
let node: &RsvgNode = unsafe { & *raw_node };
node.with_impl (|svg: &NodeSvg| {
- if let Some(pbag) = svg.atts.borrow().as_ref() {
+ if let Some(owned_pbag) = svg.pbag.borrow().as_ref() {
+ let pbag = PropertyBag::from_owned(&owned_pbag);
+
let class = pbag.lookup("class");
let id = pbag.lookup("id");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]