1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Sorted array routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups.h>
15*5e7646d2SAndroid Build Coastguard Worker #include "string-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
17*5e7646d2SAndroid Build Coastguard Worker #include "array-private.h"
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker * Limits...
22*5e7646d2SAndroid Build Coastguard Worker */
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker #define _CUPS_MAXSAVE 32 /**** Maximum number of saves ****/
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker /*
28*5e7646d2SAndroid Build Coastguard Worker * Types and structures...
29*5e7646d2SAndroid Build Coastguard Worker */
30*5e7646d2SAndroid Build Coastguard Worker
31*5e7646d2SAndroid Build Coastguard Worker struct _cups_array_s /**** CUPS array structure ****/
32*5e7646d2SAndroid Build Coastguard Worker {
33*5e7646d2SAndroid Build Coastguard Worker /*
34*5e7646d2SAndroid Build Coastguard Worker * The current implementation uses an insertion sort into an array of
35*5e7646d2SAndroid Build Coastguard Worker * sorted pointers. We leave the array type private/opaque so that we
36*5e7646d2SAndroid Build Coastguard Worker * can change the underlying implementation without affecting the users
37*5e7646d2SAndroid Build Coastguard Worker * of this API.
38*5e7646d2SAndroid Build Coastguard Worker */
39*5e7646d2SAndroid Build Coastguard Worker
40*5e7646d2SAndroid Build Coastguard Worker int num_elements, /* Number of array elements */
41*5e7646d2SAndroid Build Coastguard Worker alloc_elements, /* Allocated array elements */
42*5e7646d2SAndroid Build Coastguard Worker current, /* Current element */
43*5e7646d2SAndroid Build Coastguard Worker insert, /* Last inserted element */
44*5e7646d2SAndroid Build Coastguard Worker unique, /* Are all elements unique? */
45*5e7646d2SAndroid Build Coastguard Worker num_saved, /* Number of saved elements */
46*5e7646d2SAndroid Build Coastguard Worker saved[_CUPS_MAXSAVE];
47*5e7646d2SAndroid Build Coastguard Worker /* Saved elements */
48*5e7646d2SAndroid Build Coastguard Worker void **elements; /* Array elements */
49*5e7646d2SAndroid Build Coastguard Worker cups_array_func_t compare; /* Element comparison function */
50*5e7646d2SAndroid Build Coastguard Worker void *data; /* User data passed to compare */
51*5e7646d2SAndroid Build Coastguard Worker cups_ahash_func_t hashfunc; /* Hash function */
52*5e7646d2SAndroid Build Coastguard Worker int hashsize, /* Size of hash */
53*5e7646d2SAndroid Build Coastguard Worker *hash; /* Hash array */
54*5e7646d2SAndroid Build Coastguard Worker cups_acopy_func_t copyfunc; /* Copy function */
55*5e7646d2SAndroid Build Coastguard Worker cups_afree_func_t freefunc; /* Free function */
56*5e7646d2SAndroid Build Coastguard Worker };
57*5e7646d2SAndroid Build Coastguard Worker
58*5e7646d2SAndroid Build Coastguard Worker
59*5e7646d2SAndroid Build Coastguard Worker /*
60*5e7646d2SAndroid Build Coastguard Worker * Local functions...
61*5e7646d2SAndroid Build Coastguard Worker */
62*5e7646d2SAndroid Build Coastguard Worker
63*5e7646d2SAndroid Build Coastguard Worker static int cups_array_add(cups_array_t *a, void *e, int insert);
64*5e7646d2SAndroid Build Coastguard Worker static int cups_array_find(cups_array_t *a, void *e, int prev, int *rdiff);
65*5e7646d2SAndroid Build Coastguard Worker
66*5e7646d2SAndroid Build Coastguard Worker
67*5e7646d2SAndroid Build Coastguard Worker /*
68*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayAdd()' - Add an element to the array.
69*5e7646d2SAndroid Build Coastguard Worker *
70*5e7646d2SAndroid Build Coastguard Worker * When adding an element to a sorted array, non-unique elements are
71*5e7646d2SAndroid Build Coastguard Worker * appended at the end of the run of identical elements. For unsorted arrays,
72*5e7646d2SAndroid Build Coastguard Worker * the element is appended to the end of the array.
73*5e7646d2SAndroid Build Coastguard Worker *
74*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
75*5e7646d2SAndroid Build Coastguard Worker */
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
cupsArrayAdd(cups_array_t * a,void * e)78*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(cups_array_t *a, /* I - Array */
79*5e7646d2SAndroid Build Coastguard Worker void *e) /* I - Element */
80*5e7646d2SAndroid Build Coastguard Worker {
81*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsArrayAdd(a=%p, e=%p)", (void *)a, e));
82*5e7646d2SAndroid Build Coastguard Worker
83*5e7646d2SAndroid Build Coastguard Worker /*
84*5e7646d2SAndroid Build Coastguard Worker * Range check input...
85*5e7646d2SAndroid Build Coastguard Worker */
86*5e7646d2SAndroid Build Coastguard Worker
87*5e7646d2SAndroid Build Coastguard Worker if (!a || !e)
88*5e7646d2SAndroid Build Coastguard Worker {
89*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("3cupsArrayAdd: returning 0");
90*5e7646d2SAndroid Build Coastguard Worker return (0);
91*5e7646d2SAndroid Build Coastguard Worker }
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker /*
94*5e7646d2SAndroid Build Coastguard Worker * Append the element...
95*5e7646d2SAndroid Build Coastguard Worker */
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker return (cups_array_add(a, e, 0));
98*5e7646d2SAndroid Build Coastguard Worker }
99*5e7646d2SAndroid Build Coastguard Worker
100*5e7646d2SAndroid Build Coastguard Worker
101*5e7646d2SAndroid Build Coastguard Worker /*
102*5e7646d2SAndroid Build Coastguard Worker * '_cupsArrayAddStrings()' - Add zero or more delimited strings to an array.
103*5e7646d2SAndroid Build Coastguard Worker *
104*5e7646d2SAndroid Build Coastguard Worker * Note: The array MUST be created using the @link _cupsArrayNewStrings@
105*5e7646d2SAndroid Build Coastguard Worker * function. Duplicate strings are NOT added. If the string pointer "s" is NULL
106*5e7646d2SAndroid Build Coastguard Worker * or the empty string, no strings are added to the array.
107*5e7646d2SAndroid Build Coastguard Worker */
108*5e7646d2SAndroid Build Coastguard Worker
109*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
_cupsArrayAddStrings(cups_array_t * a,const char * s,char delim)110*5e7646d2SAndroid Build Coastguard Worker _cupsArrayAddStrings(cups_array_t *a, /* I - Array */
111*5e7646d2SAndroid Build Coastguard Worker const char *s, /* I - Delimited strings or NULL */
112*5e7646d2SAndroid Build Coastguard Worker char delim)/* I - Delimiter character */
113*5e7646d2SAndroid Build Coastguard Worker {
114*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* Copy of string */
115*5e7646d2SAndroid Build Coastguard Worker *start, /* Start of string */
116*5e7646d2SAndroid Build Coastguard Worker *end; /* End of string */
117*5e7646d2SAndroid Build Coastguard Worker int status = 1; /* Status of add */
118*5e7646d2SAndroid Build Coastguard Worker
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_cupsArrayAddStrings(a=%p, s=\"%s\", delim='%c')", (void *)a, s, delim));
121*5e7646d2SAndroid Build Coastguard Worker
122*5e7646d2SAndroid Build Coastguard Worker if (!a || !s || !*s)
123*5e7646d2SAndroid Build Coastguard Worker {
124*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsArrayAddStrings: Returning 0");
125*5e7646d2SAndroid Build Coastguard Worker return (0);
126*5e7646d2SAndroid Build Coastguard Worker }
127*5e7646d2SAndroid Build Coastguard Worker
128*5e7646d2SAndroid Build Coastguard Worker if (delim == ' ')
129*5e7646d2SAndroid Build Coastguard Worker {
130*5e7646d2SAndroid Build Coastguard Worker /*
131*5e7646d2SAndroid Build Coastguard Worker * Skip leading whitespace...
132*5e7646d2SAndroid Build Coastguard Worker */
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsArrayAddStrings: Skipping leading whitespace.");
135*5e7646d2SAndroid Build Coastguard Worker
136*5e7646d2SAndroid Build Coastguard Worker while (*s && isspace(*s & 255))
137*5e7646d2SAndroid Build Coastguard Worker s ++;
138*5e7646d2SAndroid Build Coastguard Worker
139*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsArrayAddStrings: Remaining string \"%s\".", s));
140*5e7646d2SAndroid Build Coastguard Worker }
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker if (!strchr(s, delim) &&
143*5e7646d2SAndroid Build Coastguard Worker (delim != ' ' || (!strchr(s, '\t') && !strchr(s, '\n'))))
144*5e7646d2SAndroid Build Coastguard Worker {
145*5e7646d2SAndroid Build Coastguard Worker /*
146*5e7646d2SAndroid Build Coastguard Worker * String doesn't contain a delimiter, so add it as a single value...
147*5e7646d2SAndroid Build Coastguard Worker */
148*5e7646d2SAndroid Build Coastguard Worker
149*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsArrayAddStrings: No delimiter seen, adding a single "
150*5e7646d2SAndroid Build Coastguard Worker "value.");
151*5e7646d2SAndroid Build Coastguard Worker
152*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(a, (void *)s))
153*5e7646d2SAndroid Build Coastguard Worker status = cupsArrayAdd(a, (void *)s);
154*5e7646d2SAndroid Build Coastguard Worker }
155*5e7646d2SAndroid Build Coastguard Worker else if ((buffer = strdup(s)) == NULL)
156*5e7646d2SAndroid Build Coastguard Worker {
157*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsArrayAddStrings: Unable to duplicate string.");
158*5e7646d2SAndroid Build Coastguard Worker status = 0;
159*5e7646d2SAndroid Build Coastguard Worker }
160*5e7646d2SAndroid Build Coastguard Worker else
161*5e7646d2SAndroid Build Coastguard Worker {
162*5e7646d2SAndroid Build Coastguard Worker for (start = end = buffer; *end; start = end)
163*5e7646d2SAndroid Build Coastguard Worker {
164*5e7646d2SAndroid Build Coastguard Worker /*
165*5e7646d2SAndroid Build Coastguard Worker * Find the end of the current delimited string and see if we need to add
166*5e7646d2SAndroid Build Coastguard Worker * it...
167*5e7646d2SAndroid Build Coastguard Worker */
168*5e7646d2SAndroid Build Coastguard Worker
169*5e7646d2SAndroid Build Coastguard Worker if (delim == ' ')
170*5e7646d2SAndroid Build Coastguard Worker {
171*5e7646d2SAndroid Build Coastguard Worker while (*end && !isspace(*end & 255))
172*5e7646d2SAndroid Build Coastguard Worker end ++;
173*5e7646d2SAndroid Build Coastguard Worker while (*end && isspace(*end & 255))
174*5e7646d2SAndroid Build Coastguard Worker *end++ = '\0';
175*5e7646d2SAndroid Build Coastguard Worker }
176*5e7646d2SAndroid Build Coastguard Worker else if ((end = strchr(start, delim)) != NULL)
177*5e7646d2SAndroid Build Coastguard Worker *end++ = '\0';
178*5e7646d2SAndroid Build Coastguard Worker else
179*5e7646d2SAndroid Build Coastguard Worker end = start + strlen(start);
180*5e7646d2SAndroid Build Coastguard Worker
181*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsArrayAddStrings: Adding \"%s\", end=\"%s\"", start,
182*5e7646d2SAndroid Build Coastguard Worker end));
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(a, start))
185*5e7646d2SAndroid Build Coastguard Worker status &= cupsArrayAdd(a, start);
186*5e7646d2SAndroid Build Coastguard Worker }
187*5e7646d2SAndroid Build Coastguard Worker
188*5e7646d2SAndroid Build Coastguard Worker free(buffer);
189*5e7646d2SAndroid Build Coastguard Worker }
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsArrayAddStrings: Returning %d.", status));
192*5e7646d2SAndroid Build Coastguard Worker
193*5e7646d2SAndroid Build Coastguard Worker return (status);
194*5e7646d2SAndroid Build Coastguard Worker }
195*5e7646d2SAndroid Build Coastguard Worker
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker /*
198*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayClear()' - Clear the array.
199*5e7646d2SAndroid Build Coastguard Worker *
200*5e7646d2SAndroid Build Coastguard Worker * This function is equivalent to removing all elements in the array.
201*5e7646d2SAndroid Build Coastguard Worker * The caller is responsible for freeing the memory used by the
202*5e7646d2SAndroid Build Coastguard Worker * elements themselves.
203*5e7646d2SAndroid Build Coastguard Worker *
204*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
205*5e7646d2SAndroid Build Coastguard Worker */
206*5e7646d2SAndroid Build Coastguard Worker
207*5e7646d2SAndroid Build Coastguard Worker void
cupsArrayClear(cups_array_t * a)208*5e7646d2SAndroid Build Coastguard Worker cupsArrayClear(cups_array_t *a) /* I - Array */
209*5e7646d2SAndroid Build Coastguard Worker {
210*5e7646d2SAndroid Build Coastguard Worker /*
211*5e7646d2SAndroid Build Coastguard Worker * Range check input...
212*5e7646d2SAndroid Build Coastguard Worker */
213*5e7646d2SAndroid Build Coastguard Worker
214*5e7646d2SAndroid Build Coastguard Worker if (!a)
215*5e7646d2SAndroid Build Coastguard Worker return;
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker /*
218*5e7646d2SAndroid Build Coastguard Worker * Free the existing elements as needed..
219*5e7646d2SAndroid Build Coastguard Worker */
220*5e7646d2SAndroid Build Coastguard Worker
221*5e7646d2SAndroid Build Coastguard Worker if (a->freefunc)
222*5e7646d2SAndroid Build Coastguard Worker {
223*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
224*5e7646d2SAndroid Build Coastguard Worker void **e; /* Current element */
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker for (i = a->num_elements, e = a->elements; i > 0; i --, e ++)
227*5e7646d2SAndroid Build Coastguard Worker (a->freefunc)(*e, a->data);
228*5e7646d2SAndroid Build Coastguard Worker }
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker /*
231*5e7646d2SAndroid Build Coastguard Worker * Set the number of elements to 0; we don't actually free the memory
232*5e7646d2SAndroid Build Coastguard Worker * here - that is done in cupsArrayDelete()...
233*5e7646d2SAndroid Build Coastguard Worker */
234*5e7646d2SAndroid Build Coastguard Worker
235*5e7646d2SAndroid Build Coastguard Worker a->num_elements = 0;
236*5e7646d2SAndroid Build Coastguard Worker a->current = -1;
237*5e7646d2SAndroid Build Coastguard Worker a->insert = -1;
238*5e7646d2SAndroid Build Coastguard Worker a->unique = 1;
239*5e7646d2SAndroid Build Coastguard Worker a->num_saved = 0;
240*5e7646d2SAndroid Build Coastguard Worker }
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker
243*5e7646d2SAndroid Build Coastguard Worker /*
244*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayCount()' - Get the number of elements in the array.
245*5e7646d2SAndroid Build Coastguard Worker *
246*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
247*5e7646d2SAndroid Build Coastguard Worker */
248*5e7646d2SAndroid Build Coastguard Worker
249*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of elements */
cupsArrayCount(cups_array_t * a)250*5e7646d2SAndroid Build Coastguard Worker cupsArrayCount(cups_array_t *a) /* I - Array */
251*5e7646d2SAndroid Build Coastguard Worker {
252*5e7646d2SAndroid Build Coastguard Worker /*
253*5e7646d2SAndroid Build Coastguard Worker * Range check input...
254*5e7646d2SAndroid Build Coastguard Worker */
255*5e7646d2SAndroid Build Coastguard Worker
256*5e7646d2SAndroid Build Coastguard Worker if (!a)
257*5e7646d2SAndroid Build Coastguard Worker return (0);
258*5e7646d2SAndroid Build Coastguard Worker
259*5e7646d2SAndroid Build Coastguard Worker /*
260*5e7646d2SAndroid Build Coastguard Worker * Return the number of elements...
261*5e7646d2SAndroid Build Coastguard Worker */
262*5e7646d2SAndroid Build Coastguard Worker
263*5e7646d2SAndroid Build Coastguard Worker return (a->num_elements);
264*5e7646d2SAndroid Build Coastguard Worker }
265*5e7646d2SAndroid Build Coastguard Worker
266*5e7646d2SAndroid Build Coastguard Worker
267*5e7646d2SAndroid Build Coastguard Worker /*
268*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayCurrent()' - Return the current element in the array.
269*5e7646d2SAndroid Build Coastguard Worker *
270*5e7646d2SAndroid Build Coastguard Worker * The current element is undefined until you call @link cupsArrayFind@,
271*5e7646d2SAndroid Build Coastguard Worker * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@.
272*5e7646d2SAndroid Build Coastguard Worker *
273*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
274*5e7646d2SAndroid Build Coastguard Worker */
275*5e7646d2SAndroid Build Coastguard Worker
276*5e7646d2SAndroid Build Coastguard Worker void * /* O - Element */
cupsArrayCurrent(cups_array_t * a)277*5e7646d2SAndroid Build Coastguard Worker cupsArrayCurrent(cups_array_t *a) /* I - Array */
278*5e7646d2SAndroid Build Coastguard Worker {
279*5e7646d2SAndroid Build Coastguard Worker /*
280*5e7646d2SAndroid Build Coastguard Worker * Range check input...
281*5e7646d2SAndroid Build Coastguard Worker */
282*5e7646d2SAndroid Build Coastguard Worker
283*5e7646d2SAndroid Build Coastguard Worker if (!a)
284*5e7646d2SAndroid Build Coastguard Worker return (NULL);
285*5e7646d2SAndroid Build Coastguard Worker
286*5e7646d2SAndroid Build Coastguard Worker /*
287*5e7646d2SAndroid Build Coastguard Worker * Return the current element...
288*5e7646d2SAndroid Build Coastguard Worker */
289*5e7646d2SAndroid Build Coastguard Worker
290*5e7646d2SAndroid Build Coastguard Worker if (a->current >= 0 && a->current < a->num_elements)
291*5e7646d2SAndroid Build Coastguard Worker return (a->elements[a->current]);
292*5e7646d2SAndroid Build Coastguard Worker else
293*5e7646d2SAndroid Build Coastguard Worker return (NULL);
294*5e7646d2SAndroid Build Coastguard Worker }
295*5e7646d2SAndroid Build Coastguard Worker
296*5e7646d2SAndroid Build Coastguard Worker
297*5e7646d2SAndroid Build Coastguard Worker /*
298*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayDelete()' - Free all memory used by the array.
299*5e7646d2SAndroid Build Coastguard Worker *
300*5e7646d2SAndroid Build Coastguard Worker * The caller is responsible for freeing the memory used by the
301*5e7646d2SAndroid Build Coastguard Worker * elements themselves.
302*5e7646d2SAndroid Build Coastguard Worker *
303*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
304*5e7646d2SAndroid Build Coastguard Worker */
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker void
cupsArrayDelete(cups_array_t * a)307*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(cups_array_t *a) /* I - Array */
308*5e7646d2SAndroid Build Coastguard Worker {
309*5e7646d2SAndroid Build Coastguard Worker /*
310*5e7646d2SAndroid Build Coastguard Worker * Range check input...
311*5e7646d2SAndroid Build Coastguard Worker */
312*5e7646d2SAndroid Build Coastguard Worker
313*5e7646d2SAndroid Build Coastguard Worker if (!a)
314*5e7646d2SAndroid Build Coastguard Worker return;
315*5e7646d2SAndroid Build Coastguard Worker
316*5e7646d2SAndroid Build Coastguard Worker /*
317*5e7646d2SAndroid Build Coastguard Worker * Free the elements if we have a free function (otherwise the caller is
318*5e7646d2SAndroid Build Coastguard Worker * responsible for doing the dirty work...)
319*5e7646d2SAndroid Build Coastguard Worker */
320*5e7646d2SAndroid Build Coastguard Worker
321*5e7646d2SAndroid Build Coastguard Worker if (a->freefunc)
322*5e7646d2SAndroid Build Coastguard Worker {
323*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
324*5e7646d2SAndroid Build Coastguard Worker void **e; /* Current element */
325*5e7646d2SAndroid Build Coastguard Worker
326*5e7646d2SAndroid Build Coastguard Worker for (i = a->num_elements, e = a->elements; i > 0; i --, e ++)
327*5e7646d2SAndroid Build Coastguard Worker (a->freefunc)(*e, a->data);
328*5e7646d2SAndroid Build Coastguard Worker }
329*5e7646d2SAndroid Build Coastguard Worker
330*5e7646d2SAndroid Build Coastguard Worker /*
331*5e7646d2SAndroid Build Coastguard Worker * Free the array of element pointers...
332*5e7646d2SAndroid Build Coastguard Worker */
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker if (a->alloc_elements)
335*5e7646d2SAndroid Build Coastguard Worker free(a->elements);
336*5e7646d2SAndroid Build Coastguard Worker
337*5e7646d2SAndroid Build Coastguard Worker if (a->hashsize)
338*5e7646d2SAndroid Build Coastguard Worker free(a->hash);
339*5e7646d2SAndroid Build Coastguard Worker
340*5e7646d2SAndroid Build Coastguard Worker free(a);
341*5e7646d2SAndroid Build Coastguard Worker }
342*5e7646d2SAndroid Build Coastguard Worker
343*5e7646d2SAndroid Build Coastguard Worker
344*5e7646d2SAndroid Build Coastguard Worker /*
345*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayDup()' - Duplicate the array.
346*5e7646d2SAndroid Build Coastguard Worker *
347*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
348*5e7646d2SAndroid Build Coastguard Worker */
349*5e7646d2SAndroid Build Coastguard Worker
350*5e7646d2SAndroid Build Coastguard Worker cups_array_t * /* O - Duplicate array */
cupsArrayDup(cups_array_t * a)351*5e7646d2SAndroid Build Coastguard Worker cupsArrayDup(cups_array_t *a) /* I - Array */
352*5e7646d2SAndroid Build Coastguard Worker {
353*5e7646d2SAndroid Build Coastguard Worker cups_array_t *da; /* Duplicate array */
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker
356*5e7646d2SAndroid Build Coastguard Worker /*
357*5e7646d2SAndroid Build Coastguard Worker * Range check input...
358*5e7646d2SAndroid Build Coastguard Worker */
359*5e7646d2SAndroid Build Coastguard Worker
360*5e7646d2SAndroid Build Coastguard Worker if (!a)
361*5e7646d2SAndroid Build Coastguard Worker return (NULL);
362*5e7646d2SAndroid Build Coastguard Worker
363*5e7646d2SAndroid Build Coastguard Worker /*
364*5e7646d2SAndroid Build Coastguard Worker * Allocate memory for the array...
365*5e7646d2SAndroid Build Coastguard Worker */
366*5e7646d2SAndroid Build Coastguard Worker
367*5e7646d2SAndroid Build Coastguard Worker da = calloc(1, sizeof(cups_array_t));
368*5e7646d2SAndroid Build Coastguard Worker if (!da)
369*5e7646d2SAndroid Build Coastguard Worker return (NULL);
370*5e7646d2SAndroid Build Coastguard Worker
371*5e7646d2SAndroid Build Coastguard Worker da->compare = a->compare;
372*5e7646d2SAndroid Build Coastguard Worker da->data = a->data;
373*5e7646d2SAndroid Build Coastguard Worker da->current = a->current;
374*5e7646d2SAndroid Build Coastguard Worker da->insert = a->insert;
375*5e7646d2SAndroid Build Coastguard Worker da->unique = a->unique;
376*5e7646d2SAndroid Build Coastguard Worker da->num_saved = a->num_saved;
377*5e7646d2SAndroid Build Coastguard Worker
378*5e7646d2SAndroid Build Coastguard Worker memcpy(da->saved, a->saved, sizeof(a->saved));
379*5e7646d2SAndroid Build Coastguard Worker
380*5e7646d2SAndroid Build Coastguard Worker if (a->num_elements)
381*5e7646d2SAndroid Build Coastguard Worker {
382*5e7646d2SAndroid Build Coastguard Worker /*
383*5e7646d2SAndroid Build Coastguard Worker * Allocate memory for the elements...
384*5e7646d2SAndroid Build Coastguard Worker */
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker da->elements = malloc((size_t)a->num_elements * sizeof(void *));
387*5e7646d2SAndroid Build Coastguard Worker if (!da->elements)
388*5e7646d2SAndroid Build Coastguard Worker {
389*5e7646d2SAndroid Build Coastguard Worker free(da);
390*5e7646d2SAndroid Build Coastguard Worker return (NULL);
391*5e7646d2SAndroid Build Coastguard Worker }
392*5e7646d2SAndroid Build Coastguard Worker
393*5e7646d2SAndroid Build Coastguard Worker /*
394*5e7646d2SAndroid Build Coastguard Worker * Copy the element pointers...
395*5e7646d2SAndroid Build Coastguard Worker */
396*5e7646d2SAndroid Build Coastguard Worker
397*5e7646d2SAndroid Build Coastguard Worker if (a->copyfunc)
398*5e7646d2SAndroid Build Coastguard Worker {
399*5e7646d2SAndroid Build Coastguard Worker /*
400*5e7646d2SAndroid Build Coastguard Worker * Use the copy function to make a copy of each element...
401*5e7646d2SAndroid Build Coastguard Worker */
402*5e7646d2SAndroid Build Coastguard Worker
403*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
404*5e7646d2SAndroid Build Coastguard Worker
405*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < a->num_elements; i ++)
406*5e7646d2SAndroid Build Coastguard Worker da->elements[i] = (a->copyfunc)(a->elements[i], a->data);
407*5e7646d2SAndroid Build Coastguard Worker }
408*5e7646d2SAndroid Build Coastguard Worker else
409*5e7646d2SAndroid Build Coastguard Worker {
410*5e7646d2SAndroid Build Coastguard Worker /*
411*5e7646d2SAndroid Build Coastguard Worker * Just copy raw pointers...
412*5e7646d2SAndroid Build Coastguard Worker */
413*5e7646d2SAndroid Build Coastguard Worker
414*5e7646d2SAndroid Build Coastguard Worker memcpy(da->elements, a->elements, (size_t)a->num_elements * sizeof(void *));
415*5e7646d2SAndroid Build Coastguard Worker }
416*5e7646d2SAndroid Build Coastguard Worker
417*5e7646d2SAndroid Build Coastguard Worker da->num_elements = a->num_elements;
418*5e7646d2SAndroid Build Coastguard Worker da->alloc_elements = a->num_elements;
419*5e7646d2SAndroid Build Coastguard Worker }
420*5e7646d2SAndroid Build Coastguard Worker
421*5e7646d2SAndroid Build Coastguard Worker /*
422*5e7646d2SAndroid Build Coastguard Worker * Return the new array...
423*5e7646d2SAndroid Build Coastguard Worker */
424*5e7646d2SAndroid Build Coastguard Worker
425*5e7646d2SAndroid Build Coastguard Worker return (da);
426*5e7646d2SAndroid Build Coastguard Worker }
427*5e7646d2SAndroid Build Coastguard Worker
428*5e7646d2SAndroid Build Coastguard Worker
429*5e7646d2SAndroid Build Coastguard Worker /*
430*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayFind()' - Find an element in the array.
431*5e7646d2SAndroid Build Coastguard Worker *
432*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
433*5e7646d2SAndroid Build Coastguard Worker */
434*5e7646d2SAndroid Build Coastguard Worker
435*5e7646d2SAndroid Build Coastguard Worker void * /* O - Element found or @code NULL@ */
cupsArrayFind(cups_array_t * a,void * e)436*5e7646d2SAndroid Build Coastguard Worker cupsArrayFind(cups_array_t *a, /* I - Array */
437*5e7646d2SAndroid Build Coastguard Worker void *e) /* I - Element */
438*5e7646d2SAndroid Build Coastguard Worker {
439*5e7646d2SAndroid Build Coastguard Worker int current, /* Current element */
440*5e7646d2SAndroid Build Coastguard Worker diff, /* Difference */
441*5e7646d2SAndroid Build Coastguard Worker hash; /* Hash index */
442*5e7646d2SAndroid Build Coastguard Worker
443*5e7646d2SAndroid Build Coastguard Worker
444*5e7646d2SAndroid Build Coastguard Worker /*
445*5e7646d2SAndroid Build Coastguard Worker * Range check input...
446*5e7646d2SAndroid Build Coastguard Worker */
447*5e7646d2SAndroid Build Coastguard Worker
448*5e7646d2SAndroid Build Coastguard Worker if (!a || !e)
449*5e7646d2SAndroid Build Coastguard Worker return (NULL);
450*5e7646d2SAndroid Build Coastguard Worker
451*5e7646d2SAndroid Build Coastguard Worker /*
452*5e7646d2SAndroid Build Coastguard Worker * See if we have any elements...
453*5e7646d2SAndroid Build Coastguard Worker */
454*5e7646d2SAndroid Build Coastguard Worker
455*5e7646d2SAndroid Build Coastguard Worker if (!a->num_elements)
456*5e7646d2SAndroid Build Coastguard Worker return (NULL);
457*5e7646d2SAndroid Build Coastguard Worker
458*5e7646d2SAndroid Build Coastguard Worker /*
459*5e7646d2SAndroid Build Coastguard Worker * Yes, look for a match...
460*5e7646d2SAndroid Build Coastguard Worker */
461*5e7646d2SAndroid Build Coastguard Worker
462*5e7646d2SAndroid Build Coastguard Worker if (a->hash)
463*5e7646d2SAndroid Build Coastguard Worker {
464*5e7646d2SAndroid Build Coastguard Worker hash = (*(a->hashfunc))(e, a->data);
465*5e7646d2SAndroid Build Coastguard Worker
466*5e7646d2SAndroid Build Coastguard Worker if (hash < 0 || hash >= a->hashsize)
467*5e7646d2SAndroid Build Coastguard Worker {
468*5e7646d2SAndroid Build Coastguard Worker current = a->current;
469*5e7646d2SAndroid Build Coastguard Worker hash = -1;
470*5e7646d2SAndroid Build Coastguard Worker }
471*5e7646d2SAndroid Build Coastguard Worker else
472*5e7646d2SAndroid Build Coastguard Worker {
473*5e7646d2SAndroid Build Coastguard Worker current = a->hash[hash];
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker if (current < 0 || current >= a->num_elements)
476*5e7646d2SAndroid Build Coastguard Worker current = a->current;
477*5e7646d2SAndroid Build Coastguard Worker }
478*5e7646d2SAndroid Build Coastguard Worker }
479*5e7646d2SAndroid Build Coastguard Worker else
480*5e7646d2SAndroid Build Coastguard Worker {
481*5e7646d2SAndroid Build Coastguard Worker current = a->current;
482*5e7646d2SAndroid Build Coastguard Worker hash = -1;
483*5e7646d2SAndroid Build Coastguard Worker }
484*5e7646d2SAndroid Build Coastguard Worker
485*5e7646d2SAndroid Build Coastguard Worker current = cups_array_find(a, e, current, &diff);
486*5e7646d2SAndroid Build Coastguard Worker if (!diff)
487*5e7646d2SAndroid Build Coastguard Worker {
488*5e7646d2SAndroid Build Coastguard Worker /*
489*5e7646d2SAndroid Build Coastguard Worker * Found a match! If the array does not contain unique values, find
490*5e7646d2SAndroid Build Coastguard Worker * the first element that is the same...
491*5e7646d2SAndroid Build Coastguard Worker */
492*5e7646d2SAndroid Build Coastguard Worker
493*5e7646d2SAndroid Build Coastguard Worker if (!a->unique && a->compare)
494*5e7646d2SAndroid Build Coastguard Worker {
495*5e7646d2SAndroid Build Coastguard Worker /*
496*5e7646d2SAndroid Build Coastguard Worker * The array is not unique, find the first match...
497*5e7646d2SAndroid Build Coastguard Worker */
498*5e7646d2SAndroid Build Coastguard Worker
499*5e7646d2SAndroid Build Coastguard Worker while (current > 0 && !(*(a->compare))(e, a->elements[current - 1],
500*5e7646d2SAndroid Build Coastguard Worker a->data))
501*5e7646d2SAndroid Build Coastguard Worker current --;
502*5e7646d2SAndroid Build Coastguard Worker }
503*5e7646d2SAndroid Build Coastguard Worker
504*5e7646d2SAndroid Build Coastguard Worker a->current = current;
505*5e7646d2SAndroid Build Coastguard Worker
506*5e7646d2SAndroid Build Coastguard Worker if (hash >= 0)
507*5e7646d2SAndroid Build Coastguard Worker a->hash[hash] = current;
508*5e7646d2SAndroid Build Coastguard Worker
509*5e7646d2SAndroid Build Coastguard Worker return (a->elements[current]);
510*5e7646d2SAndroid Build Coastguard Worker }
511*5e7646d2SAndroid Build Coastguard Worker else
512*5e7646d2SAndroid Build Coastguard Worker {
513*5e7646d2SAndroid Build Coastguard Worker /*
514*5e7646d2SAndroid Build Coastguard Worker * No match...
515*5e7646d2SAndroid Build Coastguard Worker */
516*5e7646d2SAndroid Build Coastguard Worker
517*5e7646d2SAndroid Build Coastguard Worker a->current = -1;
518*5e7646d2SAndroid Build Coastguard Worker
519*5e7646d2SAndroid Build Coastguard Worker return (NULL);
520*5e7646d2SAndroid Build Coastguard Worker }
521*5e7646d2SAndroid Build Coastguard Worker }
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker
524*5e7646d2SAndroid Build Coastguard Worker /*
525*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayFirst()' - Get the first element in the array.
526*5e7646d2SAndroid Build Coastguard Worker *
527*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
528*5e7646d2SAndroid Build Coastguard Worker */
529*5e7646d2SAndroid Build Coastguard Worker
530*5e7646d2SAndroid Build Coastguard Worker void * /* O - First element or @code NULL@ if the array is empty */
cupsArrayFirst(cups_array_t * a)531*5e7646d2SAndroid Build Coastguard Worker cupsArrayFirst(cups_array_t *a) /* I - Array */
532*5e7646d2SAndroid Build Coastguard Worker {
533*5e7646d2SAndroid Build Coastguard Worker /*
534*5e7646d2SAndroid Build Coastguard Worker * Range check input...
535*5e7646d2SAndroid Build Coastguard Worker */
536*5e7646d2SAndroid Build Coastguard Worker
537*5e7646d2SAndroid Build Coastguard Worker if (!a)
538*5e7646d2SAndroid Build Coastguard Worker return (NULL);
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker /*
541*5e7646d2SAndroid Build Coastguard Worker * Return the first element...
542*5e7646d2SAndroid Build Coastguard Worker */
543*5e7646d2SAndroid Build Coastguard Worker
544*5e7646d2SAndroid Build Coastguard Worker a->current = 0;
545*5e7646d2SAndroid Build Coastguard Worker
546*5e7646d2SAndroid Build Coastguard Worker return (cupsArrayCurrent(a));
547*5e7646d2SAndroid Build Coastguard Worker }
548*5e7646d2SAndroid Build Coastguard Worker
549*5e7646d2SAndroid Build Coastguard Worker
550*5e7646d2SAndroid Build Coastguard Worker /*
551*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayGetIndex()' - Get the index of the current element.
552*5e7646d2SAndroid Build Coastguard Worker *
553*5e7646d2SAndroid Build Coastguard Worker * The current element is undefined until you call @link cupsArrayFind@,
554*5e7646d2SAndroid Build Coastguard Worker * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@.
555*5e7646d2SAndroid Build Coastguard Worker *
556*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.3/macOS 10.5@
557*5e7646d2SAndroid Build Coastguard Worker */
558*5e7646d2SAndroid Build Coastguard Worker
559*5e7646d2SAndroid Build Coastguard Worker int /* O - Index of the current element, starting at 0 */
cupsArrayGetIndex(cups_array_t * a)560*5e7646d2SAndroid Build Coastguard Worker cupsArrayGetIndex(cups_array_t *a) /* I - Array */
561*5e7646d2SAndroid Build Coastguard Worker {
562*5e7646d2SAndroid Build Coastguard Worker if (!a)
563*5e7646d2SAndroid Build Coastguard Worker return (-1);
564*5e7646d2SAndroid Build Coastguard Worker else
565*5e7646d2SAndroid Build Coastguard Worker return (a->current);
566*5e7646d2SAndroid Build Coastguard Worker }
567*5e7646d2SAndroid Build Coastguard Worker
568*5e7646d2SAndroid Build Coastguard Worker
569*5e7646d2SAndroid Build Coastguard Worker /*
570*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayGetInsert()' - Get the index of the last inserted element.
571*5e7646d2SAndroid Build Coastguard Worker *
572*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.3/macOS 10.5@
573*5e7646d2SAndroid Build Coastguard Worker */
574*5e7646d2SAndroid Build Coastguard Worker
575*5e7646d2SAndroid Build Coastguard Worker int /* O - Index of the last inserted element, starting at 0 */
cupsArrayGetInsert(cups_array_t * a)576*5e7646d2SAndroid Build Coastguard Worker cupsArrayGetInsert(cups_array_t *a) /* I - Array */
577*5e7646d2SAndroid Build Coastguard Worker {
578*5e7646d2SAndroid Build Coastguard Worker if (!a)
579*5e7646d2SAndroid Build Coastguard Worker return (-1);
580*5e7646d2SAndroid Build Coastguard Worker else
581*5e7646d2SAndroid Build Coastguard Worker return (a->insert);
582*5e7646d2SAndroid Build Coastguard Worker }
583*5e7646d2SAndroid Build Coastguard Worker
584*5e7646d2SAndroid Build Coastguard Worker
585*5e7646d2SAndroid Build Coastguard Worker /*
586*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayIndex()' - Get the N-th element in the array.
587*5e7646d2SAndroid Build Coastguard Worker *
588*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
589*5e7646d2SAndroid Build Coastguard Worker */
590*5e7646d2SAndroid Build Coastguard Worker
591*5e7646d2SAndroid Build Coastguard Worker void * /* O - N-th element or @code NULL@ */
cupsArrayIndex(cups_array_t * a,int n)592*5e7646d2SAndroid Build Coastguard Worker cupsArrayIndex(cups_array_t *a, /* I - Array */
593*5e7646d2SAndroid Build Coastguard Worker int n) /* I - Index into array, starting at 0 */
594*5e7646d2SAndroid Build Coastguard Worker {
595*5e7646d2SAndroid Build Coastguard Worker if (!a)
596*5e7646d2SAndroid Build Coastguard Worker return (NULL);
597*5e7646d2SAndroid Build Coastguard Worker
598*5e7646d2SAndroid Build Coastguard Worker a->current = n;
599*5e7646d2SAndroid Build Coastguard Worker
600*5e7646d2SAndroid Build Coastguard Worker return (cupsArrayCurrent(a));
601*5e7646d2SAndroid Build Coastguard Worker }
602*5e7646d2SAndroid Build Coastguard Worker
603*5e7646d2SAndroid Build Coastguard Worker
604*5e7646d2SAndroid Build Coastguard Worker /*
605*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayInsert()' - Insert an element in the array.
606*5e7646d2SAndroid Build Coastguard Worker *
607*5e7646d2SAndroid Build Coastguard Worker * When inserting an element in a sorted array, non-unique elements are
608*5e7646d2SAndroid Build Coastguard Worker * inserted at the beginning of the run of identical elements. For unsorted
609*5e7646d2SAndroid Build Coastguard Worker * arrays, the element is inserted at the beginning of the array.
610*5e7646d2SAndroid Build Coastguard Worker *
611*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
612*5e7646d2SAndroid Build Coastguard Worker */
613*5e7646d2SAndroid Build Coastguard Worker
614*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on failure, 1 on success */
cupsArrayInsert(cups_array_t * a,void * e)615*5e7646d2SAndroid Build Coastguard Worker cupsArrayInsert(cups_array_t *a, /* I - Array */
616*5e7646d2SAndroid Build Coastguard Worker void *e) /* I - Element */
617*5e7646d2SAndroid Build Coastguard Worker {
618*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsArrayInsert(a=%p, e=%p)", (void *)a, e));
619*5e7646d2SAndroid Build Coastguard Worker
620*5e7646d2SAndroid Build Coastguard Worker /*
621*5e7646d2SAndroid Build Coastguard Worker * Range check input...
622*5e7646d2SAndroid Build Coastguard Worker */
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker if (!a || !e)
625*5e7646d2SAndroid Build Coastguard Worker {
626*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("3cupsArrayInsert: returning 0");
627*5e7646d2SAndroid Build Coastguard Worker return (0);
628*5e7646d2SAndroid Build Coastguard Worker }
629*5e7646d2SAndroid Build Coastguard Worker
630*5e7646d2SAndroid Build Coastguard Worker /*
631*5e7646d2SAndroid Build Coastguard Worker * Insert the element...
632*5e7646d2SAndroid Build Coastguard Worker */
633*5e7646d2SAndroid Build Coastguard Worker
634*5e7646d2SAndroid Build Coastguard Worker return (cups_array_add(a, e, 1));
635*5e7646d2SAndroid Build Coastguard Worker }
636*5e7646d2SAndroid Build Coastguard Worker
637*5e7646d2SAndroid Build Coastguard Worker
638*5e7646d2SAndroid Build Coastguard Worker /*
639*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayLast()' - Get the last element in the array.
640*5e7646d2SAndroid Build Coastguard Worker *
641*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
642*5e7646d2SAndroid Build Coastguard Worker */
643*5e7646d2SAndroid Build Coastguard Worker
644*5e7646d2SAndroid Build Coastguard Worker void * /* O - Last element or @code NULL@ if the array is empty */
cupsArrayLast(cups_array_t * a)645*5e7646d2SAndroid Build Coastguard Worker cupsArrayLast(cups_array_t *a) /* I - Array */
646*5e7646d2SAndroid Build Coastguard Worker {
647*5e7646d2SAndroid Build Coastguard Worker /*
648*5e7646d2SAndroid Build Coastguard Worker * Range check input...
649*5e7646d2SAndroid Build Coastguard Worker */
650*5e7646d2SAndroid Build Coastguard Worker
651*5e7646d2SAndroid Build Coastguard Worker if (!a)
652*5e7646d2SAndroid Build Coastguard Worker return (NULL);
653*5e7646d2SAndroid Build Coastguard Worker
654*5e7646d2SAndroid Build Coastguard Worker /*
655*5e7646d2SAndroid Build Coastguard Worker * Return the last element...
656*5e7646d2SAndroid Build Coastguard Worker */
657*5e7646d2SAndroid Build Coastguard Worker
658*5e7646d2SAndroid Build Coastguard Worker a->current = a->num_elements - 1;
659*5e7646d2SAndroid Build Coastguard Worker
660*5e7646d2SAndroid Build Coastguard Worker return (cupsArrayCurrent(a));
661*5e7646d2SAndroid Build Coastguard Worker }
662*5e7646d2SAndroid Build Coastguard Worker
663*5e7646d2SAndroid Build Coastguard Worker
664*5e7646d2SAndroid Build Coastguard Worker /*
665*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayNew()' - Create a new array.
666*5e7646d2SAndroid Build Coastguard Worker *
667*5e7646d2SAndroid Build Coastguard Worker * The comparison function ("f") is used to create a sorted array. The function
668*5e7646d2SAndroid Build Coastguard Worker * receives pointers to two elements and the user data pointer ("d") - the user
669*5e7646d2SAndroid Build Coastguard Worker * data pointer argument can safely be omitted when not required so functions
670*5e7646d2SAndroid Build Coastguard Worker * like @code strcmp@ can be used for sorted string arrays.
671*5e7646d2SAndroid Build Coastguard Worker *
672*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
673*5e7646d2SAndroid Build Coastguard Worker */
674*5e7646d2SAndroid Build Coastguard Worker
675*5e7646d2SAndroid Build Coastguard Worker cups_array_t * /* O - Array */
cupsArrayNew(cups_array_func_t f,void * d)676*5e7646d2SAndroid Build Coastguard Worker cupsArrayNew(cups_array_func_t f, /* I - Comparison function or @code NULL@ for an unsorted array */
677*5e7646d2SAndroid Build Coastguard Worker void *d) /* I - User data pointer or @code NULL@ */
678*5e7646d2SAndroid Build Coastguard Worker {
679*5e7646d2SAndroid Build Coastguard Worker return (cupsArrayNew3(f, d, 0, 0, 0, 0));
680*5e7646d2SAndroid Build Coastguard Worker }
681*5e7646d2SAndroid Build Coastguard Worker
682*5e7646d2SAndroid Build Coastguard Worker
683*5e7646d2SAndroid Build Coastguard Worker /*
684*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayNew2()' - Create a new array with hash.
685*5e7646d2SAndroid Build Coastguard Worker *
686*5e7646d2SAndroid Build Coastguard Worker * The comparison function ("f") is used to create a sorted array. The function
687*5e7646d2SAndroid Build Coastguard Worker * receives pointers to two elements and the user data pointer ("d") - the user
688*5e7646d2SAndroid Build Coastguard Worker * data pointer argument can safely be omitted when not required so functions
689*5e7646d2SAndroid Build Coastguard Worker * like @code strcmp@ can be used for sorted string arrays.
690*5e7646d2SAndroid Build Coastguard Worker *
691*5e7646d2SAndroid Build Coastguard Worker * The hash function ("h") is used to implement cached lookups with the
692*5e7646d2SAndroid Build Coastguard Worker * specified hash size ("hsize").
693*5e7646d2SAndroid Build Coastguard Worker *
694*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.3/macOS 10.5@
695*5e7646d2SAndroid Build Coastguard Worker */
696*5e7646d2SAndroid Build Coastguard Worker
697*5e7646d2SAndroid Build Coastguard Worker cups_array_t * /* O - Array */
cupsArrayNew2(cups_array_func_t f,void * d,cups_ahash_func_t h,int hsize)698*5e7646d2SAndroid Build Coastguard Worker cupsArrayNew2(cups_array_func_t f, /* I - Comparison function or @code NULL@ for an unsorted array */
699*5e7646d2SAndroid Build Coastguard Worker void *d, /* I - User data or @code NULL@ */
700*5e7646d2SAndroid Build Coastguard Worker cups_ahash_func_t h, /* I - Hash function or @code NULL@ for unhashed lookups */
701*5e7646d2SAndroid Build Coastguard Worker int hsize) /* I - Hash size (>= 0) */
702*5e7646d2SAndroid Build Coastguard Worker {
703*5e7646d2SAndroid Build Coastguard Worker return (cupsArrayNew3(f, d, h, hsize, 0, 0));
704*5e7646d2SAndroid Build Coastguard Worker }
705*5e7646d2SAndroid Build Coastguard Worker
706*5e7646d2SAndroid Build Coastguard Worker
707*5e7646d2SAndroid Build Coastguard Worker /*
708*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayNew3()' - Create a new array with hash and/or free function.
709*5e7646d2SAndroid Build Coastguard Worker *
710*5e7646d2SAndroid Build Coastguard Worker * The comparison function ("f") is used to create a sorted array. The function
711*5e7646d2SAndroid Build Coastguard Worker * receives pointers to two elements and the user data pointer ("d") - the user
712*5e7646d2SAndroid Build Coastguard Worker * data pointer argument can safely be omitted when not required so functions
713*5e7646d2SAndroid Build Coastguard Worker * like @code strcmp@ can be used for sorted string arrays.
714*5e7646d2SAndroid Build Coastguard Worker *
715*5e7646d2SAndroid Build Coastguard Worker * The hash function ("h") is used to implement cached lookups with the
716*5e7646d2SAndroid Build Coastguard Worker * specified hash size ("hsize").
717*5e7646d2SAndroid Build Coastguard Worker *
718*5e7646d2SAndroid Build Coastguard Worker * The copy function ("cf") is used to automatically copy/retain elements when
719*5e7646d2SAndroid Build Coastguard Worker * added or the array is copied.
720*5e7646d2SAndroid Build Coastguard Worker *
721*5e7646d2SAndroid Build Coastguard Worker * The free function ("cf") is used to automatically free/release elements when
722*5e7646d2SAndroid Build Coastguard Worker * removed or the array is deleted.
723*5e7646d2SAndroid Build Coastguard Worker *
724*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.5/macOS 10.7@
725*5e7646d2SAndroid Build Coastguard Worker */
726*5e7646d2SAndroid Build Coastguard Worker
727*5e7646d2SAndroid Build Coastguard Worker cups_array_t * /* O - Array */
cupsArrayNew3(cups_array_func_t f,void * d,cups_ahash_func_t h,int hsize,cups_acopy_func_t cf,cups_afree_func_t ff)728*5e7646d2SAndroid Build Coastguard Worker cupsArrayNew3(cups_array_func_t f, /* I - Comparison function or @code NULL@ for an unsorted array */
729*5e7646d2SAndroid Build Coastguard Worker void *d, /* I - User data or @code NULL@ */
730*5e7646d2SAndroid Build Coastguard Worker cups_ahash_func_t h, /* I - Hash function or @code NULL@ for unhashed lookups */
731*5e7646d2SAndroid Build Coastguard Worker int hsize, /* I - Hash size (>= 0) */
732*5e7646d2SAndroid Build Coastguard Worker cups_acopy_func_t cf, /* I - Copy function */
733*5e7646d2SAndroid Build Coastguard Worker cups_afree_func_t ff) /* I - Free function */
734*5e7646d2SAndroid Build Coastguard Worker {
735*5e7646d2SAndroid Build Coastguard Worker cups_array_t *a; /* Array */
736*5e7646d2SAndroid Build Coastguard Worker
737*5e7646d2SAndroid Build Coastguard Worker
738*5e7646d2SAndroid Build Coastguard Worker /*
739*5e7646d2SAndroid Build Coastguard Worker * Allocate memory for the array...
740*5e7646d2SAndroid Build Coastguard Worker */
741*5e7646d2SAndroid Build Coastguard Worker
742*5e7646d2SAndroid Build Coastguard Worker a = calloc(1, sizeof(cups_array_t));
743*5e7646d2SAndroid Build Coastguard Worker if (!a)
744*5e7646d2SAndroid Build Coastguard Worker return (NULL);
745*5e7646d2SAndroid Build Coastguard Worker
746*5e7646d2SAndroid Build Coastguard Worker a->compare = f;
747*5e7646d2SAndroid Build Coastguard Worker a->data = d;
748*5e7646d2SAndroid Build Coastguard Worker a->current = -1;
749*5e7646d2SAndroid Build Coastguard Worker a->insert = -1;
750*5e7646d2SAndroid Build Coastguard Worker a->num_saved = 0;
751*5e7646d2SAndroid Build Coastguard Worker a->unique = 1;
752*5e7646d2SAndroid Build Coastguard Worker
753*5e7646d2SAndroid Build Coastguard Worker if (hsize > 0 && h)
754*5e7646d2SAndroid Build Coastguard Worker {
755*5e7646d2SAndroid Build Coastguard Worker a->hashfunc = h;
756*5e7646d2SAndroid Build Coastguard Worker a->hashsize = hsize;
757*5e7646d2SAndroid Build Coastguard Worker a->hash = malloc((size_t)hsize * sizeof(int));
758*5e7646d2SAndroid Build Coastguard Worker
759*5e7646d2SAndroid Build Coastguard Worker if (!a->hash)
760*5e7646d2SAndroid Build Coastguard Worker {
761*5e7646d2SAndroid Build Coastguard Worker free(a);
762*5e7646d2SAndroid Build Coastguard Worker return (NULL);
763*5e7646d2SAndroid Build Coastguard Worker }
764*5e7646d2SAndroid Build Coastguard Worker
765*5e7646d2SAndroid Build Coastguard Worker memset(a->hash, -1, (size_t)hsize * sizeof(int));
766*5e7646d2SAndroid Build Coastguard Worker }
767*5e7646d2SAndroid Build Coastguard Worker
768*5e7646d2SAndroid Build Coastguard Worker a->copyfunc = cf;
769*5e7646d2SAndroid Build Coastguard Worker a->freefunc = ff;
770*5e7646d2SAndroid Build Coastguard Worker
771*5e7646d2SAndroid Build Coastguard Worker return (a);
772*5e7646d2SAndroid Build Coastguard Worker }
773*5e7646d2SAndroid Build Coastguard Worker
774*5e7646d2SAndroid Build Coastguard Worker
775*5e7646d2SAndroid Build Coastguard Worker /*
776*5e7646d2SAndroid Build Coastguard Worker * '_cupsArrayNewStrings()' - Create a new array of comma-delimited strings.
777*5e7646d2SAndroid Build Coastguard Worker *
778*5e7646d2SAndroid Build Coastguard Worker * Note: The array automatically manages copies of the strings passed. If the
779*5e7646d2SAndroid Build Coastguard Worker * string pointer "s" is NULL or the empty string, no strings are added to the
780*5e7646d2SAndroid Build Coastguard Worker * newly created array.
781*5e7646d2SAndroid Build Coastguard Worker */
782*5e7646d2SAndroid Build Coastguard Worker
783*5e7646d2SAndroid Build Coastguard Worker cups_array_t * /* O - Array */
_cupsArrayNewStrings(const char * s,char delim)784*5e7646d2SAndroid Build Coastguard Worker _cupsArrayNewStrings(const char *s, /* I - Delimited strings or NULL */
785*5e7646d2SAndroid Build Coastguard Worker char delim) /* I - Delimiter character */
786*5e7646d2SAndroid Build Coastguard Worker {
787*5e7646d2SAndroid Build Coastguard Worker cups_array_t *a; /* Array */
788*5e7646d2SAndroid Build Coastguard Worker
789*5e7646d2SAndroid Build Coastguard Worker
790*5e7646d2SAndroid Build Coastguard Worker if ((a = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0,
791*5e7646d2SAndroid Build Coastguard Worker (cups_acopy_func_t)_cupsStrAlloc,
792*5e7646d2SAndroid Build Coastguard Worker (cups_afree_func_t)_cupsStrFree)) != NULL)
793*5e7646d2SAndroid Build Coastguard Worker _cupsArrayAddStrings(a, s, delim);
794*5e7646d2SAndroid Build Coastguard Worker
795*5e7646d2SAndroid Build Coastguard Worker return (a);
796*5e7646d2SAndroid Build Coastguard Worker }
797*5e7646d2SAndroid Build Coastguard Worker
798*5e7646d2SAndroid Build Coastguard Worker
799*5e7646d2SAndroid Build Coastguard Worker /*
800*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayNext()' - Get the next element in the array.
801*5e7646d2SAndroid Build Coastguard Worker *
802*5e7646d2SAndroid Build Coastguard Worker * This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) + 1)".
803*5e7646d2SAndroid Build Coastguard Worker *
804*5e7646d2SAndroid Build Coastguard Worker * The next element is undefined until you call @link cupsArrayFind@,
805*5e7646d2SAndroid Build Coastguard Worker * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@
806*5e7646d2SAndroid Build Coastguard Worker * to set the current element.
807*5e7646d2SAndroid Build Coastguard Worker *
808*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
809*5e7646d2SAndroid Build Coastguard Worker */
810*5e7646d2SAndroid Build Coastguard Worker
811*5e7646d2SAndroid Build Coastguard Worker void * /* O - Next element or @code NULL@ */
cupsArrayNext(cups_array_t * a)812*5e7646d2SAndroid Build Coastguard Worker cupsArrayNext(cups_array_t *a) /* I - Array */
813*5e7646d2SAndroid Build Coastguard Worker {
814*5e7646d2SAndroid Build Coastguard Worker /*
815*5e7646d2SAndroid Build Coastguard Worker * Range check input...
816*5e7646d2SAndroid Build Coastguard Worker */
817*5e7646d2SAndroid Build Coastguard Worker
818*5e7646d2SAndroid Build Coastguard Worker if (!a)
819*5e7646d2SAndroid Build Coastguard Worker return (NULL);
820*5e7646d2SAndroid Build Coastguard Worker
821*5e7646d2SAndroid Build Coastguard Worker /*
822*5e7646d2SAndroid Build Coastguard Worker * Return the next element...
823*5e7646d2SAndroid Build Coastguard Worker */
824*5e7646d2SAndroid Build Coastguard Worker
825*5e7646d2SAndroid Build Coastguard Worker if (a->current < a->num_elements)
826*5e7646d2SAndroid Build Coastguard Worker a->current ++;
827*5e7646d2SAndroid Build Coastguard Worker
828*5e7646d2SAndroid Build Coastguard Worker return (cupsArrayCurrent(a));
829*5e7646d2SAndroid Build Coastguard Worker }
830*5e7646d2SAndroid Build Coastguard Worker
831*5e7646d2SAndroid Build Coastguard Worker
832*5e7646d2SAndroid Build Coastguard Worker /*
833*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayPrev()' - Get the previous element in the array.
834*5e7646d2SAndroid Build Coastguard Worker *
835*5e7646d2SAndroid Build Coastguard Worker * This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) - 1)".
836*5e7646d2SAndroid Build Coastguard Worker *
837*5e7646d2SAndroid Build Coastguard Worker * The previous element is undefined until you call @link cupsArrayFind@,
838*5e7646d2SAndroid Build Coastguard Worker * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@
839*5e7646d2SAndroid Build Coastguard Worker * to set the current element.
840*5e7646d2SAndroid Build Coastguard Worker *
841*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
842*5e7646d2SAndroid Build Coastguard Worker */
843*5e7646d2SAndroid Build Coastguard Worker
844*5e7646d2SAndroid Build Coastguard Worker void * /* O - Previous element or @code NULL@ */
cupsArrayPrev(cups_array_t * a)845*5e7646d2SAndroid Build Coastguard Worker cupsArrayPrev(cups_array_t *a) /* I - Array */
846*5e7646d2SAndroid Build Coastguard Worker {
847*5e7646d2SAndroid Build Coastguard Worker /*
848*5e7646d2SAndroid Build Coastguard Worker * Range check input...
849*5e7646d2SAndroid Build Coastguard Worker */
850*5e7646d2SAndroid Build Coastguard Worker
851*5e7646d2SAndroid Build Coastguard Worker if (!a)
852*5e7646d2SAndroid Build Coastguard Worker return (NULL);
853*5e7646d2SAndroid Build Coastguard Worker
854*5e7646d2SAndroid Build Coastguard Worker /*
855*5e7646d2SAndroid Build Coastguard Worker * Return the previous element...
856*5e7646d2SAndroid Build Coastguard Worker */
857*5e7646d2SAndroid Build Coastguard Worker
858*5e7646d2SAndroid Build Coastguard Worker if (a->current >= 0)
859*5e7646d2SAndroid Build Coastguard Worker a->current --;
860*5e7646d2SAndroid Build Coastguard Worker
861*5e7646d2SAndroid Build Coastguard Worker return (cupsArrayCurrent(a));
862*5e7646d2SAndroid Build Coastguard Worker }
863*5e7646d2SAndroid Build Coastguard Worker
864*5e7646d2SAndroid Build Coastguard Worker
865*5e7646d2SAndroid Build Coastguard Worker /*
866*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayRemove()' - Remove an element from the array.
867*5e7646d2SAndroid Build Coastguard Worker *
868*5e7646d2SAndroid Build Coastguard Worker * If more than one element matches "e", only the first matching element is
869*5e7646d2SAndroid Build Coastguard Worker * removed.
870*5e7646d2SAndroid Build Coastguard Worker *
871*5e7646d2SAndroid Build Coastguard Worker * The caller is responsible for freeing the memory used by the
872*5e7646d2SAndroid Build Coastguard Worker * removed element.
873*5e7646d2SAndroid Build Coastguard Worker *
874*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
875*5e7646d2SAndroid Build Coastguard Worker */
876*5e7646d2SAndroid Build Coastguard Worker
877*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
cupsArrayRemove(cups_array_t * a,void * e)878*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(cups_array_t *a, /* I - Array */
879*5e7646d2SAndroid Build Coastguard Worker void *e) /* I - Element */
880*5e7646d2SAndroid Build Coastguard Worker {
881*5e7646d2SAndroid Build Coastguard Worker ssize_t i, /* Looping var */
882*5e7646d2SAndroid Build Coastguard Worker current; /* Current element */
883*5e7646d2SAndroid Build Coastguard Worker int diff; /* Difference */
884*5e7646d2SAndroid Build Coastguard Worker
885*5e7646d2SAndroid Build Coastguard Worker
886*5e7646d2SAndroid Build Coastguard Worker /*
887*5e7646d2SAndroid Build Coastguard Worker * Range check input...
888*5e7646d2SAndroid Build Coastguard Worker */
889*5e7646d2SAndroid Build Coastguard Worker
890*5e7646d2SAndroid Build Coastguard Worker if (!a || !e)
891*5e7646d2SAndroid Build Coastguard Worker return (0);
892*5e7646d2SAndroid Build Coastguard Worker
893*5e7646d2SAndroid Build Coastguard Worker /*
894*5e7646d2SAndroid Build Coastguard Worker * See if the element is in the array...
895*5e7646d2SAndroid Build Coastguard Worker */
896*5e7646d2SAndroid Build Coastguard Worker
897*5e7646d2SAndroid Build Coastguard Worker if (!a->num_elements)
898*5e7646d2SAndroid Build Coastguard Worker return (0);
899*5e7646d2SAndroid Build Coastguard Worker
900*5e7646d2SAndroid Build Coastguard Worker current = cups_array_find(a, e, a->current, &diff);
901*5e7646d2SAndroid Build Coastguard Worker if (diff)
902*5e7646d2SAndroid Build Coastguard Worker return (0);
903*5e7646d2SAndroid Build Coastguard Worker
904*5e7646d2SAndroid Build Coastguard Worker /*
905*5e7646d2SAndroid Build Coastguard Worker * Yes, now remove it...
906*5e7646d2SAndroid Build Coastguard Worker */
907*5e7646d2SAndroid Build Coastguard Worker
908*5e7646d2SAndroid Build Coastguard Worker a->num_elements --;
909*5e7646d2SAndroid Build Coastguard Worker
910*5e7646d2SAndroid Build Coastguard Worker if (a->freefunc)
911*5e7646d2SAndroid Build Coastguard Worker (a->freefunc)(a->elements[current], a->data);
912*5e7646d2SAndroid Build Coastguard Worker
913*5e7646d2SAndroid Build Coastguard Worker if (current < a->num_elements)
914*5e7646d2SAndroid Build Coastguard Worker memmove(a->elements + current, a->elements + current + 1,
915*5e7646d2SAndroid Build Coastguard Worker (size_t)(a->num_elements - current) * sizeof(void *));
916*5e7646d2SAndroid Build Coastguard Worker
917*5e7646d2SAndroid Build Coastguard Worker if (current <= a->current)
918*5e7646d2SAndroid Build Coastguard Worker a->current --;
919*5e7646d2SAndroid Build Coastguard Worker
920*5e7646d2SAndroid Build Coastguard Worker if (current < a->insert)
921*5e7646d2SAndroid Build Coastguard Worker a->insert --;
922*5e7646d2SAndroid Build Coastguard Worker else if (current == a->insert)
923*5e7646d2SAndroid Build Coastguard Worker a->insert = -1;
924*5e7646d2SAndroid Build Coastguard Worker
925*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < a->num_saved; i ++)
926*5e7646d2SAndroid Build Coastguard Worker if (current <= a->saved[i])
927*5e7646d2SAndroid Build Coastguard Worker a->saved[i] --;
928*5e7646d2SAndroid Build Coastguard Worker
929*5e7646d2SAndroid Build Coastguard Worker if (a->num_elements <= 1)
930*5e7646d2SAndroid Build Coastguard Worker a->unique = 1;
931*5e7646d2SAndroid Build Coastguard Worker
932*5e7646d2SAndroid Build Coastguard Worker return (1);
933*5e7646d2SAndroid Build Coastguard Worker }
934*5e7646d2SAndroid Build Coastguard Worker
935*5e7646d2SAndroid Build Coastguard Worker
936*5e7646d2SAndroid Build Coastguard Worker /*
937*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayRestore()' - Reset the current element to the last @link cupsArraySave@.
938*5e7646d2SAndroid Build Coastguard Worker *
939*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
940*5e7646d2SAndroid Build Coastguard Worker */
941*5e7646d2SAndroid Build Coastguard Worker
942*5e7646d2SAndroid Build Coastguard Worker void * /* O - New current element */
cupsArrayRestore(cups_array_t * a)943*5e7646d2SAndroid Build Coastguard Worker cupsArrayRestore(cups_array_t *a) /* I - Array */
944*5e7646d2SAndroid Build Coastguard Worker {
945*5e7646d2SAndroid Build Coastguard Worker if (!a)
946*5e7646d2SAndroid Build Coastguard Worker return (NULL);
947*5e7646d2SAndroid Build Coastguard Worker
948*5e7646d2SAndroid Build Coastguard Worker if (a->num_saved <= 0)
949*5e7646d2SAndroid Build Coastguard Worker return (NULL);
950*5e7646d2SAndroid Build Coastguard Worker
951*5e7646d2SAndroid Build Coastguard Worker a->num_saved --;
952*5e7646d2SAndroid Build Coastguard Worker a->current = a->saved[a->num_saved];
953*5e7646d2SAndroid Build Coastguard Worker
954*5e7646d2SAndroid Build Coastguard Worker if (a->current >= 0 && a->current < a->num_elements)
955*5e7646d2SAndroid Build Coastguard Worker return (a->elements[a->current]);
956*5e7646d2SAndroid Build Coastguard Worker else
957*5e7646d2SAndroid Build Coastguard Worker return (NULL);
958*5e7646d2SAndroid Build Coastguard Worker }
959*5e7646d2SAndroid Build Coastguard Worker
960*5e7646d2SAndroid Build Coastguard Worker
961*5e7646d2SAndroid Build Coastguard Worker /*
962*5e7646d2SAndroid Build Coastguard Worker * 'cupsArraySave()' - Mark the current element for a later @link cupsArrayRestore@.
963*5e7646d2SAndroid Build Coastguard Worker *
964*5e7646d2SAndroid Build Coastguard Worker * The current element is undefined until you call @link cupsArrayFind@,
965*5e7646d2SAndroid Build Coastguard Worker * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@
966*5e7646d2SAndroid Build Coastguard Worker * to set the current element.
967*5e7646d2SAndroid Build Coastguard Worker *
968*5e7646d2SAndroid Build Coastguard Worker * The save/restore stack is guaranteed to be at least 32 elements deep.
969*5e7646d2SAndroid Build Coastguard Worker *
970*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
971*5e7646d2SAndroid Build Coastguard Worker */
972*5e7646d2SAndroid Build Coastguard Worker
973*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
cupsArraySave(cups_array_t * a)974*5e7646d2SAndroid Build Coastguard Worker cupsArraySave(cups_array_t *a) /* I - Array */
975*5e7646d2SAndroid Build Coastguard Worker {
976*5e7646d2SAndroid Build Coastguard Worker if (!a)
977*5e7646d2SAndroid Build Coastguard Worker return (0);
978*5e7646d2SAndroid Build Coastguard Worker
979*5e7646d2SAndroid Build Coastguard Worker if (a->num_saved >= _CUPS_MAXSAVE)
980*5e7646d2SAndroid Build Coastguard Worker return (0);
981*5e7646d2SAndroid Build Coastguard Worker
982*5e7646d2SAndroid Build Coastguard Worker a->saved[a->num_saved] = a->current;
983*5e7646d2SAndroid Build Coastguard Worker a->num_saved ++;
984*5e7646d2SAndroid Build Coastguard Worker
985*5e7646d2SAndroid Build Coastguard Worker return (1);
986*5e7646d2SAndroid Build Coastguard Worker }
987*5e7646d2SAndroid Build Coastguard Worker
988*5e7646d2SAndroid Build Coastguard Worker
989*5e7646d2SAndroid Build Coastguard Worker /*
990*5e7646d2SAndroid Build Coastguard Worker * 'cupsArrayUserData()' - Return the user data for an array.
991*5e7646d2SAndroid Build Coastguard Worker *
992*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
993*5e7646d2SAndroid Build Coastguard Worker */
994*5e7646d2SAndroid Build Coastguard Worker
995*5e7646d2SAndroid Build Coastguard Worker void * /* O - User data */
cupsArrayUserData(cups_array_t * a)996*5e7646d2SAndroid Build Coastguard Worker cupsArrayUserData(cups_array_t *a) /* I - Array */
997*5e7646d2SAndroid Build Coastguard Worker {
998*5e7646d2SAndroid Build Coastguard Worker if (a)
999*5e7646d2SAndroid Build Coastguard Worker return (a->data);
1000*5e7646d2SAndroid Build Coastguard Worker else
1001*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1002*5e7646d2SAndroid Build Coastguard Worker }
1003*5e7646d2SAndroid Build Coastguard Worker
1004*5e7646d2SAndroid Build Coastguard Worker
1005*5e7646d2SAndroid Build Coastguard Worker /*
1006*5e7646d2SAndroid Build Coastguard Worker * 'cups_array_add()' - Insert or append an element to the array.
1007*5e7646d2SAndroid Build Coastguard Worker *
1008*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1009*5e7646d2SAndroid Build Coastguard Worker */
1010*5e7646d2SAndroid Build Coastguard Worker
1011*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on success, 0 on failure */
cups_array_add(cups_array_t * a,void * e,int insert)1012*5e7646d2SAndroid Build Coastguard Worker cups_array_add(cups_array_t *a, /* I - Array */
1013*5e7646d2SAndroid Build Coastguard Worker void *e, /* I - Element to add */
1014*5e7646d2SAndroid Build Coastguard Worker int insert) /* I - 1 = insert, 0 = append */
1015*5e7646d2SAndroid Build Coastguard Worker {
1016*5e7646d2SAndroid Build Coastguard Worker int i, /* Looping var */
1017*5e7646d2SAndroid Build Coastguard Worker current; /* Current element */
1018*5e7646d2SAndroid Build Coastguard Worker int diff; /* Comparison with current element */
1019*5e7646d2SAndroid Build Coastguard Worker
1020*5e7646d2SAndroid Build Coastguard Worker
1021*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7cups_array_add(a=%p, e=%p, insert=%d)", (void *)a, e, insert));
1022*5e7646d2SAndroid Build Coastguard Worker
1023*5e7646d2SAndroid Build Coastguard Worker /*
1024*5e7646d2SAndroid Build Coastguard Worker * Verify we have room for the new element...
1025*5e7646d2SAndroid Build Coastguard Worker */
1026*5e7646d2SAndroid Build Coastguard Worker
1027*5e7646d2SAndroid Build Coastguard Worker if (a->num_elements >= a->alloc_elements)
1028*5e7646d2SAndroid Build Coastguard Worker {
1029*5e7646d2SAndroid Build Coastguard Worker /*
1030*5e7646d2SAndroid Build Coastguard Worker * Allocate additional elements; start with 16 elements, then
1031*5e7646d2SAndroid Build Coastguard Worker * double the size until 1024 elements, then add 1024 elements
1032*5e7646d2SAndroid Build Coastguard Worker * thereafter...
1033*5e7646d2SAndroid Build Coastguard Worker */
1034*5e7646d2SAndroid Build Coastguard Worker
1035*5e7646d2SAndroid Build Coastguard Worker void **temp; /* New array elements */
1036*5e7646d2SAndroid Build Coastguard Worker int count; /* New allocation count */
1037*5e7646d2SAndroid Build Coastguard Worker
1038*5e7646d2SAndroid Build Coastguard Worker
1039*5e7646d2SAndroid Build Coastguard Worker if (a->alloc_elements == 0)
1040*5e7646d2SAndroid Build Coastguard Worker {
1041*5e7646d2SAndroid Build Coastguard Worker count = 16;
1042*5e7646d2SAndroid Build Coastguard Worker temp = malloc((size_t)count * sizeof(void *));
1043*5e7646d2SAndroid Build Coastguard Worker }
1044*5e7646d2SAndroid Build Coastguard Worker else
1045*5e7646d2SAndroid Build Coastguard Worker {
1046*5e7646d2SAndroid Build Coastguard Worker if (a->alloc_elements < 1024)
1047*5e7646d2SAndroid Build Coastguard Worker count = a->alloc_elements * 2;
1048*5e7646d2SAndroid Build Coastguard Worker else
1049*5e7646d2SAndroid Build Coastguard Worker count = a->alloc_elements + 1024;
1050*5e7646d2SAndroid Build Coastguard Worker
1051*5e7646d2SAndroid Build Coastguard Worker temp = realloc(a->elements, (size_t)count * sizeof(void *));
1052*5e7646d2SAndroid Build Coastguard Worker }
1053*5e7646d2SAndroid Build Coastguard Worker
1054*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_array_add: count=" CUPS_LLFMT, CUPS_LLCAST count));
1055*5e7646d2SAndroid Build Coastguard Worker
1056*5e7646d2SAndroid Build Coastguard Worker if (!temp)
1057*5e7646d2SAndroid Build Coastguard Worker {
1058*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_array_add: allocation failed, returning 0");
1059*5e7646d2SAndroid Build Coastguard Worker return (0);
1060*5e7646d2SAndroid Build Coastguard Worker }
1061*5e7646d2SAndroid Build Coastguard Worker
1062*5e7646d2SAndroid Build Coastguard Worker a->alloc_elements = count;
1063*5e7646d2SAndroid Build Coastguard Worker a->elements = temp;
1064*5e7646d2SAndroid Build Coastguard Worker }
1065*5e7646d2SAndroid Build Coastguard Worker
1066*5e7646d2SAndroid Build Coastguard Worker /*
1067*5e7646d2SAndroid Build Coastguard Worker * Find the insertion point for the new element; if there is no
1068*5e7646d2SAndroid Build Coastguard Worker * compare function or elements, just add it to the beginning or end...
1069*5e7646d2SAndroid Build Coastguard Worker */
1070*5e7646d2SAndroid Build Coastguard Worker
1071*5e7646d2SAndroid Build Coastguard Worker if (!a->num_elements || !a->compare)
1072*5e7646d2SAndroid Build Coastguard Worker {
1073*5e7646d2SAndroid Build Coastguard Worker /*
1074*5e7646d2SAndroid Build Coastguard Worker * No elements or comparison function, insert/append as needed...
1075*5e7646d2SAndroid Build Coastguard Worker */
1076*5e7646d2SAndroid Build Coastguard Worker
1077*5e7646d2SAndroid Build Coastguard Worker if (insert)
1078*5e7646d2SAndroid Build Coastguard Worker current = 0; /* Insert at beginning */
1079*5e7646d2SAndroid Build Coastguard Worker else
1080*5e7646d2SAndroid Build Coastguard Worker current = a->num_elements; /* Append to the end */
1081*5e7646d2SAndroid Build Coastguard Worker }
1082*5e7646d2SAndroid Build Coastguard Worker else
1083*5e7646d2SAndroid Build Coastguard Worker {
1084*5e7646d2SAndroid Build Coastguard Worker /*
1085*5e7646d2SAndroid Build Coastguard Worker * Do a binary search for the insertion point...
1086*5e7646d2SAndroid Build Coastguard Worker */
1087*5e7646d2SAndroid Build Coastguard Worker
1088*5e7646d2SAndroid Build Coastguard Worker current = cups_array_find(a, e, a->insert, &diff);
1089*5e7646d2SAndroid Build Coastguard Worker
1090*5e7646d2SAndroid Build Coastguard Worker if (diff > 0)
1091*5e7646d2SAndroid Build Coastguard Worker {
1092*5e7646d2SAndroid Build Coastguard Worker /*
1093*5e7646d2SAndroid Build Coastguard Worker * Insert after the current element...
1094*5e7646d2SAndroid Build Coastguard Worker */
1095*5e7646d2SAndroid Build Coastguard Worker
1096*5e7646d2SAndroid Build Coastguard Worker current ++;
1097*5e7646d2SAndroid Build Coastguard Worker }
1098*5e7646d2SAndroid Build Coastguard Worker else if (!diff)
1099*5e7646d2SAndroid Build Coastguard Worker {
1100*5e7646d2SAndroid Build Coastguard Worker /*
1101*5e7646d2SAndroid Build Coastguard Worker * Compared equal, make sure we add to the begining or end of
1102*5e7646d2SAndroid Build Coastguard Worker * the current run of equal elements...
1103*5e7646d2SAndroid Build Coastguard Worker */
1104*5e7646d2SAndroid Build Coastguard Worker
1105*5e7646d2SAndroid Build Coastguard Worker a->unique = 0;
1106*5e7646d2SAndroid Build Coastguard Worker
1107*5e7646d2SAndroid Build Coastguard Worker if (insert)
1108*5e7646d2SAndroid Build Coastguard Worker {
1109*5e7646d2SAndroid Build Coastguard Worker /*
1110*5e7646d2SAndroid Build Coastguard Worker * Insert at beginning of run...
1111*5e7646d2SAndroid Build Coastguard Worker */
1112*5e7646d2SAndroid Build Coastguard Worker
1113*5e7646d2SAndroid Build Coastguard Worker while (current > 0 && !(*(a->compare))(e, a->elements[current - 1],
1114*5e7646d2SAndroid Build Coastguard Worker a->data))
1115*5e7646d2SAndroid Build Coastguard Worker current --;
1116*5e7646d2SAndroid Build Coastguard Worker }
1117*5e7646d2SAndroid Build Coastguard Worker else
1118*5e7646d2SAndroid Build Coastguard Worker {
1119*5e7646d2SAndroid Build Coastguard Worker /*
1120*5e7646d2SAndroid Build Coastguard Worker * Append at end of run...
1121*5e7646d2SAndroid Build Coastguard Worker */
1122*5e7646d2SAndroid Build Coastguard Worker
1123*5e7646d2SAndroid Build Coastguard Worker do
1124*5e7646d2SAndroid Build Coastguard Worker {
1125*5e7646d2SAndroid Build Coastguard Worker current ++;
1126*5e7646d2SAndroid Build Coastguard Worker }
1127*5e7646d2SAndroid Build Coastguard Worker while (current < a->num_elements &&
1128*5e7646d2SAndroid Build Coastguard Worker !(*(a->compare))(e, a->elements[current], a->data));
1129*5e7646d2SAndroid Build Coastguard Worker }
1130*5e7646d2SAndroid Build Coastguard Worker }
1131*5e7646d2SAndroid Build Coastguard Worker }
1132*5e7646d2SAndroid Build Coastguard Worker
1133*5e7646d2SAndroid Build Coastguard Worker /*
1134*5e7646d2SAndroid Build Coastguard Worker * Insert or append the element...
1135*5e7646d2SAndroid Build Coastguard Worker */
1136*5e7646d2SAndroid Build Coastguard Worker
1137*5e7646d2SAndroid Build Coastguard Worker if (current < a->num_elements)
1138*5e7646d2SAndroid Build Coastguard Worker {
1139*5e7646d2SAndroid Build Coastguard Worker /*
1140*5e7646d2SAndroid Build Coastguard Worker * Shift other elements to the right...
1141*5e7646d2SAndroid Build Coastguard Worker */
1142*5e7646d2SAndroid Build Coastguard Worker
1143*5e7646d2SAndroid Build Coastguard Worker memmove(a->elements + current + 1, a->elements + current,
1144*5e7646d2SAndroid Build Coastguard Worker (size_t)(a->num_elements - current) * sizeof(void *));
1145*5e7646d2SAndroid Build Coastguard Worker
1146*5e7646d2SAndroid Build Coastguard Worker if (a->current >= current)
1147*5e7646d2SAndroid Build Coastguard Worker a->current ++;
1148*5e7646d2SAndroid Build Coastguard Worker
1149*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < a->num_saved; i ++)
1150*5e7646d2SAndroid Build Coastguard Worker if (a->saved[i] >= current)
1151*5e7646d2SAndroid Build Coastguard Worker a->saved[i] ++;
1152*5e7646d2SAndroid Build Coastguard Worker
1153*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_array_add: insert element at index " CUPS_LLFMT, CUPS_LLCAST current));
1154*5e7646d2SAndroid Build Coastguard Worker }
1155*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
1156*5e7646d2SAndroid Build Coastguard Worker else
1157*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_array_add: append element at " CUPS_LLFMT, CUPS_LLCAST current));
1158*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
1159*5e7646d2SAndroid Build Coastguard Worker
1160*5e7646d2SAndroid Build Coastguard Worker if (a->copyfunc)
1161*5e7646d2SAndroid Build Coastguard Worker {
1162*5e7646d2SAndroid Build Coastguard Worker if ((a->elements[current] = (a->copyfunc)(e, a->data)) == NULL)
1163*5e7646d2SAndroid Build Coastguard Worker {
1164*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("8cups_array_add: Copy function returned NULL, returning 0");
1165*5e7646d2SAndroid Build Coastguard Worker return (0);
1166*5e7646d2SAndroid Build Coastguard Worker }
1167*5e7646d2SAndroid Build Coastguard Worker }
1168*5e7646d2SAndroid Build Coastguard Worker else
1169*5e7646d2SAndroid Build Coastguard Worker a->elements[current] = e;
1170*5e7646d2SAndroid Build Coastguard Worker
1171*5e7646d2SAndroid Build Coastguard Worker a->num_elements ++;
1172*5e7646d2SAndroid Build Coastguard Worker a->insert = current;
1173*5e7646d2SAndroid Build Coastguard Worker
1174*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
1175*5e7646d2SAndroid Build Coastguard Worker for (current = 0; current < a->num_elements; current ++)
1176*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_array_add: a->elements[" CUPS_LLFMT "]=%p", CUPS_LLCAST current, a->elements[current]));
1177*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
1178*5e7646d2SAndroid Build Coastguard Worker
1179*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_array_add: returning 1");
1180*5e7646d2SAndroid Build Coastguard Worker
1181*5e7646d2SAndroid Build Coastguard Worker return (1);
1182*5e7646d2SAndroid Build Coastguard Worker }
1183*5e7646d2SAndroid Build Coastguard Worker
1184*5e7646d2SAndroid Build Coastguard Worker
1185*5e7646d2SAndroid Build Coastguard Worker /*
1186*5e7646d2SAndroid Build Coastguard Worker * 'cups_array_find()' - Find an element in the array.
1187*5e7646d2SAndroid Build Coastguard Worker */
1188*5e7646d2SAndroid Build Coastguard Worker
1189*5e7646d2SAndroid Build Coastguard Worker static int /* O - Index of match */
cups_array_find(cups_array_t * a,void * e,int prev,int * rdiff)1190*5e7646d2SAndroid Build Coastguard Worker cups_array_find(cups_array_t *a, /* I - Array */
1191*5e7646d2SAndroid Build Coastguard Worker void *e, /* I - Element */
1192*5e7646d2SAndroid Build Coastguard Worker int prev, /* I - Previous index */
1193*5e7646d2SAndroid Build Coastguard Worker int *rdiff) /* O - Difference of match */
1194*5e7646d2SAndroid Build Coastguard Worker {
1195*5e7646d2SAndroid Build Coastguard Worker int left, /* Left side of search */
1196*5e7646d2SAndroid Build Coastguard Worker right, /* Right side of search */
1197*5e7646d2SAndroid Build Coastguard Worker current, /* Current element */
1198*5e7646d2SAndroid Build Coastguard Worker diff; /* Comparison with current element */
1199*5e7646d2SAndroid Build Coastguard Worker
1200*5e7646d2SAndroid Build Coastguard Worker
1201*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7cups_array_find(a=%p, e=%p, prev=%d, rdiff=%p)", (void *)a, e, prev, (void *)rdiff));
1202*5e7646d2SAndroid Build Coastguard Worker
1203*5e7646d2SAndroid Build Coastguard Worker if (a->compare)
1204*5e7646d2SAndroid Build Coastguard Worker {
1205*5e7646d2SAndroid Build Coastguard Worker /*
1206*5e7646d2SAndroid Build Coastguard Worker * Do a binary search for the element...
1207*5e7646d2SAndroid Build Coastguard Worker */
1208*5e7646d2SAndroid Build Coastguard Worker
1209*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_array_find: binary search");
1210*5e7646d2SAndroid Build Coastguard Worker
1211*5e7646d2SAndroid Build Coastguard Worker if (prev >= 0 && prev < a->num_elements)
1212*5e7646d2SAndroid Build Coastguard Worker {
1213*5e7646d2SAndroid Build Coastguard Worker /*
1214*5e7646d2SAndroid Build Coastguard Worker * Start search on either side of previous...
1215*5e7646d2SAndroid Build Coastguard Worker */
1216*5e7646d2SAndroid Build Coastguard Worker
1217*5e7646d2SAndroid Build Coastguard Worker if ((diff = (*(a->compare))(e, a->elements[prev], a->data)) == 0 ||
1218*5e7646d2SAndroid Build Coastguard Worker (diff < 0 && prev == 0) ||
1219*5e7646d2SAndroid Build Coastguard Worker (diff > 0 && prev == (a->num_elements - 1)))
1220*5e7646d2SAndroid Build Coastguard Worker {
1221*5e7646d2SAndroid Build Coastguard Worker /*
1222*5e7646d2SAndroid Build Coastguard Worker * Exact or edge match, return it!
1223*5e7646d2SAndroid Build Coastguard Worker */
1224*5e7646d2SAndroid Build Coastguard Worker
1225*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_array_find: Returning %d, diff=%d", prev, diff));
1226*5e7646d2SAndroid Build Coastguard Worker
1227*5e7646d2SAndroid Build Coastguard Worker *rdiff = diff;
1228*5e7646d2SAndroid Build Coastguard Worker
1229*5e7646d2SAndroid Build Coastguard Worker return (prev);
1230*5e7646d2SAndroid Build Coastguard Worker }
1231*5e7646d2SAndroid Build Coastguard Worker else if (diff < 0)
1232*5e7646d2SAndroid Build Coastguard Worker {
1233*5e7646d2SAndroid Build Coastguard Worker /*
1234*5e7646d2SAndroid Build Coastguard Worker * Start with previous on right side...
1235*5e7646d2SAndroid Build Coastguard Worker */
1236*5e7646d2SAndroid Build Coastguard Worker
1237*5e7646d2SAndroid Build Coastguard Worker left = 0;
1238*5e7646d2SAndroid Build Coastguard Worker right = prev;
1239*5e7646d2SAndroid Build Coastguard Worker }
1240*5e7646d2SAndroid Build Coastguard Worker else
1241*5e7646d2SAndroid Build Coastguard Worker {
1242*5e7646d2SAndroid Build Coastguard Worker /*
1243*5e7646d2SAndroid Build Coastguard Worker * Start wih previous on left side...
1244*5e7646d2SAndroid Build Coastguard Worker */
1245*5e7646d2SAndroid Build Coastguard Worker
1246*5e7646d2SAndroid Build Coastguard Worker left = prev;
1247*5e7646d2SAndroid Build Coastguard Worker right = a->num_elements - 1;
1248*5e7646d2SAndroid Build Coastguard Worker }
1249*5e7646d2SAndroid Build Coastguard Worker }
1250*5e7646d2SAndroid Build Coastguard Worker else
1251*5e7646d2SAndroid Build Coastguard Worker {
1252*5e7646d2SAndroid Build Coastguard Worker /*
1253*5e7646d2SAndroid Build Coastguard Worker * Start search in the middle...
1254*5e7646d2SAndroid Build Coastguard Worker */
1255*5e7646d2SAndroid Build Coastguard Worker
1256*5e7646d2SAndroid Build Coastguard Worker left = 0;
1257*5e7646d2SAndroid Build Coastguard Worker right = a->num_elements - 1;
1258*5e7646d2SAndroid Build Coastguard Worker }
1259*5e7646d2SAndroid Build Coastguard Worker
1260*5e7646d2SAndroid Build Coastguard Worker do
1261*5e7646d2SAndroid Build Coastguard Worker {
1262*5e7646d2SAndroid Build Coastguard Worker current = (left + right) / 2;
1263*5e7646d2SAndroid Build Coastguard Worker diff = (*(a->compare))(e, a->elements[current], a->data);
1264*5e7646d2SAndroid Build Coastguard Worker
1265*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_array_find: left=%d, right=%d, current=%d, diff=%d",
1266*5e7646d2SAndroid Build Coastguard Worker left, right, current, diff));
1267*5e7646d2SAndroid Build Coastguard Worker
1268*5e7646d2SAndroid Build Coastguard Worker if (diff == 0)
1269*5e7646d2SAndroid Build Coastguard Worker break;
1270*5e7646d2SAndroid Build Coastguard Worker else if (diff < 0)
1271*5e7646d2SAndroid Build Coastguard Worker right = current;
1272*5e7646d2SAndroid Build Coastguard Worker else
1273*5e7646d2SAndroid Build Coastguard Worker left = current;
1274*5e7646d2SAndroid Build Coastguard Worker }
1275*5e7646d2SAndroid Build Coastguard Worker while ((right - left) > 1);
1276*5e7646d2SAndroid Build Coastguard Worker
1277*5e7646d2SAndroid Build Coastguard Worker if (diff != 0)
1278*5e7646d2SAndroid Build Coastguard Worker {
1279*5e7646d2SAndroid Build Coastguard Worker /*
1280*5e7646d2SAndroid Build Coastguard Worker * Check the last 1 or 2 elements...
1281*5e7646d2SAndroid Build Coastguard Worker */
1282*5e7646d2SAndroid Build Coastguard Worker
1283*5e7646d2SAndroid Build Coastguard Worker if ((diff = (*(a->compare))(e, a->elements[left], a->data)) <= 0)
1284*5e7646d2SAndroid Build Coastguard Worker current = left;
1285*5e7646d2SAndroid Build Coastguard Worker else
1286*5e7646d2SAndroid Build Coastguard Worker {
1287*5e7646d2SAndroid Build Coastguard Worker diff = (*(a->compare))(e, a->elements[right], a->data);
1288*5e7646d2SAndroid Build Coastguard Worker current = right;
1289*5e7646d2SAndroid Build Coastguard Worker }
1290*5e7646d2SAndroid Build Coastguard Worker }
1291*5e7646d2SAndroid Build Coastguard Worker }
1292*5e7646d2SAndroid Build Coastguard Worker else
1293*5e7646d2SAndroid Build Coastguard Worker {
1294*5e7646d2SAndroid Build Coastguard Worker /*
1295*5e7646d2SAndroid Build Coastguard Worker * Do a linear pointer search...
1296*5e7646d2SAndroid Build Coastguard Worker */
1297*5e7646d2SAndroid Build Coastguard Worker
1298*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_array_find: linear search");
1299*5e7646d2SAndroid Build Coastguard Worker
1300*5e7646d2SAndroid Build Coastguard Worker diff = 1;
1301*5e7646d2SAndroid Build Coastguard Worker
1302*5e7646d2SAndroid Build Coastguard Worker for (current = 0; current < a->num_elements; current ++)
1303*5e7646d2SAndroid Build Coastguard Worker if (a->elements[current] == e)
1304*5e7646d2SAndroid Build Coastguard Worker {
1305*5e7646d2SAndroid Build Coastguard Worker diff = 0;
1306*5e7646d2SAndroid Build Coastguard Worker break;
1307*5e7646d2SAndroid Build Coastguard Worker }
1308*5e7646d2SAndroid Build Coastguard Worker }
1309*5e7646d2SAndroid Build Coastguard Worker
1310*5e7646d2SAndroid Build Coastguard Worker /*
1311*5e7646d2SAndroid Build Coastguard Worker * Return the closest element and the difference...
1312*5e7646d2SAndroid Build Coastguard Worker */
1313*5e7646d2SAndroid Build Coastguard Worker
1314*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("8cups_array_find: Returning %d, diff=%d", current, diff));
1315*5e7646d2SAndroid Build Coastguard Worker
1316*5e7646d2SAndroid Build Coastguard Worker *rdiff = diff;
1317*5e7646d2SAndroid Build Coastguard Worker
1318*5e7646d2SAndroid Build Coastguard Worker return (current);
1319*5e7646d2SAndroid Build Coastguard Worker }
1320