string.c revision 7fb9fc1a2796365be394aa5927e7773ca07f10ee
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-2014 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/list.h" 48#include "MagickCore/locale_.h" 49#include "MagickCore/log.h" 50#include "MagickCore/memory_.h" 51#include "MagickCore/nt-base-private.h" 52#include "MagickCore/property.h" 53#include "MagickCore/resource_.h" 54#include "MagickCore/signature-private.h" 55#include "MagickCore/string_.h" 56#include "MagickCore/string-private.h" 57#include "MagickCore/utility-private.h" 58 59/* 60 static declarations. 61*/ 62#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP) 63static const unsigned char 64 AsciiMap[] = 65 { 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% 102% AcquireString() returns an new extented string, containing a clone of the 103% given string. 104% 105% An extended string is the string length, plus an extra MaxTextExtent space 106% to allow for the string to be actively worked on. 107% 108% The returned string shoud be freed using DestoryString(). 109% 110% 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); 130 if (~length < MaxTextExtent) 131 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 132 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent, 133 sizeof(*destination)); 134 if (destination == (char *) NULL) 135 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 136 *destination='\0'; 137 if (source != (char *) NULL) 138 (void) memcpy(destination,source,length*sizeof(*destination)); 139 destination[length]='\0'; 140 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 170 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info)); 171 if (string_info == (StringInfo *) NULL) 172 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 173 (void) ResetMagickMemory(string_info,0,sizeof(*string_info)); 174 string_info->signature=MagickSignature; 175 string_info->length=length; 176 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"); 182 return(string_info); 183} 184 185/* 186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 187% % 188% % 189% % 190% B l o b T o S t r i n g I n f o % 191% % 192% % 193% % 194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 195% 196% BlobToStringInfo() returns the contents of a blob as a StringInfo structure 197% with MaxTextExtent extra space. 198% 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); 216 if (string_info->datum != (unsigned char *) NULL) 217 string_info->datum=(unsigned char *) RelinquishMagickMemory( 218 string_info->datum); 219 string_info->length=length; 220 if (~string_info->length >= (MaxTextExtent-1)) 221 string_info->datum=(unsigned char *) AcquireQuantumMemory( 222 string_info->length+MaxTextExtent,sizeof(*string_info->datum)); 223 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% % 238% C l o n e S t r i n g % 239% % 240% % 241% % 242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 243% 244% 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. 247% 248% 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. 250% 251% When finished the non-NULL string should be freed using DestoryString() 252% or using CloneString() with a NULL pointed for the source. 253% 254% 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 270 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, 286 sizeof(**destination)); 287 if (*destination == (char *) NULL) 288 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 289 if (length != 0) 290 (void) memcpy(*destination,source,length*sizeof(**destination)); 291 (*destination)[length]='\0'; 292 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 322 assert(string_info != (StringInfo *) NULL); 323 assert(string_info->signature == MagickSignature); 324 clone_info=AcquireStringInfo(string_info->length); 325 if (string_info->length != 0) 326 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1); 327 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 370 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 482 destination_length, 483 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 } 494 destination_length=strlen(*destination); 495 source_length=strlen(source); 496 length=destination_length; 497 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, 503 sizeof(**destination)); 504 if (*destination == (char *) NULL) 505 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); 506 if (source_length != 0) 507 (void) memcpy((*destination)+destination_length,source,source_length); 508 (*destination)[length]='\0'; 509 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 544 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); 551 (void) memcpy(string_info->datum+length,source->datum,source->length); 552} 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*/ 578MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename) 579{ 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); 599 file=open_utf8(filename,O_RDONLY | O_BINARY,0); 600 if (file == -1) 601 return((StringInfo *) NULL); 602 offset=(MagickOffsetType) lseek(file,0,SEEK_END); 603 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; 610 if (~length >= (MaxTextExtent-1)) 611 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 { 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 if (string_info->datum != (unsigned char *) NULL) 654 string_info->datum=(unsigned char *) RelinquishMagickMemory( 655 string_info->datum); 656 (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% 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 == 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{ 876 register ssize_t 877 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 929 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; 939 if (~length >= (MaxTextExtent-1)) 940 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); 1035 if (string_info->datum != (unsigned char *) NULL) 1036 string_info->datum=(unsigned char *) RelinquishMagickMemory( 1037 string_info->datum); 1038 (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, 1060% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by 1061% 1000. 1062% 1063% The format of the FormatMagickSize method is: 1064% 1065% ssize_t FormatMagickSize(const MagickSizeType size,char *format) 1066% 1067% A description of each parameter follows: 1068% 1069% o size: convert this size to a human readable format. 1070% 1071% o bi: use power of two rather than power of ten. 1072% 1073% o format: human readable format. 1074% 1075*/ 1076MagickExport ssize_t FormatMagickSize(const MagickSizeType size, 1077 const MagickBooleanType bi,char *format) 1078{ 1079 const char 1080 **units; 1081 1082 double 1083 bytes, 1084 length; 1085 1086 register ssize_t 1087 i, 1088 j; 1089 1090 ssize_t 1091 count; 1092 1093 static const char 1094 *bi_units[] = 1095 { 1096 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL 1097 }, 1098 *traditional_units[] = 1099 { 1100 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL 1101 }; 1102 1103 bytes=1000.0; 1104 units=traditional_units; 1105 if (bi != MagickFalse) 1106 { 1107 bytes=1024.0; 1108 units=bi_units; 1109 } 1110#if defined(_MSC_VER) && (_MSC_VER == 1200) 1111 length=(double) ((MagickOffsetType) size); 1112#else 1113 length=(double) size; 1114#endif 1115 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++) 1116 length/=bytes; 1117 count=0; 1118 for (j=2; j < 12; j++) 1119 { 1120 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length, 1121 units[i]); 1122 if (strchr(format,'+') == (char *) NULL) 1123 break; 1124 } 1125 return(count); 1126} 1127 1128/* 1129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1130% % 1131% % 1132% % 1133% 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% 1144% ssize_t FormatMagickTime(const time_t time,const size_t length, 1145% 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*/ 1157MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length, 1158 char *timestamp) 1159{ 1160 ssize_t 1161 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 { 1177 struct tm 1178 *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 { 1189 struct tm 1190 *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))); 1201 count=FormatLocaleString(timestamp,length, 1202 "%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, 1204 local_time.tm_min,local_time.tm_sec,(long) timezone); 1205 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*/ 1231MagickExport char *GetEnvironmentValue(const char *name) 1232{ 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% % 1334+ 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 1365 value=InterpretLocaleValue(string,&q); 1366 if (q != string) 1367 { 1368 if ((*q >= 'E') && (*q <= 'z')) 1369 { 1370 double 1371 e; 1372 1373 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 } 1397 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 } 1411 if (*q == 'B') 1412 q++; 1413 } 1414 if (sentinal != (char **) NULL) 1415 *sentinal=q; 1416 return(value); 1417} 1418 1419/* 1420%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1421% % 1422% % 1423% % 1424% 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% % 1507% 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 1518% 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. 1520% 1521% The format of the LocaleCompare method is: 1522% 1523% int LocaleCompare(const char *p,const char *q) 1524% 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*/ 1532MagickExport int LocaleCompare(const char *p,const char *q) 1533{ 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) 1541 return(strcasecmp(p,q)); 1542#else 1543 { 1544 register int 1545 c, 1546 d; 1547 1548 for ( ; ; ) 1549 { 1550 c=(int) *((unsigned char *) p); 1551 d=(int) *((unsigned char *) q); 1552 if ((c == 0) || (AsciiMap[c] != AsciiMap[d])) 1553 break; 1554 p++; 1555 q++; 1556 } 1557 return(AsciiMap[c]-(int) AsciiMap[d]); 1558 } 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% 1606% 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. 1618% 1619% The format of the LocaleNCompare method is: 1620% 1621% int LocaleNCompare(const char *p,const char *q,const size_t n) 1622% 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% 1629% o length: the number of characters to compare in strings p and q. 1630% 1631*/ 1632MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length) 1633{ 1634 if ((p == (char *) NULL) && (q == (char *) NULL)) 1635 return(0); 1636 if (p == (char *) NULL) 1637 return(-1); 1638 if (q == (char *) NULL) 1639 return(1); 1640#if defined(MAGICKCORE_HAVE_STRNCASECMP) 1641 return(strncasecmp(p,q,length)); 1642#else 1643 { 1644 register int 1645 c, 1646 d; 1647 1648 register size_t 1649 i; 1650 1651 for (i=length; i != 0; i--) 1652 { 1653 c=(int) *((unsigned char *) p); 1654 d=(int) *((unsigned char *) q); 1655 if (AsciiMap[c] != AsciiMap[d]) 1656 return(AsciiMap[c]-(int) AsciiMap[d]); 1657 if (c == 0) 1658 return(0); 1659 p++; 1660 q++; 1661 } 1662 return(0); 1663 } 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); 1738 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 } 1748 (void) FormatLocaleFile(file,"%s(%.20g): ",id,(double) string_info->length); 1749 if (i == string_info->length) 1750 { 1751 for (i=0; i < string_info->length; i++) 1752 (void) fputc(string_info->datum[i],file); 1753 (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 { 1762 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i)); 1763 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++) 1764 { 1765 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff); 1766 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{ 1813 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{ 1845 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); 1852 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length, 1853 source->length)); 1854} 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{ 1885 assert(string_info != (StringInfo *) NULL); 1886 assert(string_info->signature == MagickSignature); 1887 if (string_info->length != 0) 1888 (void) memcpy(string_info->datum,source,string_info->length); 1889} 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{ 1918 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{ 1959 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 1993 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); 1999 (void) memmove(string_info->datum,string_info->datum+offset, 2000 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; 2037 if (~length >= (MaxTextExtent-1)) 2038 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string)); 2039 if (string == (char *) NULL) 2040 return((char *) NULL); 2041 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string)); 2042 string[length]='\0'; 2043 return(string); 2044} 2045 2046/* 2047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2048% % 2049% % 2050% % 2051% 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% % 2127% 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. 2134% 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. 2140% 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 2165 register ssize_t 2166 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++; 2178 if (*p == '\0') 2179 break; 2180 (*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)++; 2189 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv)); 2190 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; 2197 for (i=1; i < (ssize_t) *argc; i++) 2198 { 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 { 2210 p++; 2211 for (q++; (*q != '\'') && (*q != '\0'); q++) ; 2212 } 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 } 2226 (void) memcpy(argv[i],p,(size_t) (q-p)); 2227 argv[i][q-p]='\0'; 2228 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% % 2241% S t r i n g T o A r r a y O f D o u b l e s % 2242% % 2243% % 2244% % 2245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2246% 2247% StringToArrayOfDoubles() converts a string of space or comma separated 2248% 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. 2252% 2253% A NULL value is returned on syntax or memory errors. 2254% 2255% Use RelinquishMagickMemory() to free returned array when finished. 2256% 2257% The format of the StringToArrayOfDoubles method is: 2258% 2259% double *StringToArrayOfDoubles(const char *string,size_t *count, 2260% ExceptionInfo *exception) 2261% 2262% A description of each parameter follows: 2263% 2264% o string: the string containing the comma/space separated values. 2265% 2266% o count: returns number of arguments in returned array 2267% 2268% o exception: return any errors or warnings in this structure. 2269% 2270*/ 2271MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count, 2272 ExceptionInfo *exception) 2273{ 2274 char 2275 *q; 2276 2277 const char 2278 *p; 2279 2280 double 2281 *array; 2282 2283 register ssize_t 2284 i; 2285 2286 /* 2287 Determine count of values, and check syntax. 2288 */ 2289 assert(exception != (ExceptionInfo *) NULL); 2290 assert(exception->signature == MagickSignature); 2291 *count=0; 2292 i=0; 2293 p=string; 2294 while (*p != '\0') 2295 { 2296 (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 */ 2307 } 2308 /* 2309 Allocate floating point argument list. 2310 */ 2311 *count=i; 2312 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array)); 2313 if (array == (double *) NULL) 2314 { 2315 (void) ThrowMagickException(exception,GetMagickModule(), 2316 ResourceLimitError,"MemoryAllocationFailed","`%s'",""); 2317 return((double *) NULL); 2318 } 2319 /* 2320 Fill in the floating point values. 2321 */ 2322 i=0; 2323 p=string; 2324 while ((*p != '\0') && (i < *count)) 2325 { 2326 array[i++]=StringToDouble(p,&q); 2327 p=q; 2328 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ',')) 2329 p++; 2330 } 2331 return(array); 2332} 2333 2334/* 2335%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2336% % 2337% % 2338% % 2339+ S t r i n g T o k e n % 2340% % 2341% % 2342% % 2343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2344% 2345% StringToken() looks for any one of given delimiters and splits the string 2346% 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. 2355% 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); 2386 q=p; 2387 for ( ; ; ) 2388 { 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% 2428% 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 2439 register ssize_t 2440 i; 2441 2442 size_t 2443 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; 2468 for (i=0; i < (ssize_t) lines; i++) 2469 { 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, 2474 sizeof(**textlist)); 2475 if (textlist[i] == (char *) NULL) 2476 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText"); 2477 (void) memcpy(textlist[i],p,(size_t) (q-p)); 2478 textlist[i][q-p]='\0'; 2479 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 2492 register ssize_t 2493 j; 2494 2495 /* 2496 Convert string to a HEX list. 2497 */ 2498 lines=(size_t) (strlen(text)/0x14)+1; 2499 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL, 2500 sizeof(*textlist)); 2501 if (textlist == (char **) NULL) 2502 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText"); 2503 p=text; 2504 for (i=0; i < (ssize_t) lines; i++) 2505 { 2506 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent, 2507 sizeof(**textlist)); 2508 if (textlist[i] == (char *) NULL) 2509 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText"); 2510 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ", 2511 (long) (0x14*i)); 2512 q=textlist[i]+strlen(textlist[i]); 2513 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++) 2514 { 2515 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j)); 2516 (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++=' '; 2529 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++) 2530 { 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% 2555% StringToStringInfo() converts a string to a StringInfo type. 2556% 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 2571 assert(string != (const char *) NULL); 2572 string_info=AcquireStringInfo(strlen(string)); 2573 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--; 2624 (void) memmove(message,p,(size_t) (q-p+1)); 2625 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% 2642% SubstituteString() performs string substitution on a string, replacing the 2643% string with the substituted version. Buffer must be allocated from the heap. 2644% If the string is matched and status, MagickTrue is returned otherwise 2645% MagickFalse. 2646% 2647% The format of the SubstituteString method is: 2648% 2649% MagickBooleanType SubstituteString(char **string,const char *search, 2650% const char *replace) 2651% 2652% A description of each parameter follows: 2653% 2654% o string: the string to perform replacements on; replaced with new 2655% allocation if a replacement is made. 2656% 2657% o search: search for this string. 2658% 2659% o replace: replace any matches with this string. 2660% 2661*/ 2662MagickExport MagickBooleanType SubstituteString(char **string, 2663 const char *search,const char *replace) 2664{ 2665 MagickBooleanType 2666 status; 2667 2668 register char 2669 *p; 2670 2671 size_t 2672 extent, 2673 replace_extent, 2674 search_extent; 2675 2676 ssize_t 2677 offset; 2678 2679 status=MagickFalse; 2680 search_extent=0, 2681 replace_extent=0; 2682 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search)) 2683 { 2684 if (search_extent == 0) 2685 search_extent=strlen(search); 2686 if (strncmp(p,search,search_extent) != 0) 2687 continue; 2688 /* 2689 We found a match. 2690 */ 2691 status=MagickTrue; 2692 if (replace_extent == 0) 2693 replace_extent=strlen(replace); 2694 if (replace_extent > search_extent) 2695 { 2696 /* 2697 Make room for the replacement string. 2698 */ 2699 offset=(ssize_t) (p-(*string)); 2700 extent=strlen(*string)+replace_extent-search_extent+1; 2701 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent, 2702 sizeof(*p)); 2703 if (*string == (char *) NULL) 2704 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 2705 p=(*string)+offset; 2706 } 2707 /* 2708 Replace string. 2709 */ 2710 if (search_extent != replace_extent) 2711 (void) CopyMagickMemory(p+replace_extent,p+search_extent, 2712 strlen(p+search_extent)+1); 2713 (void) CopyMagickMemory(p,replace,replace_extent); 2714 p+=replace_extent-1; 2715 } 2716 return(status); 2717} 2718