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