blob: 6921529553ce8ac6b6f03c7f96877f7a7e4aca1d [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
cristy670aa3c2011-11-03 00:54:00 +00006% 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 %
cristy3ed852e2009-09-05 21:47:34 +000011% %
12% %
cristy670aa3c2011-11-03 00:54:00 +000013% MagickCore String Methods %
cristy3ed852e2009-09-05 21:47:34 +000014% %
cristy670aa3c2011-11-03 00:54:00 +000015% Software Design %
16% John Cristy %
17% August 2003 %
cristy3ed852e2009-09-05 21:47:34 +000018% %
19% %
cristy45ef08f2012-12-07 13:13:34 +000020% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
cristy670aa3c2011-11-03 00:54:00 +000023% You may not use this file except in compliance with the license. You may %
cristy99bbf2c2011-09-26 18:27:50 +000024% obtain a copy of the license at %
cristy3ed852e2009-09-05 21:47:34 +000025% %
26% http://www.imagemagick.org/script/license.php %
27% %
cristy99bbf2c2011-09-26 18:27:50 +000028% 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. %
cristy670aa3c2011-11-03 00:54:00 +000031% See the license for the specific language governing permissions and %
cristy99bbf2c2011-09-26 18:27:50 +000032% limitations under the license. %
cristy3ed852e2009-09-05 21:47:34 +000033% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
cristy99bbf2c2011-09-26 18:27:50 +000040 include declarations.
cristy3ed852e2009-09-05 21:47:34 +000041*/
cristy4c08aed2011-07-01 19:47:50 +000042#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"
cristyd2d11ec2012-03-28 13:53:49 +000051#include "MagickCore/nt-base-private.h"
cristy4c08aed2011-07-01 19:47:50 +000052#include "MagickCore/property.h"
53#include "MagickCore/resource_.h"
54#include "MagickCore/signature-private.h"
55#include "MagickCore/string_.h"
anthonyb1d483a2012-04-14 12:53:56 +000056#include "MagickCore/string-private.h"
cristy18c6c272011-09-23 14:40:37 +000057#include "MagickCore/utility-private.h"
cristy3ed852e2009-09-05 21:47:34 +000058
59/*
cristy99bbf2c2011-09-26 18:27:50 +000060 static declarations.
cristy3ed852e2009-09-05 21:47:34 +000061*/
62#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
63static const unsigned char
cristy8e7a4612013-09-16 22:10:27 +000064 AsciiMap[] =
cristy3ed852e2009-09-05 21:47:34 +000065 {
66 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
67 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
68 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
69 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
70 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
71 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
72 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
73 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
74 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
75 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
76 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
77 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
78 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
79 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
80 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
81 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
82 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
83 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
84 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
85 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
86 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
87 0xfc, 0xfd, 0xfe, 0xff,
88 };
89#endif
90
91/*
92%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93% %
94% %
95% %
96% A c q u i r e S t r i n g %
97% %
98% %
99% %
100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101%
anthony104f8932012-05-13 01:54:53 +0000102% AcquireString() returns an new extented string, containing a clone of the
103% given string.
cristy3ed852e2009-09-05 21:47:34 +0000104%
anthony104f8932012-05-13 01:54:53 +0000105% An extended string is the string length, plus an extra MaxTextExtent space
106% to allow for the string to be activally worked on.
107%
108% The returned string shoud be freed using DestoryString().
anthonyb1d483a2012-04-14 12:53:56 +0000109%
cristy3ed852e2009-09-05 21:47:34 +0000110% The format of the AcquireString method is:
111%
112% char *AcquireString(const char *source)
113%
114% A description of each parameter follows:
115%
116% o source: A character string.
117%
118*/
119MagickExport char *AcquireString(const char *source)
120{
121 char
122 *destination;
123
124 size_t
125 length;
126
127 length=0;
128 if (source != (char *) NULL)
129 length+=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000130 if (~length < MaxTextExtent)
131 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
132 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
133 sizeof(*destination));
cristy3ed852e2009-09-05 21:47:34 +0000134 if (destination == (char *) NULL)
135 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
136 *destination='\0';
137 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000138 (void) memcpy(destination,source,length*sizeof(*destination));
139 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000140 return(destination);
141}
142
143/*
144%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145% %
146% %
147% %
148% A c q u i r e S t r i n g I n f o %
149% %
150% %
151% %
152%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153%
154% AcquireStringInfo() allocates the StringInfo structure.
155%
156% The format of the AcquireStringInfo method is:
157%
158% StringInfo *AcquireStringInfo(const size_t length)
159%
160% A description of each parameter follows:
161%
162% o length: the string length.
163%
164*/
165MagickExport StringInfo *AcquireStringInfo(const size_t length)
166{
167 StringInfo
168 *string_info;
169
cristy73bd4a52010-10-05 11:24:23 +0000170 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000171 if (string_info == (StringInfo *) NULL)
172 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
173 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
174 string_info->signature=MagickSignature;
175 string_info->length=length;
176 if (string_info->length != 0)
177 {
178 string_info->datum=(unsigned char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000179 if (~string_info->length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000180 string_info->datum=(unsigned char *) AcquireQuantumMemory(
181 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
182 if (string_info->datum == (unsigned char *) NULL)
183 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
184 }
185 return(string_info);
186}
187
188/*
189%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190% %
191% %
192% %
cristy8723e4b2011-09-01 13:11:19 +0000193% B l o b T o S t r i n g I n f o %
194% %
195% %
196% %
197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198%
anthony104f8932012-05-13 01:54:53 +0000199% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
200% with MaxTextExtent extra space.
cristy8723e4b2011-09-01 13:11:19 +0000201%
202% The format of the BlobToStringInfo method is:
203%
204% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
205%
206% A description of each parameter follows:
207%
208% o blob: the blob.
209%
210% o length: the length of the blob.
211%
212*/
213MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
214{
215 StringInfo
216 *string_info;
217
218 string_info=AcquireStringInfo(0);
cristyf8316342011-09-01 13:55:00 +0000219 string_info->length=length;
cristya10e0742011-09-01 13:50:43 +0000220 if (~string_info->length >= (MaxTextExtent-1))
cristyf8316342011-09-01 13:55:00 +0000221 string_info->datum=(unsigned char *) AcquireQuantumMemory(
222 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
cristy8723e4b2011-09-01 13:11:19 +0000223 if (string_info->datum == (unsigned char *) NULL)
224 {
225 string_info=DestroyStringInfo(string_info);
226 return((StringInfo *) NULL);
227 }
228 if (blob != (const void *) NULL)
229 (void) memcpy(string_info->datum,blob,length);
230 return(string_info);
231}
232
233/*
234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235% %
236% %
237% %
cristy3ed852e2009-09-05 21:47:34 +0000238% C l o n e S t r i n g %
239% %
240% %
241% %
242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243%
anthony104f8932012-05-13 01:54:53 +0000244% CloneString() replaces or frees the destination string to make it
245% a clone of the input string plus MaxTextExtent more space so the string may
246% be worked on on.
cristy3ed852e2009-09-05 21:47:34 +0000247%
anthony104f8932012-05-13 01:54:53 +0000248% If source is a NULL pointer the destination string will be freed and set to
249% a NULL pointer. A pointer to the stored in the destination is also returned.
anthony72feaa62012-01-17 06:46:23 +0000250%
anthony104f8932012-05-13 01:54:53 +0000251% When finished the non-NULL string should be freed using DestoryString()
252% or using CloneString() with a NULL pointed for the source.
anthony06762232012-04-29 11:45:40 +0000253%
cristy3ed852e2009-09-05 21:47:34 +0000254% The format of the CloneString method is:
255%
256% char *CloneString(char **destination,const char *source)
257%
258% A description of each parameter follows:
259%
260% o destination: A pointer to a character string.
261%
262% o source: A character string.
263%
264*/
265MagickExport char *CloneString(char **destination,const char *source)
266{
267 size_t
268 length;
269
cristy3ed852e2009-09-05 21:47:34 +0000270 assert(destination != (char **) NULL);
271 if (source == (const char *) NULL)
272 {
273 if (*destination != (char *) NULL)
274 *destination=DestroyString(*destination);
275 return(*destination);
276 }
277 if (*destination == (char *) NULL)
278 {
279 *destination=AcquireString(source);
280 return(*destination);
281 }
282 length=strlen(source);
283 if (~length < MaxTextExtent)
284 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
285 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000286 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000287 if (*destination == (char *) NULL)
288 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000289 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000290 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000291 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000292 return(*destination);
293}
294
295/*
296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297% %
298% %
299% %
300% C l o n e S t r i n g I n f o %
301% %
302% %
303% %
304%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305%
306% CloneStringInfo() clones a copy of the StringInfo structure.
307%
308% The format of the CloneStringInfo method is:
309%
310% StringInfo *CloneStringInfo(const StringInfo *string_info)
311%
312% A description of each parameter follows:
313%
314% o string_info: the string info.
315%
316*/
317MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
318{
319 StringInfo
320 *clone_info;
321
cristy3ed852e2009-09-05 21:47:34 +0000322 assert(string_info != (StringInfo *) NULL);
323 assert(string_info->signature == MagickSignature);
324 clone_info=AcquireStringInfo(string_info->length);
325 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000326 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000327 return(clone_info);
328}
329
330/*
331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332% %
333% %
334% %
335% C o m p a r e S t r i n g I n f o %
336% %
337% %
338% %
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340%
341% CompareStringInfo() compares the two datums target and source. It returns
342% an integer less than, equal to, or greater than zero if target is found,
343% respectively, to be less than, to match, or be greater than source.
344%
345% The format of the CompareStringInfo method is:
346%
347% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
348%
349% A description of each parameter follows:
350%
351% o target: the target string.
352%
353% o source: the source string.
354%
355*/
356
357static inline size_t MagickMin(const size_t x,const size_t y)
358{
359 if (x < y)
360 return(x);
361 return(y);
362}
363
364MagickExport int CompareStringInfo(const StringInfo *target,
365 const StringInfo *source)
366{
367 int
368 status;
369
cristy3ed852e2009-09-05 21:47:34 +0000370 assert(target != (StringInfo *) NULL);
371 assert(target->signature == MagickSignature);
372 assert(source != (StringInfo *) NULL);
373 assert(source->signature == MagickSignature);
374 status=memcmp(target->datum,source->datum,MagickMin(target->length,
375 source->length));
376 if (status != 0)
377 return(status);
378 if (target->length == source->length)
379 return(0);
380 return(target->length < source->length ? -1 : 1);
381}
382
383/*
384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385% %
386% %
387% %
388% C o n c a t e n a t e M a g i c k S t r i n g %
389% %
390% %
391% %
392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
393%
394% ConcatenateMagickString() concatenates the source string to the destination
395% string. The destination buffer is always null-terminated even if the
396% string must be truncated.
397%
398% The format of the ConcatenateMagickString method is:
399%
400% size_t ConcatenateMagickString(char *destination,const char *source,
401% const size_t length)
402%
403% A description of each parameter follows:
404%
405% o destination: the destination string.
406%
407% o source: the source string.
408%
409% o length: the length of the destination string.
410%
411*/
412MagickExport size_t ConcatenateMagickString(char *destination,
413 const char *source,const size_t length)
414{
415 register char
416 *q;
417
418 register const char
419 *p;
420
421 register size_t
422 i;
423
424 size_t
425 count;
426
427 assert(destination != (char *) NULL);
428 assert(source != (const char *) NULL);
429 assert(length >= 1);
430 p=source;
431 q=destination;
432 i=length;
433 while ((i-- != 0) && (*q != '\0'))
434 q++;
435 count=(size_t) (q-destination);
436 i=length-count;
437 if (i == 0)
438 return(count+strlen(p));
439 while (*p != '\0')
440 {
441 if (i != 1)
442 {
443 *q++=(*p);
444 i--;
445 }
446 p++;
447 }
448 *q='\0';
449 return(count+(p-source));
450}
451
452/*
453%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
454% %
455% %
456% %
457% C o n c a t e n a t e S t r i n g %
458% %
459% %
460% %
461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462%
463% ConcatenateString() appends a copy of string source, including the
464% terminating null character, to the end of string destination.
465%
466% The format of the ConcatenateString method is:
467%
468% MagickBooleanType ConcatenateString(char **destination,
469% const char *source)
470%
471% A description of each parameter follows:
472%
473% o destination: A pointer to a character string.
474%
475% o source: A character string.
476%
477*/
478MagickExport MagickBooleanType ConcatenateString(char **destination,
479 const char *source)
480{
481 size_t
cristy54aad5e2010-09-03 16:02:04 +0000482 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000483 length,
484 source_length;
485
486 assert(destination != (char **) NULL);
487 if (source == (const char *) NULL)
488 return(MagickTrue);
489 if (*destination == (char *) NULL)
490 {
491 *destination=AcquireString(source);
492 return(MagickTrue);
493 }
cristy54aad5e2010-09-03 16:02:04 +0000494 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000495 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000496 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000497 if (~length < source_length)
498 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
499 length+=source_length;
500 if (~length < MaxTextExtent)
501 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
502 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000503 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000504 if (*destination == (char *) NULL)
505 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000506 if (source_length != 0)
507 (void) memcpy((*destination)+destination_length,source,source_length);
508 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000509 return(MagickTrue);
510}
511
512/*
513%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514% %
515% %
516% %
517% C o n c a t e n a t e S t r i n g I n f o %
518% %
519% %
520% %
521%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
522%
523% ConcatenateStringInfo() concatenates the source string to the destination
524% string.
525%
526% The format of the ConcatenateStringInfo method is:
527%
528% void ConcatenateStringInfo(StringInfo *string_info,
529% const StringInfo *source)
530%
531% A description of each parameter follows:
532%
533% o string_info: the string info.
534%
535% o source: the source string.
536%
537*/
538MagickExport void ConcatenateStringInfo(StringInfo *string_info,
539 const StringInfo *source)
540{
541 size_t
542 length;
543
cristy3ed852e2009-09-05 21:47:34 +0000544 assert(string_info != (StringInfo *) NULL);
545 assert(string_info->signature == MagickSignature);
546 assert(source != (const StringInfo *) NULL);
547 length=string_info->length;
548 if (~length < source->length)
549 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
550 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000551 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000552}
553
554/*
555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556% %
557% %
558% %
559% 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 %
560% %
561% %
562% %
563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564%
565% ConfigureFileToStringInfo() returns the contents of a configure file as a
566% string.
567%
568% The format of the ConfigureFileToStringInfo method is:
569%
570% StringInfo *ConfigureFileToStringInfo(const char *filename)
571% ExceptionInfo *exception)
572%
573% A description of each parameter follows:
574%
575% o filename: the filename.
576%
577*/
cristy99bbf2c2011-09-26 18:27:50 +0000578MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +0000579{
580 char
581 *string;
582
583 int
584 file;
585
586 MagickOffsetType
587 offset;
588
589 size_t
590 length;
591
592 StringInfo
593 *string_info;
594
595 void
596 *map;
597
598 assert(filename != (const char *) NULL);
cristy18c6c272011-09-23 14:40:37 +0000599 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
cristy3ed852e2009-09-05 21:47:34 +0000600 if (file == -1)
601 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000602 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000603 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
604 {
605 file=close(file)-1;
606 return((StringInfo *) NULL);
607 }
608 length=(size_t) offset;
609 string=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000610 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000611 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
612 if (string == (char *) NULL)
613 {
614 file=close(file)-1;
615 return((StringInfo *) NULL);
616 }
617 map=MapBlob(file,ReadMode,0,length);
618 if (map != (void *) NULL)
619 {
cristy54aad5e2010-09-03 16:02:04 +0000620 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000621 (void) UnmapBlob(map,length);
622 }
623 else
624 {
625 register size_t
626 i;
627
628 ssize_t
629 count;
630
cristy7f317702011-02-18 20:40:28 +0000631 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000632 for (i=0; i < length; i+=count)
633 {
634 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
635 SSIZE_MAX));
636 if (count <= 0)
637 {
638 count=0;
639 if (errno != EINTR)
640 break;
641 }
642 }
643 if (i < length)
644 {
645 file=close(file)-1;
646 string=DestroyString(string);
647 return((StringInfo *) NULL);
648 }
649 }
650 string[length]='\0';
651 file=close(file)-1;
652 string_info=AcquireStringInfo(0);
653 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
654 string_info->length=length;
655 string_info->datum=(unsigned char *) string;
656 return(string_info);
657}
658
659/*
660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
661% %
662% %
663% %
664% C o n s t a n t S t r i n g %
665% %
666% %
667% %
668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
669%
anthony104f8932012-05-13 01:54:53 +0000670% ConstantString() allocates exactly the needed memory for a string and
671% copies the source string to that memory location. A NULL string pointer
672% will allocate an empty string containing just the NUL character.
cristy3ed852e2009-09-05 21:47:34 +0000673%
anthony104f8932012-05-13 01:54:53 +0000674% When finished the string should be freed using DestoryString()
anthony06762232012-04-29 11:45:40 +0000675%
cristy3ed852e2009-09-05 21:47:34 +0000676% The format of the ConstantString method is:
677%
678% char *ConstantString(const char *source)
679%
680% A description of each parameter follows:
681%
682% o source: A character string.
683%
684*/
685MagickExport char *ConstantString(const char *source)
686{
687 char
688 *destination;
689
690 size_t
691 length;
692
693 length=0;
694 if (source != (char *) NULL)
695 length+=strlen(source);
696 destination=(char *) NULL;
697 if (~length >= 1UL)
698 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
699 if (destination == (char *) NULL)
700 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
701 *destination='\0';
702 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000703 (void) memcpy(destination,source,length*sizeof(*destination));
704 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000705 return(destination);
706}
707
708/*
709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710% %
711% %
712% %
713% C o p y M a g i c k S t r i n g %
714% %
715% %
716% %
717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
718%
anthony06762232012-04-29 11:45:40 +0000719% CopyMagickString() copies the source string to the destination string, with
720% out exceeding the given pre-declared length.
721%
722% The destination buffer is always null-terminated even if the string must be
723% truncated. The return value is the minimum of the source string length or
724% the length parameter.
cristy3ed852e2009-09-05 21:47:34 +0000725%
726% The format of the CopyMagickString method is:
727%
728% size_t CopyMagickString(const char *destination,char *source,
729% const size_t length)
730%
731% A description of each parameter follows:
732%
733% o destination: the destination string.
734%
735% o source: the source string.
736%
737% o length: the length of the destination string.
738%
739*/
740MagickExport size_t CopyMagickString(char *destination,const char *source,
741 const size_t length)
742{
743 register char
744 *q;
745
746 register const char
747 *p;
748
749 register size_t
750 n;
751
cristy77e3fcc2011-10-11 00:04:41 +0000752 if (source == (const char *) NULL)
753 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000754 p=source;
755 q=destination;
756 for (n=length; n > 4; n-=4)
757 {
758 *q=(*p++);
759 if (*q == '\0')
760 return((size_t) (p-source-1));
761 q++;
762 *q=(*p++);
763 if (*q == '\0')
764 return((size_t) (p-source-1));
765 q++;
766 *q=(*p++);
767 if (*q == '\0')
768 return((size_t) (p-source-1));
769 q++;
770 *q=(*p++);
771 if (*q == '\0')
772 return((size_t) (p-source-1));
773 q++;
774 }
775 if (n != 0)
776 for (n--; n != 0; n--)
777 {
778 *q=(*p++);
779 if (*q == '\0')
780 return((size_t) (p-source-1));
781 q++;
782 }
783 if (length != 0)
784 *q='\0';
785 return((size_t) (p-source-1));
786}
787
788/*
789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
790% %
791% %
792% %
793% D e s t r o y S t r i n g %
794% %
795% %
796% %
797%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798%
799% DestroyString() destroys memory associated with a string.
800%
801% The format of the DestroyString method is:
802%
803% char *DestroyString(char *string)
804%
805% A description of each parameter follows:
806%
807% o string: the string.
808%
809*/
810MagickExport char *DestroyString(char *string)
811{
812 return((char *) RelinquishMagickMemory(string));
813}
814
815/*
816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817% %
818% %
819% %
820% D e s t r o y S t r i n g I n f o %
821% %
822% %
823% %
824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825%
826% DestroyStringInfo() destroys memory associated with the StringInfo structure.
827%
828% The format of the DestroyStringInfo method is:
829%
830% StringInfo *DestroyStringInfo(StringInfo *string_info)
831%
832% A description of each parameter follows:
833%
834% o string_info: the string info.
835%
836*/
837MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
838{
cristy3ed852e2009-09-05 21:47:34 +0000839 assert(string_info != (StringInfo *) NULL);
840 assert(string_info->signature == MagickSignature);
841 if (string_info->datum != (unsigned char *) NULL)
842 string_info->datum=(unsigned char *) RelinquishMagickMemory(
843 string_info->datum);
844 string_info->signature=(~MagickSignature);
845 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
846 return(string_info);
847}
848
849/*
850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851% %
852% %
853% %
854% D e s t r o y S t r i n g L i s t %
855% %
856% %
857% %
858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859%
860% DestroyStringList() zeros memory associated with a string list.
861%
862% The format of the DestroyStringList method is:
863%
864% char **DestroyStringList(char **list)
865%
866% A description of each parameter follows:
867%
868% o list: the string list.
869%
870*/
871MagickExport char **DestroyStringList(char **list)
872{
cristybb503372010-05-27 20:51:26 +0000873 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000874 i;
875
876 assert(list != (char **) NULL);
877 for (i=0; list[i] != (char *) NULL; i++)
878 list[i]=DestroyString(list[i]);
879 list=(char **) RelinquishMagickMemory(list);
880 return(list);
881}
882
883/*
884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885% %
886% %
887% %
888% E s c a p e S t r i n g %
889% %
890% %
891% %
892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893%
894% EscapeString() allocates memory for a backslash-escaped version of a
895% source text string, copies the escaped version of the text to that
896% memory location while adding backslash characters, and returns the
897% escaped string.
898%
899% The format of the EscapeString method is:
900%
901% char *EscapeString(const char *source,const char escape)
902%
903% A description of each parameter follows:
904%
905% o allocate_string: Method EscapeString returns the escaped string.
906%
907% o source: A character string.
908%
909% o escape: the quoted string termination character to escape (e.g. '"').
910%
911*/
912MagickExport char *EscapeString(const char *source,const char escape)
913{
914 char
915 *destination;
916
917 register char
918 *q;
919
920 register const char
921 *p;
922
923 size_t
924 length;
925
cristy3ed852e2009-09-05 21:47:34 +0000926 assert(source != (const char *) NULL);
927 length=strlen(source);
928 for (p=source; *p != '\0'; p++)
929 if ((*p == '\\') || (*p == escape))
930 {
931 if (~length < 1)
932 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
933 length++;
934 }
935 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000936 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000937 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
938 sizeof(*destination));
939 if (destination == (char *) NULL)
940 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
941 *destination='\0';
942 if (source != (char *) NULL)
943 {
944 q=destination;
945 for (p=source; *p != '\0'; p++)
946 {
947 if ((*p == '\\') || (*p == escape))
948 *q++='\\';
949 *q++=(*p);
950 }
951 *q='\0';
952 }
953 return(destination);
954}
955
956/*
957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
958% %
959% %
960% %
961% F i l e T o S t r i n g %
962% %
963% %
964% %
965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966%
967% FileToString() returns the contents of a file as a string.
968%
969% The format of the FileToString method is:
970%
971% char *FileToString(const char *filename,const size_t extent,
972% ExceptionInfo *exception)
973%
974% A description of each parameter follows:
975%
976% o filename: the filename.
977%
978% o extent: Maximum length of the string.
979%
980% o exception: return any errors or warnings in this structure.
981%
982*/
983MagickExport char *FileToString(const char *filename,const size_t extent,
984 ExceptionInfo *exception)
985{
986 size_t
987 length;
988
989 assert(filename != (const char *) NULL);
990 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
991 assert(exception != (ExceptionInfo *) NULL);
992 return((char *) FileToBlob(filename,extent,&length,exception));
993}
994
995/*
996%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
997% %
998% %
999% %
1000% F i l e T o S t r i n g I n f o %
1001% %
1002% %
1003% %
1004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1005%
1006% FileToStringInfo() returns the contents of a file as a string.
1007%
1008% The format of the FileToStringInfo method is:
1009%
1010% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1011% ExceptionInfo *exception)
1012%
1013% A description of each parameter follows:
1014%
1015% o filename: the filename.
1016%
1017% o extent: Maximum length of the string.
1018%
1019% o exception: return any errors or warnings in this structure.
1020%
1021*/
1022MagickExport StringInfo *FileToStringInfo(const char *filename,
1023 const size_t extent,ExceptionInfo *exception)
1024{
1025 StringInfo
1026 *string_info;
1027
1028 assert(filename != (const char *) NULL);
1029 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1030 assert(exception != (ExceptionInfo *) NULL);
1031 string_info=AcquireStringInfo(0);
1032 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1033 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1034 if (string_info->datum == (unsigned char *) NULL)
1035 {
1036 string_info=DestroyStringInfo(string_info);
1037 return((StringInfo *) NULL);
1038 }
1039 return(string_info);
1040}
1041
1042/*
1043%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1044% %
1045% %
1046% %
1047% F o r m a t M a g i c k S i z e %
1048% %
1049% %
1050% %
1051%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052%
1053% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +00001054% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +00001055% 1000.
cristy3ed852e2009-09-05 21:47:34 +00001056%
1057% The format of the FormatMagickSize method is:
1058%
cristybb503372010-05-27 20:51:26 +00001059% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001060%
1061% A description of each parameter follows:
1062%
1063% o size: convert this size to a human readable format.
1064%
cristyb9080c92009-12-01 20:13:26 +00001065% o bi: use power of two rather than power of ten.
1066%
cristy3ed852e2009-09-05 21:47:34 +00001067% o format: human readable format.
1068%
1069*/
cristy99bbf2c2011-09-26 18:27:50 +00001070MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001071 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001072{
cristyb9080c92009-12-01 20:13:26 +00001073 const char
1074 **units;
1075
cristy3ed852e2009-09-05 21:47:34 +00001076 double
cristyb9080c92009-12-01 20:13:26 +00001077 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001078 length;
1079
cristybb503372010-05-27 20:51:26 +00001080 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001081 i,
1082 j;
1083
cristy9d314ff2011-03-09 01:30:28 +00001084 ssize_t
1085 count;
1086
cristy3ed852e2009-09-05 21:47:34 +00001087 static const char
cristyb9080c92009-12-01 20:13:26 +00001088 *bi_units[] =
1089 {
cristy2ce15c92010-03-12 14:03:41 +00001090 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001091 },
1092 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001093 {
cristy2ce15c92010-03-12 14:03:41 +00001094 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001095 };
cristy3ed852e2009-09-05 21:47:34 +00001096
cristyb9080c92009-12-01 20:13:26 +00001097 bytes=1000.0;
1098 units=traditional_units;
1099 if (bi != MagickFalse)
1100 {
1101 bytes=1024.0;
1102 units=bi_units;
1103 }
cristy3ed852e2009-09-05 21:47:34 +00001104#if defined(_MSC_VER) && (_MSC_VER == 1200)
1105 length=(double) ((MagickOffsetType) size);
1106#else
1107 length=(double) size;
1108#endif
cristyb9080c92009-12-01 20:13:26 +00001109 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1110 length/=bytes;
cristyc3b9b362013-05-25 17:16:34 +00001111 count=0;
cristy9bf9da32009-09-27 16:48:34 +00001112 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001113 {
cristyb51dff52011-05-19 16:55:47 +00001114 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001115 units[i]);
1116 if (strchr(format,'+') == (char *) NULL)
1117 break;
1118 }
1119 return(count);
1120}
1121
1122/*
1123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124% %
1125% %
1126% %
cristy3ed852e2009-09-05 21:47:34 +00001127% F o r m a t M a g i c k T i m e %
1128% %
1129% %
1130% %
1131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1132%
1133% FormatMagickTime() returns the specified time in the Internet date/time
1134% format and the length of the timestamp.
1135%
1136% The format of the FormatMagickTime method is:
1137%
cristybb503372010-05-27 20:51:26 +00001138% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001139% char *timestamp)
1140%
1141% A description of each parameter follows.
1142%
1143% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1144% measured in seconds.
1145%
1146% o length: the maximum length of the string.
1147%
1148% o timestamp: Return the Internet date/time here.
1149%
1150*/
cristybb503372010-05-27 20:51:26 +00001151MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001152 char *timestamp)
1153{
cristybb503372010-05-27 20:51:26 +00001154 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001155 count;
1156
1157 struct tm
1158 gm_time,
1159 local_time;
1160
1161 time_t
1162 timezone;
1163
1164 assert(timestamp != (char *) NULL);
1165 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1166 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1167#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1168 (void) localtime_r(&time,&local_time);
1169#else
1170 {
cristybc3392a2009-10-06 03:15:57 +00001171 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001172 *my_time;
1173
1174 my_time=localtime(&time);
1175 if (my_time != (struct tm *) NULL)
1176 (void) memcpy(&local_time,my_time,sizeof(local_time));
1177 }
1178#endif
1179#if defined(MAGICKCORE_HAVE_GMTIME_R)
1180 (void) gmtime_r(&time,&gm_time);
1181#else
1182 {
cristybc3392a2009-10-06 03:15:57 +00001183 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001184 *my_time;
1185
1186 my_time=gmtime(&time);
1187 if (my_time != (struct tm *) NULL)
1188 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1189 }
1190#endif
1191 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1192 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1193 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1194 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001195 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001196 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1197 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001198 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001199 return(count);
1200}
1201
1202/*
1203%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1204% %
1205% %
1206% %
1207% G e t E n v i r o n m e n t V a l u e %
1208% %
1209% %
1210% %
1211%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1212%
1213% GetEnvironmentValue() returns the environment string that matches the
1214% specified name.
1215%
1216% The format of the GetEnvironmentValue method is:
1217%
1218% char *GetEnvironmentValue(const char *name)
1219%
1220% A description of each parameter follows:
1221%
1222% o name: the environment name.
1223%
1224*/
cristy99bbf2c2011-09-26 18:27:50 +00001225MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001226{
1227 const char
1228 *environment;
1229
1230 environment=getenv(name);
1231 if (environment == (const char *) NULL)
1232 return((char *) NULL);
1233 return(ConstantString(environment));
1234}
1235
1236/*
1237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1238% %
1239% %
1240% %
1241% G e t S t r i n g I n f o D a t u m %
1242% %
1243% %
1244% %
1245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1246%
1247% GetStringInfoDatum() returns the datum associated with the string.
1248%
1249% The format of the GetStringInfoDatum method is:
1250%
1251% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1252%
1253% A description of each parameter follows:
1254%
1255% o string_info: the string info.
1256%
1257*/
1258MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1259{
1260 assert(string_info != (StringInfo *) NULL);
1261 assert(string_info->signature == MagickSignature);
1262 return(string_info->datum);
1263}
1264
1265/*
1266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267% %
1268% %
1269% %
1270% G e t S t r i n g I n f o L e n g t h %
1271% %
1272% %
1273% %
1274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1275%
1276% GetStringInfoLength() returns the string length.
1277%
1278% The format of the GetStringInfoLength method is:
1279%
1280% size_t GetStringInfoLength(const StringInfo *string_info)
1281%
1282% A description of each parameter follows:
1283%
1284% o string_info: the string info.
1285%
1286*/
1287MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1288{
1289 assert(string_info != (StringInfo *) NULL);
1290 assert(string_info->signature == MagickSignature);
1291 return(string_info->length);
1292}
1293
1294/*
1295%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296% %
1297% %
1298% %
1299% G e t S t r i n g I n f o P a t h %
1300% %
1301% %
1302% %
1303%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304%
1305% GetStringInfoPath() returns the path associated with the string.
1306%
1307% The format of the GetStringInfoPath method is:
1308%
1309% const char *GetStringInfoPath(const StringInfo *string_info)
1310%
1311% A description of each parameter follows:
1312%
1313% o string_info: the string info.
1314%
1315*/
1316MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1317{
1318 assert(string_info != (StringInfo *) NULL);
1319 assert(string_info->signature == MagickSignature);
1320 return(string_info->path);
1321}
1322
1323/*
1324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1325% %
1326% %
1327% %
cristydbdd0e32011-11-04 23:29:40 +00001328+ I n t e r p r e t S i P r e f i x V a l u e %
1329% %
1330% %
1331% %
1332%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1333%
1334% InterpretSiPrefixValue() converts the initial portion of the string to a
1335% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1336% etc.).
1337%
1338% The format of the InterpretSiPrefixValue method is:
1339%
1340% double InterpretSiPrefixValue(const char *value,char **sentinal)
1341%
1342% A description of each parameter follows:
1343%
1344% o value: the string value.
1345%
1346% o sentinal: if sentinal is not NULL, return a pointer to the character
1347% after the last character used in the conversion.
1348%
1349*/
1350MagickExport double InterpretSiPrefixValue(const char *restrict string,
1351 char **restrict sentinal)
1352{
1353 char
1354 *q;
1355
1356 double
1357 value;
1358
cristydbdd0e32011-11-04 23:29:40 +00001359 value=InterpretLocaleValue(string,&q);
1360 if (q != string)
1361 {
1362 if ((*q >= 'E') && (*q <= 'z'))
1363 {
1364 double
1365 e;
1366
cristy0c2684f2011-11-05 21:39:43 +00001367 switch ((int) ((unsigned char) *q))
1368 {
1369 case 'y': e=(-24.0); break;
1370 case 'z': e=(-21.0); break;
1371 case 'a': e=(-18.0); break;
1372 case 'f': e=(-15.0); break;
1373 case 'p': e=(-12.0); break;
1374 case 'n': e=(-9.0); break;
1375 case 'u': e=(-6.0); break;
1376 case 'm': e=(-3.0); break;
1377 case 'c': e=(-2.0); break;
1378 case 'd': e=(-1.0); break;
1379 case 'h': e=2.0; break;
1380 case 'k': e=3.0; break;
1381 case 'K': e=3.0; break;
1382 case 'M': e=6.0; break;
1383 case 'G': e=9.0; break;
1384 case 'T': e=12.0; break;
1385 case 'P': e=15.0; break;
1386 case 'E': e=18.0; break;
1387 case 'Z': e=21.0; break;
1388 case 'Y': e=24.0; break;
1389 default: e=0.0; break;
1390 }
cristydbdd0e32011-11-04 23:29:40 +00001391 if (e >= MagickEpsilon)
1392 {
1393 if (q[1] == 'i')
1394 {
1395 value*=pow(2.0,e/0.3);
1396 q+=2;
1397 }
1398 else
1399 {
1400 value*=pow(10.0,e);
1401 q++;
1402 }
1403 }
1404 }
cristyc0f1ed12011-11-09 14:50:15 +00001405 if (*q == 'B')
cristy099a7352011-11-09 14:31:35 +00001406 q++;
cristydbdd0e32011-11-04 23:29:40 +00001407 }
1408 if (sentinal != (char **) NULL)
1409 *sentinal=q;
1410 return(value);
1411}
1412
1413/*
1414%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415% %
1416% %
1417% %
anthony6f201312012-03-30 04:08:15 +00001418% I s S t r i n g T r u e %
1419% %
1420% %
1421% %
1422%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1423%
1424% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1425% "1". Any other string or undefined returns MagickFalse.
1426%
1427% Typically this is used to look at strings (options or artifacts) which
1428% has a default value of "false", when not defined.
1429%
1430% The format of the IsStringTrue method is:
1431%
1432% MagickBooleanType IsStringTrue(const char *value)
1433%
1434% A description of each parameter follows:
1435%
1436% o value: Specifies a pointer to a character array.
1437%
1438*/
1439MagickExport MagickBooleanType IsStringTrue(const char *value)
1440{
1441 if (value == (const char *) NULL)
1442 return(MagickFalse);
1443 if (LocaleCompare(value,"true") == 0)
1444 return(MagickTrue);
1445 if (LocaleCompare(value,"on") == 0)
1446 return(MagickTrue);
1447 if (LocaleCompare(value,"yes") == 0)
1448 return(MagickTrue);
1449 if (LocaleCompare(value,"1") == 0)
1450 return(MagickTrue);
1451 return(MagickFalse);
1452}
1453
1454/*
1455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1456% %
1457% %
1458% %
1459% I s S t r i n g N o t F a l s e %
1460% %
1461% %
1462% %
1463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1464%
1465% IsStringNotFalse() returns MagickTrue, unless the string specifically
1466% has a value that makes this false. that is if it has a value of
1467% "false", "off", "no" or "0".
1468%
1469% Typically this is used to look at strings (options or artifacts) which
1470% has a default value of "true", when it has not been defined.
1471%
1472% The format of the IsStringNotFalse method is:
1473%
1474% MagickBooleanType IsStringNotFalse(const char *value)
1475%
1476% A description of each parameter follows:
1477%
1478% o value: Specifies a pointer to a character array.
1479%
1480*/
1481MagickExport MagickBooleanType IsStringNotFalse(const char *value)
1482{
1483 if (value == (const char *) NULL)
1484 return(MagickTrue);
1485 if (LocaleCompare(value,"false") == 0)
1486 return(MagickFalse);
1487 if (LocaleCompare(value,"off") == 0)
1488 return(MagickFalse);
1489 if (LocaleCompare(value,"no") == 0)
1490 return(MagickFalse);
1491 if (LocaleCompare(value,"0") == 0)
1492 return(MagickFalse);
1493 return(MagickTrue);
1494}
1495
1496/*
1497%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1498% %
1499% %
1500% %
cristy3ed852e2009-09-05 21:47:34 +00001501% L o c a l e C o m p a r e %
1502% %
1503% %
1504% %
1505%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1506%
1507% LocaleCompare() performs a case-insensitive comparison of two strings
1508% byte-by-byte, according to the ordering of the current locale encoding.
1509% LocaleCompare returns an integer greater than, equal to, or less than 0,
1510% if the string pointed to by p is greater than, equal to, or less than the
1511% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001512% is determined by the sign of the difference between the values of the first
1513% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001514%
1515% The format of the LocaleCompare method is:
1516%
cristyde58b412010-02-18 03:53:40 +00001517% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001518%
1519% A description of each parameter follows:
1520%
1521% o p: A pointer to a character string.
1522%
1523% o q: A pointer to a character string to compare to p.
1524%
1525*/
cristyde58b412010-02-18 03:53:40 +00001526MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001527{
1528 if ((p == (char *) NULL) && (q == (char *) NULL))
1529 return(0);
1530 if (p == (char *) NULL)
1531 return(-1);
1532 if (q == (char *) NULL)
1533 return(1);
1534#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001535 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001536#else
1537 {
cristyde58b412010-02-18 03:53:40 +00001538 register int
cristy3ed852e2009-09-05 21:47:34 +00001539 c,
cristya72c2d12010-02-18 01:20:28 +00001540 d;
cristy3ed852e2009-09-05 21:47:34 +00001541
cristya72c2d12010-02-18 01:20:28 +00001542 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001543 {
cristyde58b412010-02-18 03:53:40 +00001544 c=(int) *((unsigned char *) p);
1545 d=(int) *((unsigned char *) q);
1546 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001547 break;
cristya72c2d12010-02-18 01:20:28 +00001548 p++;
1549 q++;
cristy3ed852e2009-09-05 21:47:34 +00001550 }
cristyde58b412010-02-18 03:53:40 +00001551 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001552 }
1553#endif
1554}
1555
1556/*
1557%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1558% %
1559% %
1560% %
1561% L o c a l e L o w e r %
1562% %
1563% %
1564% %
1565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1566%
1567% LocaleLower() transforms all of the characters in the supplied
1568% null-terminated string, changing all uppercase letters to lowercase.
1569%
1570% The format of the LocaleLower method is:
1571%
1572% void LocaleLower(char *string)
1573%
1574% A description of each parameter follows:
1575%
1576% o string: A pointer to the string to convert to lower-case Locale.
1577%
1578*/
1579MagickExport void LocaleLower(char *string)
1580{
1581 register char
1582 *q;
1583
1584 assert(string != (char *) NULL);
1585 for (q=string; *q != '\0'; q++)
1586 *q=(char) tolower((int) *q);
1587}
1588
1589/*
1590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1591% %
1592% %
1593% %
1594% L o c a l e N C o m p a r e %
1595% %
1596% %
1597% %
1598%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1599%
anthony06762232012-04-29 11:45:40 +00001600% LocaleNCompare() performs a case-insensitive comparison of two strings
1601% byte-by-byte, according to the ordering of the current locale encoding.
1602%
1603% LocaleNCompare returns an integer greater than, equal to, or less than 0,
1604% if the string pointed to by p is greater than, equal to, or less than the
1605% string pointed to by q respectively. The sign of a non-zero return value
1606% is determined by the sign of the difference between the values of the first
1607% pair of bytes that differ in the strings being compared.
1608%
1609% The LocaleNCompare method makes the same comparison as LocaleCompare but
1610% looks at a maximum of n bytes. Bytes following a null byte are not
1611% compared.
cristy3ed852e2009-09-05 21:47:34 +00001612%
1613% The format of the LocaleNCompare method is:
1614%
cristyde58b412010-02-18 03:53:40 +00001615% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001616%
1617% A description of each parameter follows:
1618%
1619% o p: A pointer to a character string.
1620%
1621% o q: A pointer to a character string to compare to p.
1622%
cristy7a40ba82011-01-08 20:31:18 +00001623% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001624%
1625*/
cristyde58b412010-02-18 03:53:40 +00001626MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001627{
cristy78c21692011-10-06 14:57:26 +00001628 if ((p == (char *) NULL) && (q == (char *) NULL))
1629 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001630 if (p == (char *) NULL)
1631 return(-1);
1632 if (q == (char *) NULL)
1633 return(1);
1634#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001635 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001636#else
1637 {
cristyde58b412010-02-18 03:53:40 +00001638 register int
cristy3ed852e2009-09-05 21:47:34 +00001639 c,
1640 d;
1641
cristyb6af4a52009-10-06 13:56:23 +00001642 register size_t
cristyc4cded12010-02-18 14:40:57 +00001643 i;
cristyb6af4a52009-10-06 13:56:23 +00001644
cristyc4cded12010-02-18 14:40:57 +00001645 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001646 {
cristyde58b412010-02-18 03:53:40 +00001647 c=(int) *((unsigned char *) p);
1648 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001649 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001650 return(AsciiMap[c]-(int) AsciiMap[d]);
1651 if (c == 0)
1652 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001653 p++;
1654 q++;
1655 }
cristyde58b412010-02-18 03:53:40 +00001656 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001657 }
1658#endif
1659}
1660
1661/*
1662%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1663% %
1664% %
1665% %
1666% L o c a l e U p p e r %
1667% %
1668% %
1669% %
1670%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1671%
1672% LocaleUpper() transforms all of the characters in the supplied
1673% null-terminated string, changing all lowercase letters to uppercase.
1674%
1675% The format of the LocaleUpper method is:
1676%
1677% void LocaleUpper(char *string)
1678%
1679% A description of each parameter follows:
1680%
1681% o string: A pointer to the string to convert to upper-case Locale.
1682%
1683*/
1684MagickExport void LocaleUpper(char *string)
1685{
1686 register char
1687 *q;
1688
1689 assert(string != (char *) NULL);
1690 for (q=string; *q != '\0'; q++)
1691 *q=(char) toupper((int) *q);
1692}
1693
1694/*
1695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1696% %
1697% %
1698% %
1699% P r i n t S t r i n g I n f o %
1700% %
1701% %
1702% %
1703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1704%
1705% PrintStringInfo() prints the string.
1706%
1707% The format of the PrintStringInfo method is:
1708%
1709% void PrintStringInfo(FILE *file,const char *id,
1710% const StringInfo *string_info)
1711%
1712% A description of each parameter follows:
1713%
1714% o file: the file, typically stdout.
1715%
1716% o id: the string id.
1717%
1718% o string_info: the string info.
1719%
1720*/
1721MagickExport void PrintStringInfo(FILE *file,const char *id,
1722 const StringInfo *string_info)
1723{
1724 register const char
1725 *p;
1726
1727 register size_t
1728 i,
1729 j;
1730
1731 assert(id != (const char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001732 assert(string_info != (StringInfo *) NULL);
1733 assert(string_info->signature == MagickSignature);
1734 p=(char *) string_info->datum;
1735 for (i=0; i < string_info->length; i++)
1736 {
1737 if (((int) ((unsigned char) *p) < 32) &&
1738 (isspace((int) ((unsigned char) *p)) == 0))
1739 break;
1740 p++;
1741 }
1742 if (i == string_info->length)
1743 {
cristy53ea28b2012-06-10 22:11:59 +00001744 for (i=0; i < string_info->length; i++)
1745 (void) fputc(string_info->datum[i],file);
cristy3ed852e2009-09-05 21:47:34 +00001746 (void) fputc('\n',file);
1747 return;
1748 }
1749 /*
1750 Convert string to a HEX list.
1751 */
1752 p=(char *) string_info->datum;
1753 for (i=0; i < string_info->length; i+=0x14)
1754 {
cristyb51dff52011-05-19 16:55:47 +00001755 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001756 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1757 {
cristyb51dff52011-05-19 16:55:47 +00001758 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001759 if ((j % 0x04) == 0)
1760 (void) fputc(' ',file);
1761 }
1762 for ( ; j <= 0x14; j++)
1763 {
1764 (void) fputc(' ',file);
1765 (void) fputc(' ',file);
1766 if ((j % 0x04) == 0)
1767 (void) fputc(' ',file);
1768 }
1769 (void) fputc(' ',file);
1770 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1771 {
1772 if (isprint((int) ((unsigned char) *p)) != 0)
1773 (void) fputc(*p,file);
1774 else
1775 (void) fputc('-',file);
1776 p++;
1777 }
1778 (void) fputc('\n',file);
1779 }
1780}
1781
1782/*
1783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1784% %
1785% %
1786% %
1787% R e s e t S t r i n g I n f o %
1788% %
1789% %
1790% %
1791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1792%
1793% ResetStringInfo() reset the string to all null bytes.
1794%
1795% The format of the ResetStringInfo method is:
1796%
1797% void ResetStringInfo(StringInfo *string_info)
1798%
1799% A description of each parameter follows:
1800%
1801% o string_info: the string info.
1802%
1803*/
1804MagickExport void ResetStringInfo(StringInfo *string_info)
1805{
cristy3ed852e2009-09-05 21:47:34 +00001806 assert(string_info != (StringInfo *) NULL);
1807 assert(string_info->signature == MagickSignature);
1808 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1809}
1810
1811/*
1812%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1813% %
1814% %
1815% %
1816% S e t S t r i n g I n f o %
1817% %
1818% %
1819% %
1820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1821%
1822% SetStringInfo() copies the source string to the destination string.
1823%
1824% The format of the SetStringInfo method is:
1825%
1826% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1827%
1828% A description of each parameter follows:
1829%
1830% o string_info: the string info.
1831%
1832% o source: the source string.
1833%
1834*/
1835MagickExport void SetStringInfo(StringInfo *string_info,
1836 const StringInfo *source)
1837{
cristy3ed852e2009-09-05 21:47:34 +00001838 assert(string_info != (StringInfo *) NULL);
1839 assert(string_info->signature == MagickSignature);
1840 assert(source != (StringInfo *) NULL);
1841 assert(source->signature == MagickSignature);
1842 if (string_info->length == 0)
1843 return;
1844 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001845 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1846 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001847}
1848
1849/*
1850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1851% %
1852% %
1853% %
1854% S e t S t r i n g I n f o D a t u m %
1855% %
1856% %
1857% %
1858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1859%
1860% SetStringInfoDatum() copies bytes from the source string for the length of
1861% the destination string.
1862%
1863% The format of the SetStringInfoDatum method is:
1864%
1865% void SetStringInfoDatum(StringInfo *string_info,
1866% const unsigned char *source)
1867%
1868% A description of each parameter follows:
1869%
1870% o string_info: the string info.
1871%
1872% o source: the source string.
1873%
1874*/
1875MagickExport void SetStringInfoDatum(StringInfo *string_info,
1876 const unsigned char *source)
1877{
cristy3ed852e2009-09-05 21:47:34 +00001878 assert(string_info != (StringInfo *) NULL);
1879 assert(string_info->signature == MagickSignature);
1880 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001881 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001882}
1883
1884/*
1885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1886% %
1887% %
1888% %
1889% S e t S t r i n g I n f o L e n g t h %
1890% %
1891% %
1892% %
1893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1894%
1895% SetStringInfoLength() set the string length to the specified value.
1896%
1897% The format of the SetStringInfoLength method is:
1898%
1899% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1900%
1901% A description of each parameter follows:
1902%
1903% o string_info: the string info.
1904%
1905% o length: the string length.
1906%
1907*/
1908MagickExport void SetStringInfoLength(StringInfo *string_info,
1909 const size_t length)
1910{
cristy3ed852e2009-09-05 21:47:34 +00001911 assert(string_info != (StringInfo *) NULL);
1912 assert(string_info->signature == MagickSignature);
1913 if (~length < MaxTextExtent)
1914 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1915 string_info->length=length;
1916 if (string_info->datum == (unsigned char *) NULL)
1917 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1918 MaxTextExtent,sizeof(*string_info->datum));
1919 else
1920 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1921 length+MaxTextExtent,sizeof(*string_info->datum));
1922 if (string_info->datum == (unsigned char *) NULL)
1923 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1924}
1925
1926/*
1927%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1928% %
1929% %
1930% %
1931% S e t S t r i n g I n f o D a t u m %
1932% %
1933% %
1934% %
1935%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1936%
1937% SetStringInfoPath() sets the path associated with the string.
1938%
1939% The format of the SetStringInfoPath method is:
1940%
1941% void SetStringInfoPath(StringInfo *string_info,const char *path)
1942%
1943% A description of each parameter follows:
1944%
1945% o string_info: the string info.
1946%
1947% o path: the path.
1948%
1949*/
1950MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1951{
cristy3ed852e2009-09-05 21:47:34 +00001952 assert(string_info != (StringInfo *) NULL);
1953 assert(string_info->signature == MagickSignature);
1954 assert(path != (const char *) NULL);
1955 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1956}
1957
1958/*
1959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1960% %
1961% %
1962% %
1963% S p l i t S t r i n g I n f o %
1964% %
1965% %
1966% %
1967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1968%
1969% SplitStringInfo() splits a string into two and returns it.
1970%
1971% The format of the SplitStringInfo method is:
1972%
1973% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1974%
1975% A description of each parameter follows:
1976%
1977% o string_info: the string info.
1978%
1979*/
1980MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1981 const size_t offset)
1982{
1983 StringInfo
1984 *split_info;
1985
cristy3ed852e2009-09-05 21:47:34 +00001986 assert(string_info != (StringInfo *) NULL);
1987 assert(string_info->signature == MagickSignature);
1988 if (offset > string_info->length)
1989 return((StringInfo *) NULL);
1990 split_info=AcquireStringInfo(offset);
1991 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00001992 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00001993 string_info->length-offset+MaxTextExtent);
1994 SetStringInfoLength(string_info,string_info->length-offset);
1995 return(split_info);
1996}
1997
1998/*
1999%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2000% %
2001% %
2002% %
2003% S t r i n g I n f o T o S t r i n g %
2004% %
2005% %
2006% %
2007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2008%
2009% StringInfoToString() converts a string info string to a C string.
2010%
2011% The format of the StringInfoToString method is:
2012%
2013% char *StringInfoToString(const StringInfo *string_info)
2014%
2015% A description of each parameter follows:
2016%
2017% o string_info: the string.
2018%
2019*/
2020MagickExport char *StringInfoToString(const StringInfo *string_info)
2021{
2022 char
2023 *string;
2024
2025 size_t
2026 length;
2027
2028 string=(char *) NULL;
2029 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00002030 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002031 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002032 if (string == (char *) NULL)
2033 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00002034 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002035 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002036 return(string);
2037}
2038
2039/*
2040%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2041% %
2042% %
2043% %
anthonyb1d483a2012-04-14 12:53:56 +00002044% S t r i n g I n f o T o H e x S t r i n g %
2045% %
2046% %
2047% %
2048%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2049%
2050% StringInfoToHexString() converts a string info string to a C string.
2051%
2052% The format of the StringInfoToHexString method is:
2053%
2054% char *StringInfoToHexString(const StringInfo *string_info)
2055%
2056% A description of each parameter follows:
2057%
2058% o string_info: the string.
2059%
2060*/
2061MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2062{
2063 char
2064 *string;
2065
2066 register const unsigned char
2067 *p;
2068
2069 register ssize_t
2070 i;
2071
2072 register unsigned char
2073 *q;
2074
2075 size_t
2076 length;
2077
2078 unsigned char
2079 hex_digits[16];
2080
2081 length=string_info->length;
2082 if (~length < MaxTextExtent)
2083 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2084 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2085 if (string == (char *) NULL)
2086 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2087 hex_digits[0]='0';
2088 hex_digits[1]='1';
2089 hex_digits[2]='2';
2090 hex_digits[3]='3';
2091 hex_digits[4]='4';
2092 hex_digits[5]='5';
2093 hex_digits[6]='6';
2094 hex_digits[7]='7';
2095 hex_digits[8]='8';
2096 hex_digits[9]='9';
2097 hex_digits[10]='a';
2098 hex_digits[11]='b';
2099 hex_digits[12]='c';
2100 hex_digits[13]='d';
2101 hex_digits[14]='e';
2102 hex_digits[15]='f';
2103 p=string_info->datum;
2104 q=(unsigned char *) string;
2105 for (i=0; i < (ssize_t) string_info->length; i++)
2106 {
2107 *q++=hex_digits[(*p >> 4) & 0x0f];
2108 *q++=hex_digits[*p & 0x0f];
2109 p++;
2110 }
2111 *q='\0';
2112 return(string);
2113}
2114
2115/*
2116%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2117% %
2118% %
2119% %
cristy3ed852e2009-09-05 21:47:34 +00002120% S t r i n g T o A r g v %
2121% %
2122% %
2123% %
2124%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2125%
2126% StringToArgv() converts a text string into command line arguments.
anthony31f1bf72012-01-30 12:37:22 +00002127% The 'argv' array of arguments, is returned while the number of arguments
2128% is returned via the provided integer variable pointer.
2129%
2130% Simple 'word' tokenizer, which allows for each word to be optionally
2131% quoted. However it will not allow use of partial quotes, or escape
2132% characters.
cristy3ed852e2009-09-05 21:47:34 +00002133%
2134% The format of the StringToArgv method is:
2135%
2136% char **StringToArgv(const char *text,int *argc)
2137%
2138% A description of each parameter follows:
2139%
2140% o argv: Method StringToArgv returns the string list unless an error
2141% occurs, otherwise NULL.
2142%
2143% o text: Specifies the string to segment into a list.
2144%
2145% o argc: This integer pointer returns the number of arguments in the
2146% list.
2147%
2148*/
2149MagickExport char **StringToArgv(const char *text,int *argc)
2150{
2151 char
2152 **argv;
2153
2154 register const char
2155 *p,
2156 *q;
2157
cristybb503372010-05-27 20:51:26 +00002158 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002159 i;
2160
2161 *argc=0;
2162 if (text == (char *) NULL)
2163 return((char **) NULL);
2164 /*
2165 Determine the number of arguments.
2166 */
2167 for (p=text; *p != '\0'; )
2168 {
2169 while (isspace((int) ((unsigned char) *p)) != 0)
2170 p++;
cristya20c9042011-05-19 13:22:18 +00002171 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00002172 break;
cristy3ed852e2009-09-05 21:47:34 +00002173 (*argc)++;
2174 if (*p == '"')
2175 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2176 if (*p == '\'')
2177 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2178 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2179 p++;
2180 }
2181 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002182 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002183 if (argv == (char **) NULL)
2184 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2185 /*
2186 Convert string to an ASCII list.
2187 */
2188 argv[0]=AcquireString("magick");
2189 p=text;
cristybb503372010-05-27 20:51:26 +00002190 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002191 {
2192 while (isspace((int) ((unsigned char) *p)) != 0)
2193 p++;
2194 q=p;
2195 if (*q == '"')
2196 {
2197 p++;
2198 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2199 }
2200 else
2201 if (*q == '\'')
2202 {
cristy06b15f42011-01-22 21:36:24 +00002203 p++;
cristy3ed852e2009-09-05 21:47:34 +00002204 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002205 }
2206 else
2207 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2208 q++;
2209 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2210 sizeof(**argv));
2211 if (argv[i] == (char *) NULL)
2212 {
2213 for (i--; i >= 0; i--)
2214 argv[i]=DestroyString(argv[i]);
2215 argv=(char **) RelinquishMagickMemory(argv);
2216 ThrowFatalException(ResourceLimitFatalError,
2217 "UnableToConvertStringToARGV");
2218 }
cristy54aad5e2010-09-03 16:02:04 +00002219 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002220 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002221 p=q;
2222 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2223 p++;
2224 }
2225 argv[i]=(char *) NULL;
2226 return(argv);
2227}
2228
2229/*
2230%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2231% %
2232% %
2233% %
anthonyb1d483a2012-04-14 12:53:56 +00002234% S t r i n g T o A r r a y O f D o u b l e s %
cristy3ed852e2009-09-05 21:47:34 +00002235% %
2236% %
2237% %
2238%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2239%
anthonyb1d483a2012-04-14 12:53:56 +00002240% StringToArrayOfDoubles() converts a string of space or comma seperated
2241% numbers into array of floating point numbers (doubles). Any number that
2242% failes to parse properly will produce a syntax error. As will two commas
2243% without a number between them. However a final comma at the end will
2244% not be regarded as an error so as to simplify automatic list generation.
cristy3ed852e2009-09-05 21:47:34 +00002245%
anthonyb1d483a2012-04-14 12:53:56 +00002246% A NULL value is returned on syntax or memory errors.
cristy3ed852e2009-09-05 21:47:34 +00002247%
anthonyb1d483a2012-04-14 12:53:56 +00002248% Use RelinquishMagickMemory() to free returned array when finished.
2249%
2250% The format of the StringToArrayOfDoubles method is:
2251%
cristy0a887dc2012-08-15 22:58:36 +00002252% double *StringToArrayOfDoubles(const char *string,size_t *count,
2253% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002254%
2255% A description of each parameter follows:
2256%
anthonyb1d483a2012-04-14 12:53:56 +00002257% o string: the string containing the comma/space seperated values.
2258%
2259% o count: returns number of arguments in returned array
2260%
cristyb86be3d2012-04-14 14:53:30 +00002261% o exception: return 'memory failure' exceptions
cristy3ed852e2009-09-05 21:47:34 +00002262%
2263*/
cristy0a887dc2012-08-15 22:58:36 +00002264MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2265 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002266{
anthonyb1d483a2012-04-14 12:53:56 +00002267 char
2268 *q;
2269
cristy0a887dc2012-08-15 22:58:36 +00002270 const char
2271 *p;
2272
anthonyb1d483a2012-04-14 12:53:56 +00002273 double
2274 *array;
2275
cristybb503372010-05-27 20:51:26 +00002276 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002277 i;
2278
cristy0a887dc2012-08-15 22:58:36 +00002279 /*
2280 Determine count of values, and check syntax.
2281 */
cristyb0de93f2013-05-03 13:39:25 +00002282 assert(exception != (ExceptionInfo *) NULL);
2283 assert(exception->signature == MagickSignature);
anthonyb1d483a2012-04-14 12:53:56 +00002284 *count=0;
anthonyb1d483a2012-04-14 12:53:56 +00002285 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002286 p=string;
2287 while (*p != '\0')
cristy3ed852e2009-09-05 21:47:34 +00002288 {
cristy0a887dc2012-08-15 22:58:36 +00002289 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2290 if (p == q)
2291 return((double *) NULL); /* no value found */
2292 p=q;
2293 i++; /* increment value count */
2294 while (isspace((int) ((unsigned char) *p)) != 0)
2295 p++; /* skip spaces */
2296 if (*p == ',')
2297 p++; /* skip comma */
2298 while (isspace((int) ((unsigned char) *p)) != 0)
2299 p++; /* and more spaces */
cristy3ed852e2009-09-05 21:47:34 +00002300 }
cristy0a887dc2012-08-15 22:58:36 +00002301 /*
2302 Allocate floating point argument list.
2303 */
anthonyb1d483a2012-04-14 12:53:56 +00002304 *count=i;
cristy0a887dc2012-08-15 22:58:36 +00002305 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2306 if (array == (double *) NULL)
anthonyb1d483a2012-04-14 12:53:56 +00002307 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy0a887dc2012-08-15 22:58:36 +00002308 /*
2309 Fill in the floating point values.
2310 */
anthonyb1d483a2012-04-14 12:53:56 +00002311 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002312 p=string;
2313 while ((*p != '\0') && (i < *count))
2314 {
anthonyb1d483a2012-04-14 12:53:56 +00002315 array[i++]=StringToDouble(p,&q);
2316 p=q;
cristy0a887dc2012-08-15 22:58:36 +00002317 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2318 p++;
anthonyb1d483a2012-04-14 12:53:56 +00002319 }
anthonyb1d483a2012-04-14 12:53:56 +00002320 return(array);
cristy3ed852e2009-09-05 21:47:34 +00002321}
2322
2323/*
2324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2325% %
2326% %
2327% %
anthonyb1d483a2012-04-14 12:53:56 +00002328+ S t r i n g T o k e n %
cristy3ed852e2009-09-05 21:47:34 +00002329% %
2330% %
2331% %
2332%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2333%
anthonyb1d483a2012-04-14 12:53:56 +00002334% StringToken() Looks for any one of given delimiters and splits the string
2335% into two separate strings by replacing the delimiter character found with a
2336% nul character.
2337%
2338% The given string pointer is changed to point to the string following the
2339% delimiter character found, or NULL. A pointer to the start of the
2340% string is returned, representing the token before the delimiter.
2341%
2342% In may ways this is equivent to the strtok() C library function, but with
2343% multiple delimiter characters rather than a delimiter string.
cristy3ed852e2009-09-05 21:47:34 +00002344%
2345% The format of the StringToken method is:
2346%
2347% char *StringToken(const char *delimiters,char **string)
2348%
2349% A description of each parameter follows:
2350%
2351% o delimiters: one or more delimiters.
2352%
2353% o string: return the first token in the string. If none is found, return
2354% NULL.
2355%
2356*/
2357MagickExport char *StringToken(const char *delimiters,char **string)
2358{
2359 char
2360 *q;
2361
2362 register char
2363 *p;
2364
2365 register const char
2366 *r;
2367
2368 register int
2369 c,
2370 d;
2371
2372 p=(*string);
2373 if (p == (char *) NULL)
2374 return((char *) NULL);
anthonyb1d483a2012-04-14 12:53:56 +00002375 q=p;
2376 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00002377 {
2378 c=(*p++);
2379 r=delimiters;
2380 do
2381 {
2382 d=(*r++);
2383 if (c == d)
2384 {
2385 if (c == '\0')
2386 p=(char *) NULL;
2387 else
2388 p[-1]='\0';
2389 *string=p;
2390 return(q);
2391 }
2392 } while (d != '\0');
2393 }
2394}
2395
2396/*
2397%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2398% %
2399% %
2400% %
2401% S t r i n g T o L i s t %
2402% %
2403% %
2404% %
2405%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2406%
2407% StringToList() converts a text string into a list by segmenting the text
2408% string at each carriage return discovered. The list is converted to HEX
2409% characters if any control characters are discovered within the text string.
2410%
2411% The format of the StringToList method is:
2412%
2413% char **StringToList(const char *text)
2414%
2415% A description of each parameter follows:
2416%
cristy3ed852e2009-09-05 21:47:34 +00002417% o text: Specifies the string to segment into a list.
2418%
2419*/
2420MagickExport char **StringToList(const char *text)
2421{
2422 char
2423 **textlist;
2424
2425 register const char
2426 *p;
2427
cristybb503372010-05-27 20:51:26 +00002428 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002429 i;
2430
cristybb503372010-05-27 20:51:26 +00002431 size_t
cristy3ed852e2009-09-05 21:47:34 +00002432 lines;
2433
2434 if (text == (char *) NULL)
2435 return((char **) NULL);
2436 for (p=text; *p != '\0'; p++)
2437 if (((int) ((unsigned char) *p) < 32) &&
2438 (isspace((int) ((unsigned char) *p)) == 0))
2439 break;
2440 if (*p == '\0')
2441 {
2442 register const char
2443 *q;
2444
2445 /*
2446 Convert string to an ASCII list.
2447 */
2448 lines=1;
2449 for (p=text; *p != '\0'; p++)
2450 if (*p == '\n')
2451 lines++;
2452 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2453 sizeof(*textlist));
2454 if (textlist == (char **) NULL)
2455 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2456 p=text;
cristybb503372010-05-27 20:51:26 +00002457 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002458 {
2459 for (q=p; *q != '\0'; q++)
2460 if ((*q == '\r') || (*q == '\n'))
2461 break;
2462 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002463 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002464 if (textlist[i] == (char *) NULL)
2465 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002466 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002467 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002468 if (*q == '\r')
2469 q++;
2470 p=q+1;
2471 }
2472 }
2473 else
2474 {
2475 char
2476 hex_string[MaxTextExtent];
2477
2478 register char
2479 *q;
2480
cristybb503372010-05-27 20:51:26 +00002481 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002482 j;
2483
2484 /*
2485 Convert string to a HEX list.
2486 */
cristybb503372010-05-27 20:51:26 +00002487 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002488 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2489 sizeof(*textlist));
2490 if (textlist == (char **) NULL)
2491 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2492 p=text;
cristybb503372010-05-27 20:51:26 +00002493 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002494 {
2495 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002496 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002497 if (textlist[i] == (char *) NULL)
2498 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002499 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002500 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002501 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002502 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002503 {
cristyb51dff52011-05-19 16:55:47 +00002504 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002505 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2506 q+=2;
2507 if ((j % 0x04) == 0)
2508 *q++=' ';
2509 }
2510 for ( ; j <= 0x14; j++)
2511 {
2512 *q++=' ';
2513 *q++=' ';
2514 if ((j % 0x04) == 0)
2515 *q++=' ';
2516 }
2517 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002518 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002519 {
2520 if (isprint((int) ((unsigned char) *p)) != 0)
2521 *q++=(*p);
2522 else
2523 *q++='-';
2524 p++;
2525 }
2526 *q='\0';
2527 }
2528 }
2529 textlist[i]=(char *) NULL;
2530 return(textlist);
2531}
2532
2533/*
2534%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2535% %
2536% %
2537% %
2538% S t r i n g T o S t r i n g I n f o %
2539% %
2540% %
2541% %
2542%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2543%
cristybca58f32011-08-21 14:48:50 +00002544% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002545%
2546% The format of the StringToStringInfo method is:
2547%
2548% StringInfo *StringToStringInfo(const char *string)
2549%
2550% A description of each parameter follows:
2551%
2552% o string: The string.
2553%
2554*/
2555MagickExport StringInfo *StringToStringInfo(const char *string)
2556{
2557 StringInfo
2558 *string_info;
2559
cristy3ed852e2009-09-05 21:47:34 +00002560 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002561 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002562 SetStringInfoDatum(string_info,(const unsigned char *) string);
2563 return(string_info);
2564}
2565
2566/*
2567%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2568% %
2569% %
2570% %
2571% S t r i p S t r i n g %
2572% %
2573% %
2574% %
2575%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2576%
2577% StripString() strips any whitespace or quotes from the beginning and end of
2578% a string of characters.
2579%
2580% The format of the StripString method is:
2581%
2582% void StripString(char *message)
2583%
2584% A description of each parameter follows:
2585%
2586% o message: Specifies an array of characters.
2587%
2588*/
2589MagickExport void StripString(char *message)
2590{
2591 register char
2592 *p,
2593 *q;
2594
2595 size_t
2596 length;
2597
2598 assert(message != (char *) NULL);
2599 if (*message == '\0')
2600 return;
2601 length=strlen(message);
2602 p=message;
2603 while (isspace((int) ((unsigned char) *p)) != 0)
2604 p++;
2605 if ((*p == '\'') || (*p == '"'))
2606 p++;
2607 q=message+length-1;
2608 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2609 q--;
2610 if (q > p)
2611 if ((*q == '\'') || (*q == '"'))
2612 q--;
cristya63c1ba2011-06-02 20:33:43 +00002613 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002614 message[q-p+1]='\0';
2615 for (p=message; *p != '\0'; p++)
2616 if (*p == '\n')
2617 *p=' ';
2618}
2619
2620/*
2621%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2622% %
2623% %
2624% %
2625% S u b s t i t u t e S t r i n g %
2626% %
2627% %
2628% %
2629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2630%
cristyf1b72c12009-10-06 13:25:21 +00002631% SubstituteString() performs string substitution on a string, replacing the
2632% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002633% If the string is matched and status, MagickTrue is returned otherwise
2634% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002635%
2636% The format of the SubstituteString method is:
2637%
cristyf1b72c12009-10-06 13:25:21 +00002638% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002639% const char *replace)
2640%
2641% A description of each parameter follows:
2642%
cristyf1b72c12009-10-06 13:25:21 +00002643% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002644% allocation if a replacement is made.
2645%
cristybc3392a2009-10-06 03:15:57 +00002646% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002647%
cristybc3392a2009-10-06 03:15:57 +00002648% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002649%
2650*/
cristyf1b72c12009-10-06 13:25:21 +00002651MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002652 const char *search,const char *replace)
2653{
cristybc3392a2009-10-06 03:15:57 +00002654 MagickBooleanType
2655 status;
cristy3ed852e2009-09-05 21:47:34 +00002656
cristybc3392a2009-10-06 03:15:57 +00002657 register char
2658 *p;
cristy3ed852e2009-09-05 21:47:34 +00002659
cristy3ed852e2009-09-05 21:47:34 +00002660 size_t
cristybc3392a2009-10-06 03:15:57 +00002661 extent,
2662 replace_extent,
2663 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002664
cristyf1b72c12009-10-06 13:25:21 +00002665 ssize_t
2666 offset;
2667
cristybc3392a2009-10-06 03:15:57 +00002668 status=MagickFalse;
2669 search_extent=0,
2670 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002671 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002672 {
cristyf1b72c12009-10-06 13:25:21 +00002673 if (search_extent == 0)
2674 search_extent=strlen(search);
2675 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002676 continue;
cristy3ed852e2009-09-05 21:47:34 +00002677 /*
cristybc3392a2009-10-06 03:15:57 +00002678 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002679 */
cristyf1b72c12009-10-06 13:25:21 +00002680 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002681 if (replace_extent == 0)
2682 replace_extent=strlen(replace);
2683 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002684 {
cristybc3392a2009-10-06 03:15:57 +00002685 /*
2686 Make room for the replacement string.
2687 */
cristyde58b412010-02-18 03:53:40 +00002688 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002689 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002690 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2691 sizeof(*p));
2692 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002693 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002694 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002695 }
cristy3ed852e2009-09-05 21:47:34 +00002696 /*
cristybc3392a2009-10-06 03:15:57 +00002697 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002698 */
cristybc3392a2009-10-06 03:15:57 +00002699 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002700 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2701 strlen(p+search_extent)+1);
2702 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002703 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002704 }
cristybc3392a2009-10-06 03:15:57 +00002705 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002706}