MagickCore  6.7.5
registry.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %           RRRR    EEEEE    GGG   IIIII  SSSSS  TTTTT  RRRR   Y   Y          %
00007 %           R   R   E       G        I    SS       T    R   R   Y Y           %
00008 %           RRRR    EEE     G GGG    I     SSS     T    RRRR     Y            %
00009 %           R R     E       G   G    I       SS    T    R R      Y            %
00010 %           R  R    EEEEE    GGG   IIIII  SSSSS    T    R  R     Y            %
00011 %                                                                             %
00012 %                                                                             %
00013 %                       MagickCore Registry Methods                           %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                 March 2000                                  %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "MagickCore/studio.h"
00044 #include "MagickCore/exception.h"
00045 #include "MagickCore/exception-private.h"
00046 #include "MagickCore/image.h"
00047 #include "MagickCore/list.h"
00048 #include "MagickCore/memory_.h"
00049 #include "MagickCore/registry.h"
00050 #include "MagickCore/registry-private.h"
00051 #include "MagickCore/splay-tree.h"
00052 #include "MagickCore/string_.h"
00053 #include "MagickCore/utility.h"
00054 
00055 /*
00056   Typedef declarations.
00057 */
00058 typedef struct _RegistryInfo
00059 {
00060   RegistryType
00061     type;
00062 
00063   void
00064     *value;
00065 
00066   size_t
00067     signature;
00068 } RegistryInfo;
00069 
00070 /*
00071   Static declarations.
00072 */
00073 static SplayTreeInfo
00074   *registry = (SplayTreeInfo *) NULL;
00075 
00076 static SemaphoreInfo
00077   *registry_semaphore = (SemaphoreInfo *) NULL;
00078 
00079 static volatile MagickBooleanType
00080   instantiate_registry = MagickFalse;
00081 
00082 /*
00083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00084 %                                                                             %
00085 %                                                                             %
00086 %                                                                             %
00087 %   D e f i n e I m a g e R e g i s t r y                                     %
00088 %                                                                             %
00089 %                                                                             %
00090 %                                                                             %
00091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00092 %
00093 %  DefineImageRegistry() associates a key/value pair with the image registry.
00094 %
00095 %  The format of the DefineImageRegistry method is:
00096 %
00097 %      MagickBooleanType DefineImageRegistry(const RegistryType type,
00098 %        const char *option,ExceptionInfo *exception)
00099 %
00100 %  A description of each parameter follows:
00101 %
00102 %    o type: the type.
00103 %
00104 %    o option: the option.
00105 %
00106 %    o exception: the exception.
00107 %
00108 */
00109 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type,
00110   const char *option,ExceptionInfo *exception)
00111 {
00112   char
00113     key[MaxTextExtent],
00114     value[MaxTextExtent];
00115 
00116   register char
00117     *p;
00118 
00119   assert(option != (const char *) NULL);
00120   (void) CopyMagickString(key,option,MaxTextExtent);
00121   for (p=key; *p != '\0'; p++)
00122     if (*p == '=')
00123       break;
00124   *value='\0';
00125   if (*p == '=')
00126     (void) CopyMagickString(value,p+1,MaxTextExtent);
00127   *p='\0';
00128   return(SetImageRegistry(type,key,value,exception));
00129 }
00130 
00131 /*
00132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00133 %                                                                             %
00134 %                                                                             %
00135 %                                                                             %
00136 %   D e l e t e I m a g e R e g i s t r y                                     %
00137 %                                                                             %
00138 %                                                                             %
00139 %                                                                             %
00140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00141 %
00142 %  DeleteImageRegistry() deletes a key from the image registry.
00143 %
00144 %  The format of the DeleteImageRegistry method is:
00145 %
00146 %      MagickBooleanType DeleteImageRegistry(const char *key)
00147 %
00148 %  A description of each parameter follows:
00149 %
00150 %    o key: the registry.
00151 %
00152 */
00153 MagickExport MagickBooleanType DeleteImageRegistry(const char *key)
00154 {
00155   if (IsEventLogging() != MagickFalse)
00156     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
00157   if (registry == (void *) NULL)
00158     return(MagickFalse);
00159   return(DeleteNodeFromSplayTree(registry,key));
00160 }
00161 
00162 /*
00163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00164 %                                                                             %
00165 %                                                                             %
00166 %                                                                             %
00167 %   G e t I m a g e R e g i s t r y                                           %
00168 %                                                                             %
00169 %                                                                             %
00170 %                                                                             %
00171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00172 %
00173 %  GetImageRegistry() returns a value associated with an image registry key.
00174 %
00175 %  The format of the GetImageRegistry method is:
00176 %
00177 %      void *GetImageRegistry(const RegistryType type,const char *key,
00178 %        ExceptionInfo *exception)
00179 %
00180 %  A description of each parameter follows:
00181 %
00182 %    o type: the type.
00183 %
00184 %    o key: the key.
00185 %
00186 %    o exception: the exception.
00187 %
00188 */
00189 MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
00190   ExceptionInfo *exception)
00191 {
00192   void
00193     *value;
00194 
00195   RegistryInfo
00196     *registry_info;
00197 
00198   if (IsEventLogging() != MagickFalse)
00199     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
00200   if (registry == (void *) NULL)
00201     return((void *) NULL);
00202   registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
00203   if (registry_info == (void *) NULL)
00204     {
00205       (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
00206         "UnableToGetRegistryID","`%s'",key);
00207       return((void *) NULL);
00208     }
00209   value=(void *) NULL;
00210   switch (type)
00211   {
00212     case ImageRegistryType:
00213     {
00214       if (type == registry_info->type)
00215         value=(void *) CloneImageList((Image *) registry_info->value,exception);
00216       break;
00217     }
00218     case ImageInfoRegistryType:
00219     {
00220       if (type == registry_info->type)
00221         value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
00222       break;
00223     }
00224     case StringRegistryType:
00225     {
00226       switch (registry_info->type)
00227       {
00228         case ImageRegistryType:
00229         {
00230           value=(Image *) ConstantString(((Image *)
00231             registry_info->value)->filename);
00232           break;
00233         }
00234         case ImageInfoRegistryType:
00235         {
00236           value=(Image *) ConstantString(((ImageInfo *)
00237             registry_info->value)->filename);
00238           break;
00239         }
00240         case StringRegistryType:
00241         {
00242           value=(void *) ConstantString((char *) registry_info->value);
00243           break;
00244         }
00245         default:
00246           break;
00247       }
00248       break;
00249     }
00250     default:
00251       break;
00252   }
00253   return(value);
00254 }
00255 
00256 /*
00257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00258 %                                                                             %
00259 %                                                                             %
00260 %                                                                             %
00261 %   G e t N e x t I m a g e R e g i s t r y                                   %
00262 %                                                                             %
00263 %                                                                             %
00264 %                                                                             %
00265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00266 %
00267 %  GetNextImageRegistry() gets the next image registry value.
00268 %
00269 %  The format of the GetNextImageRegistry method is:
00270 %
00271 %      char *GetNextImageRegistry(void)
00272 %
00273 */
00274 MagickExport char *GetNextImageRegistry(void)
00275 {
00276   if (IsEventLogging() != MagickFalse)
00277     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00278   if (registry == (void *) NULL)
00279     return((char *) NULL);
00280   return((char *) GetNextKeyInSplayTree(registry));
00281 }
00282 
00283 /*
00284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00285 %                                                                             %
00286 %                                                                             %
00287 %                                                                             %
00288 +   R e g i s t r y C o m p o n e n t G e n e s i s                           %
00289 %                                                                             %
00290 %                                                                             %
00291 %                                                                             %
00292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00293 %
00294 %  RegistryComponentGenesis() instantiates the registry component.
00295 %
00296 %  The format of the RegistryComponentGenesis method is:
00297 %
00298 %      MagickBooleanType RegistryComponentGenesis(void)
00299 %
00300 */
00301 MagickPrivate MagickBooleanType RegistryComponentGenesis(void)
00302 {
00303   AcquireSemaphoreInfo(&registry_semaphore);
00304   return(MagickTrue);
00305 }
00306 
00307 /*
00308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00309 %                                                                             %
00310 %                                                                             %
00311 %                                                                             %
00312 %   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                         %
00313 %                                                                             %
00314 %                                                                             %
00315 %                                                                             %
00316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00317 %
00318 %  RegistryComponentTerminus() destroys the registry component.
00319 %
00320 %  The format of the DestroyDefines method is:
00321 %
00322 %      void RegistryComponentTerminus(void)
00323 %
00324 */
00325 MagickPrivate void RegistryComponentTerminus(void)
00326 {
00327   if (registry_semaphore == (SemaphoreInfo *) NULL)
00328     AcquireSemaphoreInfo(&registry_semaphore);
00329   LockSemaphoreInfo(registry_semaphore);
00330   if (IsEventLogging() != MagickFalse)
00331     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00332   if (registry != (void *) NULL)
00333     registry=DestroySplayTree(registry);
00334   instantiate_registry=MagickFalse;
00335   UnlockSemaphoreInfo(registry_semaphore);
00336   DestroySemaphoreInfo(&registry_semaphore);
00337 }
00338 
00339 /*
00340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00341 %                                                                             %
00342 %                                                                             %
00343 %                                                                             %
00344 %   R e m o v e I m a g e R e g i s t r y                                     %
00345 %                                                                             %
00346 %                                                                             %
00347 %                                                                             %
00348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00349 %
00350 %  RemoveImageRegistry() removes a key from the image registry and returns its
00351 %  value.
00352 %
00353 %  The format of the RemoveImageRegistry method is:
00354 %
00355 %      void *RemoveImageRegistry(const char *key)
00356 %
00357 %  A description of each parameter follows:
00358 %
00359 %    o key: the registry.
00360 %
00361 */
00362 MagickExport void *RemoveImageRegistry(const char *key)
00363 {
00364   if (IsEventLogging() != MagickFalse)
00365     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
00366   if (registry == (void *) NULL)
00367     return((void *) NULL);
00368   return(RemoveNodeFromSplayTree(registry,key));
00369 }
00370 
00371 /*
00372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00373 %                                                                             %
00374 %                                                                             %
00375 %                                                                             %
00376 %   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                       %
00377 %                                                                             %
00378 %                                                                             %
00379 %                                                                             %
00380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00381 %
00382 %  ResetImageRegistryIterator() resets the registry iterator.  Use it in
00383 %  conjunction with GetNextImageRegistry() to iterate over all the values
00384 %  in the image registry.
00385 %
00386 %  The format of the ResetImageRegistryIterator method is:
00387 %
00388 %      ResetImageRegistryIterator(void)
00389 %
00390 */
00391 MagickExport void ResetImageRegistryIterator(void)
00392 {
00393   if (IsEventLogging() != MagickFalse)
00394     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00395   if (registry == (void *) NULL)
00396     return;
00397   ResetSplayTreeIterator(registry);
00398 }
00399 
00400 /*
00401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00402 %                                                                             %
00403 %                                                                             %
00404 %                                                                             %
00405 %   S e t I m a g e R e g i s t r y                                           %
00406 %                                                                             %
00407 %                                                                             %
00408 %                                                                             %
00409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00410 %
00411 %  SetImageRegistry() associates a value with an image registry key.
00412 %
00413 %  The format of the SetImageRegistry method is:
00414 %
00415 %      MagickBooleanType SetImageRegistry(const RegistryType type,
00416 %        const char *key,const void *value,ExceptionInfo *exception)
00417 %
00418 %  A description of each parameter follows:
00419 %
00420 %    o type: the type.
00421 %
00422 %    o key: the key.
00423 %
00424 %    o value: the value.
00425 %
00426 %    o exception: the exception.
00427 %
00428 */
00429 
00430 static void *DestroyRegistryNode(void *registry_info)
00431 {
00432   register RegistryInfo
00433     *p;
00434 
00435   p=(RegistryInfo *) registry_info;
00436   switch (p->type)
00437   {
00438     case StringRegistryType:
00439     default:
00440     {
00441       p->value=RelinquishMagickMemory(p->value);
00442       break;
00443     }
00444     case ImageRegistryType:
00445     {
00446       p->value=(void *) DestroyImageList((Image *) p->value);
00447       break;
00448     }
00449     case ImageInfoRegistryType:
00450     {
00451       p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
00452       break;
00453     }
00454   }
00455   return(RelinquishMagickMemory(p));
00456 }
00457 
00458 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
00459   const char *key,const void *value,ExceptionInfo *exception)
00460 {
00461   MagickBooleanType
00462     status;
00463 
00464   RegistryInfo
00465     *registry_info;
00466 
00467   void
00468     *clone_value;
00469 
00470   if (IsEventLogging() != MagickFalse)
00471     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
00472   clone_value=(void *) NULL;
00473   switch (type)
00474   {
00475     case StringRegistryType:
00476     default:
00477     {
00478       const char
00479         *string;
00480 
00481       string=(const char *) value;
00482       clone_value=(void *) ConstantString(string);
00483       break;
00484     }
00485     case ImageRegistryType:
00486     {
00487       const Image
00488         *image;
00489 
00490       image=(const Image *) value;
00491       if (image->signature != MagickSignature)
00492         {
00493           (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
00494             "UnableToSetRegistry","%s",key);
00495           return(MagickFalse);
00496         }
00497       clone_value=(void *) CloneImageList(image,exception);
00498       break;
00499     }
00500     case ImageInfoRegistryType:
00501     {
00502       const ImageInfo
00503         *image_info;
00504 
00505       image_info=(const ImageInfo *) value;
00506       if (image_info->signature != MagickSignature)
00507         {
00508           (void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
00509             "UnableToSetRegistry","%s",key);
00510           return(MagickFalse);
00511         }
00512       clone_value=(void *) CloneImageInfo(image_info);
00513       break;
00514     }
00515   }
00516   if (clone_value == (void *) NULL)
00517     return(MagickFalse);
00518   registry_info=(RegistryInfo *) AcquireMagickMemory(sizeof(*registry_info));
00519   if (registry_info == (RegistryInfo *) NULL)
00520     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00521   (void) ResetMagickMemory(registry_info,0,sizeof(*registry_info));
00522   registry_info->type=type;
00523   registry_info->value=clone_value;
00524   registry_info->signature=MagickSignature;
00525   if ((registry == (SplayTreeInfo *) NULL) &&
00526       (instantiate_registry == MagickFalse))
00527     {
00528       if (registry_semaphore == (SemaphoreInfo *) NULL)
00529         AcquireSemaphoreInfo(&registry_semaphore);
00530       LockSemaphoreInfo(registry_semaphore);
00531       if ((registry == (SplayTreeInfo *) NULL) &&
00532           (instantiate_registry == MagickFalse))
00533         {
00534           registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
00535             DestroyRegistryNode);
00536           instantiate_registry=MagickTrue;
00537         }
00538       UnlockSemaphoreInfo(registry_semaphore);
00539     }
00540   status=AddValueToSplayTree(registry,ConstantString(key),registry_info);
00541   return(status);
00542 }