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