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