1 /*
2 ****************************************************************************
3 *
4 * MODULE: Vector library
5 *
6 * AUTHOR(S): Original author CERL, probably Dave Gerdes.
7 * Update to GRASS 5.7 Radim Blazek.
8 *
9 * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
10 *
11 * COPYRIGHT: (C) 2001 by the GRASS Development Team
12 *
13 * This program is free software under the GNU General Public
14 * License (>=v2). Read the file COPYING that comes with GRASS
15 * for details.
16 *
17 *****************************************************************************/
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <grass/vector.h>
21
22 /* functions - alloc_space(), falloc(), frealloc() _falloc() _frealloc() */
23
24
25 /* alloc_space () allocates space if needed.
26 * All allocated space is created by calloc (2).
27 *
28 * args: number of elements wanted, pointer to number of currently allocated
29 * elements, size of chunks to allocate, pointer to current array, sizeof
30 * an element.
31 */
32
dig_alloc_space(int n_wanted,int * n_elements,int chunk_size,void * ptr,int element_size)33 void *dig_alloc_space(int n_wanted,
34 int *n_elements,
35 int chunk_size, void *ptr, int element_size)
36 {
37 char *p;
38
39 p = dig__alloc_space(n_wanted, n_elements, chunk_size, ptr, element_size);
40
41 if (p == NULL) {
42 fprintf(stderr, "\nERROR: out of memory. memory asked for: %d\n",
43 n_wanted);
44 exit(EXIT_FAILURE);
45 }
46
47 return (p);
48 }
49
dig__alloc_space(int n_wanted,int * n_elements,int chunk_size,void * ptr,int element_size)50 void *dig__alloc_space(int n_wanted, int *n_elements, int chunk_size, void *ptr, /* changed char -> void instead of casting. WBH 8/16/1998 */
51 int element_size)
52 {
53 int to_alloc;
54
55 to_alloc = *n_elements;
56
57 /* do we need to allocate more space */
58 if (n_wanted < to_alloc)
59 return (ptr);
60
61 /* calculate the number needed by chunk size */
62 /* ORIGINAL
63 while (n_wanted >= to_alloc)
64 to_alloc += chunk_size;
65 */
66 /*
67 ** This was changed as a test on Aug 21, 1990
68 ** Build.vect was taking outrageous amounts of
69 ** memory to run, so instead of blaming my
70 ** code, I decided that it could be the realloc/malloc
71 ** stuff not making efficient use of the space.
72 ** So the fix is to instead of asking for many small
73 ** increments, ask for twice as much space as we are currently
74 ** using, each time we need more space.
75 */
76 while (n_wanted >= to_alloc)
77 to_alloc += *n_elements ? *n_elements : chunk_size;
78
79 /* first time called allocate initial storage */
80 if (*n_elements == 0)
81 ptr = G_calloc(to_alloc, element_size);
82 else
83 ptr = dig__frealloc((char *)ptr, to_alloc, element_size, *n_elements);
84
85 *n_elements = to_alloc;
86
87 return (ptr);
88 }
89
90
dig_falloc(int nelem,int elsize)91 void *dig_falloc(int nelem, int elsize)
92 {
93 void *ret;
94
95 if ((ret = dig__falloc(nelem, elsize)) == NULL) {
96 fprintf(stderr, "Out of Memory.\n");
97 G_sleep(2);
98 exit(EXIT_FAILURE);
99 }
100 return (ret);
101 }
102
dig_frealloc(void * oldptr,int nelem,int elsize,int oldnelem)103 void *dig_frealloc(void *oldptr, int nelem, int elsize, int oldnelem)
104 {
105 char *ret;
106
107 if ((ret = dig__frealloc(oldptr, nelem, elsize, oldnelem)) == NULL) {
108 fprintf(stderr, "\nOut of Memory on realloc.\n");
109 G_sleep(2);
110 exit(EXIT_FAILURE);
111 }
112 return (ret);
113 }
114
115 /* these functions don't exit on "no more memory", calling function should
116 check the return value */
117
dig__falloc(int nelem,int elsize)118 void *dig__falloc(int nelem, int elsize)
119 {
120 char *ptr;
121
122 if (elsize == 0) {
123 elsize = 4;
124 }
125 if (nelem == 0) {
126 nelem = 1;
127 }
128
129 ptr = G_calloc(nelem, elsize);
130 return (ptr);
131 }
132
dig__frealloc(void * oldptr,int nelem,int elsize,int oldnelem)133 void *dig__frealloc(void *oldptr, int nelem, int elsize, int oldnelem)
134 {
135 char *ptr;
136
137 if (elsize == 0) {
138 elsize = 4;
139 }
140 if (nelem == 0) {
141 nelem = 1;
142 }
143
144 ptr = G_calloc(nelem, elsize);
145
146 /* out of memory */
147 if (!ptr)
148 return (ptr);
149
150 {
151 register char *a;
152 register char *b;
153 register size_t n;
154
155 n = oldnelem * elsize;
156 a = ptr;
157 b = oldptr;
158 while (n--)
159 *a++ = *b++;
160 }
161
162 G_free(oldptr);
163 return (ptr);
164 }
165