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