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