GnuCash  4.12-73-g094a971c03+
gtable.c
1 /********************************************************************\
2  * gtable.c -- glib -- basic datatype for 2D array of values *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA gnu@gnu.org *
20  * *
21 \********************************************************************/
22 
23 #include <config.h>
24 
25 #include "gtable.h"
26 
27 
28 struct GTable
29 {
30  GArray *array;
31 
32  guint entry_size;
33 
34  int rows;
35  int cols;
36 
37  g_table_entry_constructor constructor;
38  g_table_entry_destroyer destroyer;
39 
40  gpointer user_data;
41 };
42 
43 GTable *
44 g_table_new (guint entry_size,
45  g_table_entry_constructor constructor,
46  g_table_entry_destroyer destroyer,
47  gpointer user_data)
48 {
49  GTable *gtable;
50 
51  gtable = g_new(GTable, 1);
52 
53  gtable->array = g_array_new(FALSE, FALSE, entry_size);
54 
55  gtable->entry_size = entry_size;
56 
57  gtable->rows = 0;
58  gtable->cols = 0;
59 
60  gtable->constructor = constructor;
61  gtable->destroyer = destroyer;
62 
63  gtable->user_data = user_data;
64 
65  return gtable;
66 }
67 
68 void
70 {
71  if (gtable == NULL)
72  return;
73 
74  g_table_resize (gtable, 0, 0);
75 
76  g_array_free (gtable->array, TRUE);
77 
78  gtable->array = NULL;
79 
80  g_free(gtable);
81 }
82 
83 gpointer
84 g_table_index (GTable *gtable, int row, int col)
85 {
86  guint index = row * gtable->cols + col;
87  guint offset = index * gtable->entry_size;
88 
89  if (gtable == NULL)
90  return NULL;
91  if ((row < 0) || (col < 0))
92  return NULL;
93  if (row >= gtable->rows)
94  return NULL;
95  if (col >= gtable->cols)
96  return NULL;
97 
98  g_return_val_if_fail (gtable->array != NULL, NULL);
99  g_return_val_if_fail (gtable->array->len > index, NULL);
100  return &gtable->array->data[offset];
101 }
102 
103 void
104 g_table_resize (GTable *gtable, int rows, int cols)
105 {
106  guint old_len;
107  guint new_len;
108 
109  if (gtable == NULL)
110  return;
111  if ((rows < 0) || (cols < 0))
112  return;
113 
114  old_len = gtable->array->len;
115  new_len = rows * cols;
116 
117  if (new_len == old_len)
118  return;
119 
120  /* If shrinking, destroy extra cells */
121  if ((new_len < old_len) && gtable->destroyer)
122  {
123  gchar *entry;
124  guint i;
125 
126  entry = &gtable->array->data[new_len * gtable->entry_size];
127  for (i = new_len; i < old_len; i++)
128  {
129  gtable->destroyer(entry, gtable->user_data);
130  entry += gtable->entry_size;
131  }
132  }
133 
134  /* Change the size */
135  g_array_set_size(gtable->array, new_len);
136 
137  /* If expanding, construct the new cells */
138  if ((new_len > old_len) && gtable->constructor)
139  {
140  gchar *entry;
141  guint i;
142 
143  entry = &gtable->array->data[old_len * gtable->entry_size];
144  for (i = old_len; i < new_len; i++)
145  {
146  gtable->constructor(entry, gtable->user_data);
147  entry += gtable->entry_size;
148  }
149  }
150 
151  gtable->rows = rows;
152  gtable->cols = cols;
153 }
154 
155 int
157 {
158  if (gtable == NULL)
159  return 0;
160 
161  return gtable->rows;
162 }
163 
164 int
166 {
167  if (gtable == NULL)
168  return 0;
169 
170  return gtable->cols;
171 }
int g_table_cols(GTable *gtable)
Return the number of table columns.
Definition: gtable.c:165
GTable * g_table_new(guint entry_size, g_table_entry_constructor constructor, g_table_entry_destroyer destroyer, gpointer user_data)
Create a new table with the given entry constructor and destroyer.
Definition: gtable.c:44
gpointer g_table_index(GTable *gtable, int row, int col)
Return the element at the given row and column.
Definition: gtable.c:84
Definition: gtable.c:28
int g_table_rows(GTable *gtable)
Return the number of table rows.
Definition: gtable.c:156
void g_table_destroy(GTable *gtable)
Free the table and all associated table elements.
Definition: gtable.c:69
void g_table_resize(GTable *gtable, int rows, int cols)
Resize the table, allocating and deallocating extra table members if needed.
Definition: gtable.c:104
This is the API for GTables, a datatype for 2-dimensional tables with automatic resizing and memory m...