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