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