1 /*++ 2 3 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 String.c 15 16 Abstract: 17 18 Unicode string primatives 19 20 --*/ 21 22 #include "Tiano.h" 23 #include "EfiDriverLib.h" 24 #include "EfiCommonLib.h" 25 26 VOID 27 EfiStrCpy ( 28 IN CHAR16 *Destination, 29 IN CHAR16 *Source 30 ) 31 /*++ 32 33 Routine Description: 34 Copy the Unicode string Source to Destination. 35 36 Arguments: 37 Destination - Location to copy string 38 Source - String to copy 39 40 Returns: 41 NONE 42 43 --*/ 44 { 45 while (*Source) { 46 *(Destination++) = *(Source++); 47 } 48 *Destination = 0; 49 } 50 51 VOID 52 EfiStrnCpy ( 53 OUT CHAR16 *Dst, 54 IN CHAR16 *Src, 55 IN UINTN Length 56 ) 57 /*++ 58 59 Routine Description: 60 Copy a string from source to destination 61 62 Arguments: 63 Dst Destination string 64 Src Source string 65 Length Length of destination string 66 67 Returns: 68 69 --*/ 70 { 71 UINTN Index; 72 UINTN SrcLen; 73 74 SrcLen = EfiStrLen (Src); 75 76 Index = 0; 77 while (Index < Length && Index < SrcLen) { 78 Dst[Index] = Src[Index]; 79 Index++; 80 } 81 for (Index = SrcLen; Index < Length; Index++) { 82 Dst[Index] = 0; 83 } 84 } 85 86 UINTN 87 EfiStrLen ( 88 IN CHAR16 *String 89 ) 90 /*++ 91 92 Routine Description: 93 Return the number of Unicode characters in String. This is not the same as 94 the length of the string in bytes. 95 96 Arguments: 97 String - String to process 98 99 Returns: 100 Number of Unicode characters in String 101 102 --*/ 103 { 104 UINTN Length; 105 106 for (Length=0; *String; String++, Length++); 107 return Length; 108 } 109 110 111 UINTN 112 EfiStrSize ( 113 IN CHAR16 *String 114 ) 115 /*++ 116 117 Routine Description: 118 Return the number bytes in the Unicode String. This is not the same as 119 the length of the string in characters. The string size includes the NULL 120 121 Arguments: 122 String - String to process 123 124 Returns: 125 Number of bytes in String 126 127 --*/ 128 { 129 return ((EfiStrLen (String) + 1) * sizeof (CHAR16)); 130 } 131 132 133 INTN 134 EfiStrCmp ( 135 IN CHAR16 *String, 136 IN CHAR16 *String2 137 ) 138 /*++ 139 140 Routine Description: 141 Compare the Unicode string pointed by String to the string pointed by String2. 142 143 Arguments: 144 String - String to process 145 146 String2 - The other string to process 147 148 Returns: 149 Return a positive integer if String is lexicall greater than String2; Zero if 150 the two strings are identical; and a negative integer if String is lexically 151 less than String2. 152 153 --*/ 154 { 155 while (*String) { 156 if (*String != *String2) { 157 break; 158 } 159 160 String += 1; 161 String2 += 1; 162 } 163 164 return *String - *String2; 165 } 166 167 INTN 168 EfiStrnCmp ( 169 IN CHAR16 *String, 170 IN CHAR16 *String2, 171 IN UINTN Length 172 ) 173 /*++ 174 175 Routine Description: 176 This function compares the Unicode string String to the Unicode 177 string String2 for len characters. If the first len characters 178 of String is identical to the first len characters of String2, 179 then 0 is returned. If substring of String sorts lexicographically 180 after String2, the function returns a number greater than 0. If 181 substring of String sorts lexicographically before String2, the 182 function returns a number less than 0. 183 184 Arguments: 185 String - Compare to String2 186 String2 - Compare to String 187 Length - Number of Unicode characters to compare 188 189 Returns: 190 0 - The substring of String and String2 is identical. 191 > 0 - The substring of String sorts lexicographically after String2 192 < 0 - The substring of String sorts lexicographically before String2 193 194 --*/ 195 { 196 while (*String && Length != 0) { 197 if (*String != *String2) { 198 break; 199 } 200 String += 1; 201 String2 += 1; 202 Length -= 1; 203 } 204 return Length > 0 ? *String - *String2 : 0; 205 } 206 207 VOID 208 EfiStrCat ( 209 IN CHAR16 *Destination, 210 IN CHAR16 *Source 211 ) 212 /*++ 213 214 Routine Description: 215 Concatinate Source on the end of Destination 216 217 Arguments: 218 Destination - String to added to the end of. 219 Source - String to concatinate. 220 221 Returns: 222 NONE 223 224 --*/ 225 { 226 EfiStrCpy (Destination + EfiStrLen (Destination), Source); 227 } 228 229 VOID 230 EfiStrnCat ( 231 IN CHAR16 *Dest, 232 IN CHAR16 *Src, 233 IN UINTN Length 234 ) 235 /*++ 236 237 Routine Description: 238 Concatinate Source on the end of Destination 239 240 Arguments: 241 Dst Destination string 242 Src Source string 243 Length Length of destination string 244 245 Returns: 246 247 --*/ 248 { 249 EfiStrnCpy (Dest + EfiStrLen (Dest), Src, Length); 250 } 251 252 UINTN 253 EfiAsciiStrLen ( 254 IN CHAR8 *String 255 ) 256 /*++ 257 258 Routine Description: 259 Return the number of Ascii characters in String. This is not the same as 260 the length of the string in bytes. 261 262 Arguments: 263 String - String to process 264 265 Returns: 266 Number of Ascii characters in String 267 268 --*/ 269 { 270 UINTN Length; 271 272 for (Length=0; *String; String++, Length++); 273 return Length; 274 } 275 276 277 CHAR8 * 278 EfiAsciiStrCpy ( 279 IN CHAR8 *Destination, 280 IN CHAR8 *Source 281 ) 282 /*++ 283 284 Routine Description: 285 Copy the Ascii string Source to Destination. 286 287 Arguments: 288 Destination - Location to copy string 289 Source - String to copy 290 291 Returns: 292 Pointer just pass the end of Destination 293 294 --*/ 295 { 296 while (*Source) { 297 *(Destination++) = *(Source++); 298 } 299 *Destination = 0; 300 return Destination + 1; 301 } 302 303 VOID 304 EfiAsciiStrnCpy ( 305 OUT CHAR8 *Dst, 306 IN CHAR8 *Src, 307 IN UINTN Length 308 ) 309 /*++ 310 311 Routine Description: 312 Copy the Ascii string from source to destination 313 314 Arguments: 315 Dst Destination string 316 Src Source string 317 Length Length of destination string 318 319 Returns: 320 321 --*/ 322 { 323 UINTN Index; 324 UINTN SrcLen; 325 326 SrcLen = EfiAsciiStrLen (Src); 327 328 Index = 0; 329 while (Index < Length && Index < SrcLen) { 330 Dst[Index] = Src[Index]; 331 Index++; 332 } 333 for (Index = SrcLen; Index < Length; Index++) { 334 Dst[Index] = 0; 335 } 336 } 337 338 UINTN 339 EfiAsciiStrSize ( 340 IN CHAR8 *String 341 ) 342 /*++ 343 344 Routine Description: 345 Return the number bytes in the Ascii String. This is not the same as 346 the length of the string in characters. The string size includes the NULL 347 348 Arguments: 349 String - String to process 350 351 Returns: 352 Number of bytes in String 353 354 --*/ 355 { 356 return (EfiAsciiStrLen (String) + 1); 357 } 358 359 360 INTN 361 EfiAsciiStrCmp ( 362 IN CHAR8 *String, 363 IN CHAR8 *String2 364 ) 365 /*++ 366 367 Routine Description: 368 Compare the Ascii string pointed by String to the string pointed by String2. 369 370 Arguments: 371 String - String to process 372 373 String2 - The other string to process 374 375 Returns: 376 Return a positive integer if String is lexicall greater than String2; Zero if 377 the two strings are identical; and a negative integer if String is lexically 378 less than String2. 379 --*/ 380 { 381 while (*String) { 382 if (*String != *String2) { 383 break; 384 } 385 386 String += 1; 387 String2 += 1; 388 } 389 390 return *String - *String2; 391 } 392 393 INTN 394 EfiAsciiStrnCmp ( 395 IN CHAR8 *String, 396 IN CHAR8 *String2, 397 IN UINTN Length 398 ) 399 { 400 if (Length == 0) { 401 return 0; 402 } 403 404 while ((*String != '\0') && 405 (*String == *String2) && 406 (Length > 1)) { 407 String++; 408 String2++; 409 Length--; 410 } 411 return *String - *String2; 412 } 413 414 VOID 415 EfiAsciiStrCat ( 416 IN CHAR8 *Destination, 417 IN CHAR8 *Source 418 ) 419 /*++ 420 421 Routine Description: 422 Concatinate Source on the end of Destination 423 424 Arguments: 425 Destination - String to added to the end of. 426 Source - String to concatinate. 427 428 Returns: 429 NONE 430 431 --*/ 432 { 433 EfiAsciiStrCpy (Destination + EfiAsciiStrLen (Destination), Source); 434 } 435 436 VOID 437 EfiAsciiStrnCat ( 438 IN CHAR8 *Destination, 439 IN CHAR8 *Source, 440 IN UINTN Length 441 ) 442 /*++ 443 444 Routine Description: 445 Concatinate Source on the end of Destination 446 447 Arguments: 448 Destination - String to added to the end of. 449 Source - String to concatinate. 450 451 Returns: 452 NONE 453 454 --*/ 455 { 456 EfiAsciiStrnCpy (Destination + EfiAsciiStrLen (Destination), Source, Length); 457 } 458 459 BOOLEAN 460 IsHexDigit ( 461 OUT UINT8 *Digit, 462 IN CHAR16 Char 463 ) 464 /*++ 465 466 Routine Description: 467 Determines if a Unicode character is a hexadecimal digit. 468 The test is case insensitive. 469 470 Arguments: 471 Digit - Pointer to byte that receives the value of the hex character. 472 Char - Unicode character to test. 473 474 Returns: 475 TRUE - If the character is a hexadecimal digit. 476 FALSE - Otherwise. 477 478 --*/ 479 { 480 if ((Char >= L'0') && (Char <= L'9')) { 481 *Digit = (UINT8) (Char - L'0'); 482 return TRUE; 483 } 484 485 if ((Char >= L'A') && (Char <= L'F')) { 486 *Digit = (UINT8) (Char - L'A' + 0x0A); 487 return TRUE; 488 } 489 490 if ((Char >= L'a') && (Char <= L'f')) { 491 *Digit = (UINT8) (Char - L'a' + 0x0A); 492 return TRUE; 493 } 494 495 return FALSE; 496 } 497 498 CHAR16 499 NibbleToHexChar ( 500 IN UINT8 Nibble 501 ) 502 /*++ 503 504 Routine Description: 505 Converts the low nibble of a byte to hex unicode character. 506 507 Arguments: 508 Nibble - lower nibble of a byte. 509 510 Returns: 511 Hex unicode character. 512 513 --*/ 514 { 515 Nibble &= 0x0F; 516 if (Nibble <= 0x9) { 517 return (CHAR16)(Nibble + L'0'); 518 } 519 520 return (CHAR16)(Nibble - 0xA + L'A'); 521 } 522 523 EFI_STATUS 524 HexStringToBuf ( 525 IN OUT UINT8 *Buf, 526 IN OUT UINTN *Len, 527 IN CHAR16 *Str, 528 OUT UINTN *ConvertedStrLen OPTIONAL 529 ) 530 /*++ 531 532 Routine Description: 533 Converts Unicode string to binary buffer. 534 The conversion may be partial. 535 The first character in the string that is not hex digit stops the conversion. 536 At a minimum, any blob of data could be represented as a hex string. 537 538 Arguments: 539 Buf - Pointer to buffer that receives the data. 540 Len - Length in bytes of the buffer to hold converted data. 541 If routine return with EFI_SUCCESS, containing length of converted data. 542 If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired. 543 Str - String to be converted from. 544 ConvertedStrLen - Length of the Hex String consumed. 545 546 Returns: 547 EFI_SUCCESS: Routine Success. 548 EFI_BUFFER_TOO_SMALL: The buffer is too small to hold converted data. 549 EFI_ 550 551 --*/ 552 { 553 UINTN HexCnt; 554 UINTN Idx; 555 UINTN BufferLength; 556 UINT8 Digit; 557 UINT8 Byte; 558 559 // 560 // Find out how many hex characters the string has. 561 // 562 for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++); 563 564 if (HexCnt == 0) { 565 *Len = 0; 566 return EFI_SUCCESS; 567 } 568 // 569 // Two Unicode characters make up 1 buffer byte. Round up. 570 // 571 BufferLength = (HexCnt + 1) / 2; 572 573 // 574 // Test if buffer is passed enough. 575 // 576 if (BufferLength > (*Len)) { 577 *Len = BufferLength; 578 return EFI_BUFFER_TOO_SMALL; 579 } 580 581 *Len = BufferLength; 582 583 for (Idx = 0; Idx < HexCnt; Idx++) { 584 585 IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]); 586 587 // 588 // For odd charaters, write the lower nibble for each buffer byte, 589 // and for even characters, the upper nibble. 590 // 591 if ((Idx & 1) == 0) { 592 Byte = Digit; 593 } else { 594 Byte = Buf[Idx / 2]; 595 Byte &= 0x0F; 596 Byte = (UINT8)(Byte | (Digit << 4)); 597 } 598 599 Buf[Idx / 2] = Byte; 600 } 601 602 if (ConvertedStrLen != NULL) { 603 *ConvertedStrLen = HexCnt; 604 } 605 606 return EFI_SUCCESS; 607 } 608 609 EFI_STATUS 610 BufToHexString ( 611 IN OUT CHAR16 *Str, 612 IN OUT UINTN *HexStringBufferLength, 613 IN UINT8 *Buf, 614 IN UINTN Len 615 ) 616 /*++ 617 618 Routine Description: 619 Converts binary buffer to Unicode string. 620 At a minimum, any blob of data could be represented as a hex string. 621 622 Arguments: 623 Str - Pointer to the string. 624 HexStringBufferLength - Length in bytes of buffer to hold the hex string. Includes tailing '\0' character. 625 If routine return with EFI_SUCCESS, containing length of hex string buffer. 626 If routine return with EFI_BUFFER_TOO_SMALL, containg length of hex string buffer desired. 627 Buf - Buffer to be converted from. 628 Len - Length in bytes of the buffer to be converted. 629 630 Returns: 631 EFI_SUCCESS: Routine success. 632 EFI_BUFFER_TOO_SMALL: The hex string buffer is too small. 633 634 --*/ 635 { 636 UINTN Idx; 637 UINT8 Byte; 638 UINTN StrLen; 639 640 // 641 // Make sure string is either passed or allocate enough. 642 // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer. 643 // Plus the Unicode termination character. 644 // 645 StrLen = Len * 2; 646 if (StrLen > ((*HexStringBufferLength) - 1)) { 647 *HexStringBufferLength = StrLen + 1; 648 return EFI_BUFFER_TOO_SMALL; 649 } 650 651 *HexStringBufferLength = StrLen + 1; 652 // 653 // Ends the string. 654 // 655 Str[StrLen] = L'\0'; 656 657 for (Idx = 0; Idx < Len; Idx++) { 658 659 Byte = Buf[Idx]; 660 Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte); 661 Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4)); 662 } 663 664 return EFI_SUCCESS; 665 } 666 667 VOID 668 EfiStrTrim ( 669 IN OUT CHAR16 *str, 670 IN CHAR16 CharC 671 ) 672 /*++ 673 674 Routine Description: 675 676 Removes (trims) specified leading and trailing characters from a string. 677 678 Arguments: 679 680 str - Pointer to the null-terminated string to be trimmed. On return, 681 str will hold the trimmed string. 682 CharC - Character will be trimmed from str. 683 684 Returns: 685 686 --*/ 687 { 688 CHAR16 *p1; 689 CHAR16 *p2; 690 691 if (*str == 0) { 692 return; 693 } 694 695 // 696 // Trim off the leading and trailing characters c 697 // 698 for (p1 = str; *p1 && *p1 == CharC; p1++) { 699 ; 700 } 701 702 p2 = str; 703 if (p2 == p1) { 704 while (*p1) { 705 p2++; 706 p1++; 707 } 708 } else { 709 while (*p1) { 710 *p2 = *p1; 711 p1++; 712 p2++; 713 } 714 *p2 = 0; 715 } 716 717 718 for (p1 = str + EfiStrLen(str) - 1; p1 >= str && *p1 == CharC; p1--) { 719 ; 720 } 721 if (p1 != str + EfiStrLen(str) - 1) { 722 *(p1 + 1) = 0; 723 } 724 } 725 CHAR16* 726 EfiStrStr ( 727 IN CHAR16 *String, 728 IN CHAR16 *StrCharSet 729 ) 730 /*++ 731 732 Routine Description: 733 734 Find a substring. 735 736 Arguments: 737 738 String - Null-terminated string to search. 739 StrCharSet - Null-terminated string to search for. 740 741 Returns: 742 The address of the first occurrence of the matching substring if successful, or NULL otherwise. 743 --*/ 744 { 745 CHAR16 *Src; 746 CHAR16 *Sub; 747 748 Src = String; 749 Sub = StrCharSet; 750 751 while ((*String != L'\0') && (*StrCharSet != L'\0')) { 752 if (*String++ != *StrCharSet) { 753 String = ++Src; 754 StrCharSet = Sub; 755 } else { 756 StrCharSet++; 757 } 758 } 759 if (*StrCharSet == L'\0') { 760 return Src; 761 } else { 762 return NULL; 763 } 764 } 765 766 CHAR8* 767 EfiAsciiStrStr ( 768 IN CHAR8 *String, 769 IN CHAR8 *StrCharSet 770 ) 771 /*++ 772 773 Routine Description: 774 775 Find a Ascii substring. 776 777 Arguments: 778 779 String - Null-terminated Ascii string to search. 780 StrCharSet - Null-terminated Ascii string to search for. 781 782 Returns: 783 The address of the first occurrence of the matching Ascii substring if successful, or NULL otherwise. 784 --*/ 785 { 786 CHAR8 *Src; 787 CHAR8 *Sub; 788 789 Src = String; 790 Sub = StrCharSet; 791 792 while ((*String != '\0') && (*StrCharSet != '\0')) { 793 if (*String++ != *StrCharSet) { 794 String = ++Src; 795 StrCharSet = Sub; 796 } else { 797 StrCharSet++; 798 } 799 } 800 if (*StrCharSet == '\0') { 801 return Src; 802 } else { 803 return NULL; 804 } 805 } 806 807