45#include "MagickCore/studio.h"
46#include "MagickCore/exception.h"
47#include "MagickCore/exception-private.h"
48#include "MagickCore/linked-list.h"
49#include "MagickCore/linked-list-private.h"
50#include "MagickCore/locale_.h"
51#include "MagickCore/memory_.h"
52#include "MagickCore/memory-private.h"
53#include "MagickCore/semaphore.h"
54#include "MagickCore/signature-private.h"
55#include "MagickCore/string_.h"
103MagickExport MagickBooleanType AppendValueToLinkedList(
110 assert(list_info->signature == MagickCoreSignature);
111 if (list_info->elements == list_info->capacity)
113 next=(
ElementInfo *) AcquireMagickMemory(
sizeof(*next));
116 next->value=(
void *) value;
118 LockSemaphoreInfo(list_info->semaphore);
120 list_info->next=next;
121 if (list_info->elements == 0)
122 list_info->head=next;
124 list_info->tail->next=next;
125 list_info->tail=next;
126 list_info->elements++;
127 UnlockSemaphoreInfo(list_info->semaphore);
158 void *(*relinquish_value)(
void *))
167 assert(list_info->signature == MagickCoreSignature);
168 LockSemaphoreInfo(list_info->semaphore);
169 next=list_info->head;
172 if (relinquish_value != (
void *(*)(
void *)) NULL)
173 next->value=relinquish_value(next->value);
176 element=(
ElementInfo *) RelinquishMagickMemory(element);
181 list_info->elements=0;
182 UnlockSemaphoreInfo(list_info->semaphore);
212 void *(*relinquish_value)(
void *))
221 assert(list_info->signature == MagickCoreSignature);
222 LockSemaphoreInfo(list_info->semaphore);
223 for (next=list_info->head; next != (
ElementInfo *) NULL; )
225 if (relinquish_value != (
void *(*)(
void *)) NULL)
226 next->value=relinquish_value(next->value);
229 entry=(
ElementInfo *) RelinquishMagickMemory(entry);
231 list_info->signature=(~MagickCoreSignature);
232 UnlockSemaphoreInfo(list_info->semaphore);
233 RelinquishSemaphoreInfo(&list_info->semaphore);
260MagickPrivate
ElementInfo *GetHeadElementInLinkedList(
264 assert(list_info->signature == MagickCoreSignature);
265 return(list_info->head);
290MagickExport
void *GetLastValueInLinkedList(
LinkedListInfo *list_info)
296 assert(list_info->signature == MagickCoreSignature);
297 if (list_info->elements == 0)
298 return((
void *) NULL);
299 LockSemaphoreInfo(list_info->semaphore);
300 value=list_info->tail->value;
301 UnlockSemaphoreInfo(list_info->semaphore);
327MagickExport
void *GetNextValueInLinkedList(
LinkedListInfo *list_info)
333 assert(list_info->signature == MagickCoreSignature);
334 LockSemaphoreInfo(list_info->semaphore);
337 UnlockSemaphoreInfo(list_info->semaphore);
338 return((
void *) NULL);
340 value=list_info->next->value;
341 list_info->next=list_info->next->next;
342 UnlockSemaphoreInfo(list_info->semaphore);
370MagickExport
size_t GetNumberOfElementsInLinkedList(
374 assert(list_info->signature == MagickCoreSignature);
375 return(list_info->elements);
404MagickExport
void *GetValueFromLinkedList(
LinkedListInfo *list_info,
417 assert(list_info->signature == MagickCoreSignature);
418 if (index >= list_info->elements)
419 return((
void *) NULL);
420 LockSemaphoreInfo(list_info->semaphore);
423 value=list_info->head->value;
424 UnlockSemaphoreInfo(list_info->semaphore);
427 if (index == (list_info->elements-1))
429 value=list_info->tail->value;
430 UnlockSemaphoreInfo(list_info->semaphore);
433 next=list_info->head;
434 for (i=0; i < (ssize_t) index; i++)
437 UnlockSemaphoreInfo(list_info->semaphore);
469MagickExport MagickBooleanType InsertValueInLinkedList(
479 assert(list_info->signature == MagickCoreSignature);
480 if (value == (
const void *) NULL)
482 if ((index > list_info->elements) ||
483 (list_info->elements == list_info->capacity))
485 next=(
ElementInfo *) AcquireMagickMemory(
sizeof(*next));
488 next->value=(
void *) value;
490 LockSemaphoreInfo(list_info->semaphore);
491 if (list_info->elements == 0)
494 list_info->next=next;
495 list_info->head=next;
496 list_info->tail=next;
502 if (list_info->next == list_info->head)
503 list_info->next=next;
504 next->next=list_info->head;
505 list_info->head=next;
508 if (index == list_info->elements)
511 list_info->next=next;
512 list_info->tail->next=next;
513 list_info->tail=next;
520 element=list_info->head;
521 next->next=element->next;
522 for (i=1; i < (ssize_t) index; i++)
524 element=element->next;
525 next->next=element->next;
529 if (list_info->next == next->next)
530 list_info->next=next;
533 list_info->elements++;
534 UnlockSemaphoreInfo(list_info->semaphore);
570MagickExport MagickBooleanType InsertValueInSortedLinkedList(
571 LinkedListInfo *list_info,
int (*compare)(
const void *,
const void *),
572 void **replace,
const void *value)
584 assert(list_info->signature == MagickCoreSignature);
585 if ((compare == (
int (*)(
const void *,
const void *)) NULL) ||
586 (value == (
const void *) NULL))
588 if (list_info->elements == list_info->capacity)
590 next=(
ElementInfo *) AcquireMagickMemory(
sizeof(*next));
593 next->value=(
void *) value;
595 LockSemaphoreInfo(list_info->semaphore);
596 next->next=list_info->head;
599 i=(ssize_t) compare(value,next->next->value);
600 if ((i < 0) || ((replace != (
void **) NULL) && (i == 0)))
604 *replace=next->next->value;
605 next->next=next->next->next;
607 element->next=(
ElementInfo *) RelinquishMagickMemory(
609 list_info->elements--;
614 list_info->head=next;
618 next->next=next->next->next;
625 list_info->head=next;
626 list_info->tail=next;
628 list_info->elements++;
629 UnlockSemaphoreInfo(list_info->semaphore);
655MagickExport MagickBooleanType IsLinkedListEmpty(
659 assert(list_info->signature == MagickCoreSignature);
660 return(list_info->elements == 0 ? MagickTrue : MagickFalse);
688MagickExport MagickBooleanType LinkedListToArray(
LinkedListInfo *list_info,
698 assert(list_info->signature == MagickCoreSignature);
699 if (array == (
void **) NULL)
701 LockSemaphoreInfo(list_info->semaphore);
702 next=list_info->head;
705 array[i]=next->value;
708 UnlockSemaphoreInfo(list_info->semaphore);
740 list_info=(
LinkedListInfo *) AcquireCriticalMemory(
sizeof(*list_info));
741 (void) memset(list_info,0,
sizeof(*list_info));
742 list_info->capacity=capacity == 0 ? (size_t) (~0) : capacity;
743 list_info->elements=0;
747 list_info->semaphore=AcquireSemaphoreInfo();
748 list_info->signature=MagickCoreSignature;
778MagickExport
void *RemoveElementByValueFromLinkedList(
LinkedListInfo *list_info,
785 assert(list_info->signature == MagickCoreSignature);
786 if ((list_info->elements == 0) || (value == (
const void *) NULL))
787 return((
void *) NULL);
788 LockSemaphoreInfo(list_info->semaphore);
789 if (value == list_info->head->value)
791 if (list_info->next == list_info->head)
792 list_info->next=list_info->head->next;
793 next=list_info->head;
794 list_info->head=list_info->head->next;
802 next=list_info->head;
804 (next->next->value != value))
808 UnlockSemaphoreInfo(list_info->semaphore);
809 return((
void *) NULL);
812 next->next=element->next;
813 if (element == list_info->tail)
814 list_info->tail=next;
815 if (list_info->next == element)
816 list_info->next=element->next;
817 element=(
ElementInfo *) RelinquishMagickMemory(element);
819 list_info->elements--;
820 UnlockSemaphoreInfo(list_info->semaphore);
821 return((
void *) value);
850MagickExport
void *RemoveElementFromLinkedList(
LinkedListInfo *list_info,
863 assert(list_info->signature == MagickCoreSignature);
864 if (index >= list_info->elements)
865 return((
void *) NULL);
866 LockSemaphoreInfo(list_info->semaphore);
869 if (list_info->next == list_info->head)
870 list_info->next=list_info->head->next;
871 value=list_info->head->value;
872 next=list_info->head;
873 list_info->head=list_info->head->next;
881 next=list_info->head;
882 for (i=1; i < (ssize_t) index; i++)
885 next->next=element->next;
886 if (element == list_info->tail)
887 list_info->tail=next;
888 if (list_info->next == element)
889 list_info->next=element->next;
890 value=element->value;
891 element=(
ElementInfo *) RelinquishMagickMemory(element);
893 list_info->elements--;
894 UnlockSemaphoreInfo(list_info->semaphore);
921MagickExport
void *RemoveLastElementFromLinkedList(
LinkedListInfo *list_info)
927 assert(list_info->signature == MagickCoreSignature);
928 if (list_info->elements == 0)
929 return((
void *) NULL);
930 LockSemaphoreInfo(list_info->semaphore);
931 if (list_info->next == list_info->tail)
933 if (list_info->elements == 1UL)
935 value=list_info->head->value;
937 list_info->tail=(
ElementInfo *) RelinquishMagickMemory(list_info->tail);
944 value=list_info->tail->value;
945 next=list_info->head;
946 while (next->next != list_info->tail)
948 list_info->tail=(
ElementInfo *) RelinquishMagickMemory(list_info->tail);
949 list_info->tail=next;
952 list_info->elements--;
953 UnlockSemaphoreInfo(list_info->semaphore);
981MagickExport
void ResetLinkedListIterator(
LinkedListInfo *list_info)
984 assert(list_info->signature == MagickCoreSignature);
985 LockSemaphoreInfo(list_info->semaphore);
986 list_info->next=list_info->head;
987 UnlockSemaphoreInfo(list_info->semaphore);
1015MagickPrivate
void SetHeadElementInLinkedList(
LinkedListInfo *list_info,
1022 assert(list_info->signature == MagickCoreSignature);
1024 if (element == list_info->head)
1026 prev=list_info->head;
1029 if (prev->next == element)
1031 prev->next=element->next;
1032 element->next=list_info->head;
1033 if (list_info->head == list_info->next)
1034 list_info->next=element;
1035 list_info->head=element;