00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "magick/studio.h"
00046 #include "magick/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/hashmap.h"
00049 #include "magick/memory_.h"
00050 #include "magick/semaphore.h"
00051 #include "magick/signature-private.h"
00052 #include "magick/string_.h"
00053
00054
00055
00056
00057 typedef struct _ElementInfo
00058 {
00059 void
00060 *value;
00061
00062 struct _ElementInfo
00063 *next;
00064 } ElementInfo;
00065
00066 typedef struct _EntryInfo
00067 {
00068 size_t
00069 hash;
00070
00071 void
00072 *key,
00073 *value;
00074 } EntryInfo;
00075
00076 struct _LinkedListInfo
00077 {
00078 unsigned long
00079 capacity,
00080 elements;
00081
00082 ElementInfo
00083 *head,
00084 *tail,
00085 *next;
00086
00087 MagickBooleanType
00088 debug;
00089
00090 SemaphoreInfo
00091 *semaphore;
00092
00093 unsigned long
00094 signature;
00095 };
00096
00097 struct _HashmapInfo
00098 {
00099 size_t
00100 (*hash)(const void *);
00101
00102 MagickBooleanType
00103 (*compare)(const void *,const void *);
00104
00105 void
00106 *(*relinquish_key)(void *),
00107 *(*relinquish_value)(void *);
00108
00109 unsigned long
00110 capacity,
00111 entries,
00112 next;
00113
00114 MagickBooleanType
00115 head_of_list;
00116
00117 LinkedListInfo
00118 **map;
00119
00120 MagickBooleanType
00121 debug;
00122
00123 SemaphoreInfo
00124 *semaphore;
00125
00126 unsigned long
00127 signature;
00128 };
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 MagickExport MagickBooleanType AppendValueToLinkedList(
00156 LinkedListInfo *list_info,const void *value)
00157 {
00158 register ElementInfo
00159 *next;
00160
00161 assert(list_info != (LinkedListInfo *) NULL);
00162 assert(list_info->signature == MagickSignature);
00163 list_info->debug=IsEventLogging();
00164 if (list_info->debug != MagickFalse)
00165 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00166 if (list_info->elements == list_info->capacity)
00167 return(MagickFalse);
00168 next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
00169 if (next == (ElementInfo *) NULL)
00170 return(MagickFalse);
00171 next->value=(void *) value;
00172 next->next=(ElementInfo *) NULL;
00173 (void) LockSemaphoreInfo(list_info->semaphore);
00174 if (list_info->next == (ElementInfo *) NULL)
00175 list_info->next=next;
00176 if (list_info->elements == 0)
00177 list_info->head=next;
00178 else
00179 list_info->tail->next=next;
00180 list_info->tail=next;
00181 list_info->elements++;
00182 (void) UnlockSemaphoreInfo(list_info->semaphore);
00183 return(MagickTrue);
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 MagickExport void ClearLinkedList(LinkedListInfo *list_info,
00213 void *(*relinquish_value)(void *))
00214 {
00215 ElementInfo
00216 *element;
00217
00218 register ElementInfo
00219 *next;
00220
00221 assert(list_info != (LinkedListInfo *) NULL);
00222 assert(list_info->signature == MagickSignature);
00223 if (list_info->debug != MagickFalse)
00224 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00225 (void) LockSemaphoreInfo(list_info->semaphore);
00226 next=list_info->head;
00227 while (next != (ElementInfo *) NULL)
00228 {
00229 if (relinquish_value != (void *(*)(void *)) NULL)
00230 next->value=relinquish_value(next->value);
00231 element=next;
00232 next=next->next;
00233 element=(ElementInfo *) RelinquishMagickMemory(element);
00234 }
00235 list_info->head=(ElementInfo *) NULL;
00236 list_info->tail=(ElementInfo *) NULL;
00237 list_info->next=(ElementInfo *) NULL;
00238 list_info->elements=0;
00239 (void) UnlockSemaphoreInfo(list_info->semaphore);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 MagickExport MagickBooleanType CompareHashmapString(const void *target,
00269 const void *source)
00270 {
00271 const char
00272 *p,
00273 *q;
00274
00275 p=(const char *) target;
00276 q=(const char *) source;
00277 return(LocaleCompare(p,q) == 0 ? MagickTrue : MagickFalse);
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 MagickExport MagickBooleanType CompareHashmapStringInfo(const void *target,
00307 const void *source)
00308 {
00309 const StringInfo
00310 *p,
00311 *q;
00312
00313 p=(const StringInfo *) target;
00314 q=(const StringInfo *) source;
00315 return(CompareStringInfo(p,q) == 0 ? MagickTrue : MagickFalse);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 MagickExport HashmapInfo *DestroyHashmap(HashmapInfo *hashmap_info)
00341 {
00342 LinkedListInfo
00343 *list_info;
00344
00345 register EntryInfo
00346 *entry;
00347
00348 register long
00349 i;
00350
00351 assert(hashmap_info != (HashmapInfo *) NULL);
00352 assert(hashmap_info->signature == MagickSignature);
00353 if (hashmap_info->debug != MagickFalse)
00354 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00355 (void) LockSemaphoreInfo(hashmap_info->semaphore);
00356 for (i=0; i < (long) hashmap_info->capacity; i++)
00357 {
00358 list_info=hashmap_info->map[i];
00359 if (list_info != (LinkedListInfo *) NULL)
00360 {
00361 list_info->next=list_info->head;
00362 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00363 while (entry != (EntryInfo *) NULL)
00364 {
00365 if (hashmap_info->relinquish_key != (void *(*)(void *)) NULL)
00366 entry->key=hashmap_info->relinquish_key(entry->key);
00367 if (hashmap_info->relinquish_value != (void *(*)(void *)) NULL)
00368 entry->value=hashmap_info->relinquish_value(entry->value);
00369 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00370 }
00371 }
00372 if (list_info != (LinkedListInfo *) NULL)
00373 list_info=DestroyLinkedList(list_info,RelinquishMagickMemory);
00374 }
00375 hashmap_info->map=(LinkedListInfo **) RelinquishMagickMemory(
00376 hashmap_info->map);
00377 hashmap_info->signature=(~MagickSignature);
00378 (void) UnlockSemaphoreInfo(hashmap_info->semaphore);
00379 DestroySemaphoreInfo(&hashmap_info->semaphore);
00380 hashmap_info=(HashmapInfo *) RelinquishMagickMemory(hashmap_info);
00381 return(hashmap_info);
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 MagickExport LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
00411 void *(*relinquish_value)(void *))
00412 {
00413 ElementInfo
00414 *entry;
00415
00416 register ElementInfo
00417 *next;
00418
00419 assert(list_info != (LinkedListInfo *) NULL);
00420 assert(list_info->signature == MagickSignature);
00421 if (list_info->debug != MagickFalse)
00422 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00423 (void) LockSemaphoreInfo(list_info->semaphore);
00424 for (next=list_info->head; next != (ElementInfo *) NULL; )
00425 {
00426 if (relinquish_value != (void *(*)(void *)) NULL)
00427 next->value=relinquish_value(next->value);
00428 entry=next;
00429 next=next->next;
00430 entry=(ElementInfo *) RelinquishMagickMemory(entry);
00431 }
00432 list_info->signature=(~MagickSignature);
00433 (void) UnlockSemaphoreInfo(list_info->semaphore);
00434 DestroySemaphoreInfo(&list_info->semaphore);
00435 list_info=(LinkedListInfo *) RelinquishMagickMemory(list_info);
00436 return(list_info);
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 MagickExport void *GetLastValueInLinkedList(LinkedListInfo *list_info)
00462 {
00463 void
00464 *value;
00465
00466 assert(list_info != (LinkedListInfo *) NULL);
00467 assert(list_info->signature == MagickSignature);
00468 if (list_info->debug != MagickFalse)
00469 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00470 if (list_info->elements == 0)
00471 return((void *) NULL);
00472 (void) LockSemaphoreInfo(list_info->semaphore);
00473 value=list_info->tail->value;
00474 (void) UnlockSemaphoreInfo(list_info->semaphore);
00475 return(value);
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 MagickExport void *GetNextKeyInHashmap(HashmapInfo *hashmap_info)
00501 {
00502 LinkedListInfo
00503 *list_info;
00504
00505 register EntryInfo
00506 *entry;
00507
00508 void
00509 *key;
00510
00511 assert(hashmap_info != (HashmapInfo *) NULL);
00512 assert(hashmap_info->signature == MagickSignature);
00513 if (hashmap_info->debug != MagickFalse)
00514 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00515 (void) LockSemaphoreInfo(hashmap_info->semaphore);
00516 while (hashmap_info->next < hashmap_info->capacity)
00517 {
00518 list_info=hashmap_info->map[hashmap_info->next];
00519 if (list_info != (LinkedListInfo *) NULL)
00520 {
00521 if (hashmap_info->head_of_list == MagickFalse)
00522 {
00523 list_info->next=list_info->head;
00524 hashmap_info->head_of_list=MagickTrue;
00525 }
00526 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00527 if (entry != (EntryInfo *) NULL)
00528 {
00529 key=entry->key;
00530 (void) UnlockSemaphoreInfo(hashmap_info->semaphore);
00531 return(key);
00532 }
00533 hashmap_info->head_of_list=MagickFalse;
00534 }
00535 hashmap_info->next++;
00536 }
00537 (void) UnlockSemaphoreInfo(hashmap_info->semaphore);
00538 return((void *) NULL);
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 MagickExport void *GetNextValueInHashmap(HashmapInfo *hashmap_info)
00564 {
00565 LinkedListInfo
00566 *list_info;
00567
00568 register EntryInfo
00569 *entry;
00570
00571 void
00572 *value;
00573
00574 assert(hashmap_info != (HashmapInfo *) NULL);
00575 assert(hashmap_info->signature == MagickSignature);
00576 if (hashmap_info->debug != MagickFalse)
00577 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00578 (void) LockSemaphoreInfo(hashmap_info->semaphore);
00579 while (hashmap_info->next < hashmap_info->capacity)
00580 {
00581 list_info=hashmap_info->map[hashmap_info->next];
00582 if (list_info != (LinkedListInfo *) NULL)
00583 {
00584 if (hashmap_info->head_of_list == MagickFalse)
00585 {
00586 list_info->next=list_info->head;
00587 hashmap_info->head_of_list=MagickTrue;
00588 }
00589 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00590 if (entry != (EntryInfo *) NULL)
00591 {
00592 value=entry->value;
00593 (void) UnlockSemaphoreInfo(hashmap_info->semaphore);
00594 return(value);
00595 }
00596 hashmap_info->head_of_list=MagickFalse;
00597 }
00598 hashmap_info->next++;
00599 }
00600 (void) UnlockSemaphoreInfo(hashmap_info->semaphore);
00601 return((void *) NULL);
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 MagickExport void *GetNextValueInLinkedList(LinkedListInfo *list_info)
00627 {
00628 void
00629 *value;
00630
00631 assert(list_info != (LinkedListInfo *) NULL);
00632 assert(list_info->signature == MagickSignature);
00633 if (list_info->debug != MagickFalse)
00634 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00635 if (list_info->next == (ElementInfo *) NULL)
00636 return((void *) NULL);
00637 (void) LockSemaphoreInfo(list_info->semaphore);
00638 value=list_info->next->value;
00639 list_info->next=list_info->next->next;
00640 (void) UnlockSemaphoreInfo(list_info->semaphore);
00641 return(value);
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 MagickExport unsigned long GetNumberOfEntriesInHashmap(
00667 const HashmapInfo *hashmap_info)
00668 {
00669 assert(hashmap_info != (HashmapInfo *) NULL);
00670 assert(hashmap_info->signature == MagickSignature);
00671 if (hashmap_info->debug != MagickFalse)
00672 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00673 return(hashmap_info->entries);
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 MagickExport unsigned long GetNumberOfElementsInLinkedList(
00701 const LinkedListInfo *list_info)
00702 {
00703 assert(list_info != (LinkedListInfo *) NULL);
00704 assert(list_info->signature == MagickSignature);
00705 if (list_info->debug != MagickFalse)
00706 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00707 return(list_info->elements);
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 MagickExport void *GetValueFromHashmap(HashmapInfo *hashmap_info,
00735 const void *key)
00736 {
00737 LinkedListInfo
00738 *list_info;
00739
00740 register EntryInfo
00741 *entry;
00742
00743 size_t
00744 hash;
00745
00746 void
00747 *value;
00748
00749 assert(hashmap_info != (HashmapInfo *) NULL);
00750 assert(hashmap_info->signature == MagickSignature);
00751 if (hashmap_info->debug != MagickFalse)
00752 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00753 if (key == (const void *) NULL)
00754 return((void *) NULL);
00755 (void) LockSemaphoreInfo(hashmap_info->semaphore);
00756 hash=hashmap_info->hash(key);
00757 list_info=hashmap_info->map[hash % hashmap_info->capacity];
00758 if (list_info != (LinkedListInfo *) NULL)
00759 {
00760 list_info->next=list_info->head;
00761 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00762 while (entry != (EntryInfo *) NULL)
00763 {
00764 if (entry->hash == hash)
00765 {
00766 MagickBooleanType
00767 compare;
00768
00769 compare=MagickTrue;
00770 if (hashmap_info->compare !=
00771 (MagickBooleanType (*)(const void *,const void *)) NULL)
00772 compare=hashmap_info->compare(key,entry->key);
00773 if (compare == MagickTrue)
00774 {
00775 value=entry->value;
00776 (void) UnlockSemaphoreInfo(hashmap_info->semaphore);
00777 return(value);
00778 }
00779 }
00780 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00781 }
00782 }
00783 (void) UnlockSemaphoreInfo(hashmap_info->semaphore);
00784 return((void *) NULL);
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 MagickExport void *GetValueFromLinkedList(LinkedListInfo *list_info,
00814 const unsigned long index)
00815 {
00816 register ElementInfo
00817 *next;
00818
00819 register long
00820 i;
00821
00822 void
00823 *value;
00824
00825 assert(list_info != (LinkedListInfo *) NULL);
00826 assert(list_info->signature == MagickSignature);
00827 if (list_info->debug != MagickFalse)
00828 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00829 if (index >= list_info->elements)
00830 return((void *) NULL);
00831 (void) LockSemaphoreInfo(list_info->semaphore);
00832 if (index == 0)
00833 {
00834 value=list_info->head->value;
00835 (void) UnlockSemaphoreInfo(list_info->semaphore);
00836 return(value);
00837 }
00838 if (index == (list_info->elements-1))
00839 {
00840 value=list_info->tail->value;
00841 (void) UnlockSemaphoreInfo(list_info->semaphore);
00842 return(value);
00843 }
00844 next=list_info->head;
00845 for (i=0; i < (long) index; i++)
00846 next=next->next;
00847 value=next->value;
00848 (void) UnlockSemaphoreInfo(list_info->semaphore);
00849 return(value);
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 MagickExport size_t HashPointerType(const void *pointer)
00876 {
00877 size_t
00878 hash;
00879
00880 hash=(size_t) pointer;
00881 hash+=(~(hash << 9));
00882 hash^=(hash >> 14);
00883 hash+=(hash << 4);
00884 hash^=(hash >> 10);
00885 return(hash);
00886 }
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 MagickExport size_t HashStringType(const void *string)
00912 {
00913 const unsigned char
00914 *digest;
00915
00916 register long
00917 i;
00918
00919 SignatureInfo
00920 *signature_info;
00921
00922 size_t
00923 hash;
00924
00925 StringInfo
00926 *signature;
00927
00928 signature_info=AcquireSignatureInfo();
00929 signature=StringToStringInfo((const char *) string);
00930 UpdateSignature(signature_info,signature);
00931 FinalizeSignature(signature_info);
00932 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00933 hash=0;
00934 for (i=0; i < 8; i++)
00935 hash^=digest[i];
00936 signature=DestroyStringInfo(signature);
00937 signature_info=DestroySignatureInfo(signature_info);
00938 return(hash);
00939 }
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 MagickExport size_t HashStringInfoType(const void *string_info)
00965 {
00966 const unsigned char
00967 *digest;
00968
00969 register long
00970 i;
00971
00972 SignatureInfo
00973 *signature_info;
00974
00975 size_t
00976 hash;
00977
00978 signature_info=AcquireSignatureInfo();
00979 UpdateSignature(signature_info,(const StringInfo *) string_info);
00980 FinalizeSignature(signature_info);
00981 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
00982 hash=0;
00983 for (i=0; i < 8; i++)
00984 hash^=digest[i];
00985 signature_info=DestroySignatureInfo(signature_info);
00986 return(hash);
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 MagickExport MagickBooleanType InsertValueInLinkedList(
01018 LinkedListInfo *list_info,const unsigned long index,const void *value)
01019 {
01020 register ElementInfo
01021 *next;
01022
01023 register long
01024 i;
01025
01026 assert(list_info != (LinkedListInfo *) NULL);
01027 assert(list_info->signature == MagickSignature);
01028 if (list_info->debug != MagickFalse)
01029 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01030 if (value == (const void *) NULL)
01031 return(MagickFalse);
01032 if ((index > list_info->elements) ||
01033 (list_info->elements == list_info->capacity))
01034 return(MagickFalse);
01035 next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
01036 if (next == (ElementInfo *) NULL)
01037 return(MagickFalse);
01038 next->value=(void *) value;
01039 next->next=(ElementInfo *) NULL;
01040 (void) LockSemaphoreInfo(list_info->semaphore);
01041 if (list_info->elements == 0)
01042 {
01043 if (list_info->next == (ElementInfo *) NULL)
01044 list_info->next=next;
01045 list_info->head=next;
01046 list_info->tail=next;
01047 }
01048 else
01049 {
01050 if (index == 0)
01051 {
01052 if (list_info->next == list_info->head)
01053 list_info->next=next;
01054 next->next=list_info->head;
01055 list_info->head=next;
01056 }
01057 else
01058 if (index == list_info->elements)
01059 {
01060 if (list_info->next == (ElementInfo *) NULL)
01061 list_info->next=next;
01062 list_info-><