Array.c revision fc544a13
1/*
2Copyright 1989, 1998  The Open Group
3
4Permission to use, copy, modify, distribute, and sell this software and its
5documentation for any purpose is hereby granted without fee, provided that
6the above copyright notice appear in all copies and that both that
7copyright notice and this permission notice appear in supporting
8documentation.
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
16OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20Except as contained in this notice, the name of The Open Group shall not be
21used in advertising or otherwise to promote the sale, use or other dealings
22in this Software without prior written authorization from The Open Group.
23 *
24 * Author:  Keith Packard, MIT X Consortium
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include <X11/Xos.h>
31#include <X11/X.h>
32#include <X11/Xmd.h>
33#include <X11/Xdmcp.h>
34#include <stdint.h>
35#include <stdlib.h>
36
37/*
38 * This variant of malloc does not return NULL if zero size is passed into.
39 */
40static void *
41xmalloc(size_t size)
42{
43    return malloc(size ? size : 1);
44}
45
46/*
47 * This variant of calloc does not return NULL if zero count is passed into.
48 */
49static void *
50xcalloc(size_t n, size_t size)
51{
52    return calloc(n ? n : 1, size);
53}
54
55/*
56 * This variant of realloc does not return NULL if zero size is passed into
57 */
58static void *
59xrealloc(void *ptr, size_t size)
60{
61    return realloc(ptr, size ? size : 1);
62}
63
64int
65XdmcpAllocARRAY8 (ARRAY8Ptr array, int length)
66{
67    /* length defined in ARRAY8 struct is a CARD16 (not CARD8 like the rest) */
68    if ((length > UINT16_MAX) || (length < 0))
69        array->data = NULL;
70    else
71        array->data = xmalloc(length * sizeof (CARD8));
72
73    if (array->data == NULL) {
74	array->length = 0;
75	return FALSE;
76    }
77    array->length = (CARD16) length;
78    return TRUE;
79}
80
81int
82XdmcpAllocARRAY16 (ARRAY16Ptr array, int length)
83{
84    /* length defined in ARRAY16 struct is a CARD8 */
85    if ((length > UINT8_MAX) || (length < 0))
86        array->data = NULL;
87    else
88        array->data = xmalloc(length * sizeof (CARD16));
89
90    if (array->data == NULL) {
91	array->length = 0;
92	return FALSE;
93    }
94    array->length = (CARD8) length;
95    return TRUE;
96}
97
98int
99XdmcpAllocARRAY32 (ARRAY32Ptr array, int length)
100{
101    /* length defined in ARRAY32 struct is a CARD8 */
102    if ((length > UINT8_MAX) || (length < 0))
103        array->data = NULL;
104    else
105        array->data = xmalloc(length * sizeof (CARD32));
106
107    if (array->data == NULL) {
108	array->length = 0;
109	return FALSE;
110    }
111    array->length = (CARD8) length;
112    return TRUE;
113}
114
115int
116XdmcpAllocARRAYofARRAY8 (ARRAYofARRAY8Ptr array, int length)
117{
118    /* length defined in ARRAYofARRAY8 struct is a CARD8 */
119    if ((length > UINT8_MAX) || (length < 0))
120        array->data = NULL;
121    else
122        /*
123         * Use calloc to ensure the pointers are cleared out so we
124         * don't try to free garbage if XdmcpDisposeARRAYofARRAY8()
125         * is called before the caller sets them to valid pointers.
126         */
127        array->data = xcalloc(length, sizeof (ARRAY8));
128
129    if (array->data == NULL) {
130	array->length = 0;
131	return FALSE;
132    }
133    array->length = (CARD8) length;
134    return TRUE;
135}
136
137int
138XdmcpARRAY8Equal (const ARRAY8Ptr array1, const ARRAY8Ptr array2)
139{
140    if (array1->length != array2->length)
141	return FALSE;
142    if (memcmp(array1->data, array2->data, array1->length) != 0)
143	return FALSE;
144    return TRUE;
145}
146
147int
148XdmcpCopyARRAY8 (const ARRAY8Ptr src, ARRAY8Ptr dst)
149{
150    if (!XdmcpAllocARRAY8(dst, src->length))
151	return FALSE;
152    memmove (dst->data, src->data, src->length * sizeof (CARD8));
153    return TRUE;
154}
155
156int
157XdmcpReallocARRAY8 (ARRAY8Ptr array, int length)
158{
159    CARD8Ptr	newData;
160
161    /* length defined in ARRAY8 struct is a CARD16 (not CARD8 like the rest) */
162    if ((length > UINT16_MAX) || (length < 0))
163	return FALSE;
164
165    newData = (CARD8Ptr) xrealloc(array->data, length * sizeof (CARD8));
166    if (!newData)
167	return FALSE;
168    array->length = (CARD16) length;
169    array->data = newData;
170    return TRUE;
171}
172
173int
174XdmcpReallocARRAYofARRAY8 (ARRAYofARRAY8Ptr array, int length)
175{
176    ARRAY8Ptr	newData;
177
178    /* length defined in ARRAYofARRAY8 struct is a CARD8 */
179    if ((length > UINT8_MAX) || (length < 0))
180	return FALSE;
181
182    newData = (ARRAY8Ptr) xrealloc(array->data, length * sizeof (ARRAY8));
183    if (!newData)
184	return FALSE;
185    if (length > array->length)
186        memset(newData + array->length, 0,
187               (length - array->length) * sizeof (ARRAY8));
188    array->length = (CARD8) length;
189    array->data = newData;
190    return TRUE;
191}
192
193int
194XdmcpReallocARRAY16 (ARRAY16Ptr array, int length)
195{
196    CARD16Ptr	newData;
197
198    /* length defined in ARRAY16 struct is a CARD8 */
199    if ((length > UINT8_MAX) || (length < 0))
200	return FALSE;
201    newData = (CARD16Ptr) xrealloc(array->data, length * sizeof (CARD16));
202    if (!newData)
203	return FALSE;
204    array->length = (CARD8) length;
205    array->data = newData;
206    return TRUE;
207}
208
209int
210XdmcpReallocARRAY32 (ARRAY32Ptr array, int length)
211{
212    CARD32Ptr	newData;
213
214    /* length defined in ARRAY32 struct is a CARD8 */
215    if ((length > UINT8_MAX) || (length < 0))
216	return FALSE;
217
218    newData = (CARD32Ptr) xrealloc(array->data, length * sizeof (CARD32));
219    if (!newData)
220	return FALSE;
221    array->length = (CARD8) length;
222    array->data = newData;
223    return TRUE;
224}
225
226void
227XdmcpDisposeARRAY8 (ARRAY8Ptr array)
228{
229    free(array->data);
230    array->length = 0;
231    array->data = NULL;
232}
233
234void
235XdmcpDisposeARRAY16 (ARRAY16Ptr array)
236{
237    free(array->data);
238    array->length = 0;
239    array->data = NULL;
240}
241
242void
243XdmcpDisposeARRAY32 (ARRAY32Ptr array)
244{
245    free(array->data);
246    array->length = 0;
247    array->data = NULL;
248}
249
250void
251XdmcpDisposeARRAYofARRAY8 (ARRAYofARRAY8Ptr array)
252{
253    int	i;
254
255    if (array->data != NULL) {
256	for (i = 0; i < (int)array->length; i++)
257	    XdmcpDisposeARRAY8 (&array->data[i]);
258	free(array->data);
259    }
260    array->length = 0;
261    array->data = NULL;
262}
263