1 /*!
2 \file lib/vector/diglib/struct_alloc.c
3
4 \brief Vector library - allocate and zero array space (lower level functions)
5
6 Lower level functions for reading/writing/manipulating vectors.
7
8 These routines all eventually call calloc() to allocate and zero the
9 new space. BUT It is not necessarily safe to assume that the memory
10 will be zero. The next memory location asked for could have been
11 previously used and not zeroed. (e.g. compress()).
12
13 This program is free software under the GNU General Public License
14 (>=v2). Read the file COPYING that comes with GRASS for details.
15
16 \author CERL (probably Dave Gerdes)
17 \author Radim Blazek
18 */
19
20 #include <stdlib.h>
21 #include <grass/vector.h>
22 #include <grass/glocale.h>
23
24 /*!
25 \brief Allocate new node structure
26
27 \return pointer to allocated P_node struct
28 \return NULL on error
29 */
dig_alloc_node()30 struct P_node *dig_alloc_node()
31 {
32 struct P_node *Node;
33
34 Node = (struct P_node *) G_malloc(sizeof(struct P_node));
35 if (Node == NULL)
36 return NULL;
37
38 G_zero(Node, sizeof(struct P_node));
39
40 return Node;
41 }
42
43 /*!
44 \brief Free node structure
45
46 \param Node pointer to P_node struct to be freed
47 */
dig_free_node(struct P_node * Node)48 void dig_free_node(struct P_node *Node)
49 {
50 if (Node->alloc_lines > 0) {
51 G_free(Node->lines);
52 G_free(Node->angles);
53 }
54
55 G_free(Node);
56 }
57
58 /*!
59 \brief Allocate space in P_node struct
60
61 Lines and angles arrays to add 'add' more lines
62
63 \param node pointer to P_node struct
64 \param add number lines to be added
65
66 \return 0 on success
67 \return -1 on error
68 */
dig_node_alloc_line(struct P_node * node,int add)69 int dig_node_alloc_line(struct P_node * node, int add)
70 {
71 int num;
72 char *p;
73
74 G_debug(5, "dig_node_alloc_line(): add = %d", add);
75
76 if (node->n_lines + add <= node->alloc_lines)
77 return 0;
78
79 num = node->alloc_lines + add;
80
81 p = G_realloc(node->lines, num * sizeof(plus_t));
82 if (p == NULL)
83 return -1;
84 node->lines = (plus_t *) p;
85
86 p = G_realloc(node->angles, num * sizeof(float));
87 if (p == NULL)
88 return -1;
89 node->angles = (float *)p;
90
91 node->alloc_lines = num;
92
93 return 0;
94 }
95
96 /*!
97 \brief Reallocate array of pointers to nodes
98
99 \param Plus pointer to Plus_head structure
100 \param add number of nodes to be added
101
102 \return 0 on success
103 \return -1 on error
104 */
dig_alloc_nodes(struct Plus_head * Plus,int add)105 int dig_alloc_nodes(struct Plus_head *Plus, int add)
106 {
107 int size;
108 char *p;
109
110 size = Plus->alloc_nodes + 1 + add;
111 p = G_realloc(Plus->Node, size * sizeof(struct P_node *));
112 if (p == NULL)
113 return -1;
114
115 Plus->Node = (struct P_node **) p;
116 Plus->alloc_nodes = size - 1;
117
118 return 0;
119 }
120
121 /*!
122 \brief Allocate new line structure
123
124 \return pointer to allocated P_node struct
125 \return NULL on error
126 */
dig_alloc_line()127 struct P_line *dig_alloc_line()
128 {
129 struct P_line *Line;
130
131 Line = (struct P_line *) G_malloc(sizeof(struct P_line));
132 if (Line == NULL)
133 return NULL;
134
135 G_zero(Line, sizeof(struct P_line));
136
137 return Line;
138 }
139
140 /*!
141 \brief Allocate new topo struct
142
143 \param type to of struct to allocate
144 */
dig_alloc_topo(char type)145 void *dig_alloc_topo(char type)
146 {
147 void *Topo = NULL;
148
149 switch (type) {
150 case GV_LINE:
151 Topo = G_malloc(sizeof(struct P_topo_l));
152 break;
153 case GV_BOUNDARY:
154 Topo = G_malloc(sizeof(struct P_topo_b));
155 break;
156 case GV_CENTROID:
157 Topo = G_malloc(sizeof(struct P_topo_c));
158 break;
159 case GV_FACE:
160 Topo = G_malloc(sizeof(struct P_topo_f));
161 break;
162 case GV_KERNEL:
163 Topo = G_malloc(sizeof(struct P_topo_k));
164 break;
165 default:
166 return NULL;
167 }
168
169 return Topo;
170 }
171
172 /*!
173 \brief Free line structure
174
175 \param pointer to P_line struct to be freed
176 */
dig_free_line(struct P_line * Line)177 void dig_free_line(struct P_line *Line)
178 {
179 if (Line->topo)
180 G_free(Line->topo);
181 G_free(Line);
182 }
183
184 /*!
185 \brief Reallocate array of pointers to lines.
186
187 \param Plus pointer to Plus_head structure
188 \param add space for 'add' number of lines is added.
189
190 \return 0 on success
191 \return -1 on error
192 */
dig_alloc_lines(struct Plus_head * Plus,int add)193 int dig_alloc_lines(struct Plus_head *Plus, int add)
194 {
195 int size;
196 char *p;
197
198 size = Plus->alloc_lines + 1 + add;
199 p = G_realloc(Plus->Line, size * sizeof(struct P_line *));
200 if (p == NULL)
201 return -1;
202
203 Plus->Line = (struct P_line **) p;
204 Plus->alloc_lines = size - 1;
205
206 return 0;
207 }
208
209 /*!
210 \brief Reallocate array of pointers to areas.
211
212 \param Plus pointer to Plus_head structure
213 \param add space for 'add' number of areas is added
214
215 \return 0 on success
216 \return -1 on error
217 */
dig_alloc_areas(struct Plus_head * Plus,int add)218 int dig_alloc_areas(struct Plus_head *Plus, int add)
219 {
220 int size;
221 char *p;
222
223 size = Plus->alloc_areas + 1 + add;
224 p = G_realloc(Plus->Area, size * sizeof(struct P_area *));
225 if (p == NULL)
226 return -1;
227
228 Plus->Area = (struct P_area **) p;
229 Plus->alloc_areas = size - 1;
230
231 return 0;
232 }
233
234 /*!
235 \brief Reallocate array of pointers to isles
236
237 \param Plus pointer to Plus_head structure
238 \param add space for 'add' number of isles is added.
239
240 \return 0 on success
241 \return -1 on error
242 */
dig_alloc_isles(struct Plus_head * Plus,int add)243 int dig_alloc_isles(struct Plus_head *Plus, int add)
244 {
245 int size;
246 char *p;
247
248 G_debug(5, "dig_alloc_isle():");
249 size = Plus->alloc_isles + 1 + add;
250 p = G_realloc(Plus->Isle, size * sizeof(struct P_isle *));
251 if (p == NULL)
252 return -1;
253
254 Plus->Isle = (struct P_isle **) p;
255 Plus->alloc_isles = size - 1;
256
257 return 0;
258 }
259
260 /*!
261 \brief Allocate new area structure
262
263 \return pointer to allocated P_area struct
264 \return NULL on error
265 */
dig_alloc_area()266 struct P_area *dig_alloc_area()
267 {
268 struct P_area *Area;
269
270 Area = (struct P_area *) G_malloc(sizeof(struct P_area));
271 if (Area == NULL)
272 return NULL;
273
274 G_zero(Area, sizeof(struct P_area));
275
276 return Area;
277 }
278
279 /*!
280 \brief Free area structure
281
282 \param Area pointer to P_area struct to be freed
283 */
dig_free_area(struct P_area * Area)284 void dig_free_area(struct P_area *Area)
285 {
286 if (Area->alloc_lines > 0)
287 free(Area->lines);
288
289 if (Area->alloc_isles > 0)
290 free(Area->isles);
291
292 G_free(Area);
293 }
294
295 /*!
296 \brief Allocate new isle structure
297
298 \return pointer to allocated P_isle struct
299 \return NULL on error
300 */
dig_alloc_isle()301 struct P_isle *dig_alloc_isle()
302 {
303 struct P_isle *Isle;
304
305 Isle = (struct P_isle *) G_malloc(sizeof(struct P_isle));
306 if (Isle == NULL)
307 return NULL;
308
309 G_zero(Isle, sizeof(struct P_isle));
310
311 return Isle;
312 }
313
314 /*!
315 \brief Free isle structure
316
317 \param Isle pointer to P_isle struct to be freed
318 */
dig_free_isle(struct P_isle * Isle)319 void dig_free_isle(struct P_isle *Isle)
320 {
321 if (Isle->alloc_lines > 0)
322 G_free(Isle->lines);
323
324 G_free(Isle);
325 }
326
327 /*!
328 \brief allocate room for 'num' X and Y arrays in struct line_pnts
329
330 \param points pointer to line_pnts struct
331 \param num number of points
332
333 \return 0 on success
334 \return returns -1 on out of memory
335 */
dig_alloc_points(struct line_pnts * points,int num)336 int dig_alloc_points(struct line_pnts *points, int num)
337 {
338 int alloced;
339 char *p;
340
341 alloced = points->alloc_points;
342 /* alloc_space will just return if no space is needed */
343 if (!(p =
344 dig__alloc_space(num, &alloced, 50, (char *)points->x,
345 sizeof(double)))) {
346 return (dig_out_of_memory());
347 }
348 points->x = (double *)p;
349
350 alloced = points->alloc_points;
351 /* alloc_space will just return if no space is needed */
352 if (!(p =
353 dig__alloc_space(num, &alloced, 50, (char *)points->y,
354 sizeof(double)))) {
355 return (dig_out_of_memory());
356 }
357 points->y = (double *)p;
358
359 alloced = points->alloc_points;
360 /* alloc_space will just return if no space is needed */
361 if (!(p =
362 dig__alloc_space(num, &alloced, 50, (char *)points->z,
363 sizeof(double)))) {
364 return (dig_out_of_memory());
365 }
366 points->z = (double *)p;
367
368 points->alloc_points = alloced;
369
370 return 0;
371 }
372
373 /*!
374 \brief Allocate room for 'num' fields and category arrays
375 in struct line_cats
376
377 \param cats pointer to line_cats struct
378 \param num number of cats
379
380 \return 0 on success
381 \return returns -1 on out of memory
382 */
dig_alloc_cats(struct line_cats * cats,int num)383 int dig_alloc_cats(struct line_cats *cats, int num)
384 {
385 int alloced;
386 char *p;
387
388 /* alloc_space will just return if no space is needed */
389 alloced = cats->alloc_cats;
390 if (!(p =
391 dig__alloc_space(num, &alloced, 1, (int *)cats->field,
392 sizeof(int)))) {
393 return dig_out_of_memory();
394 }
395 cats->field = (int *)p;
396
397 alloced = cats->alloc_cats;
398 if (!(p =
399 dig__alloc_space(num, &alloced, 1, (int *)cats->cat,
400 sizeof(int)))) {
401 return dig_out_of_memory();
402 }
403 cats->cat = (int *)p;
404
405 cats->alloc_cats = alloced;
406
407 return 0;
408 }
409
410 /*!
411 \brief allocate space in P_area for add new lines
412
413 \param area pointer to P_area struct
414 \param add number of lines to be added
415
416 \return 0 on success
417 \return -1 on error
418 */
dig_area_alloc_line(struct P_area * area,int add)419 int dig_area_alloc_line(struct P_area * area, int add)
420 {
421 int num;
422 char *p;
423
424 num = area->alloc_lines + add;
425
426 p = G_realloc(area->lines, num * sizeof(plus_t));
427 if (p == NULL)
428 return -1;
429 area->lines = (plus_t *) p;
430
431 area->alloc_lines = num;
432
433 return (0);
434 }
435
436 /*!
437 \brief Allocate space in P_area for add new isles
438
439 \param area pointer to P_area struct
440 \param add number of isle to be added
441
442 \return 0 on success
443 \return -1 on error
444 */
dig_area_alloc_isle(struct P_area * area,int add)445 int dig_area_alloc_isle(struct P_area * area, int add)
446 {
447 int num;
448 char *p;
449
450 G_debug(5, "dig_area_alloc_isle(): add = %d", add);
451 num = area->alloc_isles + add;
452
453 p = G_realloc(area->isles, num * sizeof(plus_t));
454 if (p == NULL)
455 return -1;
456 area->isles = (plus_t *) p;
457
458 area->alloc_isles = num;
459 return (0);
460 }
461
462 /*!
463 \brief Allocate space in P_isle for add new lines
464
465 \param isle pointer to P_area struct
466 \param add number of isle to be added
467
468 \return 0 on success
469 \return -1 on error
470 */
dig_isle_alloc_line(struct P_isle * isle,int add)471 int dig_isle_alloc_line(struct P_isle * isle, int add)
472 {
473 int num;
474 char *p;
475
476 G_debug(5, "dig_isle_alloc_line():");
477 num = isle->alloc_lines + add;
478
479 p = G_realloc(isle->lines, num * sizeof(plus_t));
480 if (p == NULL)
481 return -1;
482 isle->lines = (plus_t *) p;
483
484 isle->alloc_lines = num;
485
486 return (0);
487 }
488
489 /*!
490 \brief For now just print message and return error code
491 */
dig_out_of_memory()492 int dig_out_of_memory()
493 {
494 G_warning(_("Out of memory"));
495 return -1;
496 }
497