]> granicus.if.org Git - imagemagick/blob - MagickCore/string.c
(no commit message)
[imagemagick] / MagickCore / string.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                  SSSSS   TTTTT  RRRR   IIIII  N   N   GGGG                  %
7 %                  SS        T    R   R    I    NN  N  G                      %
8 %                   SSS      T    RRRR     I    N N N  G GGG                  %
9 %                     SS     T    R R      I    N  NN  G   G                  %
10 %                  SSSSS     T    R  R   IIIII  N   N   GGGG                  %
11 %                                                                             %
12 %                                                                             %
13 %                        MagickCore String Methods                            %
14 %                                                                             %
15 %                             Software Design                                 %
16 %                               John Cristy                                   %
17 %                               August 2003                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2011 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 %    http://www.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 \f
39 /*
40   include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/exception.h"
46 #include "MagickCore/exception-private.h"
47 #include "MagickCore/list.h"
48 #include "MagickCore/locale_.h"
49 #include "MagickCore/log.h"
50 #include "MagickCore/memory_.h"
51 #include "MagickCore/property.h"
52 #include "MagickCore/resource_.h"
53 #include "MagickCore/signature-private.h"
54 #include "MagickCore/string_.h"
55 #include "MagickCore/utility-private.h"
56 \f
57 /*
58   static declarations.
59 */
60 #if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
61 static const unsigned char
62   asciimap[] =
63   {
64     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
65     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
66     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
67     0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
68     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
69     0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
70     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
71     0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
72     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
73     0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
74     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
75     0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
76     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
77     0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
78     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
79     0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
80     0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
81     0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
82     0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
83     0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
84     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
85     0xfc, 0xfd, 0xfe, 0xff,
86   };
87 #endif
88 \f
89 /*
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 %                                                                             %
92 %                                                                             %
93 %                                                                             %
94 %   A c q u i r e S t r i n g                                                 %
95 %                                                                             %
96 %                                                                             %
97 %                                                                             %
98 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99 %
100 %  AcquireString() allocates memory for a string and copies the source string
101 %  to that memory location (and returns it).
102 %
103 %  The format of the AcquireString method is:
104 %
105 %      char *AcquireString(const char *source)
106 %
107 %  A description of each parameter follows:
108 %
109 %    o source: A character string.
110 %
111 */
112 MagickExport char *AcquireString(const char *source)
113 {
114   char
115     *destination;
116
117   size_t
118     length;
119
120   length=0;
121   if (source != (char *) NULL)
122     length+=strlen(source);
123   if (~length < MaxTextExtent)
124     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
125   destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
126     sizeof(*destination));
127   if (destination == (char *) NULL)
128     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
129   *destination='\0';
130   if (source != (char *) NULL)
131     (void) memcpy(destination,source,length*sizeof(*destination));
132   destination[length]='\0';
133   return(destination);
134 }
135 \f
136 /*
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 %                                                                             %
139 %                                                                             %
140 %                                                                             %
141 %   A c q u i r e S t r i n g I n f o                                         %
142 %                                                                             %
143 %                                                                             %
144 %                                                                             %
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 %
147 %  AcquireStringInfo() allocates the StringInfo structure.
148 %
149 %  The format of the AcquireStringInfo method is:
150 %
151 %      StringInfo *AcquireStringInfo(const size_t length)
152 %
153 %  A description of each parameter follows:
154 %
155 %    o length: the string length.
156 %
157 */
158 MagickExport StringInfo *AcquireStringInfo(const size_t length)
159 {
160   StringInfo
161     *string_info;
162
163   string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
164   if (string_info == (StringInfo *) NULL)
165     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
166   (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
167   string_info->signature=MagickSignature;
168   string_info->length=length;
169   if (string_info->length != 0)
170     {
171       string_info->datum=(unsigned char *) NULL;
172       if (~string_info->length >= (MaxTextExtent-1))
173         string_info->datum=(unsigned char *) AcquireQuantumMemory(
174           string_info->length+MaxTextExtent,sizeof(*string_info->datum));
175       if (string_info->datum == (unsigned char *) NULL)
176         ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
177     }
178   return(string_info);
179 }
180 \f
181 /*
182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183 %                                                                             %
184 %                                                                             %
185 %                                                                             %
186 %   B l o b T o S t r i n g I n f o                                           %
187 %                                                                             %
188 %                                                                             %
189 %                                                                             %
190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191 %
192 %  BlobToStringInfo() returns the contents of a blob as a string.
193 %
194 %  The format of the BlobToStringInfo method is:
195 %
196 %      StringInfo *BlobToStringInfo(const void *blob,const size_t length)
197 %
198 %  A description of each parameter follows:
199 %
200 %    o blob: the blob.
201 %
202 %    o length: the length of the blob.
203 %
204 */
205 MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
206 {
207   StringInfo
208     *string_info;
209
210   string_info=AcquireStringInfo(0);
211   string_info->length=length;
212   if (~string_info->length >= (MaxTextExtent-1))
213     string_info->datum=(unsigned char *) AcquireQuantumMemory(
214       string_info->length+MaxTextExtent,sizeof(*string_info->datum));
215   if (string_info->datum == (unsigned char *) NULL)
216     {
217       string_info=DestroyStringInfo(string_info);
218       return((StringInfo *) NULL);
219     }
220   if (blob != (const void *) NULL)
221     (void) memcpy(string_info->datum,blob,length);
222   return(string_info);
223 }
224 \f
225 /*
226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 %                                                                             %
228 %                                                                             %
229 %                                                                             %
230 %   C l o n e S t r i n g                                                     %
231 %                                                                             %
232 %                                                                             %
233 %                                                                             %
234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235 %
236 %  CloneString() allocates memory for the destination string and copies
237 %  the source string to that memory location.
238 %
239 %  The format of the CloneString method is:
240 %
241 %      char *CloneString(char **destination,const char *source)
242 %
243 %  A description of each parameter follows:
244 %
245 %    o destination:  A pointer to a character string.
246 %
247 %    o source: A character string.
248 %
249 */
250 MagickExport char *CloneString(char **destination,const char *source)
251 {
252   size_t
253     length;
254
255   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
256   assert(destination != (char **) NULL);
257   if (source == (const char *) NULL)
258     {
259       if (*destination != (char *) NULL)
260         *destination=DestroyString(*destination);
261       return(*destination);
262     }
263   if (*destination == (char *) NULL)
264     {
265       *destination=AcquireString(source);
266       return(*destination);
267     }
268   length=strlen(source);
269   if (~length < MaxTextExtent)
270     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
271   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
272     sizeof(**destination));
273   if (*destination == (char *) NULL)
274     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
275   if (length != 0)
276     (void) memcpy(*destination,source,length*sizeof(**destination));
277   (*destination)[length]='\0';
278   return(*destination);
279 }
280 \f
281 /*
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 %                                                                             %
284 %                                                                             %
285 %                                                                             %
286 %   C l o n e S t r i n g I n f o                                             %
287 %                                                                             %
288 %                                                                             %
289 %                                                                             %
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 %
292 %  CloneStringInfo() clones a copy of the StringInfo structure.
293 %
294 %  The format of the CloneStringInfo method is:
295 %
296 %      StringInfo *CloneStringInfo(const StringInfo *string_info)
297 %
298 %  A description of each parameter follows:
299 %
300 %    o string_info: the string info.
301 %
302 */
303 MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
304 {
305   StringInfo
306     *clone_info;
307
308   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
309   assert(string_info != (StringInfo *) NULL);
310   assert(string_info->signature == MagickSignature);
311   clone_info=AcquireStringInfo(string_info->length);
312   if (string_info->length != 0)
313     (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
314   return(clone_info);
315 }
316 \f
317 /*
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 %                                                                             %
320 %                                                                             %
321 %                                                                             %
322 %   C o m p a r e S t r i n g I n f o                                         %
323 %                                                                             %
324 %                                                                             %
325 %                                                                             %
326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327 %
328 %  CompareStringInfo() compares the two datums target and source.  It returns
329 %  an integer less than, equal to, or greater than zero if target is found,
330 %  respectively, to be less than, to match, or be greater than source.
331 %
332 %  The format of the CompareStringInfo method is:
333 %
334 %      int CompareStringInfo(const StringInfo *target,const StringInfo *source)
335 %
336 %  A description of each parameter follows:
337 %
338 %    o target: the target string.
339 %
340 %    o source: the source string.
341 %
342 */
343
344 static inline size_t MagickMin(const size_t x,const size_t y)
345 {
346   if (x < y)
347     return(x);
348   return(y);
349 }
350
351 MagickExport int CompareStringInfo(const StringInfo *target,
352   const StringInfo *source)
353 {
354   int
355     status;
356
357   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
358   assert(target != (StringInfo *) NULL);
359   assert(target->signature == MagickSignature);
360   assert(source != (StringInfo *) NULL);
361   assert(source->signature == MagickSignature);
362   status=memcmp(target->datum,source->datum,MagickMin(target->length,
363     source->length));
364   if (status != 0)
365     return(status);
366   if (target->length == source->length)
367     return(0);
368   return(target->length < source->length ? -1 : 1);
369 }
370 \f
371 /*
372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373 %                                                                             %
374 %                                                                             %
375 %                                                                             %
376 %   C o n c a t e n a t e M a g i c k S t r i n g                             %
377 %                                                                             %
378 %                                                                             %
379 %                                                                             %
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 %
382 %  ConcatenateMagickString() concatenates the source string to the destination
383 %  string.  The destination buffer is always null-terminated even if the
384 %  string must be truncated.
385 %
386 %  The format of the ConcatenateMagickString method is:
387 %
388 %      size_t ConcatenateMagickString(char *destination,const char *source,
389 %        const size_t length)
390 %
391 %  A description of each parameter follows:
392 %
393 %    o destination: the destination string.
394 %
395 %    o source: the source string.
396 %
397 %    o length: the length of the destination string.
398 %
399 */
400 MagickExport size_t ConcatenateMagickString(char *destination,
401   const char *source,const size_t length)
402 {
403   register char
404     *q;
405
406   register const char
407     *p;
408
409   register size_t
410     i;
411
412   size_t
413     count;
414
415   assert(destination != (char *) NULL);
416   assert(source != (const char *) NULL);
417   assert(length >= 1);
418   p=source;
419   q=destination;
420   i=length;
421   while ((i-- != 0) && (*q != '\0'))
422     q++;
423   count=(size_t) (q-destination);
424   i=length-count;
425   if (i == 0)
426     return(count+strlen(p));
427   while (*p != '\0')
428   {
429     if (i != 1)
430       {
431         *q++=(*p);
432         i--;
433       }
434     p++;
435   }
436   *q='\0';
437   return(count+(p-source));
438 }
439 \f
440 /*
441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442 %                                                                             %
443 %                                                                             %
444 %                                                                             %
445 %   C o n c a t e n a t e S t r i n g                                         %
446 %                                                                             %
447 %                                                                             %
448 %                                                                             %
449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 %
451 %  ConcatenateString() appends a copy of string source, including the
452 %  terminating null character, to the end of string destination.
453 %
454 %  The format of the ConcatenateString method is:
455 %
456 %      MagickBooleanType ConcatenateString(char **destination,
457 %        const char *source)
458 %
459 %  A description of each parameter follows:
460 %
461 %    o destination:  A pointer to a character string.
462 %
463 %    o source: A character string.
464 %
465 */
466 MagickExport MagickBooleanType ConcatenateString(char **destination,
467   const char *source)
468 {
469   size_t
470     destination_length,
471     length,
472     source_length;
473
474   assert(destination != (char **) NULL);
475   if (source == (const char *) NULL)
476     return(MagickTrue);
477   if (*destination == (char *) NULL)
478     {
479       *destination=AcquireString(source);
480       return(MagickTrue);
481     }
482   destination_length=strlen(*destination);
483   source_length=strlen(source);
484   length=destination_length;
485   if (~length < source_length)
486     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
487   length+=source_length;
488   if (~length < MaxTextExtent)
489     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
490   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
491     sizeof(**destination));
492   if (*destination == (char *) NULL)
493     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
494   if (source_length != 0)
495     (void) memcpy((*destination)+destination_length,source,source_length);
496   (*destination)[length]='\0';
497   return(MagickTrue);
498 }
499 \f
500 /*
501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502 %                                                                             %
503 %                                                                             %
504 %                                                                             %
505 %   C o n c a t e n a t e S t r i n g I n f o                                 %
506 %                                                                             %
507 %                                                                             %
508 %                                                                             %
509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510 %
511 %  ConcatenateStringInfo() concatenates the source string to the destination
512 %  string.
513 %
514 %  The format of the ConcatenateStringInfo method is:
515 %
516 %      void ConcatenateStringInfo(StringInfo *string_info,
517 %        const StringInfo *source)
518 %
519 %  A description of each parameter follows:
520 %
521 %    o string_info: the string info.
522 %
523 %    o source: the source string.
524 %
525 */
526 MagickExport void ConcatenateStringInfo(StringInfo *string_info,
527   const StringInfo *source)
528 {
529   size_t
530     length;
531
532   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
533   assert(string_info != (StringInfo *) NULL);
534   assert(string_info->signature == MagickSignature);
535   assert(source != (const StringInfo *) NULL);
536   length=string_info->length;
537   if (~length < source->length)
538     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
539   SetStringInfoLength(string_info,length+source->length);
540   (void) memcpy(string_info->datum+length,source->datum,source->length);
541 }
542 \f
543 /*
544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545 %                                                                             %
546 %                                                                             %
547 %                                                                             %
548 %   C o n f i g u r e F i l e T o S t r i n g I n f o                         %
549 %                                                                             %
550 %                                                                             %
551 %                                                                             %
552 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553 %
554 %  ConfigureFileToStringInfo() returns the contents of a configure file as a
555 %  string.
556 %
557 %  The format of the ConfigureFileToStringInfo method is:
558 %
559 %      StringInfo *ConfigureFileToStringInfo(const char *filename)
560 %        ExceptionInfo *exception)
561 %
562 %  A description of each parameter follows:
563 %
564 %    o filename: the filename.
565 %
566 */
567 MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
568 {
569   char
570     *string;
571
572   int
573     file;
574
575   MagickOffsetType
576     offset;
577
578   size_t
579     length;
580
581   StringInfo
582     *string_info;
583
584   void
585     *map;
586
587   assert(filename != (const char *) NULL);
588   file=open_utf8(filename,O_RDONLY | O_BINARY,0);
589   if (file == -1)
590     return((StringInfo *) NULL);
591   offset=(MagickOffsetType) lseek(file,0,SEEK_END);
592   if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
593     {
594       file=close(file)-1;
595       return((StringInfo *) NULL);
596     }
597   length=(size_t) offset;
598   string=(char *) NULL;
599   if (~length >= (MaxTextExtent-1))
600     string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
601   if (string == (char *) NULL)
602     {
603       file=close(file)-1;
604       return((StringInfo *) NULL);
605     }
606   map=MapBlob(file,ReadMode,0,length);
607   if (map != (void *) NULL)
608     {
609       (void) memcpy(string,map,length);
610       (void) UnmapBlob(map,length);
611     }
612   else
613     {
614       register size_t
615         i;
616
617       ssize_t
618         count;
619
620       (void) lseek(file,0,SEEK_SET);
621       for (i=0; i < length; i+=count)
622       {
623         count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
624           SSIZE_MAX));
625         if (count <= 0)
626           {
627             count=0;
628             if (errno != EINTR)
629               break;
630           }
631       }
632       if (i < length)
633         {
634           file=close(file)-1;
635           string=DestroyString(string);
636           return((StringInfo *) NULL);
637         }
638     }
639   string[length]='\0';
640   file=close(file)-1;
641   string_info=AcquireStringInfo(0);
642   (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
643   string_info->length=length;
644   string_info->datum=(unsigned char *) string;
645   return(string_info);
646 }
647 \f
648 /*
649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
650 %                                                                             %
651 %                                                                             %
652 %                                                                             %
653 %   C o n s t a n t S t r i n g                                               %
654 %                                                                             %
655 %                                                                             %
656 %                                                                             %
657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
658 %
659 %  ConstantString() allocates memory for a string and copies the source string
660 %  to that memory location (and returns it).  Use it for strings that you do
661 %  do not expect to change over its lifetime.
662 %
663 %  The format of the ConstantString method is:
664 %
665 %      char *ConstantString(const char *source)
666 %
667 %  A description of each parameter follows:
668 %
669 %    o source: A character string.
670 %
671 */
672 MagickExport char *ConstantString(const char *source)
673 {
674   char
675     *destination;
676
677   size_t
678     length;
679
680   length=0;
681   if (source != (char *) NULL)
682     length+=strlen(source);
683   destination=(char *) NULL;
684   if (~length >= 1UL)
685     destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
686   if (destination == (char *) NULL)
687     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
688   *destination='\0';
689   if (source != (char *) NULL)
690     (void) memcpy(destination,source,length*sizeof(*destination));
691   destination[length]='\0';
692   return(destination);
693 }
694 \f
695 /*
696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697 %                                                                             %
698 %                                                                             %
699 %                                                                             %
700 %   C o p y M a g i c k S t r i n g                                           %
701 %                                                                             %
702 %                                                                             %
703 %                                                                             %
704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
705 %
706 %  CopyMagickString() copies the source string to the destination string.  The
707 %  destination buffer is always null-terminated even if the string must be
708 %  truncated.  The return value is the minimum of the source string length
709 %  or the length parameter.
710 %
711 %  The format of the CopyMagickString method is:
712 %
713 %      size_t CopyMagickString(const char *destination,char *source,
714 %        const size_t length)
715 %
716 %  A description of each parameter follows:
717 %
718 %    o destination: the destination string.
719 %
720 %    o source: the source string.
721 %
722 %    o length: the length of the destination string.
723 %
724 */
725 MagickExport size_t CopyMagickString(char *destination,const char *source,
726   const size_t length)
727 {
728   register char
729     *q;
730
731   register const char
732     *p;
733
734   register size_t
735     n;
736
737   if (source == (const char *) NULL)
738     return(0);
739   p=source;
740   q=destination;
741   for (n=length; n > 4; n-=4)
742   {
743     *q=(*p++);
744     if (*q == '\0')
745       return((size_t) (p-source-1));
746     q++;
747     *q=(*p++);
748     if (*q == '\0')
749       return((size_t) (p-source-1));
750     q++;
751     *q=(*p++);
752     if (*q == '\0')
753       return((size_t) (p-source-1));
754     q++;
755     *q=(*p++);
756     if (*q == '\0')
757       return((size_t) (p-source-1));
758     q++;
759   }
760   if (n != 0)
761     for (n--; n != 0; n--)
762     {
763       *q=(*p++);
764       if (*q == '\0')
765         return((size_t) (p-source-1));
766       q++;
767     }
768   if (length != 0)
769     *q='\0';
770   return((size_t) (p-source-1));
771 }
772 \f
773 /*
774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775 %                                                                             %
776 %                                                                             %
777 %                                                                             %
778 %   D e s t r o y S t r i n g                                                 %
779 %                                                                             %
780 %                                                                             %
781 %                                                                             %
782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783 %
784 %  DestroyString() destroys memory associated with a string.
785 %
786 %  The format of the DestroyString method is:
787 %
788 %      char *DestroyString(char *string)
789 %
790 %  A description of each parameter follows:
791 %
792 %    o string: the string.
793 %
794 */
795 MagickExport char *DestroyString(char *string)
796 {
797   return((char *) RelinquishMagickMemory(string));
798 }
799 \f
800 /*
801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 %                                                                             %
803 %                                                                             %
804 %                                                                             %
805 %   D e s t r o y S t r i n g I n f o                                         %
806 %                                                                             %
807 %                                                                             %
808 %                                                                             %
809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
810 %
811 %  DestroyStringInfo() destroys memory associated with the StringInfo structure.
812 %
813 %  The format of the DestroyStringInfo method is:
814 %
815 %      StringInfo *DestroyStringInfo(StringInfo *string_info)
816 %
817 %  A description of each parameter follows:
818 %
819 %    o string_info: the string info.
820 %
821 */
822 MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
823 {
824   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
825   assert(string_info != (StringInfo *) NULL);
826   assert(string_info->signature == MagickSignature);
827   if (string_info->datum != (unsigned char *) NULL)
828     string_info->datum=(unsigned char *) RelinquishMagickMemory(
829       string_info->datum);
830   string_info->signature=(~MagickSignature);
831   string_info=(StringInfo *) RelinquishMagickMemory(string_info);
832   return(string_info);
833 }
834 \f
835 /*
836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837 %                                                                             %
838 %                                                                             %
839 %                                                                             %
840 %   D e s t r o y S t r i n g L i s t                                         %
841 %                                                                             %
842 %                                                                             %
843 %                                                                             %
844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845 %
846 %  DestroyStringList() zeros memory associated with a string list.
847 %
848 %  The format of the DestroyStringList method is:
849 %
850 %      char **DestroyStringList(char **list)
851 %
852 %  A description of each parameter follows:
853 %
854 %    o list: the string list.
855 %
856 */
857 MagickExport char **DestroyStringList(char **list)
858 {
859   register ssize_t
860     i;
861
862   assert(list != (char **) NULL);
863   for (i=0; list[i] != (char *) NULL; i++)
864     list[i]=DestroyString(list[i]);
865   list=(char **) RelinquishMagickMemory(list);
866   return(list);
867 }
868 \f
869 /*
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871 %                                                                             %
872 %                                                                             %
873 %                                                                             %
874 %   E s c a p e S t r i n g                                                   %
875 %                                                                             %
876 %                                                                             %
877 %                                                                             %
878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879 %
880 %  EscapeString() allocates memory for a backslash-escaped version of a
881 %  source text string, copies the escaped version of the text to that
882 %  memory location while adding backslash characters, and returns the
883 %  escaped string.
884 %
885 %  The format of the EscapeString method is:
886 %
887 %      char *EscapeString(const char *source,const char escape)
888 %
889 %  A description of each parameter follows:
890 %
891 %    o allocate_string:  Method EscapeString returns the escaped string.
892 %
893 %    o source: A character string.
894 %
895 %    o escape: the quoted string termination character to escape (e.g. '"').
896 %
897 */
898 MagickExport char *EscapeString(const char *source,const char escape)
899 {
900   char
901     *destination;
902
903   register char
904     *q;
905
906   register const char
907     *p;
908
909   size_t
910     length;
911
912   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
913   assert(source != (const char *) NULL);
914   length=strlen(source);
915   for (p=source; *p != '\0'; p++)
916     if ((*p == '\\') || (*p == escape))
917       {
918         if (~length < 1)
919           ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
920         length++;
921       }
922   destination=(char *) NULL;
923   if (~length >= (MaxTextExtent-1))
924     destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
925       sizeof(*destination));
926   if (destination == (char *) NULL)
927     ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
928   *destination='\0';
929   if (source != (char *) NULL)
930     {
931       q=destination;
932       for (p=source; *p != '\0'; p++)
933       {
934         if ((*p == '\\') || (*p == escape))
935           *q++='\\';
936         *q++=(*p);
937       }
938       *q='\0';
939     }
940   return(destination);
941 }
942 \f
943 /*
944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 %                                                                             %
946 %                                                                             %
947 %                                                                             %
948 %   F i l e T o S t r i n g                                                   %
949 %                                                                             %
950 %                                                                             %
951 %                                                                             %
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953 %
954 %  FileToString() returns the contents of a file as a string.
955 %
956 %  The format of the FileToString method is:
957 %
958 %      char *FileToString(const char *filename,const size_t extent,
959 %        ExceptionInfo *exception)
960 %
961 %  A description of each parameter follows:
962 %
963 %    o filename: the filename.
964 %
965 %    o extent: Maximum length of the string.
966 %
967 %    o exception: return any errors or warnings in this structure.
968 %
969 */
970 MagickExport char *FileToString(const char *filename,const size_t extent,
971   ExceptionInfo *exception)
972 {
973   size_t
974     length;
975
976   assert(filename != (const char *) NULL);
977   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
978   assert(exception != (ExceptionInfo *) NULL);
979   return((char *) FileToBlob(filename,extent,&length,exception));
980 }
981 \f
982 /*
983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
984 %                                                                             %
985 %                                                                             %
986 %                                                                             %
987 %   F i l e T o S t r i n g I n f o                                           %
988 %                                                                             %
989 %                                                                             %
990 %                                                                             %
991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992 %
993 %  FileToStringInfo() returns the contents of a file as a string.
994 %
995 %  The format of the FileToStringInfo method is:
996 %
997 %      StringInfo *FileToStringInfo(const char *filename,const size_t extent,
998 %        ExceptionInfo *exception)
999 %
1000 %  A description of each parameter follows:
1001 %
1002 %    o filename: the filename.
1003 %
1004 %    o extent: Maximum length of the string.
1005 %
1006 %    o exception: return any errors or warnings in this structure.
1007 %
1008 */
1009 MagickExport StringInfo *FileToStringInfo(const char *filename,
1010   const size_t extent,ExceptionInfo *exception)
1011 {
1012   StringInfo
1013     *string_info;
1014
1015   assert(filename != (const char *) NULL);
1016   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1017   assert(exception != (ExceptionInfo *) NULL);
1018   string_info=AcquireStringInfo(0);
1019   (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1020   string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1021   if (string_info->datum == (unsigned char *) NULL)
1022     {
1023       string_info=DestroyStringInfo(string_info);
1024       return((StringInfo *) NULL);
1025     }
1026   return(string_info);
1027 }
1028 \f
1029 /*
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031 %                                                                             %
1032 %                                                                             %
1033 %                                                                             %
1034 %  F o r m a t M a g i c k S i z e                                            %
1035 %                                                                             %
1036 %                                                                             %
1037 %                                                                             %
1038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039 %
1040 %  FormatMagickSize() converts a size to a human readable format, for example,
1041 %  14k, 234m, 2.7g, or 3.0t.  Scaling is done by repetitively dividing by
1042 %  1000.
1043 %
1044 %  The format of the FormatMagickSize method is:
1045 %
1046 %      ssize_t FormatMagickSize(const MagickSizeType size,char *format)
1047 %
1048 %  A description of each parameter follows:
1049 %
1050 %    o size:  convert this size to a human readable format.
1051 %
1052 %    o bi:  use power of two rather than power of ten.
1053 %
1054 %    o format:  human readable format.
1055 %
1056 */
1057 MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
1058   const MagickBooleanType bi,char *format)
1059 {
1060   const char
1061     **units;
1062
1063   double
1064     bytes,
1065     length;
1066
1067   register ssize_t
1068     i,
1069     j;
1070
1071   ssize_t
1072     count;
1073
1074   static const char
1075     *bi_units[] =
1076     {
1077       "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
1078     },
1079     *traditional_units[] =
1080     {
1081       "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
1082     };
1083
1084   bytes=1000.0;
1085   units=traditional_units;
1086   if (bi != MagickFalse)
1087     {
1088       bytes=1024.0;
1089       units=bi_units;
1090     }
1091 #if defined(_MSC_VER) && (_MSC_VER == 1200)
1092   length=(double) ((MagickOffsetType) size);
1093 #else
1094   length=(double) size;
1095 #endif
1096   for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1097     length/=bytes;
1098   for (j=2; j < 12; j++)
1099   {
1100     count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
1101       units[i]);
1102     if (strchr(format,'+') == (char *) NULL)
1103       break;
1104   }
1105   return(count);
1106 }
1107 \f
1108 /*
1109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110 %                                                                             %
1111 %                                                                             %
1112 %                                                                             %
1113 %  F o r m a t M a g i c k T i m e                                            %
1114 %                                                                             %
1115 %                                                                             %
1116 %                                                                             %
1117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118 %
1119 %  FormatMagickTime() returns the specified time in the Internet date/time
1120 %  format and the length of the timestamp.
1121 %
1122 %  The format of the FormatMagickTime method is:
1123 %
1124 %      ssize_t FormatMagickTime(const time_t time,const size_t length,
1125 %        char *timestamp)
1126 %
1127 %  A description of each parameter follows.
1128 %
1129 %   o time:  the time since the Epoch (00:00:00 UTC, January 1, 1970),
1130 %     measured in seconds.
1131 %
1132 %   o length: the maximum length of the string.
1133 %
1134 %   o timestamp:  Return the Internet date/time here.
1135 %
1136 */
1137 MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
1138   char *timestamp)
1139 {
1140   ssize_t
1141     count;
1142
1143   struct tm
1144     gm_time,
1145     local_time;
1146
1147   time_t
1148     timezone;
1149
1150   assert(timestamp != (char *) NULL);
1151   (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1152   (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1153 #if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1154   (void) localtime_r(&time,&local_time);
1155 #else
1156   {
1157     struct tm
1158       *my_time;
1159
1160     my_time=localtime(&time);
1161     if (my_time != (struct tm *) NULL)
1162       (void) memcpy(&local_time,my_time,sizeof(local_time));
1163   }
1164 #endif
1165 #if defined(MAGICKCORE_HAVE_GMTIME_R)
1166   (void) gmtime_r(&time,&gm_time);
1167 #else
1168   {
1169     struct tm
1170       *my_time;
1171
1172     my_time=gmtime(&time);
1173     if (my_time != (struct tm *) NULL)
1174       (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1175   }
1176 #endif
1177   timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1178     local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1179     gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1180     (local_time.tm_yday-gm_time.tm_yday)));
1181   count=FormatLocaleString(timestamp,length,
1182     "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1183     local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
1184     local_time.tm_min,local_time.tm_sec,(long) timezone);
1185   return(count);
1186 }
1187 \f
1188 /*
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1190 %                                                                             %
1191 %                                                                             %
1192 %                                                                             %
1193 %   G e t E n v i r o n m e n t V a l u e                                     %
1194 %                                                                             %
1195 %                                                                             %
1196 %                                                                             %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1198 %
1199 %  GetEnvironmentValue() returns the environment string that matches the
1200 %  specified name.
1201 %
1202 %  The format of the GetEnvironmentValue method is:
1203 %
1204 %      char *GetEnvironmentValue(const char *name)
1205 %
1206 %  A description of each parameter follows:
1207 %
1208 %    o name: the environment name.
1209 %
1210 */
1211 MagickExport char *GetEnvironmentValue(const char *name)
1212 {
1213   const char
1214     *environment;
1215
1216   environment=getenv(name);
1217   if (environment == (const char *) NULL)
1218     return((char *) NULL);
1219   return(ConstantString(environment));
1220 }
1221 \f
1222 /*
1223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1224 %                                                                             %
1225 %                                                                             %
1226 %                                                                             %
1227 %   G e t S t r i n g I n f o D a t u m                                       %
1228 %                                                                             %
1229 %                                                                             %
1230 %                                                                             %
1231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1232 %
1233 %  GetStringInfoDatum() returns the datum associated with the string.
1234 %
1235 %  The format of the GetStringInfoDatum method is:
1236 %
1237 %      unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1238 %
1239 %  A description of each parameter follows:
1240 %
1241 %    o string_info: the string info.
1242 %
1243 */
1244 MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1245 {
1246   assert(string_info != (StringInfo *) NULL);
1247   assert(string_info->signature == MagickSignature);
1248   return(string_info->datum);
1249 }
1250 \f
1251 /*
1252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1253 %                                                                             %
1254 %                                                                             %
1255 %                                                                             %
1256 %   G e t S t r i n g I n f o L e n g t h                                     %
1257 %                                                                             %
1258 %                                                                             %
1259 %                                                                             %
1260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1261 %
1262 %  GetStringInfoLength() returns the string length.
1263 %
1264 %  The format of the GetStringInfoLength method is:
1265 %
1266 %      size_t GetStringInfoLength(const StringInfo *string_info)
1267 %
1268 %  A description of each parameter follows:
1269 %
1270 %    o string_info: the string info.
1271 %
1272 */
1273 MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1274 {
1275   assert(string_info != (StringInfo *) NULL);
1276   assert(string_info->signature == MagickSignature);
1277   return(string_info->length);
1278 }
1279 \f
1280 /*
1281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1282 %                                                                             %
1283 %                                                                             %
1284 %                                                                             %
1285 %   G e t S t r i n g I n f o P a t h                                         %
1286 %                                                                             %
1287 %                                                                             %
1288 %                                                                             %
1289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290 %
1291 %  GetStringInfoPath() returns the path associated with the string.
1292 %
1293 %  The format of the GetStringInfoPath method is:
1294 %
1295 %      const char *GetStringInfoPath(const StringInfo *string_info)
1296 %
1297 %  A description of each parameter follows:
1298 %
1299 %    o string_info: the string info.
1300 %
1301 */
1302 MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1303 {
1304   assert(string_info != (StringInfo *) NULL);
1305   assert(string_info->signature == MagickSignature);
1306   return(string_info->path);
1307 }
1308 \f
1309 /*
1310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1311 %                                                                             %
1312 %                                                                             %
1313 %                                                                             %
1314 +   I n t e r p r e t S i P r e f i x V a l u e                               %
1315 %                                                                             %
1316 %                                                                             %
1317 %                                                                             %
1318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319 %
1320 %  InterpretSiPrefixValue() converts the initial portion of the string to a
1321 %  double representation.  It also recognizes SI prefixes (e.g. B, KB, MiB,
1322 %  etc.).
1323 %
1324 %  The format of the InterpretSiPrefixValue method is:
1325 %
1326 %      double InterpretSiPrefixValue(const char *value,char **sentinal)
1327 %
1328 %  A description of each parameter follows:
1329 %
1330 %    o value: the string value.
1331 %
1332 %    o sentinal:  if sentinal is not NULL, return a pointer to the character
1333 %      after the last character used in the conversion.
1334 %
1335 */
1336 MagickExport double InterpretSiPrefixValue(const char *restrict string,
1337   char **restrict sentinal)
1338 {
1339   char
1340     *q;
1341
1342   double
1343     value;
1344
1345   value=InterpretLocaleValue(string,&q);
1346   if (q != string)
1347     {
1348       if ((*q >= 'E') && (*q <= 'z'))
1349         {
1350           double
1351             e;
1352
1353           switch ((int) ((unsigned char) *q))
1354           {
1355             case 'y': e=(-24.0); break;
1356             case 'z': e=(-21.0); break;
1357             case 'a': e=(-18.0); break;
1358             case 'f': e=(-15.0); break;
1359             case 'p': e=(-12.0); break;
1360             case 'n': e=(-9.0); break;
1361             case 'u': e=(-6.0); break;
1362             case 'm': e=(-3.0); break;
1363             case 'c': e=(-2.0); break;
1364             case 'd': e=(-1.0); break;
1365             case 'h': e=2.0; break;
1366             case 'k': e=3.0; break;
1367             case 'K': e=3.0; break;
1368             case 'M': e=6.0; break;
1369             case 'G': e=9.0; break;
1370             case 'T': e=12.0; break;
1371             case 'P': e=15.0; break;
1372             case 'E': e=18.0; break;
1373             case 'Z': e=21.0; break;
1374             case 'Y': e=24.0; break;
1375             default: e=0.0; break;
1376           }
1377           if (e >= MagickEpsilon)
1378             {
1379               if (q[1] == 'i')
1380                 {
1381                   value*=pow(2.0,e/0.3);
1382                   q+=2;
1383                 }
1384               else
1385                 {
1386                   value*=pow(10.0,e);
1387                   q++;
1388                 }
1389             }
1390         }
1391       if (*q == 'B')
1392         q++;
1393     }
1394   if (sentinal != (char **) NULL)
1395     *sentinal=q;
1396   return(value);
1397 }
1398 \f
1399 /*
1400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1401 %                                                                             %
1402 %                                                                             %
1403 %                                                                             %
1404 %   L o c a l e C o m p a r e                                                 %
1405 %                                                                             %
1406 %                                                                             %
1407 %                                                                             %
1408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409 %
1410 %  LocaleCompare() performs a case-insensitive comparison of two strings
1411 %  byte-by-byte, according to the ordering of the current locale encoding.
1412 %  LocaleCompare returns an integer greater than, equal to, or less than 0,
1413 %  if the string pointed to by p is greater than, equal to, or less than the
1414 %  string pointed to by q respectively.  The sign of a non-zero return value
1415 %  is determined by the sign of the difference between the values of the first
1416 %  pair of bytes that differ in the strings being compared.
1417 %
1418 %  The format of the LocaleCompare method is:
1419 %
1420 %      int LocaleCompare(const char *p,const char *q)
1421 %
1422 %  A description of each parameter follows:
1423 %
1424 %    o p: A pointer to a character string.
1425 %
1426 %    o q: A pointer to a character string to compare to p.
1427 %
1428 */
1429 MagickExport int LocaleCompare(const char *p,const char *q)
1430 {
1431   if ((p == (char *) NULL) && (q == (char *) NULL))
1432     return(0);
1433   if (p == (char *) NULL)
1434     return(-1);
1435   if (q == (char *) NULL)
1436     return(1);
1437 #if defined(MAGICKCORE_HAVE_STRCASECMP)
1438   return(strcasecmp(p,q));
1439 #else
1440   {
1441     register int
1442       c,
1443       d;
1444
1445     for ( ; ; )
1446     {
1447       c=(int) *((unsigned char *) p);
1448       d=(int) *((unsigned char *) q);
1449       if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
1450         break;
1451       p++;
1452       q++;
1453     }
1454     return(AsciiMap[c]-(int) AsciiMap[d]);
1455   }
1456 #endif
1457 }
1458 \f
1459 /*
1460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1461 %                                                                             %
1462 %                                                                             %
1463 %                                                                             %
1464 %   L o c a l e L o w e r                                                     %
1465 %                                                                             %
1466 %                                                                             %
1467 %                                                                             %
1468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469 %
1470 %  LocaleLower() transforms all of the characters in the supplied
1471 %  null-terminated string, changing all uppercase letters to lowercase.
1472 %
1473 %  The format of the LocaleLower method is:
1474 %
1475 %      void LocaleLower(char *string)
1476 %
1477 %  A description of each parameter follows:
1478 %
1479 %    o string: A pointer to the string to convert to lower-case Locale.
1480 %
1481 */
1482 MagickExport void LocaleLower(char *string)
1483 {
1484   register char
1485     *q;
1486
1487   assert(string != (char *) NULL);
1488   for (q=string; *q != '\0'; q++)
1489     *q=(char) tolower((int) *q);
1490 }
1491 \f
1492 /*
1493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1494 %                                                                             %
1495 %                                                                             %
1496 %                                                                             %
1497 %   L o c a l e N C o m p a r e                                               %
1498 %                                                                             %
1499 %                                                                             %
1500 %                                                                             %
1501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1502 %
1503 %  LocaleNCompare() performs a case-insensitive comparison of two
1504 %  strings byte-by-byte, according to the ordering of the current locale
1505 %  encoding. LocaleNCompare returns an integer greater than, equal to, or
1506 %  less than 0, if the string pointed to by p is greater than, equal to, or
1507 %  less than the string pointed to by q respectively.  The sign of a non-zero
1508 %  return value is determined by the sign of the difference between the
1509 %  values of the first pair of bytes that differ in the strings being
1510 %  compared.  The LocaleNCompare method makes the same comparison as
1511 %  LocaleCompare but looks at a maximum of n bytes.  Bytes following a
1512 %  null byte are not compared.
1513 %
1514 %  The format of the LocaleNCompare method is:
1515 %
1516 %      int LocaleNCompare(const char *p,const char *q,const size_t n)
1517 %
1518 %  A description of each parameter follows:
1519 %
1520 %    o p: A pointer to a character string.
1521 %
1522 %    o q: A pointer to a character string to compare to p.
1523 %
1524 %    o length: the number of characters to compare in strings p and q.
1525 %
1526 */
1527 MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
1528 {
1529   if ((p == (char *) NULL) && (q == (char *) NULL))
1530     return(0);
1531   if (p == (char *) NULL)
1532     return(-1);
1533   if (q == (char *) NULL)
1534     return(1);
1535 #if defined(MAGICKCORE_HAVE_STRNCASECMP)
1536   return(strncasecmp(p,q,length));
1537 #else
1538   {
1539     register int
1540       c,
1541       d;
1542
1543     register size_t
1544       i;
1545
1546     for (i=length; i != 0; i--)
1547     {
1548       c=(int) *((unsigned char *) p);
1549       d=(int) *((unsigned char *) q);
1550       if (AsciiMap[c] != AsciiMap[d])
1551         return(AsciiMap[c]-(int) AsciiMap[d]);
1552       if (c == 0)
1553         return(0);
1554       p++;
1555       q++;
1556     }
1557     return(0);
1558   }
1559 #endif
1560 }
1561 \f
1562 /*
1563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564 %                                                                             %
1565 %                                                                             %
1566 %                                                                             %
1567 %   L o c a l e U p p e r                                                     %
1568 %                                                                             %
1569 %                                                                             %
1570 %                                                                             %
1571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1572 %
1573 %  LocaleUpper() transforms all of the characters in the supplied
1574 %  null-terminated string, changing all lowercase letters to uppercase.
1575 %
1576 %  The format of the LocaleUpper method is:
1577 %
1578 %      void LocaleUpper(char *string)
1579 %
1580 %  A description of each parameter follows:
1581 %
1582 %    o string: A pointer to the string to convert to upper-case Locale.
1583 %
1584 */
1585 MagickExport void LocaleUpper(char *string)
1586 {
1587   register char
1588     *q;
1589
1590   assert(string != (char *) NULL);
1591   for (q=string; *q != '\0'; q++)
1592     *q=(char) toupper((int) *q);
1593 }
1594 \f
1595 /*
1596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1597 %                                                                             %
1598 %                                                                             %
1599 %                                                                             %
1600 %   P r i n t S t r i n g I n f o                                             %
1601 %                                                                             %
1602 %                                                                             %
1603 %                                                                             %
1604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605 %
1606 %  PrintStringInfo() prints the string.
1607 %
1608 %  The format of the PrintStringInfo method is:
1609 %
1610 %      void PrintStringInfo(FILE *file,const char *id,
1611 %        const StringInfo *string_info)
1612 %
1613 %  A description of each parameter follows:
1614 %
1615 %    o file: the file, typically stdout.
1616 %
1617 %    o id: the string id.
1618 %
1619 %    o string_info: the string info.
1620 %
1621 */
1622 MagickExport void PrintStringInfo(FILE *file,const char *id,
1623   const StringInfo *string_info)
1624 {
1625   register const char
1626     *p;
1627
1628   register size_t
1629     i,
1630     j;
1631
1632   assert(id != (const char *) NULL);
1633   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1634   assert(string_info != (StringInfo *) NULL);
1635   assert(string_info->signature == MagickSignature);
1636   p=(char *) string_info->datum;
1637   for (i=0; i < string_info->length; i++)
1638   {
1639     if (((int) ((unsigned char) *p) < 32) &&
1640         (isspace((int) ((unsigned char) *p)) == 0))
1641       break;
1642     p++;
1643   }
1644   if (i == string_info->length)
1645     {
1646       (void) fputs((char *) string_info->datum,file);
1647       (void) fputc('\n',file);
1648       return;
1649     }
1650   /*
1651     Convert string to a HEX list.
1652   */
1653   p=(char *) string_info->datum;
1654   for (i=0; i < string_info->length; i+=0x14)
1655   {
1656     (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
1657     for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1658     {
1659       (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
1660       if ((j % 0x04) == 0)
1661         (void) fputc(' ',file);
1662     }
1663     for ( ; j <= 0x14; j++)
1664     {
1665       (void) fputc(' ',file);
1666       (void) fputc(' ',file);
1667       if ((j % 0x04) == 0)
1668         (void) fputc(' ',file);
1669     }
1670     (void) fputc(' ',file);
1671     for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1672     {
1673       if (isprint((int) ((unsigned char) *p)) != 0)
1674         (void) fputc(*p,file);
1675       else
1676         (void) fputc('-',file);
1677       p++;
1678     }
1679     (void) fputc('\n',file);
1680   }
1681 }
1682 \f
1683 /*
1684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1685 %                                                                             %
1686 %                                                                             %
1687 %                                                                             %
1688 %   R e s e t S t r i n g I n f o                                             %
1689 %                                                                             %
1690 %                                                                             %
1691 %                                                                             %
1692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693 %
1694 %  ResetStringInfo() reset the string to all null bytes.
1695 %
1696 %  The format of the ResetStringInfo method is:
1697 %
1698 %      void ResetStringInfo(StringInfo *string_info)
1699 %
1700 %  A description of each parameter follows:
1701 %
1702 %    o string_info: the string info.
1703 %
1704 */
1705 MagickExport void ResetStringInfo(StringInfo *string_info)
1706 {
1707   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1708   assert(string_info != (StringInfo *) NULL);
1709   assert(string_info->signature == MagickSignature);
1710   (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1711 }
1712 \f
1713 /*
1714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1715 %                                                                             %
1716 %                                                                             %
1717 %                                                                             %
1718 %   S e t S t r i n g I n f o                                                 %
1719 %                                                                             %
1720 %                                                                             %
1721 %                                                                             %
1722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1723 %
1724 %  SetStringInfo() copies the source string to the destination string.
1725 %
1726 %  The format of the SetStringInfo method is:
1727 %
1728 %      void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1729 %
1730 %  A description of each parameter follows:
1731 %
1732 %    o string_info: the string info.
1733 %
1734 %    o source: the source string.
1735 %
1736 */
1737 MagickExport void SetStringInfo(StringInfo *string_info,
1738   const StringInfo *source)
1739 {
1740   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1741   assert(string_info != (StringInfo *) NULL);
1742   assert(string_info->signature == MagickSignature);
1743   assert(source != (StringInfo *) NULL);
1744   assert(source->signature == MagickSignature);
1745   if (string_info->length == 0)
1746     return;
1747   (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1748   (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1749     source->length));
1750 }
1751 \f
1752 /*
1753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1754 %                                                                             %
1755 %                                                                             %
1756 %                                                                             %
1757 %   S e t S t r i n g I n f o D a t u m                                       %
1758 %                                                                             %
1759 %                                                                             %
1760 %                                                                             %
1761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1762 %
1763 %  SetStringInfoDatum() copies bytes from the source string for the length of
1764 %  the destination string.
1765 %
1766 %  The format of the SetStringInfoDatum method is:
1767 %
1768 %      void SetStringInfoDatum(StringInfo *string_info,
1769 %        const unsigned char *source)
1770 %
1771 %  A description of each parameter follows:
1772 %
1773 %    o string_info: the string info.
1774 %
1775 %    o source: the source string.
1776 %
1777 */
1778 MagickExport void SetStringInfoDatum(StringInfo *string_info,
1779   const unsigned char *source)
1780 {
1781   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1782   assert(string_info != (StringInfo *) NULL);
1783   assert(string_info->signature == MagickSignature);
1784   if (string_info->length != 0)
1785     (void) memcpy(string_info->datum,source,string_info->length);
1786 }
1787 \f
1788 /*
1789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1790 %                                                                             %
1791 %                                                                             %
1792 %                                                                             %
1793 %   S e t S t r i n g I n f o L e n g t h                                     %
1794 %                                                                             %
1795 %                                                                             %
1796 %                                                                             %
1797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1798 %
1799 %  SetStringInfoLength() set the string length to the specified value.
1800 %
1801 %  The format of the SetStringInfoLength method is:
1802 %
1803 %      void SetStringInfoLength(StringInfo *string_info,const size_t length)
1804 %
1805 %  A description of each parameter follows:
1806 %
1807 %    o string_info: the string info.
1808 %
1809 %    o length: the string length.
1810 %
1811 */
1812 MagickExport void SetStringInfoLength(StringInfo *string_info,
1813   const size_t length)
1814 {
1815   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1816   assert(string_info != (StringInfo *) NULL);
1817   assert(string_info->signature == MagickSignature);
1818   if (~length < MaxTextExtent)
1819     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1820   string_info->length=length;
1821   if (string_info->datum == (unsigned char *) NULL)
1822     string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1823       MaxTextExtent,sizeof(*string_info->datum));
1824   else
1825     string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1826       length+MaxTextExtent,sizeof(*string_info->datum));
1827   if (string_info->datum == (unsigned char *) NULL)
1828     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1829 }
1830 \f
1831 /*
1832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1833 %                                                                             %
1834 %                                                                             %
1835 %                                                                             %
1836 %   S e t S t r i n g I n f o D a t u m                                       %
1837 %                                                                             %
1838 %                                                                             %
1839 %                                                                             %
1840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1841 %
1842 %  SetStringInfoPath() sets the path associated with the string.
1843 %
1844 %  The format of the SetStringInfoPath method is:
1845 %
1846 %      void SetStringInfoPath(StringInfo *string_info,const char *path)
1847 %
1848 %  A description of each parameter follows:
1849 %
1850 %    o string_info: the string info.
1851 %
1852 %    o path: the path.
1853 %
1854 */
1855 MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1856 {
1857   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1858   assert(string_info != (StringInfo *) NULL);
1859   assert(string_info->signature == MagickSignature);
1860   assert(path != (const char *) NULL);
1861   (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1862 }
1863 \f
1864 /*
1865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1866 %                                                                             %
1867 %                                                                             %
1868 %                                                                             %
1869 %   S p l i t S t r i n g I n f o                                             %
1870 %                                                                             %
1871 %                                                                             %
1872 %                                                                             %
1873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1874 %
1875 %  SplitStringInfo() splits a string into two and returns it.
1876 %
1877 %  The format of the SplitStringInfo method is:
1878 %
1879 %      StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1880 %
1881 %  A description of each parameter follows:
1882 %
1883 %    o string_info: the string info.
1884 %
1885 */
1886 MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1887   const size_t offset)
1888 {
1889   StringInfo
1890     *split_info;
1891
1892   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1893   assert(string_info != (StringInfo *) NULL);
1894   assert(string_info->signature == MagickSignature);
1895   if (offset > string_info->length)
1896     return((StringInfo *) NULL);
1897   split_info=AcquireStringInfo(offset);
1898   SetStringInfo(split_info,string_info);
1899   (void) memmove(string_info->datum,string_info->datum+offset,
1900     string_info->length-offset+MaxTextExtent);
1901   SetStringInfoLength(string_info,string_info->length-offset);
1902   return(split_info);
1903 }
1904 \f
1905 /*
1906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1907 %                                                                             %
1908 %                                                                             %
1909 %                                                                             %
1910 %   S t r i n g I n f o T o S t r i n g                                       %
1911 %                                                                             %
1912 %                                                                             %
1913 %                                                                             %
1914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1915 %
1916 %  StringInfoToString() converts a string info string to a C string.
1917 %
1918 %  The format of the StringInfoToString method is:
1919 %
1920 %      char *StringInfoToString(const StringInfo *string_info)
1921 %
1922 %  A description of each parameter follows:
1923 %
1924 %    o string_info: the string.
1925 %
1926 */
1927 MagickExport char *StringInfoToString(const StringInfo *string_info)
1928 {
1929   char
1930     *string;
1931
1932   size_t
1933     length;
1934
1935   string=(char *) NULL;
1936   length=string_info->length;
1937   if (~length >= (MaxTextExtent-1))
1938     string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
1939   if (string == (char *) NULL)
1940     return((char *) NULL);
1941   (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
1942   string[length]='\0';
1943   return(string);
1944 }
1945 \f
1946 /*
1947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1948 %                                                                             %
1949 %                                                                             %
1950 %                                                                             %
1951 %  S t r i n g T o A r g v                                                    %
1952 %                                                                             %
1953 %                                                                             %
1954 %                                                                             %
1955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1956 %
1957 %  StringToArgv() converts a text string into command line arguments.
1958 %
1959 %  The format of the StringToArgv method is:
1960 %
1961 %      char **StringToArgv(const char *text,int *argc)
1962 %
1963 %  A description of each parameter follows:
1964 %
1965 %    o argv:  Method StringToArgv returns the string list unless an error
1966 %      occurs, otherwise NULL.
1967 %
1968 %    o text:  Specifies the string to segment into a list.
1969 %
1970 %    o argc:  This integer pointer returns the number of arguments in the
1971 %      list.
1972 %
1973 */
1974 MagickExport char **StringToArgv(const char *text,int *argc)
1975 {
1976   char
1977     **argv;
1978
1979   register const char
1980     *p,
1981     *q;
1982
1983   register ssize_t
1984     i;
1985
1986   *argc=0;
1987   if (text == (char *) NULL)
1988     return((char **) NULL);
1989   /*
1990     Determine the number of arguments.
1991   */
1992   for (p=text; *p != '\0'; )
1993   {
1994     while (isspace((int) ((unsigned char) *p)) != 0)
1995       p++;
1996     if (*p == '\0')
1997       break;
1998     (*argc)++;
1999     if (*p == '"')
2000       for (p++; (*p != '"') && (*p != '\0'); p++) ;
2001     if (*p == '\'')
2002       for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2003     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2004       p++;
2005   }
2006   (*argc)++;
2007   argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
2008   if (argv == (char **) NULL)
2009     ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2010   /*
2011     Convert string to an ASCII list.
2012   */
2013   argv[0]=AcquireString("magick");
2014   p=text;
2015   for (i=1; i < (ssize_t) *argc; i++)
2016   {
2017     while (isspace((int) ((unsigned char) *p)) != 0)
2018       p++;
2019     q=p;
2020     if (*q == '"')
2021       {
2022         p++;
2023         for (q++; (*q != '"') && (*q != '\0'); q++) ;
2024       }
2025     else
2026       if (*q == '\'')
2027         {
2028           p++;
2029           for (q++; (*q != '\'') && (*q != '\0'); q++) ;
2030         }
2031       else
2032         while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2033           q++;
2034     argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2035       sizeof(**argv));
2036     if (argv[i] == (char *) NULL)
2037       {
2038         for (i--; i >= 0; i--)
2039           argv[i]=DestroyString(argv[i]);
2040         argv=(char **) RelinquishMagickMemory(argv);
2041         ThrowFatalException(ResourceLimitFatalError,
2042           "UnableToConvertStringToARGV");
2043       }
2044     (void) memcpy(argv[i],p,(size_t) (q-p));
2045     argv[i][q-p]='\0';
2046     p=q;
2047     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2048       p++;
2049   }
2050   argv[i]=(char *) NULL;
2051   return(argv);
2052 }
2053 \f
2054 /*
2055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2056 %                                                                             %
2057 %                                                                             %
2058 %                                                                             %
2059 %   S t r i n g I n f o T o H e x S t r i n g                                 %
2060 %                                                                             %
2061 %                                                                             %
2062 %                                                                             %
2063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2064 %
2065 %  StringInfoToHexString() converts a string info string to a C string.
2066 %
2067 %  The format of the StringInfoToHexString method is:
2068 %
2069 %      char *StringInfoToHexString(const StringInfo *string_info)
2070 %
2071 %  A description of each parameter follows:
2072 %
2073 %    o string_info: the string.
2074 %
2075 */
2076 MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2077 {
2078   char
2079     *string;
2080
2081   register const unsigned char
2082     *p;
2083
2084   register ssize_t
2085     i;
2086
2087   register unsigned char
2088     *q;
2089
2090   size_t
2091     length;
2092
2093   unsigned char
2094     hex_digits[16];
2095
2096   length=string_info->length;
2097   if (~length < MaxTextExtent)
2098     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2099   string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2100   if (string == (char *) NULL)
2101     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2102   hex_digits[0]='0';
2103   hex_digits[1]='1';
2104   hex_digits[2]='2';
2105   hex_digits[3]='3';
2106   hex_digits[4]='4';
2107   hex_digits[5]='5';
2108   hex_digits[6]='6';
2109   hex_digits[7]='7';
2110   hex_digits[8]='8';
2111   hex_digits[9]='9';
2112   hex_digits[10]='a';
2113   hex_digits[11]='b';
2114   hex_digits[12]='c';
2115   hex_digits[13]='d';
2116   hex_digits[14]='e';
2117   hex_digits[15]='f';
2118   p=string_info->datum;
2119   q=(unsigned char *) string;
2120   for (i=0; i < (ssize_t) string_info->length; i++)
2121   {
2122     *q++=hex_digits[(*p >> 4) & 0x0f];
2123     *q++=hex_digits[*p & 0x0f];
2124     p++;
2125   }
2126   *q='\0';
2127   return(string);
2128 }
2129 \f
2130 /*
2131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2132 %                                                                             %
2133 %                                                                             %
2134 %                                                                             %
2135 %   S t r i n g T o k e n                                                     %
2136 %                                                                             %
2137 %                                                                             %
2138 %                                                                             %
2139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2140 %
2141 %  StringToken() extracts a token a from the string.
2142 %
2143 %  The format of the StringToken method is:
2144 %
2145 %      char *StringToken(const char *delimiters,char **string)
2146 %
2147 %  A description of each parameter follows:
2148 %
2149 %    o delimiters: one or more delimiters.
2150 %
2151 %    o string: return the first token in the string.  If none is found, return
2152 %      NULL.
2153 %
2154 */
2155 MagickExport char *StringToken(const char *delimiters,char **string)
2156 {
2157   char
2158     *q;
2159
2160   register char
2161     *p;
2162
2163   register const char
2164     *r;
2165
2166   register int
2167     c,
2168     d;
2169
2170   p=(*string);
2171   if (p == (char *) NULL)
2172     return((char *) NULL);
2173   for (q=p; ; )
2174   {
2175     c=(*p++);
2176     r=delimiters;
2177     do
2178     {
2179       d=(*r++);
2180       if (c == d)
2181         {
2182           if (c == '\0')
2183             p=(char *) NULL;
2184           else
2185             p[-1]='\0';
2186           *string=p;
2187           return(q);
2188         }
2189     } while (d != '\0');
2190   }
2191 }
2192 \f
2193 /*
2194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2195 %                                                                             %
2196 %                                                                             %
2197 %                                                                             %
2198 %  S t r i n g T o L i s t                                                    %
2199 %                                                                             %
2200 %                                                                             %
2201 %                                                                             %
2202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2203 %
2204 %  StringToList() converts a text string into a list by segmenting the text
2205 %  string at each carriage return discovered.  The list is converted to HEX
2206 %  characters if any control characters are discovered within the text string.
2207 %
2208 %  The format of the StringToList method is:
2209 %
2210 %      char **StringToList(const char *text)
2211 %
2212 %  A description of each parameter follows:
2213 %
2214 %    o text:  Specifies the string to segment into a list.
2215 %
2216 */
2217 MagickExport char **StringToList(const char *text)
2218 {
2219   char
2220     **textlist;
2221
2222   register const char
2223     *p;
2224
2225   register ssize_t
2226     i;
2227
2228   size_t
2229     lines;
2230
2231   if (text == (char *) NULL)
2232     return((char **) NULL);
2233   for (p=text; *p != '\0'; p++)
2234     if (((int) ((unsigned char) *p) < 32) &&
2235         (isspace((int) ((unsigned char) *p)) == 0))
2236       break;
2237   if (*p == '\0')
2238     {
2239       register const char
2240         *q;
2241
2242       /*
2243         Convert string to an ASCII list.
2244       */
2245       lines=1;
2246       for (p=text; *p != '\0'; p++)
2247         if (*p == '\n')
2248           lines++;
2249       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2250         sizeof(*textlist));
2251       if (textlist == (char **) NULL)
2252         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2253       p=text;
2254       for (i=0; i < (ssize_t) lines; i++)
2255       {
2256         for (q=p; *q != '\0'; q++)
2257           if ((*q == '\r') || (*q == '\n'))
2258             break;
2259         textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2260           sizeof(**textlist));
2261         if (textlist[i] == (char *) NULL)
2262           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2263         (void) memcpy(textlist[i],p,(size_t) (q-p));
2264         textlist[i][q-p]='\0';
2265         if (*q == '\r')
2266           q++;
2267         p=q+1;
2268       }
2269     }
2270   else
2271     {
2272       char
2273         hex_string[MaxTextExtent];
2274
2275       register char
2276         *q;
2277
2278       register ssize_t
2279         j;
2280
2281       /*
2282         Convert string to a HEX list.
2283       */
2284       lines=(size_t) (strlen(text)/0x14)+1;
2285       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2286         sizeof(*textlist));
2287       if (textlist == (char **) NULL)
2288         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2289       p=text;
2290       for (i=0; i < (ssize_t) lines; i++)
2291       {
2292         textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
2293           sizeof(**textlist));
2294         if (textlist[i] == (char *) NULL)
2295           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2296         (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
2297           (long) (0x14*i));
2298         q=textlist[i]+strlen(textlist[i]);
2299         for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
2300         {
2301           (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
2302           (void) CopyMagickString(q,hex_string,MaxTextExtent);
2303           q+=2;
2304           if ((j % 0x04) == 0)
2305             *q++=' ';
2306         }
2307         for ( ; j <= 0x14; j++)
2308         {
2309           *q++=' ';
2310           *q++=' ';
2311           if ((j % 0x04) == 0)
2312             *q++=' ';
2313         }
2314         *q++=' ';
2315         for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
2316         {
2317           if (isprint((int) ((unsigned char) *p)) != 0)
2318             *q++=(*p);
2319           else
2320             *q++='-';
2321           p++;
2322         }
2323         *q='\0';
2324       }
2325     }
2326   textlist[i]=(char *) NULL;
2327   return(textlist);
2328 }
2329 \f
2330 /*
2331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2332 %                                                                             %
2333 %                                                                             %
2334 %                                                                             %
2335 %   S t r i n g T o S t r i n g I n f o                                       %
2336 %                                                                             %
2337 %                                                                             %
2338 %                                                                             %
2339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2340 %
2341 %  StringToStringInfo() converts a string to a StringInfo type.
2342 %
2343 %  The format of the StringToStringInfo method is:
2344 %
2345 %      StringInfo *StringToStringInfo(const char *string)
2346 %
2347 %  A description of each parameter follows:
2348 %
2349 %    o string:  The string.
2350 %
2351 */
2352 MagickExport StringInfo *StringToStringInfo(const char *string)
2353 {
2354   StringInfo
2355     *string_info;
2356
2357   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2358   assert(string != (const char *) NULL);
2359   string_info=AcquireStringInfo(strlen(string));
2360   SetStringInfoDatum(string_info,(const unsigned char *) string);
2361   return(string_info);
2362 }
2363 \f
2364 /*
2365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2366 %                                                                             %
2367 %                                                                             %
2368 %                                                                             %
2369 %   S t r i p S t r i n g                                                     %
2370 %                                                                             %
2371 %                                                                             %
2372 %                                                                             %
2373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2374 %
2375 %  StripString() strips any whitespace or quotes from the beginning and end of
2376 %  a string of characters.
2377 %
2378 %  The format of the StripString method is:
2379 %
2380 %      void StripString(char *message)
2381 %
2382 %  A description of each parameter follows:
2383 %
2384 %    o message: Specifies an array of characters.
2385 %
2386 */
2387 MagickExport void StripString(char *message)
2388 {
2389   register char
2390     *p,
2391     *q;
2392
2393   size_t
2394     length;
2395
2396   assert(message != (char *) NULL);
2397   if (*message == '\0')
2398     return;
2399   length=strlen(message);
2400   p=message;
2401   while (isspace((int) ((unsigned char) *p)) != 0)
2402     p++;
2403   if ((*p == '\'') || (*p == '"'))
2404     p++;
2405   q=message+length-1;
2406   while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2407     q--;
2408   if (q > p)
2409     if ((*q == '\'') || (*q == '"'))
2410       q--;
2411   (void) memmove(message,p,(size_t) (q-p+1));
2412   message[q-p+1]='\0';
2413   for (p=message; *p != '\0'; p++)
2414     if (*p == '\n')
2415       *p=' ';
2416 }
2417 \f
2418 /*
2419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2420 %                                                                             %
2421 %                                                                             %
2422 %                                                                             %
2423 %   S u b s t i t u t e S t r i n g                                           %
2424 %                                                                             %
2425 %                                                                             %
2426 %                                                                             %
2427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2428 %
2429 %  SubstituteString() performs string substitution on a string, replacing the
2430 %  string with the substituted version. Buffer must be allocated from the heap.
2431 %  If the string is matched and status, MagickTrue is returned otherwise
2432 %  MagickFalse.
2433 %
2434 %  The format of the SubstituteString method is:
2435 %
2436 %      MagickBooleanType SubstituteString(char **string,const char *search,
2437 %        const char *replace)
2438 %
2439 %  A description of each parameter follows:
2440 %
2441 %    o string: the string to perform replacements on;  replaced with new
2442 %      allocation if a replacement is made.
2443 %
2444 %    o search: search for this string.
2445 %
2446 %    o replace: replace any matches with this string.
2447 %
2448 */
2449 MagickExport MagickBooleanType SubstituteString(char **string,
2450   const char *search,const char *replace)
2451 {
2452   MagickBooleanType
2453     status;
2454
2455   register char
2456     *p;
2457
2458   size_t
2459     extent,
2460     replace_extent,
2461     search_extent;
2462
2463   ssize_t
2464     offset;
2465
2466   status=MagickFalse;
2467   search_extent=0,
2468   replace_extent=0;
2469   for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
2470   {
2471     if (search_extent == 0)
2472       search_extent=strlen(search);
2473     if (strncmp(p,search,search_extent) != 0)
2474       continue;
2475     /*
2476       We found a match.
2477     */
2478     status=MagickTrue;
2479     if (replace_extent == 0)
2480       replace_extent=strlen(replace);
2481     if (replace_extent > search_extent)
2482       {
2483         /*
2484           Make room for the replacement string.
2485         */
2486         offset=(ssize_t) (p-(*string));
2487         extent=strlen(*string)+replace_extent-search_extent+1;
2488         *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2489           sizeof(*p));
2490         if (*string == (char *) NULL)
2491           ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2492         p=(*string)+offset;
2493       }
2494     /*
2495       Replace string.
2496     */
2497     if (search_extent != replace_extent)
2498       (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2499         strlen(p+search_extent)+1);
2500     (void) CopyMagickMemory(p,replace,replace_extent);
2501     p+=replace_extent-1;
2502   }
2503   return(status);
2504 }