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
EfiStrCpy(IN CHAR16 * Destination,IN CHAR16 * Source)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
EfiStrnCpy(OUT CHAR16 * Dst,IN CHAR16 * Src,IN UINTN Length)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
EfiStrLen(IN CHAR16 * String)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
EfiStrSize(IN CHAR16 * String)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
EfiStrCmp(IN CHAR16 * String,IN CHAR16 * String2)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
EfiStrnCmp(IN CHAR16 * String,IN CHAR16 * String2,IN UINTN Length)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
EfiStrCat(IN CHAR16 * Destination,IN CHAR16 * Source)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
EfiStrnCat(IN CHAR16 * Dest,IN CHAR16 * Src,IN UINTN Length)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
EfiAsciiStrLen(IN CHAR8 * String)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 *
EfiAsciiStrCpy(IN CHAR8 * Destination,IN CHAR8 * Source)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
EfiAsciiStrnCpy(OUT CHAR8 * Dst,IN CHAR8 * Src,IN UINTN Length)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
EfiAsciiStrSize(IN CHAR8 * String)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
EfiAsciiStrCmp(IN CHAR8 * String,IN CHAR8 * String2)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
EfiAsciiStrnCmp(IN CHAR8 * String,IN CHAR8 * String2,IN UINTN Length)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
EfiAsciiStrCat(IN CHAR8 * Destination,IN CHAR8 * Source)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
EfiAsciiStrnCat(IN CHAR8 * Destination,IN CHAR8 * Source,IN UINTN Length)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
IsHexDigit(OUT UINT8 * Digit,IN CHAR16 Char)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
NibbleToHexChar(IN UINT8 Nibble)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
HexStringToBuf(IN OUT UINT8 * Buf,IN OUT UINTN * Len,IN CHAR16 * Str,OUT UINTN * ConvertedStrLen OPTIONAL)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
BufToHexString(IN OUT CHAR16 * Str,IN OUT UINTN * HexStringBufferLength,IN UINT8 * Buf,IN UINTN Len)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
EfiStrTrim(IN OUT CHAR16 * str,IN CHAR16 CharC)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*
EfiStrStr(IN CHAR16 * String,IN CHAR16 * StrCharSet)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*
EfiAsciiStrStr(IN CHAR8 * String,IN CHAR8 * StrCharSet)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