From 75c2358b6967c0148087638364b64da66667f8a2 Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Wed, 2 Feb 2011 19:30:06 +0100 Subject: Extend LdPointArray. --- liblogdiag/ld-canvas.c | 4 +- liblogdiag/ld-diagram-connection.c | 15 ++-- liblogdiag/ld-lua.c | 11 ++- liblogdiag/ld-types.c | 137 +++++++++++++++++++++++++++++++++---- liblogdiag/ld-types.h | 13 +++- 5 files changed, 150 insertions(+), 30 deletions(-) diff --git a/liblogdiag/ld-canvas.c b/liblogdiag/ld-canvas.c index 420232d..de24513 100644 --- a/liblogdiag/ld-canvas.c +++ b/liblogdiag/ld-canvas.c @@ -1064,7 +1064,7 @@ check_terminals (LdCanvas *self, gdouble x, gdouble y) LdDiagramSymbol *diagram_symbol; LdSymbol *symbol; const LdPointArray *terminals; - gint i; + guint i; if (!LD_IS_DIAGRAM_SYMBOL (iter->data)) continue; @@ -1079,7 +1079,7 @@ check_terminals (LdCanvas *self, gdouble x, gdouble y) terminals = ld_symbol_get_terminals (symbol); - for (i = 0; i < terminals->num_points; i++) + for (i = 0; i < terminals->length; i++) { LdPoint cur_term; gdouble distance; diff --git a/liblogdiag/ld-diagram-connection.c b/liblogdiag/ld-diagram-connection.c index 04e5888..8eadbf6 100644 --- a/liblogdiag/ld-diagram-connection.c +++ b/liblogdiag/ld-diagram-connection.c @@ -168,22 +168,23 @@ ld_diagram_connection_get_points (LdDiagramConnection *self) storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self)); node = json_object_get_member (storage, "points"); if (!node || json_node_is_null (node)) - return ld_point_array_new (0); + return ld_point_array_new (); if (!JSON_NODE_HOLDS_ARRAY (node)) { WARN_NODE_TYPE (node, LD_TYPE_POINT_ARRAY); - return ld_point_array_new (0); + return ld_point_array_new (); } array = json_node_get_array (node); point_node_list = json_array_get_elements (array); - points = ld_point_array_new (json_array_get_length (array)); + points = ld_point_array_sized_new (json_array_get_length (array)); - points->num_points = 0; for (iter = point_node_list; iter; iter = g_list_next (iter)) { - if (read_point_node (iter->data, &points->points[points->num_points])) - points->num_points++; + g_assert (points->length < points->size); + + if (read_point_node (iter->data, &points->points[points->length])) + points->length++; } return points; } @@ -267,7 +268,7 @@ ld_diagram_connection_set_points (LdDiagramConnection *self, storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self)); array = json_array_new (); - for (i = 0; i < points->num_points; i++) + for (i = 0; i < points->length; i++) { point_array = json_array_new (); json_array_add_double_element (point_array, points->points[i].x); diff --git a/liblogdiag/ld-lua.c b/liblogdiag/ld-lua.c index 973de4e..b97b892 100644 --- a/liblogdiag/ld-lua.c +++ b/liblogdiag/ld-lua.c @@ -576,15 +576,14 @@ read_terminals (lua_State *L, int index, LdPointArray **terminals) { LdPointArray *points; size_t num_points; - unsigned i = 0; num_points = lua_objlen (L, index); - points = ld_point_array_new (num_points); + points = ld_point_array_sized_new (num_points); lua_pushnil (L); while (lua_next (L, index) != 0) { - g_assert (i < num_points); + g_assert (points->length < points->size); if (!lua_istable (L, -1) || lua_objlen (L, -1) != 2) goto read_terminals_fail; @@ -592,16 +591,16 @@ read_terminals (lua_State *L, int index, LdPointArray **terminals) lua_rawgeti (L, -1, 1); if (!lua_isnumber (L, -1)) goto read_terminals_fail; - points->points[i].x = lua_tonumber (L, -1); + points->points[points->length].x = lua_tonumber (L, -1); lua_pop (L, 1); lua_rawgeti (L, -1, 2); if (!lua_isnumber (L, -1)) goto read_terminals_fail; - points->points[i].y = lua_tonumber (L, -1); + points->points[points->length].y = lua_tonumber (L, -1); lua_pop (L, 2); - i++; + points->length++; } *terminals = points; return TRUE; diff --git a/liblogdiag/ld-types.c b/liblogdiag/ld-types.c index c5723a9..7721e36 100644 --- a/liblogdiag/ld-types.c +++ b/liblogdiag/ld-types.c @@ -9,6 +9,7 @@ */ #include +#include #include "liblogdiag.h" #include "config.h" @@ -102,22 +103,34 @@ ld_point_distance (LdPoint *self, gdouble x, gdouble y) /** * ld_point_array_new: - * @num_points: the number of points the array can store. * - * Create a new array of points and initialize. + * Create a new #LdPointArray. * - * Return value: an #LdPointArray structure. + * Return value: (transfer full): an #LdPointArray structure. */ LdPointArray * -ld_point_array_new (gint num_points) +ld_point_array_new (void) { - LdPointArray *new_array; + return ld_point_array_sized_new (0); +} - g_return_val_if_fail (num_points >= 1, NULL); +/** + * ld_point_array_sized_new: + * @preallocated: the number of points preallocated. + * + * Create a new #LdPointArray and preallocate storage for @preallocated items. + * + * Return value: (transfer full): an #LdPointArray structure. + */ +LdPointArray * +ld_point_array_sized_new (guint preallocated) +{ + LdPointArray *new_array; new_array = g_slice_new (LdPointArray); - new_array->num_points = num_points; - new_array->points = g_malloc0 (num_points * sizeof (LdPoint)); + new_array->length = 0; + new_array->size = preallocated; + new_array->points = g_malloc0 (preallocated * sizeof (LdPoint)); return new_array; } @@ -128,7 +141,7 @@ ld_point_array_new (gint num_points) * Makes a copy of the structure. * The result must be freed by ld_point_array_free(). * - * Return value: a copy of @self. + * Return value: (transfer full): a copy of @self. */ LdPointArray * ld_point_array_copy (const LdPointArray *self) @@ -138,9 +151,9 @@ ld_point_array_copy (const LdPointArray *self) g_return_val_if_fail (self != NULL, NULL); new_array = g_slice_new (LdPointArray); - new_array->num_points = self->num_points; - new_array->points = g_memdup (self->points, - self->num_points * sizeof (LdPoint)); + new_array->length = self->length; + new_array->size = self->size; + new_array->points = g_memdup (self->points, self->size * sizeof (LdPoint)); return new_array; } @@ -159,6 +172,106 @@ ld_point_array_free (LdPointArray *self) g_slice_free (LdPointArray, self); } +/** + * ld_point_array_insert: + * @self: an #LdPointArray structure. + * @points: an array of points to be inserted. + * @pos: the position at which the points should be inserted. This number + * must not be bigger than the number of points already present + * in the array. Negative values append to the array. + * @length: count of points in @points. + * + * Insert points into the array. + */ +void +ld_point_array_insert (LdPointArray *self, LdPoint *points, + gint pos, guint length) +{ + guint new_size; + + g_return_if_fail (self != NULL); + g_return_if_fail (points != NULL); + g_return_if_fail (pos <= (signed) self->length); + + new_size = self->size ? self->size : 1; + while (self->length + length > new_size) + new_size <<= 1; + if (new_size != self->size) + ld_point_array_set_size (self, new_size); + + if (pos < 0) + pos = self->length; + + g_memmove (self->points + pos + length, self->points + pos, + (self->length - pos) * sizeof (LdPoint)); + memcpy (self->points + pos, points, length * sizeof (LdPoint)); + self->length += length; +} + +/** + * ld_point_array_remove: + * @self: an #LdPointArray structure. + * @pos: the position at which the points should be removed. + * Negative values are relative to the end of the array. + * @length: count of points to remove. + * + * Remove points from the array. The array may be resized as a result. + */ +void +ld_point_array_remove (LdPointArray *self, gint pos, guint length) +{ + guint new_size; + + g_return_if_fail (self != NULL); + + if (pos < 0) + { + pos += self->length; + if (pos < 0) + { + length += pos; + pos = 0; + } + } + if ((unsigned) pos >= self->length) + return; + if (pos + length > self->length) + length = self->length - pos; + + g_memmove (self->points + pos, self->points + pos + length, + (self->length - pos) * sizeof (LdPoint)); + self->length -= length; + + new_size = self->size; + while (new_size >> 2 > self->length) + new_size >>= 1; + if (new_size != self->size) + ld_point_array_set_size (self, new_size); +} + +/** + * ld_point_array_set_size: + * @self: an #LdPointArray structure. + * @size: the new size. + * + * Change size of the array. + */ +void ld_point_array_set_size (LdPointArray *self, guint size) +{ + g_return_if_fail (self != NULL); + + if (self->size == size) + return; + + self->points = g_realloc (self->points, size * sizeof (LdPoint)); + if (self->length > size) + self->length = size; + if (self->size < size) + memset (self->points + self->length, 0, size - self->length); + + self->size = size; +} + /** * ld_rectangle_copy: * @self: an #LdRectangle structure. diff --git a/liblogdiag/ld-types.h b/liblogdiag/ld-types.h index 04fedfa..29c0acc 100644 --- a/liblogdiag/ld-types.h +++ b/liblogdiag/ld-types.h @@ -45,21 +45,28 @@ gdouble ld_point_distance (LdPoint *self, gdouble x, gdouble y); /** * LdPointArray: * @points: an array of #LdPoint structures. - * @num_points: count of points in @points. + * @length: count of points in @points. + * @size: how many points can be stored in @points. * * Defines an array of points. */ struct _LdPointArray { LdPoint *points; - gint num_points; + guint length; + guint size; }; GType ld_point_array_get_type (void) G_GNUC_CONST; -LdPointArray *ld_point_array_new (gint num_points); +LdPointArray *ld_point_array_new (void); +LdPointArray *ld_point_array_sized_new (guint preallocated); LdPointArray *ld_point_array_copy (const LdPointArray *self); void ld_point_array_free (LdPointArray *self); +void ld_point_array_insert (LdPointArray *self, LdPoint *points, + gint pos, guint length); +void ld_point_array_remove (LdPointArray *self, gint pos, guint length); +void ld_point_array_set_size (LdPointArray *self, guint size); /** -- cgit v1.2.3-70-g09d2