]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/array.c
Merge changes from CUPS 1.4svn-r7255.
[thirdparty/cups.git] / cups / array.c
CommitLineData
ef416fc2 1/*
bc44d920 2 * "$Id: array.c 6649 2007-07-11 21:46:42Z mike $"
ef416fc2 3 *
4 * Sorted array routines for the Common UNIX Printing System (CUPS).
5 *
bc44d920 6 * Copyright 2007 by Apple Inc.
b94498cf 7 * Copyright 1997-2007 by Easy Software Products.
ef416fc2 8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
f7deaa1a 19 * cupsArrayAdd() - Add an element to the array.
20 * cupsArrayClear() - Clear the array.
21 * cupsArrayCount() - Get the number of elements in the array.
22 * cupsArrayCurrent() - Return the current element in the array.
23 * cupsArrayDelete() - Free all memory used by the array.
24 * cupsArrayDup() - Duplicate the array.
25 * cupsArrayFind() - Find an element in the array.
26 * cupsArrayFirst() - Get the first element in the array.
27 * cupsArrayGetIndex() - Get the index of the current element.
28 * cupsArrayGetInsert() - Get the index of the last inserted element.
29 * cupsArrayIndex() - Get the N-th element in the array.
30 * cupsArrayInsert() - Insert an element in the array.
31 * cupsArrayLast() - Get the last element in the array.
32 * cupsArrayNew() - Create a new array.
33 * cupsArrayNext() - Get the next element in the array.
34 * cupsArrayPrev() - Get the previous element in the array.
35 * cupsArrayRemove() - Remove an element from the array.
36 * cupsArrayRestore() - Reset the current element to the last cupsArraySave.
37 * cupsArraySave() - Mark the current element for a later
38 * cupsArrayRestore.
39 * cupsArrayUserData() - Return the user data for an array.
40 * cups_array_add() - Insert or append an element to the array...
41 * cups_array_find() - Find an element in the array...
ef416fc2 42 */
43
44/*
45 * Include necessary headers...
46 */
47
48#include "array.h"
49#include "string.h"
50#include "debug.h"
51
52
53/*
54 * Limits...
55 */
56
57#define _CUPS_MAXSAVE 32 /**** Maximum number of saves ****/
58
59
60/*
61 * Types and structures...
62 */
63
64struct _cups_array_s /**** CUPS array structure ****/
65{
66 /*
67 * The current implementation uses an insertion sort into an array of
68 * sorted pointers. We leave the array type private/opaque so that we
69 * can change the underlying implementation without affecting the users
70 * of this API.
71 */
72
73 int num_elements, /* Number of array elements */
74 alloc_elements, /* Allocated array elements */
75 current, /* Current element */
76 insert, /* Last inserted element */
bd7854cb 77 unique, /* Are all elements unique? */
ef416fc2 78 num_saved, /* Number of saved elements */
79 saved[_CUPS_MAXSAVE];
80 /* Saved elements */
81 void **elements; /* Array elements */
82 cups_array_func_t compare; /* Element comparison function */
83 void *data; /* User data passed to compare */
b94498cf 84 cups_ahash_func_t hashfunc; /* Hash function */
85 int hashsize, /* Size of hash */
86 *hash; /* Hash array */
ef416fc2 87};
88
89
90/*
91 * Local functions...
92 */
93
bd7854cb 94static int cups_array_add(cups_array_t *a, void *e, int insert);
95static int cups_array_find(cups_array_t *a, void *e, int prev, int *rdiff);
ef416fc2 96
97
98/*
99 * 'cupsArrayAdd()' - Add an element to the array.
bd7854cb 100 *
101 * When adding an element to a sorted array, non-unique elements are
102 * appended at the end of the run. For unsorted arrays, the element
103 * is inserted at the end of the array.
ef416fc2 104 */
105
106int /* O - 1 on success, 0 on failure */
107cupsArrayAdd(cups_array_t *a, /* I - Array */
108 void *e) /* I - Element */
109{
ef416fc2 110 DEBUG_printf(("cupsArrayAdd(a=%p, e=%p)\n", a, e));
111
112 /*
113 * Range check input...
114 */
115
116 if (!a || !e)
117 {
118 DEBUG_puts("cupsArrayAdd: returning 0");
119 return (0);
120 }
121
122 /*
bd7854cb 123 * Append the element...
ef416fc2 124 */
125
bd7854cb 126 return (cups_array_add(a, e, 0));
ef416fc2 127}
128
129
130/*
131 * 'cupsArrayClear()' - Clear the array.
132 */
133
134void
135cupsArrayClear(cups_array_t *a) /* I - Array */
136{
137 /*
138 * Range check input...
139 */
140
141 if (!a)
142 return;
143
144 /*
145 * Set the number of elements to 0; we don't actually free the memory
146 * here - that is done in cupsArrayDelete()...
147 */
148
149 a->num_elements = 0;
150 a->current = -1;
151 a->insert = -1;
bd7854cb 152 a->unique = 1;
ef416fc2 153 a->num_saved = 0;
154}
155
156
157/*
158 * 'cupsArrayCount()' - Get the number of elements in the array.
159 */
160
161int /* O - Number of elements */
162cupsArrayCount(cups_array_t *a) /* I - Array */
163{
164 /*
165 * Range check input...
166 */
167
168 if (!a)
169 return (0);
170
171 /*
172 * Return the number of elements...
173 */
174
175 return (a->num_elements);
176}
177
178
179/*
180 * 'cupsArrayCurrent()' - Return the current element in the array.
181 */
182
183void * /* O - Element */
184cupsArrayCurrent(cups_array_t *a) /* I - Array */
185{
186 /*
187 * Range check input...
188 */
189
190 if (!a)
191 return (NULL);
192
193 /*
194 * Return the current element...
195 */
196
197 if (a->current >= 0 && a->current < a->num_elements)
198 return (a->elements[a->current]);
199 else
200 return (NULL);
201}
202
203
204/*
205 * 'cupsArrayDelete()' - Free all memory used by the array.
206 */
207
208void
209cupsArrayDelete(cups_array_t *a) /* I - Array */
210{
211 /*
212 * Range check input...
213 */
214
215 if (!a)
216 return;
217
218 /*
219 * Free the array of element pointers - the caller is responsible
220 * for freeing the elements themselves...
221 */
222
223 if (a->alloc_elements)
224 free(a->elements);
225
b94498cf 226 if (a->hashsize)
227 free(a->hash);
228
ef416fc2 229 free(a);
230}
231
232
233/*
234 * 'cupsArrayDup()' - Duplicate the array.
235 */
236
237cups_array_t * /* O - Duplicate array */
238cupsArrayDup(cups_array_t *a) /* I - Array */
239{
240 cups_array_t *da; /* Duplicate array */
241
242
243 /*
244 * Range check input...
245 */
246
247 if (!a)
248 return (NULL);
249
250 /*
251 * Allocate memory for the array...
252 */
253
254 da = calloc(1, sizeof(cups_array_t));
255 if (!da)
256 return (NULL);
257
258 da->compare = a->compare;
259 da->data = a->data;
260 da->current = a->current;
261 da->insert = a->insert;
bd7854cb 262 da->unique = a->unique;
ef416fc2 263 da->num_saved = a->num_saved;
264
265 memcpy(da->saved, a->saved, sizeof(a->saved));
266
267 if (a->num_elements)
268 {
269 /*
270 * Allocate memory for the elements...
271 */
272
273 da->elements = malloc(a->num_elements * sizeof(void *));
274 if (!da->elements)
275 {
276 free(da);
277 return (NULL);
278 }
279
280 /*
281 * Copy the element pointers...
282 */
283
284 memcpy(da->elements, a->elements, a->num_elements * sizeof(void *));
285 da->num_elements = a->num_elements;
286 da->alloc_elements = a->num_elements;
287 }
288
289 /*
290 * Return the new array...
291 */
292
293 return (da);
294}
295
296
297/*
298 * 'cupsArrayFind()' - Find an element in the array.
299 */
300
301void * /* O - Element found or NULL */
302cupsArrayFind(cups_array_t *a, /* I - Array */
303 void *e) /* I - Element */
304{
305 int current, /* Current element */
b94498cf 306 diff, /* Difference */
307 hash; /* Hash index */
ef416fc2 308
309
310 /*
311 * Range check input...
312 */
313
314 if (!a || !e)
315 return (NULL);
316
317 /*
318 * See if we have any elements...
319 */
320
321 if (!a->num_elements)
322 return (NULL);
323
324 /*
325 * Yes, look for a match...
326 */
327
b94498cf 328 if (a->hash)
329 {
330 hash = (*(a->hashfunc))(e, a->data);
331
332 if (hash < 0 || hash >= a->hashsize)
333 {
334 current = a->current;
335 hash = -1;
336 }
337 else
338 {
339 current = a->hash[hash];
340
341 if (current < 0 || current >= a->num_elements)
342 current = a->current;
343 }
344 }
345 else
346 {
347 current = a->current;
348 hash = -1;
349 }
350
351 current = cups_array_find(a, e, current, &diff);
ef416fc2 352 if (!diff)
353 {
354 /*
bd7854cb 355 * Found a match! If the array does not contain unique values, find
356 * the first element that is the same...
ef416fc2 357 */
358
bd7854cb 359 if (!a->unique && a->compare)
360 {
361 /*
362 * The array is not unique, find the first match...
363 */
364
365 while (current > 0 && !(*(a->compare))(e, a->elements[current - 1],
366 a->data))
367 current --;
368 }
369
ef416fc2 370 a->current = current;
371
b94498cf 372 if (hash >= 0)
373 a->hash[hash] = current;
374
ef416fc2 375 return (a->elements[current]);
376 }
377 else
378 {
379 /*
380 * No match...
381 */
382
383 a->current = -1;
384
385 return (NULL);
386 }
387}
388
389
390/*
391 * 'cupsArrayFirst()' - Get the first element in the array.
392 */
393
394void * /* O - First element or NULL */
395cupsArrayFirst(cups_array_t *a) /* I - Array */
396{
397 /*
398 * Range check input...
399 */
400
401 if (!a)
402 return (NULL);
403
404 /*
405 * Return the first element...
406 */
407
408 a->current = 0;
409
410 return (cupsArrayCurrent(a));
411}
412
413
f7deaa1a 414/*
415 * 'cupsArrayGetIndex()' - Get the index of the current element.
416 *
417 * @since CUPS 1.3@
418 */
419
420int /* O - Index of the current element */
421cupsArrayGetIndex(cups_array_t *a) /* I - Array */
422{
423 if (!a)
424 return (-1);
425 else
426 return (a->current);
427}
428
429
430/*
431 * 'cupsArrayGetInsert()' - Get the index of the last inserted element.
432 *
433 * @since CUPS 1.3@
434 */
435
436int /* O - Index of the last inserted element */
437cupsArrayGetInsert(cups_array_t *a) /* I - Array */
438{
439 if (!a)
440 return (-1);
441 else
442 return (a->insert);
443}
444
445
ef416fc2 446/*
447 * 'cupsArrayIndex()' - Get the N-th element in the array.
448 */
449
450void * /* O - N-th element or NULL */
451cupsArrayIndex(cups_array_t *a, /* I - Array */
452 int n) /* I - Index into array, starting at 0 */
453{
454 if (!a)
455 return (NULL);
456
457 a->current = n;
458
459 return (cupsArrayCurrent(a));
460}
461
462
fa73b229 463/*
464 * 'cupsArrayInsert()' - Insert an element in the array.
465 *
bd7854cb 466 * When inserting an element in a sorted array, non-unique elements are
467 * inserted at the beginning of the run. For unsorted arrays, the element
468 * is inserted at the beginning of the array.
fa73b229 469 */
470
471int /* O - 0 on failure, 1 on success */
472cupsArrayInsert(cups_array_t *a, /* I - Array */
473 void *e) /* I - Element */
474{
fa73b229 475 DEBUG_printf(("cupsArrayInsert(a=%p, e=%p)\n", a, e));
476
477 /*
478 * Range check input...
479 */
480
481 if (!a || !e)
482 {
483 DEBUG_puts("cupsArrayInsert: returning 0");
484 return (0);
485 }
486
fa73b229 487 /*
488 * Insert the element...
489 */
490
bd7854cb 491 return (cups_array_add(a, e, 1));
fa73b229 492}
493
494
ef416fc2 495/*
496 * 'cupsArrayLast()' - Get the last element in the array.
497 */
498
499void * /* O - Last element or NULL */
500cupsArrayLast(cups_array_t *a) /* I - Array */
501{
502 /*
503 * Range check input...
504 */
505
506 if (!a)
507 return (NULL);
508
509 /*
510 * Return the last element...
511 */
512
513 a->current = a->num_elements - 1;
514
515 return (cupsArrayCurrent(a));
516}
517
518
519/*
520 * 'cupsArrayNew()' - Create a new array.
521 */
522
523cups_array_t * /* O - Array */
524cupsArrayNew(cups_array_func_t f, /* I - Comparison function */
525 void *d) /* I - User data */
b94498cf 526{
527 return (cupsArrayNew2(f, d, 0, 0));
528}
529
530
531/*
532 * 'cupsArrayNew2()' - Create a new array with hash.
533 *
534 * @since CUPS 1.3@
535 */
536
537cups_array_t * /* O - Array */
538cupsArrayNew2(cups_array_func_t f, /* I - Comparison function */
539 void *d, /* I - User data */
540 cups_ahash_func_t h, /* I - Hash function*/
541 int hsize) /* I - Hash size */
ef416fc2 542{
543 cups_array_t *a; /* Array */
544
545
546 /*
547 * Allocate memory for the array...
548 */
549
550 a = calloc(1, sizeof(cups_array_t));
551 if (!a)
552 return (NULL);
553
554 a->compare = f;
555 a->data = d;
556 a->current = -1;
557 a->insert = -1;
558 a->num_saved = 0;
bd7854cb 559 a->unique = 1;
ef416fc2 560
b94498cf 561 if (hsize > 0 && h)
562 {
563 a->hashfunc = h;
564 a->hashsize = hsize;
565 a->hash = malloc(hsize * sizeof(int));
566
567 if (!a->hash)
568 {
569 free(a);
570 return (NULL);
571 }
572
573 memset(a->hash, -1, hsize * sizeof(int));
574 }
575
ef416fc2 576 return (a);
577}
578
579
580/*
581 * 'cupsArrayNext()' - Get the next element in the array.
582 */
583
584void * /* O - Next element or NULL */
585cupsArrayNext(cups_array_t *a) /* I - Array */
586{
587 /*
588 * Range check input...
589 */
590
591 if (!a)
592 return (NULL);
593
594 /*
595 * Return the next element...
596 */
597
598 if (a->current < a->num_elements)
599 a->current ++;
600
601 return (cupsArrayCurrent(a));
602}
603
604
605/*
606 * 'cupsArrayPrev()' - Get the previous element in the array.
607 */
608
609void * /* O - Previous element or NULL */
610cupsArrayPrev(cups_array_t *a) /* I - Array */
611{
612 /*
613 * Range check input...
614 */
615
616 if (!a)
617 return (NULL);
618
619 /*
620 * Return the previous element...
621 */
622
623 if (a->current >= 0)
624 a->current --;
625
626 return (cupsArrayCurrent(a));
627}
628
629
630/*
631 * 'cupsArrayRemove()' - Remove an element from the array.
632 */
633
634int /* O - 1 on success, 0 on failure */
635cupsArrayRemove(cups_array_t *a, /* I - Array */
636 void *e) /* I - Element */
637{
638 int i, /* Looping var */
639 current, /* Current element */
640 diff; /* Difference */
641
642
643 /*
644 * Range check input...
645 */
646
647 if (!a || !e)
648 return (0);
649
650 /*
651 * See if the element is in the array...
652 */
653
654 if (!a->num_elements)
655 return (0);
656
bd7854cb 657 current = cups_array_find(a, e, a->current, &diff);
ef416fc2 658 if (diff)
659 return (0);
660
661 /*
662 * Yes, now remove it...
663 */
664
665 a->num_elements --;
666
667 if (current < a->num_elements)
668 memmove(a->elements + current, a->elements + current + 1,
669 (a->num_elements - current) * sizeof(void *));
670
671 if (current <= a->current)
672 a->current --;
673
f7deaa1a 674 if (current < a->insert)
ef416fc2 675 a->insert --;
f7deaa1a 676 else if (current == a->insert)
677 a->insert = -1;
ef416fc2 678
679 for (i = 0; i < a->num_saved; i ++)
680 if (current <= a->saved[i])
681 a->saved[i] --;
682
bd7854cb 683 if (a->num_elements <= 1)
684 a->unique = 1;
685
ef416fc2 686 return (1);
687}
688
689
690/*
691 * 'cupsArrayRestore()' - Reset the current element to the last cupsArraySave.
692 */
693
694void * /* O - New current element */
695cupsArrayRestore(cups_array_t *a) /* I - Array */
696{
697 if (!a)
698 return (NULL);
699
700 if (a->num_saved <= 0)
701 return (NULL);
702
703 a->num_saved --;
704 a->current = a->saved[a->num_saved];
705
706 if (a->current >= 0 && a->current < a->num_elements)
707 return (a->elements[a->current]);
708 else
709 return (NULL);
710}
711
712
713/*
714 * 'cupsArraySave()' - Mark the current element for a later cupsArrayRestore.
715 *
716 * The save/restore stack is guaranteed to be at least 32 elements deep.
717 */
718
719int /* O - 1 on success, 0 on failure */
720cupsArraySave(cups_array_t *a) /* I - Array */
721{
722 if (!a)
723 return (0);
724
725 if (a->num_saved >= _CUPS_MAXSAVE)
726 return (0);
727
728 a->saved[a->num_saved] = a->current;
729 a->num_saved ++;
730
731 return (1);
732}
733
734
e1d6a774 735/*
736 * 'cupsArrayUserData()' - Return the user data for an array.
737 */
738
739void * /* O - User data */
740cupsArrayUserData(cups_array_t *a) /* I - Array */
741{
742 if (a)
743 return (a->data);
744 else
745 return (NULL);
746}
747
748
ef416fc2 749/*
bd7854cb 750 * 'cups_array_add()' - Insert or append an element to the array...
751 */
752
753static int /* O - 1 on success, 0 on failure */
754cups_array_add(cups_array_t *a, /* I - Array */
755 void *e, /* I - Element to add */
756 int insert) /* I - 1 = insert, 0 = append */
757{
758 int i, /* Looping var */
759 current, /* Current element */
760 diff; /* Comparison with current element */
761
762
763 DEBUG_printf(("cups_array_add(a=%p, e=%p, insert=%d)\n", a, e, insert));
764
765 /*
766 * Verify we have room for the new element...
767 */
768
769 if (a->num_elements >= a->alloc_elements)
770 {
771 /*
772 * Allocate additional elements; start with 16 elements, then
773 * double the size until 1024 elements, then add 1024 elements
774 * thereafter...
775 */
776
777 void **temp; /* New array elements */
778 int count; /* New allocation count */
779
780
781 if (a->alloc_elements == 0)
782 {
783 count = 16;
784 temp = malloc(count * sizeof(void *));
785 }
786 else
787 {
788 if (a->alloc_elements < 1024)
789 count = a->alloc_elements * 2;
790 else
791 count = a->alloc_elements + 1024;
792
793 temp = realloc(a->elements, count * sizeof(void *));
794 }
795
796 DEBUG_printf(("cups_array_add: count=%d\n", count));
797
798 if (!temp)
799 {
800 DEBUG_puts("cupsAddAdd: allocation failed, returning 0");
801 return (0);
802 }
803
804 a->alloc_elements = count;
805 a->elements = temp;
806 }
807
808 /*
809 * Find the insertion point for the new element; if there is no
810 * compare function or elements, just add it to the beginning or end...
811 */
812
813 if (!a->num_elements || !a->compare)
814 {
815 /*
816 * No elements or comparison function, insert/append as needed...
817 */
818
819 if (insert)
820 current = 0; /* Insert at beginning */
821 else
822 current = a->num_elements; /* Append to the end */
823 }
824 else
825 {
826 /*
827 * Do a binary search for the insertion point...
828 */
829
830 current = cups_array_find(a, e, a->insert, &diff);
831
832 if (diff > 0)
833 {
834 /*
835 * Insert after the current element...
836 */
837
838 current ++;
839 }
840 else if (!diff)
841 {
842 /*
843 * Compared equal, make sure we add to the begining or end of
844 * the current run of equal elements...
845 */
846
847 a->unique = 0;
848
849 if (insert)
850 {
851 /*
852 * Insert at beginning of run...
853 */
854
855 while (current > 0 && !(*(a->compare))(e, a->elements[current - 1],
856 a->data))
857 current --;
858 }
859 else
860 {
861 /*
862 * Append at end of run...
863 */
864
865 do
866 {
867 current ++;
868 }
869 while (current < a->num_elements &&
870 !(*(a->compare))(e, a->elements[current], a->data));
871 }
872 }
873 }
874
875 /*
876 * Insert or append the element...
877 */
878
879 if (current < a->num_elements)
880 {
881 /*
882 * Shift other elements to the right...
883 */
884
885 memmove(a->elements + current + 1, a->elements + current,
886 (a->num_elements - current) * sizeof(void *));
887
888 if (a->current >= current)
889 a->current ++;
890
891 for (i = 0; i < a->num_saved; i ++)
892 if (a->saved[i] >= current)
893 a->saved[i] ++;
894
895 DEBUG_printf(("cups_array_add: insert element at index %d...\n", current));
896 }
897#ifdef DEBUG
898 else
899 printf("cups_array_add: append element at %d...\n", current);
900#endif /* DEBUG */
901
902 a->elements[current] = e;
903 a->num_elements ++;
904 a->insert = current;
905
906#ifdef DEBUG
907 for (current = 0; current < a->num_elements; current ++)
908 printf("cups_array_add: a->elements[%d]=%p\n", current, a->elements[current]);
909#endif /* DEBUG */
910
911 DEBUG_puts("cups_array_add: returning 1");
912
913 return (1);
914}
915
916
917/*
918 * 'cups_array_find()' - Find an element in the array...
ef416fc2 919 */
920
921static int /* O - Index of match */
bd7854cb 922cups_array_find(cups_array_t *a, /* I - Array */
923 void *e, /* I - Element */
924 int prev, /* I - Previous index */
925 int *rdiff) /* O - Difference of match */
ef416fc2 926{
927 int left, /* Left side of search */
928 right, /* Right side of search */
929 current, /* Current element */
930 diff; /* Comparison with current element */
931
932
bd7854cb 933 DEBUG_printf(("cups_array_find(a=%p, e=%p, prev=%d, rdiff=%p)\n", a, e, prev,
ef416fc2 934 rdiff));
935
936 if (a->compare)
937 {
938 /*
939 * Do a binary search for the element...
940 */
941
bd7854cb 942 DEBUG_puts("cups_array_find: binary search");
ef416fc2 943
944 if (prev >= 0 && prev < a->num_elements)
945 {
946 /*
947 * Start search on either side of previous...
948 */
949
950 if ((diff = (*(a->compare))(e, a->elements[prev], a->data)) == 0 ||
951 (diff < 0 && prev == 0) ||
952 (diff > 0 && prev == (a->num_elements - 1)))
953 {
954 /*
955 * Exact or edge match, return it!
956 */
957
bd7854cb 958 DEBUG_printf(("cups_array_find: Returning %d, diff=%d\n", prev, diff));
ef416fc2 959
960 *rdiff = diff;
961
962 return (prev);
963 }
964 else if (diff < 0)
965 {
966 /*
967 * Start with previous on right side...
968 */
969
970 left = 0;
971 right = prev;
972 }
973 else
974 {
975 /*
976 * Start wih previous on left side...
977 */
978
979 left = prev;
980 right = a->num_elements - 1;
981 }
982 }
983 else
984 {
985 /*
986 * Start search in the middle...
987 */
988
989 left = 0;
990 right = a->num_elements - 1;
991 }
992
993 do
994 {
995 current = (left + right) / 2;
996 diff = (*(a->compare))(e, a->elements[current], a->data);
997
bd7854cb 998 DEBUG_printf(("cups_array_find: left=%d, right=%d, current=%d, diff=%d\n",
ef416fc2 999 left, right, current, diff));
1000
1001 if (diff == 0)
1002 break;
1003 else if (diff < 0)
1004 right = current;
1005 else
1006 left = current;
1007 }
1008 while ((right - left) > 1);
1009
1010 if (diff != 0)
1011 {
1012 /*
1013 * Check the last 1 or 2 elements...
1014 */
1015
1016 if ((diff = (*(a->compare))(e, a->elements[left], a->data)) <= 0)
1017 current = left;
1018 else
1019 {
1020 diff = (*(a->compare))(e, a->elements[right], a->data);
1021 current = right;
1022 }
1023 }
1024 }
1025 else
1026 {
1027 /*
1028 * Do a linear pointer search...
1029 */
1030
bd7854cb 1031 DEBUG_puts("cups_array_find: linear search");
ef416fc2 1032
a74454a7 1033 diff = 1;
ef416fc2 1034
1035 for (current = 0; current < a->num_elements; current ++)
1036 if (a->elements[current] == e)
a74454a7 1037 {
1038 diff = 0;
ef416fc2 1039 break;
a74454a7 1040 }
ef416fc2 1041 }
1042
1043 /*
1044 * Return the closest element and the difference...
1045 */
1046
bd7854cb 1047 DEBUG_printf(("cups_array_find: Returning %d, diff=%d\n", current, diff));
ef416fc2 1048
1049 *rdiff = diff;
1050
1051 return (current);
1052}
1053
1054
1055/*
bc44d920 1056 * End of "$Id: array.c 6649 2007-07-11 21:46:42Z mike $".
ef416fc2 1057 */