blob: 1c9eb8526780bb7e0d508fa6ac25b44ae1b15733 [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 %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy670aa3c2011-11-03 00:54:00 +000017% August 2003 %
cristy3ed852e2009-09-05 21:47:34 +000018% %
19% %
cristyfe676ee2013-11-18 13:03:38 +000020% Copyright 1999-2014 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
cristy5364f9c2013-12-28 23:29:28 +0000106% to allow for the string to be actively worked on.
anthony104f8932012-05-13 01:54:53 +0000107%
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;
cristy8a68c242014-04-07 20:43:37 +0000176 string_info->datum=(unsigned char *) NULL;
177 if (~string_info->length >= (MaxTextExtent-1))
178 string_info->datum=(unsigned char *) AcquireQuantumMemory(
179 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
180 if (string_info->datum == (unsigned char *) NULL)
181 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000182 return(string_info);
183}
184
185/*
186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187% %
188% %
189% %
cristy8723e4b2011-09-01 13:11:19 +0000190% B l o b T o S t r i n g I n f o %
191% %
192% %
193% %
194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195%
anthony104f8932012-05-13 01:54:53 +0000196% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
197% with MaxTextExtent extra space.
cristy8723e4b2011-09-01 13:11:19 +0000198%
199% The format of the BlobToStringInfo method is:
200%
201% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
202%
203% A description of each parameter follows:
204%
205% o blob: the blob.
206%
207% o length: the length of the blob.
208%
209*/
210MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
211{
212 StringInfo
213 *string_info;
214
215 string_info=AcquireStringInfo(0);
cristy7fb9fc12014-05-28 01:18:24 +0000216 if (string_info->datum != (unsigned char *) NULL)
217 string_info->datum=(unsigned char *) RelinquishMagickMemory(
218 string_info->datum);
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);
cristy7fb9fc12014-05-28 01:18:24 +0000653 if (string_info->datum != (unsigned char *) NULL)
654 string_info->datum=(unsigned char *) RelinquishMagickMemory(
655 string_info->datum);
cristy3ed852e2009-09-05 21:47:34 +0000656 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
657 string_info->length=length;
658 string_info->datum=(unsigned char *) string;
659 return(string_info);
660}
661
662/*
663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664% %
665% %
666% %
667% C o n s t a n t S t r i n g %
668% %
669% %
670% %
671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672%
anthony104f8932012-05-13 01:54:53 +0000673% ConstantString() allocates exactly the needed memory for a string and
674% copies the source string to that memory location. A NULL string pointer
675% will allocate an empty string containing just the NUL character.
cristy3ed852e2009-09-05 21:47:34 +0000676%
anthony104f8932012-05-13 01:54:53 +0000677% When finished the string should be freed using DestoryString()
anthony06762232012-04-29 11:45:40 +0000678%
cristy3ed852e2009-09-05 21:47:34 +0000679% The format of the ConstantString method is:
680%
681% char *ConstantString(const char *source)
682%
683% A description of each parameter follows:
684%
685% o source: A character string.
686%
687*/
688MagickExport char *ConstantString(const char *source)
689{
690 char
691 *destination;
692
693 size_t
694 length;
695
696 length=0;
697 if (source != (char *) NULL)
698 length+=strlen(source);
699 destination=(char *) NULL;
700 if (~length >= 1UL)
701 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
702 if (destination == (char *) NULL)
703 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
704 *destination='\0';
705 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000706 (void) memcpy(destination,source,length*sizeof(*destination));
707 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000708 return(destination);
709}
710
711/*
712%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713% %
714% %
715% %
716% C o p y M a g i c k S t r i n g %
717% %
718% %
719% %
720%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721%
anthony06762232012-04-29 11:45:40 +0000722% CopyMagickString() copies the source string to the destination string, with
723% out exceeding the given pre-declared length.
724%
725% The destination buffer is always null-terminated even if the string must be
726% truncated. The return value is the minimum of the source string length or
727% the length parameter.
cristy3ed852e2009-09-05 21:47:34 +0000728%
729% The format of the CopyMagickString method is:
730%
731% size_t CopyMagickString(const char *destination,char *source,
732% const size_t length)
733%
734% A description of each parameter follows:
735%
736% o destination: the destination string.
737%
738% o source: the source string.
739%
740% o length: the length of the destination string.
741%
742*/
743MagickExport size_t CopyMagickString(char *destination,const char *source,
744 const size_t length)
745{
746 register char
747 *q;
748
749 register const char
750 *p;
751
752 register size_t
753 n;
754
cristy77e3fcc2011-10-11 00:04:41 +0000755 if (source == (const char *) NULL)
756 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000757 p=source;
758 q=destination;
759 for (n=length; n > 4; n-=4)
760 {
761 *q=(*p++);
762 if (*q == '\0')
763 return((size_t) (p-source-1));
764 q++;
765 *q=(*p++);
766 if (*q == '\0')
767 return((size_t) (p-source-1));
768 q++;
769 *q=(*p++);
770 if (*q == '\0')
771 return((size_t) (p-source-1));
772 q++;
773 *q=(*p++);
774 if (*q == '\0')
775 return((size_t) (p-source-1));
776 q++;
777 }
778 if (n != 0)
779 for (n--; n != 0; n--)
780 {
781 *q=(*p++);
782 if (*q == '\0')
783 return((size_t) (p-source-1));
784 q++;
785 }
786 if (length != 0)
787 *q='\0';
788 return((size_t) (p-source-1));
789}
790
791/*
792%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793% %
794% %
795% %
796% D e s t r o y S t r i n g %
797% %
798% %
799% %
800%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801%
802% DestroyString() destroys memory associated with a string.
803%
804% The format of the DestroyString method is:
805%
806% char *DestroyString(char *string)
807%
808% A description of each parameter follows:
809%
810% o string: the string.
811%
812*/
813MagickExport char *DestroyString(char *string)
814{
815 return((char *) RelinquishMagickMemory(string));
816}
817
818/*
819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820% %
821% %
822% %
823% D e s t r o y S t r i n g I n f o %
824% %
825% %
826% %
827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828%
829% DestroyStringInfo() destroys memory associated with the StringInfo structure.
830%
831% The format of the DestroyStringInfo method is:
832%
833% StringInfo *DestroyStringInfo(StringInfo *string_info)
834%
835% A description of each parameter follows:
836%
837% o string_info: the string info.
838%
839*/
840MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
841{
cristy3ed852e2009-09-05 21:47:34 +0000842 assert(string_info != (StringInfo *) NULL);
843 assert(string_info->signature == MagickSignature);
844 if (string_info->datum != (unsigned char *) NULL)
845 string_info->datum=(unsigned char *) RelinquishMagickMemory(
846 string_info->datum);
847 string_info->signature=(~MagickSignature);
848 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
849 return(string_info);
850}
851
852/*
853%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
854% %
855% %
856% %
857% D e s t r o y S t r i n g L i s t %
858% %
859% %
860% %
861%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
862%
863% DestroyStringList() zeros memory associated with a string list.
864%
865% The format of the DestroyStringList method is:
866%
867% char **DestroyStringList(char **list)
868%
869% A description of each parameter follows:
870%
871% o list: the string list.
872%
873*/
874MagickExport char **DestroyStringList(char **list)
875{
cristybb503372010-05-27 20:51:26 +0000876 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000877 i;
878
879 assert(list != (char **) NULL);
880 for (i=0; list[i] != (char *) NULL; i++)
881 list[i]=DestroyString(list[i]);
882 list=(char **) RelinquishMagickMemory(list);
883 return(list);
884}
885
886/*
887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
888% %
889% %
890% %
891% E s c a p e S t r i n g %
892% %
893% %
894% %
895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
896%
897% EscapeString() allocates memory for a backslash-escaped version of a
898% source text string, copies the escaped version of the text to that
899% memory location while adding backslash characters, and returns the
900% escaped string.
901%
902% The format of the EscapeString method is:
903%
904% char *EscapeString(const char *source,const char escape)
905%
906% A description of each parameter follows:
907%
908% o allocate_string: Method EscapeString returns the escaped string.
909%
910% o source: A character string.
911%
912% o escape: the quoted string termination character to escape (e.g. '"').
913%
914*/
915MagickExport char *EscapeString(const char *source,const char escape)
916{
917 char
918 *destination;
919
920 register char
921 *q;
922
923 register const char
924 *p;
925
926 size_t
927 length;
928
cristy3ed852e2009-09-05 21:47:34 +0000929 assert(source != (const char *) NULL);
930 length=strlen(source);
931 for (p=source; *p != '\0'; p++)
932 if ((*p == '\\') || (*p == escape))
933 {
934 if (~length < 1)
935 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
936 length++;
937 }
938 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000939 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000940 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
941 sizeof(*destination));
942 if (destination == (char *) NULL)
943 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
944 *destination='\0';
945 if (source != (char *) NULL)
946 {
947 q=destination;
948 for (p=source; *p != '\0'; p++)
949 {
950 if ((*p == '\\') || (*p == escape))
951 *q++='\\';
952 *q++=(*p);
953 }
954 *q='\0';
955 }
956 return(destination);
957}
958
959/*
960%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961% %
962% %
963% %
964% F i l e T o S t r i n g %
965% %
966% %
967% %
968%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969%
970% FileToString() returns the contents of a file as a string.
971%
972% The format of the FileToString method is:
973%
974% char *FileToString(const char *filename,const size_t extent,
975% ExceptionInfo *exception)
976%
977% A description of each parameter follows:
978%
979% o filename: the filename.
980%
981% o extent: Maximum length of the string.
982%
983% o exception: return any errors or warnings in this structure.
984%
985*/
986MagickExport char *FileToString(const char *filename,const size_t extent,
987 ExceptionInfo *exception)
988{
989 size_t
990 length;
991
992 assert(filename != (const char *) NULL);
993 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
994 assert(exception != (ExceptionInfo *) NULL);
995 return((char *) FileToBlob(filename,extent,&length,exception));
996}
997
998/*
999%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000% %
1001% %
1002% %
1003% F i l e T o S t r i n g I n f o %
1004% %
1005% %
1006% %
1007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008%
1009% FileToStringInfo() returns the contents of a file as a string.
1010%
1011% The format of the FileToStringInfo method is:
1012%
1013% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1014% ExceptionInfo *exception)
1015%
1016% A description of each parameter follows:
1017%
1018% o filename: the filename.
1019%
1020% o extent: Maximum length of the string.
1021%
1022% o exception: return any errors or warnings in this structure.
1023%
1024*/
1025MagickExport StringInfo *FileToStringInfo(const char *filename,
1026 const size_t extent,ExceptionInfo *exception)
1027{
1028 StringInfo
1029 *string_info;
1030
1031 assert(filename != (const char *) NULL);
1032 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1033 assert(exception != (ExceptionInfo *) NULL);
1034 string_info=AcquireStringInfo(0);
cristy7fb9fc12014-05-28 01:18:24 +00001035 if (string_info->datum != (unsigned char *) NULL)
1036 string_info->datum=(unsigned char *) RelinquishMagickMemory(
1037 string_info->datum);
cristy3ed852e2009-09-05 21:47:34 +00001038 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1039 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1040 if (string_info->datum == (unsigned char *) NULL)
1041 {
1042 string_info=DestroyStringInfo(string_info);
1043 return((StringInfo *) NULL);
1044 }
1045 return(string_info);
1046}
1047
1048/*
1049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050% %
1051% %
1052% %
1053% F o r m a t M a g i c k S i z e %
1054% %
1055% %
1056% %
1057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1058%
1059% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +00001060% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +00001061% 1000.
cristy3ed852e2009-09-05 21:47:34 +00001062%
1063% The format of the FormatMagickSize method is:
1064%
cristybb503372010-05-27 20:51:26 +00001065% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001066%
1067% A description of each parameter follows:
1068%
1069% o size: convert this size to a human readable format.
1070%
cristyb9080c92009-12-01 20:13:26 +00001071% o bi: use power of two rather than power of ten.
1072%
cristy3ed852e2009-09-05 21:47:34 +00001073% o format: human readable format.
1074%
1075*/
cristy99bbf2c2011-09-26 18:27:50 +00001076MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001077 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001078{
cristyb9080c92009-12-01 20:13:26 +00001079 const char
1080 **units;
1081
cristy3ed852e2009-09-05 21:47:34 +00001082 double
cristyb9080c92009-12-01 20:13:26 +00001083 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001084 length;
1085
cristybb503372010-05-27 20:51:26 +00001086 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001087 i,
1088 j;
1089
cristy9d314ff2011-03-09 01:30:28 +00001090 ssize_t
1091 count;
1092
cristy3ed852e2009-09-05 21:47:34 +00001093 static const char
cristyb9080c92009-12-01 20:13:26 +00001094 *bi_units[] =
1095 {
cristy2ce15c92010-03-12 14:03:41 +00001096 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001097 },
1098 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001099 {
cristy2ce15c92010-03-12 14:03:41 +00001100 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001101 };
cristy3ed852e2009-09-05 21:47:34 +00001102
cristyb9080c92009-12-01 20:13:26 +00001103 bytes=1000.0;
1104 units=traditional_units;
1105 if (bi != MagickFalse)
1106 {
1107 bytes=1024.0;
1108 units=bi_units;
1109 }
cristy3ed852e2009-09-05 21:47:34 +00001110#if defined(_MSC_VER) && (_MSC_VER == 1200)
1111 length=(double) ((MagickOffsetType) size);
1112#else
1113 length=(double) size;
1114#endif
cristyb9080c92009-12-01 20:13:26 +00001115 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1116 length/=bytes;
cristyc3b9b362013-05-25 17:16:34 +00001117 count=0;
cristy9bf9da32009-09-27 16:48:34 +00001118 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001119 {
cristyb51dff52011-05-19 16:55:47 +00001120 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001121 units[i]);
1122 if (strchr(format,'+') == (char *) NULL)
1123 break;
1124 }
1125 return(count);
1126}
1127
1128/*
1129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1130% %
1131% %
1132% %
cristy3ed852e2009-09-05 21:47:34 +00001133% F o r m a t M a g i c k T i m e %
1134% %
1135% %
1136% %
1137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1138%
1139% FormatMagickTime() returns the specified time in the Internet date/time
1140% format and the length of the timestamp.
1141%
1142% The format of the FormatMagickTime method is:
1143%
cristybb503372010-05-27 20:51:26 +00001144% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001145% char *timestamp)
1146%
1147% A description of each parameter follows.
1148%
1149% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1150% measured in seconds.
1151%
1152% o length: the maximum length of the string.
1153%
1154% o timestamp: Return the Internet date/time here.
1155%
1156*/
cristybb503372010-05-27 20:51:26 +00001157MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001158 char *timestamp)
1159{
cristybb503372010-05-27 20:51:26 +00001160 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001161 count;
1162
1163 struct tm
1164 gm_time,
1165 local_time;
1166
1167 time_t
1168 timezone;
1169
1170 assert(timestamp != (char *) NULL);
1171 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1172 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1173#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1174 (void) localtime_r(&time,&local_time);
1175#else
1176 {
cristybc3392a2009-10-06 03:15:57 +00001177 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001178 *my_time;
1179
1180 my_time=localtime(&time);
1181 if (my_time != (struct tm *) NULL)
1182 (void) memcpy(&local_time,my_time,sizeof(local_time));
1183 }
1184#endif
1185#if defined(MAGICKCORE_HAVE_GMTIME_R)
1186 (void) gmtime_r(&time,&gm_time);
1187#else
1188 {
cristybc3392a2009-10-06 03:15:57 +00001189 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001190 *my_time;
1191
1192 my_time=gmtime(&time);
1193 if (my_time != (struct tm *) NULL)
1194 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1195 }
1196#endif
1197 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1198 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1199 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1200 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001201 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001202 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1203 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001204 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001205 return(count);
1206}
1207
1208/*
1209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1210% %
1211% %
1212% %
1213% G e t E n v i r o n m e n t V a l u e %
1214% %
1215% %
1216% %
1217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1218%
1219% GetEnvironmentValue() returns the environment string that matches the
1220% specified name.
1221%
1222% The format of the GetEnvironmentValue method is:
1223%
1224% char *GetEnvironmentValue(const char *name)
1225%
1226% A description of each parameter follows:
1227%
1228% o name: the environment name.
1229%
1230*/
cristy99bbf2c2011-09-26 18:27:50 +00001231MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001232{
1233 const char
1234 *environment;
1235
1236 environment=getenv(name);
1237 if (environment == (const char *) NULL)
1238 return((char *) NULL);
1239 return(ConstantString(environment));
1240}
1241
1242/*
1243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1244% %
1245% %
1246% %
1247% G e t S t r i n g I n f o D a t u m %
1248% %
1249% %
1250% %
1251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1252%
1253% GetStringInfoDatum() returns the datum associated with the string.
1254%
1255% The format of the GetStringInfoDatum method is:
1256%
1257% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1258%
1259% A description of each parameter follows:
1260%
1261% o string_info: the string info.
1262%
1263*/
1264MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1265{
1266 assert(string_info != (StringInfo *) NULL);
1267 assert(string_info->signature == MagickSignature);
1268 return(string_info->datum);
1269}
1270
1271/*
1272%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1273% %
1274% %
1275% %
1276% G e t S t r i n g I n f o L e n g t h %
1277% %
1278% %
1279% %
1280%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1281%
1282% GetStringInfoLength() returns the string length.
1283%
1284% The format of the GetStringInfoLength method is:
1285%
1286% size_t GetStringInfoLength(const StringInfo *string_info)
1287%
1288% A description of each parameter follows:
1289%
1290% o string_info: the string info.
1291%
1292*/
1293MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1294{
1295 assert(string_info != (StringInfo *) NULL);
1296 assert(string_info->signature == MagickSignature);
1297 return(string_info->length);
1298}
1299
1300/*
1301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1302% %
1303% %
1304% %
1305% G e t S t r i n g I n f o P a t h %
1306% %
1307% %
1308% %
1309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1310%
1311% GetStringInfoPath() returns the path associated with the string.
1312%
1313% The format of the GetStringInfoPath method is:
1314%
1315% const char *GetStringInfoPath(const StringInfo *string_info)
1316%
1317% A description of each parameter follows:
1318%
1319% o string_info: the string info.
1320%
1321*/
1322MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1323{
1324 assert(string_info != (StringInfo *) NULL);
1325 assert(string_info->signature == MagickSignature);
1326 return(string_info->path);
1327}
1328
1329/*
1330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1331% %
1332% %
1333% %
cristydbdd0e32011-11-04 23:29:40 +00001334+ I n t e r p r e t S i P r e f i x V a l u e %
1335% %
1336% %
1337% %
1338%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1339%
1340% InterpretSiPrefixValue() converts the initial portion of the string to a
1341% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1342% etc.).
1343%
1344% The format of the InterpretSiPrefixValue method is:
1345%
1346% double InterpretSiPrefixValue(const char *value,char **sentinal)
1347%
1348% A description of each parameter follows:
1349%
1350% o value: the string value.
1351%
1352% o sentinal: if sentinal is not NULL, return a pointer to the character
1353% after the last character used in the conversion.
1354%
1355*/
1356MagickExport double InterpretSiPrefixValue(const char *restrict string,
1357 char **restrict sentinal)
1358{
1359 char
1360 *q;
1361
1362 double
1363 value;
1364
cristydbdd0e32011-11-04 23:29:40 +00001365 value=InterpretLocaleValue(string,&q);
1366 if (q != string)
1367 {
1368 if ((*q >= 'E') && (*q <= 'z'))
1369 {
1370 double
1371 e;
1372
cristy0c2684f2011-11-05 21:39:43 +00001373 switch ((int) ((unsigned char) *q))
1374 {
1375 case 'y': e=(-24.0); break;
1376 case 'z': e=(-21.0); break;
1377 case 'a': e=(-18.0); break;
1378 case 'f': e=(-15.0); break;
1379 case 'p': e=(-12.0); break;
1380 case 'n': e=(-9.0); break;
1381 case 'u': e=(-6.0); break;
1382 case 'm': e=(-3.0); break;
1383 case 'c': e=(-2.0); break;
1384 case 'd': e=(-1.0); break;
1385 case 'h': e=2.0; break;
1386 case 'k': e=3.0; break;
1387 case 'K': e=3.0; break;
1388 case 'M': e=6.0; break;
1389 case 'G': e=9.0; break;
1390 case 'T': e=12.0; break;
1391 case 'P': e=15.0; break;
1392 case 'E': e=18.0; break;
1393 case 'Z': e=21.0; break;
1394 case 'Y': e=24.0; break;
1395 default: e=0.0; break;
1396 }
cristydbdd0e32011-11-04 23:29:40 +00001397 if (e >= MagickEpsilon)
1398 {
1399 if (q[1] == 'i')
1400 {
1401 value*=pow(2.0,e/0.3);
1402 q+=2;
1403 }
1404 else
1405 {
1406 value*=pow(10.0,e);
1407 q++;
1408 }
1409 }
1410 }
cristyc0f1ed12011-11-09 14:50:15 +00001411 if (*q == 'B')
cristy099a7352011-11-09 14:31:35 +00001412 q++;
cristydbdd0e32011-11-04 23:29:40 +00001413 }
1414 if (sentinal != (char **) NULL)
1415 *sentinal=q;
1416 return(value);
1417}
1418
1419/*
1420%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1421% %
1422% %
1423% %
anthony6f201312012-03-30 04:08:15 +00001424% I s S t r i n g T r u e %
1425% %
1426% %
1427% %
1428%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1429%
1430% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1431% "1". Any other string or undefined returns MagickFalse.
1432%
1433% Typically this is used to look at strings (options or artifacts) which
1434% has a default value of "false", when not defined.
1435%
1436% The format of the IsStringTrue method is:
1437%
1438% MagickBooleanType IsStringTrue(const char *value)
1439%
1440% A description of each parameter follows:
1441%
1442% o value: Specifies a pointer to a character array.
1443%
1444*/
1445MagickExport MagickBooleanType IsStringTrue(const char *value)
1446{
1447 if (value == (const char *) NULL)
1448 return(MagickFalse);
1449 if (LocaleCompare(value,"true") == 0)
1450 return(MagickTrue);
1451 if (LocaleCompare(value,"on") == 0)
1452 return(MagickTrue);
1453 if (LocaleCompare(value,"yes") == 0)
1454 return(MagickTrue);
1455 if (LocaleCompare(value,"1") == 0)
1456 return(MagickTrue);
1457 return(MagickFalse);
1458}
1459
1460/*
1461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1462% %
1463% %
1464% %
1465% I s S t r i n g N o t F a l s e %
1466% %
1467% %
1468% %
1469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1470%
1471% IsStringNotFalse() returns MagickTrue, unless the string specifically
1472% has a value that makes this false. that is if it has a value of
1473% "false", "off", "no" or "0".
1474%
1475% Typically this is used to look at strings (options or artifacts) which
1476% has a default value of "true", when it has not been defined.
1477%
1478% The format of the IsStringNotFalse method is:
1479%
1480% MagickBooleanType IsStringNotFalse(const char *value)
1481%
1482% A description of each parameter follows:
1483%
1484% o value: Specifies a pointer to a character array.
1485%
1486*/
1487MagickExport MagickBooleanType IsStringNotFalse(const char *value)
1488{
1489 if (value == (const char *) NULL)
1490 return(MagickTrue);
1491 if (LocaleCompare(value,"false") == 0)
1492 return(MagickFalse);
1493 if (LocaleCompare(value,"off") == 0)
1494 return(MagickFalse);
1495 if (LocaleCompare(value,"no") == 0)
1496 return(MagickFalse);
1497 if (LocaleCompare(value,"0") == 0)
1498 return(MagickFalse);
1499 return(MagickTrue);
1500}
1501
1502/*
1503%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1504% %
1505% %
1506% %
cristy3ed852e2009-09-05 21:47:34 +00001507% L o c a l e C o m p a r e %
1508% %
1509% %
1510% %
1511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1512%
1513% LocaleCompare() performs a case-insensitive comparison of two strings
1514% byte-by-byte, according to the ordering of the current locale encoding.
1515% LocaleCompare returns an integer greater than, equal to, or less than 0,
1516% if the string pointed to by p is greater than, equal to, or less than the
1517% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001518% is determined by the sign of the difference between the values of the first
1519% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001520%
1521% The format of the LocaleCompare method is:
1522%
cristyde58b412010-02-18 03:53:40 +00001523% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001524%
1525% A description of each parameter follows:
1526%
1527% o p: A pointer to a character string.
1528%
1529% o q: A pointer to a character string to compare to p.
1530%
1531*/
cristyde58b412010-02-18 03:53:40 +00001532MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001533{
1534 if ((p == (char *) NULL) && (q == (char *) NULL))
1535 return(0);
1536 if (p == (char *) NULL)
1537 return(-1);
1538 if (q == (char *) NULL)
1539 return(1);
1540#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001541 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001542#else
1543 {
cristyde58b412010-02-18 03:53:40 +00001544 register int
cristy3ed852e2009-09-05 21:47:34 +00001545 c,
cristya72c2d12010-02-18 01:20:28 +00001546 d;
cristy3ed852e2009-09-05 21:47:34 +00001547
cristya72c2d12010-02-18 01:20:28 +00001548 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001549 {
cristyde58b412010-02-18 03:53:40 +00001550 c=(int) *((unsigned char *) p);
1551 d=(int) *((unsigned char *) q);
1552 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001553 break;
cristya72c2d12010-02-18 01:20:28 +00001554 p++;
1555 q++;
cristy3ed852e2009-09-05 21:47:34 +00001556 }
cristyde58b412010-02-18 03:53:40 +00001557 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001558 }
1559#endif
1560}
1561
1562/*
1563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564% %
1565% %
1566% %
1567% L o c a l e L o w e r %
1568% %
1569% %
1570% %
1571%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1572%
1573% LocaleLower() transforms all of the characters in the supplied
1574% null-terminated string, changing all uppercase letters to lowercase.
1575%
1576% The format of the LocaleLower method is:
1577%
1578% void LocaleLower(char *string)
1579%
1580% A description of each parameter follows:
1581%
1582% o string: A pointer to the string to convert to lower-case Locale.
1583%
1584*/
1585MagickExport void LocaleLower(char *string)
1586{
1587 register char
1588 *q;
1589
1590 assert(string != (char *) NULL);
1591 for (q=string; *q != '\0'; q++)
1592 *q=(char) tolower((int) *q);
1593}
1594
1595/*
1596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1597% %
1598% %
1599% %
1600% L o c a l e N C o m p a r e %
1601% %
1602% %
1603% %
1604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605%
anthony06762232012-04-29 11:45:40 +00001606% LocaleNCompare() performs a case-insensitive comparison of two strings
1607% byte-by-byte, according to the ordering of the current locale encoding.
1608%
1609% LocaleNCompare returns an integer greater than, equal to, or less than 0,
1610% if the string pointed to by p is greater than, equal to, or less than the
1611% string pointed to by q respectively. The sign of a non-zero return value
1612% is determined by the sign of the difference between the values of the first
1613% pair of bytes that differ in the strings being compared.
1614%
1615% The LocaleNCompare method makes the same comparison as LocaleCompare but
1616% looks at a maximum of n bytes. Bytes following a null byte are not
1617% compared.
cristy3ed852e2009-09-05 21:47:34 +00001618%
1619% The format of the LocaleNCompare method is:
1620%
cristyde58b412010-02-18 03:53:40 +00001621% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001622%
1623% A description of each parameter follows:
1624%
1625% o p: A pointer to a character string.
1626%
1627% o q: A pointer to a character string to compare to p.
1628%
cristy7a40ba82011-01-08 20:31:18 +00001629% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001630%
1631*/
cristyde58b412010-02-18 03:53:40 +00001632MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001633{
cristy78c21692011-10-06 14:57:26 +00001634 if ((p == (char *) NULL) && (q == (char *) NULL))
1635 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001636 if (p == (char *) NULL)
1637 return(-1);
1638 if (q == (char *) NULL)
1639 return(1);
1640#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001641 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001642#else
1643 {
cristyde58b412010-02-18 03:53:40 +00001644 register int
cristy3ed852e2009-09-05 21:47:34 +00001645 c,
1646 d;
1647
cristyb6af4a52009-10-06 13:56:23 +00001648 register size_t
cristyc4cded12010-02-18 14:40:57 +00001649 i;
cristyb6af4a52009-10-06 13:56:23 +00001650
cristyc4cded12010-02-18 14:40:57 +00001651 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001652 {
cristyde58b412010-02-18 03:53:40 +00001653 c=(int) *((unsigned char *) p);
1654 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001655 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001656 return(AsciiMap[c]-(int) AsciiMap[d]);
1657 if (c == 0)
1658 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001659 p++;
1660 q++;
1661 }
cristyde58b412010-02-18 03:53:40 +00001662 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001663 }
1664#endif
1665}
1666
1667/*
1668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1669% %
1670% %
1671% %
1672% L o c a l e U p p e r %
1673% %
1674% %
1675% %
1676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1677%
1678% LocaleUpper() transforms all of the characters in the supplied
1679% null-terminated string, changing all lowercase letters to uppercase.
1680%
1681% The format of the LocaleUpper method is:
1682%
1683% void LocaleUpper(char *string)
1684%
1685% A description of each parameter follows:
1686%
1687% o string: A pointer to the string to convert to upper-case Locale.
1688%
1689*/
1690MagickExport void LocaleUpper(char *string)
1691{
1692 register char
1693 *q;
1694
1695 assert(string != (char *) NULL);
1696 for (q=string; *q != '\0'; q++)
1697 *q=(char) toupper((int) *q);
1698}
1699
1700/*
1701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1702% %
1703% %
1704% %
1705% P r i n t S t r i n g I n f o %
1706% %
1707% %
1708% %
1709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1710%
1711% PrintStringInfo() prints the string.
1712%
1713% The format of the PrintStringInfo method is:
1714%
1715% void PrintStringInfo(FILE *file,const char *id,
1716% const StringInfo *string_info)
1717%
1718% A description of each parameter follows:
1719%
1720% o file: the file, typically stdout.
1721%
1722% o id: the string id.
1723%
1724% o string_info: the string info.
1725%
1726*/
1727MagickExport void PrintStringInfo(FILE *file,const char *id,
1728 const StringInfo *string_info)
1729{
1730 register const char
1731 *p;
1732
1733 register size_t
1734 i,
1735 j;
1736
1737 assert(id != (const char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001738 assert(string_info != (StringInfo *) NULL);
1739 assert(string_info->signature == MagickSignature);
1740 p=(char *) string_info->datum;
1741 for (i=0; i < string_info->length; i++)
1742 {
1743 if (((int) ((unsigned char) *p) < 32) &&
1744 (isspace((int) ((unsigned char) *p)) == 0))
1745 break;
1746 p++;
1747 }
cristy2d8723c2013-11-14 16:41:27 +00001748 (void) FormatLocaleFile(file,"%s(%.20g): ",id,(double) string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001749 if (i == string_info->length)
1750 {
cristy53ea28b2012-06-10 22:11:59 +00001751 for (i=0; i < string_info->length; i++)
1752 (void) fputc(string_info->datum[i],file);
cristy3ed852e2009-09-05 21:47:34 +00001753 (void) fputc('\n',file);
1754 return;
1755 }
1756 /*
1757 Convert string to a HEX list.
1758 */
1759 p=(char *) string_info->datum;
1760 for (i=0; i < string_info->length; i+=0x14)
1761 {
cristyb51dff52011-05-19 16:55:47 +00001762 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001763 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1764 {
cristyb51dff52011-05-19 16:55:47 +00001765 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001766 if ((j % 0x04) == 0)
1767 (void) fputc(' ',file);
1768 }
1769 for ( ; j <= 0x14; j++)
1770 {
1771 (void) fputc(' ',file);
1772 (void) fputc(' ',file);
1773 if ((j % 0x04) == 0)
1774 (void) fputc(' ',file);
1775 }
1776 (void) fputc(' ',file);
1777 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1778 {
1779 if (isprint((int) ((unsigned char) *p)) != 0)
1780 (void) fputc(*p,file);
1781 else
1782 (void) fputc('-',file);
1783 p++;
1784 }
1785 (void) fputc('\n',file);
1786 }
1787}
1788
1789/*
1790%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1791% %
1792% %
1793% %
1794% R e s e t S t r i n g I n f o %
1795% %
1796% %
1797% %
1798%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1799%
1800% ResetStringInfo() reset the string to all null bytes.
1801%
1802% The format of the ResetStringInfo method is:
1803%
1804% void ResetStringInfo(StringInfo *string_info)
1805%
1806% A description of each parameter follows:
1807%
1808% o string_info: the string info.
1809%
1810*/
1811MagickExport void ResetStringInfo(StringInfo *string_info)
1812{
cristy3ed852e2009-09-05 21:47:34 +00001813 assert(string_info != (StringInfo *) NULL);
1814 assert(string_info->signature == MagickSignature);
1815 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1816}
1817
1818/*
1819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1820% %
1821% %
1822% %
1823% S e t S t r i n g I n f o %
1824% %
1825% %
1826% %
1827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828%
1829% SetStringInfo() copies the source string to the destination string.
1830%
1831% The format of the SetStringInfo method is:
1832%
1833% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1834%
1835% A description of each parameter follows:
1836%
1837% o string_info: the string info.
1838%
1839% o source: the source string.
1840%
1841*/
1842MagickExport void SetStringInfo(StringInfo *string_info,
1843 const StringInfo *source)
1844{
cristy3ed852e2009-09-05 21:47:34 +00001845 assert(string_info != (StringInfo *) NULL);
1846 assert(string_info->signature == MagickSignature);
1847 assert(source != (StringInfo *) NULL);
1848 assert(source->signature == MagickSignature);
1849 if (string_info->length == 0)
1850 return;
1851 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001852 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1853 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001854}
1855
1856/*
1857%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1858% %
1859% %
1860% %
1861% S e t S t r i n g I n f o D a t u m %
1862% %
1863% %
1864% %
1865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1866%
1867% SetStringInfoDatum() copies bytes from the source string for the length of
1868% the destination string.
1869%
1870% The format of the SetStringInfoDatum method is:
1871%
1872% void SetStringInfoDatum(StringInfo *string_info,
1873% const unsigned char *source)
1874%
1875% A description of each parameter follows:
1876%
1877% o string_info: the string info.
1878%
1879% o source: the source string.
1880%
1881*/
1882MagickExport void SetStringInfoDatum(StringInfo *string_info,
1883 const unsigned char *source)
1884{
cristy3ed852e2009-09-05 21:47:34 +00001885 assert(string_info != (StringInfo *) NULL);
1886 assert(string_info->signature == MagickSignature);
1887 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001888 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001889}
1890
1891/*
1892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1893% %
1894% %
1895% %
1896% S e t S t r i n g I n f o L e n g t h %
1897% %
1898% %
1899% %
1900%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1901%
1902% SetStringInfoLength() set the string length to the specified value.
1903%
1904% The format of the SetStringInfoLength method is:
1905%
1906% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1907%
1908% A description of each parameter follows:
1909%
1910% o string_info: the string info.
1911%
1912% o length: the string length.
1913%
1914*/
1915MagickExport void SetStringInfoLength(StringInfo *string_info,
1916 const size_t length)
1917{
cristy3ed852e2009-09-05 21:47:34 +00001918 assert(string_info != (StringInfo *) NULL);
1919 assert(string_info->signature == MagickSignature);
1920 if (~length < MaxTextExtent)
1921 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1922 string_info->length=length;
1923 if (string_info->datum == (unsigned char *) NULL)
1924 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1925 MaxTextExtent,sizeof(*string_info->datum));
1926 else
1927 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1928 length+MaxTextExtent,sizeof(*string_info->datum));
1929 if (string_info->datum == (unsigned char *) NULL)
1930 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1931}
1932
1933/*
1934%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1935% %
1936% %
1937% %
1938% S e t S t r i n g I n f o D a t u m %
1939% %
1940% %
1941% %
1942%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1943%
1944% SetStringInfoPath() sets the path associated with the string.
1945%
1946% The format of the SetStringInfoPath method is:
1947%
1948% void SetStringInfoPath(StringInfo *string_info,const char *path)
1949%
1950% A description of each parameter follows:
1951%
1952% o string_info: the string info.
1953%
1954% o path: the path.
1955%
1956*/
1957MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1958{
cristy3ed852e2009-09-05 21:47:34 +00001959 assert(string_info != (StringInfo *) NULL);
1960 assert(string_info->signature == MagickSignature);
1961 assert(path != (const char *) NULL);
1962 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1963}
1964
1965/*
1966%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1967% %
1968% %
1969% %
1970% S p l i t S t r i n g I n f o %
1971% %
1972% %
1973% %
1974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1975%
1976% SplitStringInfo() splits a string into two and returns it.
1977%
1978% The format of the SplitStringInfo method is:
1979%
1980% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1981%
1982% A description of each parameter follows:
1983%
1984% o string_info: the string info.
1985%
1986*/
1987MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1988 const size_t offset)
1989{
1990 StringInfo
1991 *split_info;
1992
cristy3ed852e2009-09-05 21:47:34 +00001993 assert(string_info != (StringInfo *) NULL);
1994 assert(string_info->signature == MagickSignature);
1995 if (offset > string_info->length)
1996 return((StringInfo *) NULL);
1997 split_info=AcquireStringInfo(offset);
1998 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00001999 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00002000 string_info->length-offset+MaxTextExtent);
2001 SetStringInfoLength(string_info,string_info->length-offset);
2002 return(split_info);
2003}
2004
2005/*
2006%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2007% %
2008% %
2009% %
2010% S t r i n g I n f o T o S t r i n g %
2011% %
2012% %
2013% %
2014%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2015%
2016% StringInfoToString() converts a string info string to a C string.
2017%
2018% The format of the StringInfoToString method is:
2019%
2020% char *StringInfoToString(const StringInfo *string_info)
2021%
2022% A description of each parameter follows:
2023%
2024% o string_info: the string.
2025%
2026*/
2027MagickExport char *StringInfoToString(const StringInfo *string_info)
2028{
2029 char
2030 *string;
2031
2032 size_t
2033 length;
2034
2035 string=(char *) NULL;
2036 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00002037 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002038 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002039 if (string == (char *) NULL)
2040 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00002041 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002042 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002043 return(string);
2044}
2045
2046/*
2047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2048% %
2049% %
2050% %
anthonyb1d483a2012-04-14 12:53:56 +00002051% S t r i n g I n f o T o H e x S t r i n g %
2052% %
2053% %
2054% %
2055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2056%
2057% StringInfoToHexString() converts a string info string to a C string.
2058%
2059% The format of the StringInfoToHexString method is:
2060%
2061% char *StringInfoToHexString(const StringInfo *string_info)
2062%
2063% A description of each parameter follows:
2064%
2065% o string_info: the string.
2066%
2067*/
2068MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2069{
2070 char
2071 *string;
2072
2073 register const unsigned char
2074 *p;
2075
2076 register ssize_t
2077 i;
2078
2079 register unsigned char
2080 *q;
2081
2082 size_t
2083 length;
2084
2085 unsigned char
2086 hex_digits[16];
2087
2088 length=string_info->length;
2089 if (~length < MaxTextExtent)
2090 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2091 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2092 if (string == (char *) NULL)
2093 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2094 hex_digits[0]='0';
2095 hex_digits[1]='1';
2096 hex_digits[2]='2';
2097 hex_digits[3]='3';
2098 hex_digits[4]='4';
2099 hex_digits[5]='5';
2100 hex_digits[6]='6';
2101 hex_digits[7]='7';
2102 hex_digits[8]='8';
2103 hex_digits[9]='9';
2104 hex_digits[10]='a';
2105 hex_digits[11]='b';
2106 hex_digits[12]='c';
2107 hex_digits[13]='d';
2108 hex_digits[14]='e';
2109 hex_digits[15]='f';
2110 p=string_info->datum;
2111 q=(unsigned char *) string;
2112 for (i=0; i < (ssize_t) string_info->length; i++)
2113 {
2114 *q++=hex_digits[(*p >> 4) & 0x0f];
2115 *q++=hex_digits[*p & 0x0f];
2116 p++;
2117 }
2118 *q='\0';
2119 return(string);
2120}
2121
2122/*
2123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2124% %
2125% %
2126% %
cristy3ed852e2009-09-05 21:47:34 +00002127% S t r i n g T o A r g v %
2128% %
2129% %
2130% %
2131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2132%
2133% StringToArgv() converts a text string into command line arguments.
anthony31f1bf72012-01-30 12:37:22 +00002134% The 'argv' array of arguments, is returned while the number of arguments
2135% is returned via the provided integer variable pointer.
2136%
2137% Simple 'word' tokenizer, which allows for each word to be optionally
2138% quoted. However it will not allow use of partial quotes, or escape
2139% characters.
cristy3ed852e2009-09-05 21:47:34 +00002140%
2141% The format of the StringToArgv method is:
2142%
2143% char **StringToArgv(const char *text,int *argc)
2144%
2145% A description of each parameter follows:
2146%
2147% o argv: Method StringToArgv returns the string list unless an error
2148% occurs, otherwise NULL.
2149%
2150% o text: Specifies the string to segment into a list.
2151%
2152% o argc: This integer pointer returns the number of arguments in the
2153% list.
2154%
2155*/
2156MagickExport char **StringToArgv(const char *text,int *argc)
2157{
2158 char
2159 **argv;
2160
2161 register const char
2162 *p,
2163 *q;
2164
cristybb503372010-05-27 20:51:26 +00002165 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002166 i;
2167
2168 *argc=0;
2169 if (text == (char *) NULL)
2170 return((char **) NULL);
2171 /*
2172 Determine the number of arguments.
2173 */
2174 for (p=text; *p != '\0'; )
2175 {
2176 while (isspace((int) ((unsigned char) *p)) != 0)
2177 p++;
cristya20c9042011-05-19 13:22:18 +00002178 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00002179 break;
cristy3ed852e2009-09-05 21:47:34 +00002180 (*argc)++;
2181 if (*p == '"')
2182 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2183 if (*p == '\'')
2184 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2185 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2186 p++;
2187 }
2188 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002189 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002190 if (argv == (char **) NULL)
2191 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2192 /*
2193 Convert string to an ASCII list.
2194 */
2195 argv[0]=AcquireString("magick");
2196 p=text;
cristybb503372010-05-27 20:51:26 +00002197 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002198 {
2199 while (isspace((int) ((unsigned char) *p)) != 0)
2200 p++;
2201 q=p;
2202 if (*q == '"')
2203 {
2204 p++;
2205 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2206 }
2207 else
2208 if (*q == '\'')
2209 {
cristy06b15f42011-01-22 21:36:24 +00002210 p++;
cristy3ed852e2009-09-05 21:47:34 +00002211 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002212 }
2213 else
2214 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2215 q++;
2216 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2217 sizeof(**argv));
2218 if (argv[i] == (char *) NULL)
2219 {
2220 for (i--; i >= 0; i--)
2221 argv[i]=DestroyString(argv[i]);
2222 argv=(char **) RelinquishMagickMemory(argv);
2223 ThrowFatalException(ResourceLimitFatalError,
2224 "UnableToConvertStringToARGV");
2225 }
cristy54aad5e2010-09-03 16:02:04 +00002226 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002227 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002228 p=q;
2229 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2230 p++;
2231 }
2232 argv[i]=(char *) NULL;
2233 return(argv);
2234}
2235
2236/*
2237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238% %
2239% %
2240% %
anthonyb1d483a2012-04-14 12:53:56 +00002241% 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 +00002242% %
2243% %
2244% %
2245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2246%
glennrp6ab82382013-10-28 13:54:30 +00002247% StringToArrayOfDoubles() converts a string of space or comma separated
anthonyb1d483a2012-04-14 12:53:56 +00002248% numbers into array of floating point numbers (doubles). Any number that
2249% failes to parse properly will produce a syntax error. As will two commas
2250% without a number between them. However a final comma at the end will
2251% not be regarded as an error so as to simplify automatic list generation.
cristy3ed852e2009-09-05 21:47:34 +00002252%
anthonyb1d483a2012-04-14 12:53:56 +00002253% A NULL value is returned on syntax or memory errors.
cristy3ed852e2009-09-05 21:47:34 +00002254%
anthonyb1d483a2012-04-14 12:53:56 +00002255% Use RelinquishMagickMemory() to free returned array when finished.
2256%
2257% The format of the StringToArrayOfDoubles method is:
2258%
cristy66336b02014-04-07 20:48:46 +00002259% double *StringToArrayOfDoubles(const char *string,size_t *count,
2260% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002261%
2262% A description of each parameter follows:
2263%
glennrp6ab82382013-10-28 13:54:30 +00002264% o string: the string containing the comma/space separated values.
anthonyb1d483a2012-04-14 12:53:56 +00002265%
2266% o count: returns number of arguments in returned array
2267%
cristy52085732013-11-09 02:32:27 +00002268% o exception: return any errors or warnings in this structure.
2269%
cristy3ed852e2009-09-05 21:47:34 +00002270*/
cristy52085732013-11-09 02:32:27 +00002271MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2272 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002273{
anthonyb1d483a2012-04-14 12:53:56 +00002274 char
2275 *q;
2276
cristy0a887dc2012-08-15 22:58:36 +00002277 const char
2278 *p;
2279
anthonyb1d483a2012-04-14 12:53:56 +00002280 double
2281 *array;
2282
cristybb503372010-05-27 20:51:26 +00002283 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002284 i;
2285
cristy0a887dc2012-08-15 22:58:36 +00002286 /*
2287 Determine count of values, and check syntax.
2288 */
cristyb0de93f2013-05-03 13:39:25 +00002289 assert(exception != (ExceptionInfo *) NULL);
2290 assert(exception->signature == MagickSignature);
anthonyb1d483a2012-04-14 12:53:56 +00002291 *count=0;
anthonyb1d483a2012-04-14 12:53:56 +00002292 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002293 p=string;
2294 while (*p != '\0')
cristy3ed852e2009-09-05 21:47:34 +00002295 {
cristy0a887dc2012-08-15 22:58:36 +00002296 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2297 if (p == q)
2298 return((double *) NULL); /* no value found */
2299 p=q;
2300 i++; /* increment value count */
2301 while (isspace((int) ((unsigned char) *p)) != 0)
2302 p++; /* skip spaces */
2303 if (*p == ',')
2304 p++; /* skip comma */
2305 while (isspace((int) ((unsigned char) *p)) != 0)
2306 p++; /* and more spaces */
cristy3ed852e2009-09-05 21:47:34 +00002307 }
cristy0a887dc2012-08-15 22:58:36 +00002308 /*
2309 Allocate floating point argument list.
2310 */
anthonyb1d483a2012-04-14 12:53:56 +00002311 *count=i;
cristy0a887dc2012-08-15 22:58:36 +00002312 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2313 if (array == (double *) NULL)
cristy70ca0222013-11-09 02:34:16 +00002314 {
2315 (void) ThrowMagickException(exception,GetMagickModule(),
2316 ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2317 return((double *) NULL);
2318 }
cristy0a887dc2012-08-15 22:58:36 +00002319 /*
2320 Fill in the floating point values.
2321 */
anthonyb1d483a2012-04-14 12:53:56 +00002322 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002323 p=string;
2324 while ((*p != '\0') && (i < *count))
2325 {
anthonyb1d483a2012-04-14 12:53:56 +00002326 array[i++]=StringToDouble(p,&q);
2327 p=q;
cristy0a887dc2012-08-15 22:58:36 +00002328 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2329 p++;
anthonyb1d483a2012-04-14 12:53:56 +00002330 }
anthonyb1d483a2012-04-14 12:53:56 +00002331 return(array);
cristy3ed852e2009-09-05 21:47:34 +00002332}
2333
2334/*
2335%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2336% %
2337% %
2338% %
anthonyb1d483a2012-04-14 12:53:56 +00002339+ S t r i n g T o k e n %
cristy3ed852e2009-09-05 21:47:34 +00002340% %
2341% %
2342% %
2343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2344%
cristy66336b02014-04-07 20:48:46 +00002345% StringToken() looks for any one of given delimiters and splits the string
anthonyb1d483a2012-04-14 12:53:56 +00002346% into two separate strings by replacing the delimiter character found with a
2347% nul character.
2348%
2349% The given string pointer is changed to point to the string following the
2350% delimiter character found, or NULL. A pointer to the start of the
2351% string is returned, representing the token before the delimiter.
2352%
2353% In may ways this is equivent to the strtok() C library function, but with
2354% multiple delimiter characters rather than a delimiter string.
cristy3ed852e2009-09-05 21:47:34 +00002355%
2356% The format of the StringToken method is:
2357%
2358% char *StringToken(const char *delimiters,char **string)
2359%
2360% A description of each parameter follows:
2361%
2362% o delimiters: one or more delimiters.
2363%
2364% o string: return the first token in the string. If none is found, return
2365% NULL.
2366%
2367*/
2368MagickExport char *StringToken(const char *delimiters,char **string)
2369{
2370 char
2371 *q;
2372
2373 register char
2374 *p;
2375
2376 register const char
2377 *r;
2378
2379 register int
2380 c,
2381 d;
2382
2383 p=(*string);
2384 if (p == (char *) NULL)
2385 return((char *) NULL);
anthonyb1d483a2012-04-14 12:53:56 +00002386 q=p;
2387 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00002388 {
2389 c=(*p++);
2390 r=delimiters;
2391 do
2392 {
2393 d=(*r++);
2394 if (c == d)
2395 {
2396 if (c == '\0')
2397 p=(char *) NULL;
2398 else
2399 p[-1]='\0';
2400 *string=p;
2401 return(q);
2402 }
2403 } while (d != '\0');
2404 }
2405}
2406
2407/*
2408%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2409% %
2410% %
2411% %
2412% S t r i n g T o L i s t %
2413% %
2414% %
2415% %
2416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2417%
2418% StringToList() converts a text string into a list by segmenting the text
2419% string at each carriage return discovered. The list is converted to HEX
2420% characters if any control characters are discovered within the text string.
2421%
2422% The format of the StringToList method is:
2423%
2424% char **StringToList(const char *text)
2425%
2426% A description of each parameter follows:
2427%
cristy3ed852e2009-09-05 21:47:34 +00002428% o text: Specifies the string to segment into a list.
2429%
2430*/
2431MagickExport char **StringToList(const char *text)
2432{
2433 char
2434 **textlist;
2435
2436 register const char
2437 *p;
2438
cristybb503372010-05-27 20:51:26 +00002439 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002440 i;
2441
cristybb503372010-05-27 20:51:26 +00002442 size_t
cristy3ed852e2009-09-05 21:47:34 +00002443 lines;
2444
2445 if (text == (char *) NULL)
2446 return((char **) NULL);
2447 for (p=text; *p != '\0'; p++)
2448 if (((int) ((unsigned char) *p) < 32) &&
2449 (isspace((int) ((unsigned char) *p)) == 0))
2450 break;
2451 if (*p == '\0')
2452 {
2453 register const char
2454 *q;
2455
2456 /*
2457 Convert string to an ASCII list.
2458 */
2459 lines=1;
2460 for (p=text; *p != '\0'; p++)
2461 if (*p == '\n')
2462 lines++;
2463 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2464 sizeof(*textlist));
2465 if (textlist == (char **) NULL)
2466 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2467 p=text;
cristybb503372010-05-27 20:51:26 +00002468 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002469 {
2470 for (q=p; *q != '\0'; q++)
2471 if ((*q == '\r') || (*q == '\n'))
2472 break;
2473 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002474 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002475 if (textlist[i] == (char *) NULL)
2476 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002477 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002478 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002479 if (*q == '\r')
2480 q++;
2481 p=q+1;
2482 }
2483 }
2484 else
2485 {
2486 char
2487 hex_string[MaxTextExtent];
2488
2489 register char
2490 *q;
2491
cristybb503372010-05-27 20:51:26 +00002492 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002493 j;
2494
2495 /*
2496 Convert string to a HEX list.
2497 */
cristybb503372010-05-27 20:51:26 +00002498 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002499 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2500 sizeof(*textlist));
2501 if (textlist == (char **) NULL)
2502 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2503 p=text;
cristybb503372010-05-27 20:51:26 +00002504 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002505 {
2506 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002507 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002508 if (textlist[i] == (char *) NULL)
2509 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002510 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002511 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002512 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002513 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002514 {
cristyb51dff52011-05-19 16:55:47 +00002515 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002516 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2517 q+=2;
2518 if ((j % 0x04) == 0)
2519 *q++=' ';
2520 }
2521 for ( ; j <= 0x14; j++)
2522 {
2523 *q++=' ';
2524 *q++=' ';
2525 if ((j % 0x04) == 0)
2526 *q++=' ';
2527 }
2528 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002529 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002530 {
2531 if (isprint((int) ((unsigned char) *p)) != 0)
2532 *q++=(*p);
2533 else
2534 *q++='-';
2535 p++;
2536 }
2537 *q='\0';
2538 }
2539 }
2540 textlist[i]=(char *) NULL;
2541 return(textlist);
2542}
2543
2544/*
2545%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2546% %
2547% %
2548% %
2549% S t r i n g T o S t r i n g I n f o %
2550% %
2551% %
2552% %
2553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2554%
cristybca58f32011-08-21 14:48:50 +00002555% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002556%
2557% The format of the StringToStringInfo method is:
2558%
2559% StringInfo *StringToStringInfo(const char *string)
2560%
2561% A description of each parameter follows:
2562%
2563% o string: The string.
2564%
2565*/
2566MagickExport StringInfo *StringToStringInfo(const char *string)
2567{
2568 StringInfo
2569 *string_info;
2570
cristy3ed852e2009-09-05 21:47:34 +00002571 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002572 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002573 SetStringInfoDatum(string_info,(const unsigned char *) string);
2574 return(string_info);
2575}
2576
2577/*
2578%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2579% %
2580% %
2581% %
2582% S t r i p S t r i n g %
2583% %
2584% %
2585% %
2586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2587%
2588% StripString() strips any whitespace or quotes from the beginning and end of
2589% a string of characters.
2590%
2591% The format of the StripString method is:
2592%
2593% void StripString(char *message)
2594%
2595% A description of each parameter follows:
2596%
2597% o message: Specifies an array of characters.
2598%
2599*/
2600MagickExport void StripString(char *message)
2601{
2602 register char
2603 *p,
2604 *q;
2605
2606 size_t
2607 length;
2608
2609 assert(message != (char *) NULL);
2610 if (*message == '\0')
2611 return;
2612 length=strlen(message);
2613 p=message;
2614 while (isspace((int) ((unsigned char) *p)) != 0)
2615 p++;
2616 if ((*p == '\'') || (*p == '"'))
2617 p++;
2618 q=message+length-1;
2619 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2620 q--;
2621 if (q > p)
2622 if ((*q == '\'') || (*q == '"'))
2623 q--;
cristya63c1ba2011-06-02 20:33:43 +00002624 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002625 message[q-p+1]='\0';
2626 for (p=message; *p != '\0'; p++)
2627 if (*p == '\n')
2628 *p=' ';
2629}
2630
2631/*
2632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2633% %
2634% %
2635% %
2636% S u b s t i t u t e S t r i n g %
2637% %
2638% %
2639% %
2640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2641%
cristyf1b72c12009-10-06 13:25:21 +00002642% SubstituteString() performs string substitution on a string, replacing the
2643% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002644% If the string is matched and status, MagickTrue is returned otherwise
2645% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002646%
2647% The format of the SubstituteString method is:
2648%
cristyf1b72c12009-10-06 13:25:21 +00002649% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002650% const char *replace)
2651%
2652% A description of each parameter follows:
2653%
cristyf1b72c12009-10-06 13:25:21 +00002654% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002655% allocation if a replacement is made.
2656%
cristybc3392a2009-10-06 03:15:57 +00002657% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002658%
cristybc3392a2009-10-06 03:15:57 +00002659% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002660%
2661*/
cristyf1b72c12009-10-06 13:25:21 +00002662MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002663 const char *search,const char *replace)
2664{
cristybc3392a2009-10-06 03:15:57 +00002665 MagickBooleanType
2666 status;
cristy3ed852e2009-09-05 21:47:34 +00002667
cristybc3392a2009-10-06 03:15:57 +00002668 register char
2669 *p;
cristy3ed852e2009-09-05 21:47:34 +00002670
cristy3ed852e2009-09-05 21:47:34 +00002671 size_t
cristybc3392a2009-10-06 03:15:57 +00002672 extent,
2673 replace_extent,
2674 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002675
cristyf1b72c12009-10-06 13:25:21 +00002676 ssize_t
2677 offset;
2678
cristybc3392a2009-10-06 03:15:57 +00002679 status=MagickFalse;
2680 search_extent=0,
2681 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002682 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002683 {
cristyf1b72c12009-10-06 13:25:21 +00002684 if (search_extent == 0)
2685 search_extent=strlen(search);
2686 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002687 continue;
cristy3ed852e2009-09-05 21:47:34 +00002688 /*
cristybc3392a2009-10-06 03:15:57 +00002689 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002690 */
cristyf1b72c12009-10-06 13:25:21 +00002691 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002692 if (replace_extent == 0)
2693 replace_extent=strlen(replace);
2694 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002695 {
cristybc3392a2009-10-06 03:15:57 +00002696 /*
2697 Make room for the replacement string.
2698 */
cristyde58b412010-02-18 03:53:40 +00002699 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002700 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002701 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2702 sizeof(*p));
2703 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002704 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002705 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002706 }
cristy3ed852e2009-09-05 21:47:34 +00002707 /*
cristybc3392a2009-10-06 03:15:57 +00002708 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002709 */
cristybc3392a2009-10-06 03:15:57 +00002710 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002711 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2712 strlen(p+search_extent)+1);
2713 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002714 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002715 }
cristybc3392a2009-10-06 03:15:57 +00002716 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002717}