/src/imagemagick/MagickCore/registry.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
3 | | % % |
4 | | % % |
5 | | % % |
6 | | % RRRR EEEEE GGG IIIII SSSSS TTTTT RRRR Y Y % |
7 | | % R R E G I SS T R R Y Y % |
8 | | % RRRR EEE G GGG I SSS T RRRR Y % |
9 | | % R R E G G I SS T R R Y % |
10 | | % R R EEEEE GGG IIIII SSSSS T R R Y % |
11 | | % % |
12 | | % % |
13 | | % MagickCore Registry Methods % |
14 | | % % |
15 | | % Software Design % |
16 | | % Cristy % |
17 | | % March 2000 % |
18 | | % % |
19 | | % % |
20 | | % Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization % |
21 | | % dedicated to making software imaging solutions freely available. % |
22 | | % % |
23 | | % You may not use this file except in compliance with the License. You may % |
24 | | % obtain a copy of the License at % |
25 | | % % |
26 | | % https://imagemagick.org/script/license.php % |
27 | | % % |
28 | | % Unless required by applicable law or agreed to in writing, software % |
29 | | % distributed under the License is distributed on an "AS IS" BASIS, % |
30 | | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
31 | | % See the License for the specific language governing permissions and % |
32 | | % limitations under the License. % |
33 | | % % |
34 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
35 | | % |
36 | | % |
37 | | % |
38 | | */ |
39 | | |
40 | | /* |
41 | | Include declarations. |
42 | | */ |
43 | | #include "MagickCore/studio.h" |
44 | | #include "MagickCore/exception.h" |
45 | | #include "MagickCore/exception-private.h" |
46 | | #include "MagickCore/image.h" |
47 | | #include "MagickCore/list.h" |
48 | | #include "MagickCore/memory_.h" |
49 | | #include "MagickCore/memory-private.h" |
50 | | #include "MagickCore/registry.h" |
51 | | #include "MagickCore/registry-private.h" |
52 | | #include "MagickCore/splay-tree.h" |
53 | | #include "MagickCore/string_.h" |
54 | | #include "MagickCore/string-private.h" |
55 | | #include "MagickCore/timer-private.h" |
56 | | #include "MagickCore/utility.h" |
57 | | |
58 | | /* |
59 | | Typedef declarations. |
60 | | */ |
61 | | typedef struct _RegistryInfo |
62 | | { |
63 | | RegistryType |
64 | | type; |
65 | | |
66 | | void |
67 | | *value; |
68 | | |
69 | | size_t |
70 | | signature; |
71 | | } RegistryInfo; |
72 | | |
73 | | /* |
74 | | Static declarations. |
75 | | */ |
76 | | static SplayTreeInfo |
77 | | *registry = (SplayTreeInfo *) NULL; |
78 | | |
79 | | static SemaphoreInfo |
80 | | *registry_semaphore = (SemaphoreInfo *) NULL; |
81 | | |
82 | | /* |
83 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
84 | | % % |
85 | | % % |
86 | | % % |
87 | | % D e f i n e I m a g e R e g i s t r y % |
88 | | % % |
89 | | % % |
90 | | % % |
91 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
92 | | % |
93 | | % DefineImageRegistry() associates a key/value pair with the image registry. |
94 | | % |
95 | | % The format of the DefineImageRegistry method is: |
96 | | % |
97 | | % MagickBooleanType DefineImageRegistry(const RegistryType type, |
98 | | % const char *option,ExceptionInfo *exception) |
99 | | % |
100 | | % A description of each parameter follows: |
101 | | % |
102 | | % o type: the type. |
103 | | % |
104 | | % o option: the option. |
105 | | % |
106 | | % o exception: the exception. |
107 | | % |
108 | | */ |
109 | | MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type, |
110 | | const char *option,ExceptionInfo *exception) |
111 | 0 | { |
112 | 0 | char |
113 | 0 | key[MagickPathExtent], |
114 | 0 | value[MagickPathExtent]; |
115 | |
|
116 | 0 | char |
117 | 0 | *p; |
118 | |
|
119 | 0 | assert(option != (const char *) NULL); |
120 | 0 | (void) CopyMagickString(key,option,MagickPathExtent); |
121 | 0 | for (p=key; *p != '\0'; p++) |
122 | 0 | if (*p == '=') |
123 | 0 | break; |
124 | 0 | *value='\0'; |
125 | 0 | if (*p == '=') |
126 | 0 | (void) CopyMagickString(value,p+1,MagickPathExtent); |
127 | 0 | *p='\0'; |
128 | 0 | return(SetImageRegistry(type,key,value,exception)); |
129 | 0 | } |
130 | | |
131 | | /* |
132 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
133 | | % % |
134 | | % % |
135 | | % % |
136 | | % D e l e t e I m a g e R e g i s t r y % |
137 | | % % |
138 | | % % |
139 | | % % |
140 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
141 | | % |
142 | | % DeleteImageRegistry() deletes a key from the image registry. |
143 | | % |
144 | | % The format of the DeleteImageRegistry method is: |
145 | | % |
146 | | % MagickBooleanType DeleteImageRegistry(const char *key) |
147 | | % |
148 | | % A description of each parameter follows: |
149 | | % |
150 | | % o key: the registry. |
151 | | % |
152 | | */ |
153 | | MagickExport MagickBooleanType DeleteImageRegistry(const char *key) |
154 | 0 | { |
155 | 0 | assert(key != (const char *) NULL); |
156 | 0 | if (IsEventLogging() != MagickFalse) |
157 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); |
158 | 0 | if (registry == (void *) NULL) |
159 | 0 | return(MagickFalse); |
160 | 0 | return(DeleteNodeFromSplayTree(registry,key)); |
161 | 0 | } |
162 | | |
163 | | /* |
164 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
165 | | % % |
166 | | % % |
167 | | % % |
168 | | % G e t I m a g e R e g i s t r y % |
169 | | % % |
170 | | % % |
171 | | % % |
172 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
173 | | % |
174 | | % GetImageRegistry() returns a value associated with an image registry key. |
175 | | % |
176 | | % The format of the GetImageRegistry method is: |
177 | | % |
178 | | % void *GetImageRegistry(const RegistryType type,const char *key, |
179 | | % ExceptionInfo *exception) |
180 | | % |
181 | | % A description of each parameter follows: |
182 | | % |
183 | | % o type: the type. |
184 | | % |
185 | | % o key: the key. |
186 | | % |
187 | | % o exception: the exception. |
188 | | % |
189 | | */ |
190 | | MagickExport void *GetImageRegistry(const RegistryType type,const char *key, |
191 | | ExceptionInfo *exception) |
192 | 470k | { |
193 | 470k | void |
194 | 470k | *value; |
195 | | |
196 | 470k | RegistryInfo |
197 | 470k | *registry_info; |
198 | | |
199 | 470k | assert(key != (const char *) NULL); |
200 | 470k | if (IsEventLogging() != MagickFalse) |
201 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); |
202 | 470k | if (registry == (void *) NULL) |
203 | 470k | return((void *) NULL); |
204 | 0 | registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key); |
205 | 0 | if (registry_info == (void *) NULL) |
206 | 0 | return((void *) NULL); |
207 | 0 | value=(void *) NULL; |
208 | 0 | switch (type) |
209 | 0 | { |
210 | 0 | case ImageRegistryType: |
211 | 0 | { |
212 | 0 | if (type == registry_info->type) |
213 | 0 | value=(void *) CloneImageList((Image *) registry_info->value,exception); |
214 | 0 | break; |
215 | 0 | } |
216 | 0 | case ImageInfoRegistryType: |
217 | 0 | { |
218 | 0 | if (type == registry_info->type) |
219 | 0 | value=(void *) CloneImageInfo((ImageInfo *) registry_info->value); |
220 | 0 | break; |
221 | 0 | } |
222 | 0 | case StringRegistryType: |
223 | 0 | { |
224 | 0 | switch (registry_info->type) |
225 | 0 | { |
226 | 0 | case ImageRegistryType: |
227 | 0 | { |
228 | 0 | value=(Image *) ConstantString(((Image *) |
229 | 0 | registry_info->value)->filename); |
230 | 0 | break; |
231 | 0 | } |
232 | 0 | case ImageInfoRegistryType: |
233 | 0 | { |
234 | 0 | value=(Image *) ConstantString(((ImageInfo *) |
235 | 0 | registry_info->value)->filename); |
236 | 0 | break; |
237 | 0 | } |
238 | 0 | case StringRegistryType: |
239 | 0 | { |
240 | 0 | value=(void *) ConstantString((char *) registry_info->value); |
241 | 0 | break; |
242 | 0 | } |
243 | 0 | default: |
244 | 0 | break; |
245 | 0 | } |
246 | 0 | break; |
247 | 0 | } |
248 | 0 | default: |
249 | 0 | break; |
250 | 0 | } |
251 | 0 | return(value); |
252 | 0 | } |
253 | | |
254 | | /* |
255 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
256 | | % % |
257 | | % % |
258 | | % % |
259 | | % G e t N e x t I m a g e R e g i s t r y % |
260 | | % % |
261 | | % % |
262 | | % % |
263 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
264 | | % |
265 | | % GetNextImageRegistry() gets the next image registry value. |
266 | | % |
267 | | % The format of the GetNextImageRegistry method is: |
268 | | % |
269 | | % char *GetNextImageRegistry(void) |
270 | | % |
271 | | */ |
272 | | MagickExport char *GetNextImageRegistry(void) |
273 | 0 | { |
274 | 0 | if (IsEventLogging() != MagickFalse) |
275 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); |
276 | 0 | if (registry == (void *) NULL) |
277 | 0 | return((char *) NULL); |
278 | 0 | return((char *) GetNextKeyInSplayTree(registry)); |
279 | 0 | } |
280 | | |
281 | | /* |
282 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
283 | | % % |
284 | | % % |
285 | | % % |
286 | | + R e g i s t r y C o m p o n e n t G e n e s i s % |
287 | | % % |
288 | | % % |
289 | | % % |
290 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
291 | | % |
292 | | % RegistryComponentGenesis() instantiates the registry component. |
293 | | % |
294 | | % The format of the RegistryComponentGenesis method is: |
295 | | % |
296 | | % MagickBooleanType RegistryComponentGenesis(void) |
297 | | % |
298 | | */ |
299 | | MagickPrivate MagickBooleanType RegistryComponentGenesis(void) |
300 | 294 | { |
301 | 294 | if (registry_semaphore == (SemaphoreInfo *) NULL) |
302 | 294 | registry_semaphore=AcquireSemaphoreInfo(); |
303 | 294 | return(MagickTrue); |
304 | 294 | } |
305 | | |
306 | | /* |
307 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
308 | | % % |
309 | | % % |
310 | | % % |
311 | | % R e g i s t r y C o m p o n e n t T e r m i n u s % |
312 | | % % |
313 | | % % |
314 | | % % |
315 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
316 | | % |
317 | | % RegistryComponentTerminus() destroys the registry component. |
318 | | % |
319 | | % The format of the DestroyDefines method is: |
320 | | % |
321 | | % void RegistryComponentTerminus(void) |
322 | | % |
323 | | */ |
324 | | MagickPrivate void RegistryComponentTerminus(void) |
325 | 0 | { |
326 | 0 | if (registry_semaphore == (SemaphoreInfo *) NULL) |
327 | 0 | ActivateSemaphoreInfo(®istry_semaphore); |
328 | 0 | LockSemaphoreInfo(registry_semaphore); |
329 | 0 | if (IsEventLogging() != MagickFalse) |
330 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); |
331 | 0 | if (registry != (void *) NULL) |
332 | 0 | registry=DestroySplayTree(registry); |
333 | 0 | UnlockSemaphoreInfo(registry_semaphore); |
334 | 0 | RelinquishSemaphoreInfo(®istry_semaphore); |
335 | 0 | } |
336 | | |
337 | | /* |
338 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
339 | | % % |
340 | | % % |
341 | | % % |
342 | | % R e m o v e I m a g e R e g i s t r y % |
343 | | % % |
344 | | % % |
345 | | % % |
346 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
347 | | % |
348 | | % RemoveImageRegistry() removes a key from the image registry and returns its |
349 | | % value. |
350 | | % |
351 | | % The format of the RemoveImageRegistry method is: |
352 | | % |
353 | | % void *RemoveImageRegistry(const char *key) |
354 | | % |
355 | | % A description of each parameter follows: |
356 | | % |
357 | | % o key: the registry. |
358 | | % |
359 | | */ |
360 | | MagickExport void *RemoveImageRegistry(const char *key) |
361 | 0 | { |
362 | 0 | assert(key != (const char *) NULL); |
363 | 0 | if (IsEventLogging() != MagickFalse) |
364 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); |
365 | 0 | if (registry == (void *) NULL) |
366 | 0 | return((void *) NULL); |
367 | 0 | return(RemoveNodeFromSplayTree(registry,key)); |
368 | 0 | } |
369 | | |
370 | | /* |
371 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
372 | | % % |
373 | | % % |
374 | | % % |
375 | | % R e s e t I m a g e R e g i s t r y I t e r a t o r % |
376 | | % % |
377 | | % % |
378 | | % % |
379 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
380 | | % |
381 | | % ResetImageRegistryIterator() resets the registry iterator. Use it in |
382 | | % conjunction with GetNextImageRegistry() to iterate over all the values |
383 | | % in the image registry. |
384 | | % |
385 | | % The format of the ResetImageRegistryIterator method is: |
386 | | % |
387 | | % ResetImageRegistryIterator(void) |
388 | | % |
389 | | */ |
390 | | MagickExport void ResetImageRegistryIterator(void) |
391 | 0 | { |
392 | 0 | if (IsEventLogging() != MagickFalse) |
393 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); |
394 | 0 | if (registry == (void *) NULL) |
395 | 0 | return; |
396 | 0 | ResetSplayTreeIterator(registry); |
397 | 0 | } |
398 | | |
399 | | /* |
400 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
401 | | % % |
402 | | % % |
403 | | % % |
404 | | % S e t I m a g e R e g i s t r y % |
405 | | % % |
406 | | % % |
407 | | % % |
408 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
409 | | % |
410 | | % SetImageRegistry() associates a value with an image registry key. |
411 | | % |
412 | | % The format of the SetImageRegistry method is: |
413 | | % |
414 | | % MagickBooleanType SetImageRegistry(const RegistryType type, |
415 | | % const char *key,const void *value,ExceptionInfo *exception) |
416 | | % |
417 | | % A description of each parameter follows: |
418 | | % |
419 | | % o type: the type. |
420 | | % |
421 | | % o key: the key. |
422 | | % |
423 | | % o value: the value. |
424 | | % |
425 | | % o exception: the exception. |
426 | | % |
427 | | */ |
428 | | |
429 | | static void *DestroyRegistryNode(void *registry_info) |
430 | 0 | { |
431 | 0 | RegistryInfo |
432 | 0 | *p; |
433 | |
|
434 | 0 | p=(RegistryInfo *) registry_info; |
435 | 0 | switch (p->type) |
436 | 0 | { |
437 | 0 | case StringRegistryType: |
438 | 0 | default: |
439 | 0 | { |
440 | 0 | p->value=RelinquishMagickMemory(p->value); |
441 | 0 | break; |
442 | 0 | } |
443 | 0 | case ImageRegistryType: |
444 | 0 | { |
445 | 0 | p->value=(void *) DestroyImageList((Image *) p->value); |
446 | 0 | break; |
447 | 0 | } |
448 | 0 | case ImageInfoRegistryType: |
449 | 0 | { |
450 | 0 | p->value=(void *) DestroyImageInfo((ImageInfo *) p->value); |
451 | 0 | break; |
452 | 0 | } |
453 | 0 | } |
454 | 0 | return(RelinquishMagickMemory(p)); |
455 | 0 | } |
456 | | |
457 | | MagickExport MagickBooleanType SetImageRegistry(const RegistryType type, |
458 | | const char *key,const void *value,ExceptionInfo *exception) |
459 | 0 | { |
460 | 0 | RegistryInfo |
461 | 0 | *registry_info; |
462 | |
|
463 | 0 | void |
464 | 0 | *clone_value; |
465 | |
|
466 | 0 | assert(key != (const char *) NULL); |
467 | 0 | if (IsEventLogging() != MagickFalse) |
468 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); |
469 | 0 | if (value == (const void *) NULL) |
470 | 0 | return(MagickFalse); |
471 | 0 | clone_value=(void *) NULL; |
472 | 0 | switch (type) |
473 | 0 | { |
474 | 0 | case StringRegistryType: |
475 | 0 | default: |
476 | 0 | { |
477 | 0 | const char |
478 | 0 | *string; |
479 | |
|
480 | 0 | string=(const char *) value; |
481 | 0 | if (LocaleCompare(key,"date:precision") == 0) |
482 | 0 | SetMagickDatePrecision((size_t) StringToInteger(string)); |
483 | 0 | clone_value=(void *) ConstantString(string); |
484 | 0 | break; |
485 | 0 | } |
486 | 0 | case ImageRegistryType: |
487 | 0 | { |
488 | 0 | const Image |
489 | 0 | *image; |
490 | |
|
491 | 0 | image=(const Image *) value; |
492 | 0 | if ((image == (const Image *) NULL) || |
493 | 0 | (image->signature != MagickCoreSignature)) |
494 | 0 | { |
495 | 0 | (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, |
496 | 0 | "UnableToSetRegistry","%s",key); |
497 | 0 | return(MagickFalse); |
498 | 0 | } |
499 | 0 | clone_value=(void *) CloneImageList(image,exception); |
500 | 0 | break; |
501 | 0 | } |
502 | 0 | case ImageInfoRegistryType: |
503 | 0 | { |
504 | 0 | const ImageInfo |
505 | 0 | *image_info; |
506 | |
|
507 | 0 | image_info=(const ImageInfo *) value; |
508 | 0 | if ((image_info == (const ImageInfo *) NULL) || |
509 | 0 | (image_info->signature != MagickCoreSignature)) |
510 | 0 | { |
511 | 0 | (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, |
512 | 0 | "UnableToSetRegistry","%s",key); |
513 | 0 | return(MagickFalse); |
514 | 0 | } |
515 | 0 | clone_value=(void *) CloneImageInfo(image_info); |
516 | 0 | break; |
517 | 0 | } |
518 | 0 | } |
519 | 0 | if (clone_value == (void *) NULL) |
520 | 0 | return(MagickFalse); |
521 | 0 | registry_info=(RegistryInfo *) AcquireCriticalMemory(sizeof(*registry_info)); |
522 | 0 | (void) memset(registry_info,0,sizeof(*registry_info)); |
523 | 0 | registry_info->type=type; |
524 | 0 | registry_info->value=clone_value; |
525 | 0 | registry_info->signature=MagickCoreSignature; |
526 | 0 | if (registry == (SplayTreeInfo *) NULL) |
527 | 0 | { |
528 | 0 | if (registry_semaphore == (SemaphoreInfo *) NULL) |
529 | 0 | ActivateSemaphoreInfo(®istry_semaphore); |
530 | 0 | LockSemaphoreInfo(registry_semaphore); |
531 | 0 | if (registry == (SplayTreeInfo *) NULL) |
532 | 0 | registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, |
533 | 0 | DestroyRegistryNode); |
534 | 0 | UnlockSemaphoreInfo(registry_semaphore); |
535 | 0 | } |
536 | 0 | return(AddValueToSplayTree(registry,ConstantString(key),registry_info)); |
537 | 0 | } |