]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/String.c
Update the copyright notice format
[mirror_edk2.git] / MdePkg / Library / BaseLib / String.c
1 /** @file
2 Unicode and ASCII string primatives.
3
4 Copyright (c) 2006 - 2009, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "BaseLibInternals.h"
16
17 #define QUOTIENT_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 / 10)
18 #define REMAINDER_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 % 10)
19
20 #define QUOTIENT_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 / 16)
21 #define REMAINDER_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 % 16)
22
23 #define QUOTIENT_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 / 10)
24 #define REMAINDER_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 % 10)
25
26 #define QUOTIENT_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 / 16)
27 #define REMAINDER_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 % 16)
28
29 /**
30 Copies one Null-terminated Unicode string to another Null-terminated Unicode
31 string and returns the new Unicode string.
32
33 This function copies the contents of the Unicode string Source to the Unicode
34 string Destination, and returns Destination. If Source and Destination
35 overlap, then the results are undefined.
36
37 If Destination is NULL, then ASSERT().
38 If Destination is not aligned on a 16-bit boundary, then ASSERT().
39 If Source is NULL, then ASSERT().
40 If Source is not aligned on a 16-bit boundary, then ASSERT().
41 If Source and Destination overlap, then ASSERT().
42 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
43 PcdMaximumUnicodeStringLength Unicode characters, not including the
44 Null-terminator, then ASSERT().
45
46 @param Destination Pointer to a Null-terminated Unicode string.
47 @param Source Pointer to a Null-terminated Unicode string.
48
49 @return Destination.
50
51 **/
52 CHAR16 *
53 EFIAPI
54 StrCpy (
55 OUT CHAR16 *Destination,
56 IN CONST CHAR16 *Source
57 )
58 {
59 CHAR16 *ReturnValue;
60
61 //
62 // Destination cannot be NULL
63 //
64 ASSERT (Destination != NULL);
65 ASSERT (((UINTN) Destination & BIT0) == 0);
66
67 //
68 // Destination and source cannot overlap
69 //
70 ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
71 ASSERT ((UINTN)(Source - Destination) > StrLen (Source));
72
73 ReturnValue = Destination;
74 while (*Source != 0) {
75 *(Destination++) = *(Source++);
76 }
77 *Destination = 0;
78 return ReturnValue;
79 }
80
81 /**
82 Copies up to a specified length from one Null-terminated Unicode string to
83 another Null-terminated Unicode string and returns the new Unicode string.
84
85 This function copies the contents of the Unicode string Source to the Unicode
86 string Destination, and returns Destination. At most, Length Unicode
87 characters are copied from Source to Destination. If Length is 0, then
88 Destination is returned unmodified. If Length is greater that the number of
89 Unicode characters in Source, then Destination is padded with Null Unicode
90 characters. If Source and Destination overlap, then the results are
91 undefined.
92
93 If Length > 0 and Destination is NULL, then ASSERT().
94 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
95 If Length > 0 and Source is NULL, then ASSERT().
96 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
97 If Source and Destination overlap, then ASSERT().
98 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
99 PcdMaximumUnicodeStringLength, then ASSERT().
100 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
101 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
102 then ASSERT().
103
104 @param Destination Pointer to a Null-terminated Unicode string.
105 @param Source Pointer to a Null-terminated Unicode string.
106 @param Length Maximum number of Unicode characters to copy.
107
108 @return Destination.
109
110 **/
111 CHAR16 *
112 EFIAPI
113 StrnCpy (
114 OUT CHAR16 *Destination,
115 IN CONST CHAR16 *Source,
116 IN UINTN Length
117 )
118 {
119 CHAR16 *ReturnValue;
120
121 if (Length == 0) {
122 return Destination;
123 }
124
125 //
126 // Destination cannot be NULL if Length is not zero
127 //
128 ASSERT (Destination != NULL);
129 ASSERT (((UINTN) Destination & BIT0) == 0);
130
131 //
132 // Destination and source cannot overlap
133 //
134 ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
135 ASSERT ((UINTN)(Source - Destination) >= Length);
136
137 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
138 ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
139 }
140
141 ReturnValue = Destination;
142
143 while ((*Source != L'\0') && (Length > 0)) {
144 *(Destination++) = *(Source++);
145 Length--;
146 }
147
148 ZeroMem (Destination, Length * sizeof (*Destination));
149 return ReturnValue;
150 }
151
152 /**
153 Returns the length of a Null-terminated Unicode string.
154
155 This function returns the number of Unicode characters in the Null-terminated
156 Unicode string specified by String.
157
158 If String is NULL, then ASSERT().
159 If String is not aligned on a 16-bit boundary, then ASSERT().
160 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
161 PcdMaximumUnicodeStringLength Unicode characters, not including the
162 Null-terminator, then ASSERT().
163
164 @param String Pointer to a Null-terminated Unicode string.
165
166 @return The length of String.
167
168 **/
169 UINTN
170 EFIAPI
171 StrLen (
172 IN CONST CHAR16 *String
173 )
174 {
175 UINTN Length;
176
177 ASSERT (String != NULL);
178 ASSERT (((UINTN) String & BIT0) == 0);
179
180 for (Length = 0; *String != L'\0'; String++, Length++) {
181 //
182 // If PcdMaximumUnicodeStringLength is not zero,
183 // length should not more than PcdMaximumUnicodeStringLength
184 //
185 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
186 ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));
187 }
188 }
189 return Length;
190 }
191
192 /**
193 Returns the size of a Null-terminated Unicode string in bytes, including the
194 Null terminator.
195
196 This function returns the size, in bytes, of the Null-terminated Unicode string
197 specified by String.
198
199 If String is NULL, then ASSERT().
200 If String is not aligned on a 16-bit boundary, then ASSERT().
201 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
202 PcdMaximumUnicodeStringLength Unicode characters, not including the
203 Null-terminator, then ASSERT().
204
205 @param String Pointer to a Null-terminated Unicode string.
206
207 @return The size of String.
208
209 **/
210 UINTN
211 EFIAPI
212 StrSize (
213 IN CONST CHAR16 *String
214 )
215 {
216 return (StrLen (String) + 1) * sizeof (*String);
217 }
218
219 /**
220 Compares two Null-terminated Unicode strings, and returns the difference
221 between the first mismatched Unicode characters.
222
223 This function compares the Null-terminated Unicode string FirstString to the
224 Null-terminated Unicode string SecondString. If FirstString is identical to
225 SecondString, then 0 is returned. Otherwise, the value returned is the first
226 mismatched Unicode character in SecondString subtracted from the first
227 mismatched Unicode character in FirstString.
228
229 If FirstString is NULL, then ASSERT().
230 If FirstString is not aligned on a 16-bit boundary, then ASSERT().
231 If SecondString is NULL, then ASSERT().
232 If SecondString is not aligned on a 16-bit boundary, then ASSERT().
233 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
234 than PcdMaximumUnicodeStringLength Unicode characters, not including the
235 Null-terminator, then ASSERT().
236 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
237 than PcdMaximumUnicodeStringLength Unicode characters, not including the
238 Null-terminator, then ASSERT().
239
240 @param FirstString Pointer to a Null-terminated Unicode string.
241 @param SecondString Pointer to a Null-terminated Unicode string.
242
243 @retval 0 FirstString is identical to SecondString.
244 @return others FirstString is not identical to SecondString.
245
246 **/
247 INTN
248 EFIAPI
249 StrCmp (
250 IN CONST CHAR16 *FirstString,
251 IN CONST CHAR16 *SecondString
252 )
253 {
254 //
255 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
256 //
257 ASSERT (StrSize (FirstString) != 0);
258 ASSERT (StrSize (SecondString) != 0);
259
260 while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
261 FirstString++;
262 SecondString++;
263 }
264 return *FirstString - *SecondString;
265 }
266
267 /**
268 Compares up to a specified length the contents of two Null-terminated Unicode strings,
269 and returns the difference between the first mismatched Unicode characters.
270
271 This function compares the Null-terminated Unicode string FirstString to the
272 Null-terminated Unicode string SecondString. At most, Length Unicode
273 characters will be compared. If Length is 0, then 0 is returned. If
274 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
275 value returned is the first mismatched Unicode character in SecondString
276 subtracted from the first mismatched Unicode character in FirstString.
277
278 If Length > 0 and FirstString is NULL, then ASSERT().
279 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
280 If Length > 0 and SecondString is NULL, then ASSERT().
281 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
282 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
283 PcdMaximumUnicodeStringLength, then ASSERT().
284 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
285 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
286 then ASSERT().
287 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
288 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
289 then ASSERT().
290
291 @param FirstString Pointer to a Null-terminated Unicode string.
292 @param SecondString Pointer to a Null-terminated Unicode string.
293 @param Length Maximum number of Unicode characters to compare.
294
295 @retval 0 FirstString is identical to SecondString.
296 @return others FirstString is not identical to SecondString.
297
298 **/
299 INTN
300 EFIAPI
301 StrnCmp (
302 IN CONST CHAR16 *FirstString,
303 IN CONST CHAR16 *SecondString,
304 IN UINTN Length
305 )
306 {
307 if (Length == 0) {
308 return 0;
309 }
310
311 //
312 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
313 // Length tests are performed inside StrLen().
314 //
315 ASSERT (StrSize (FirstString) != 0);
316 ASSERT (StrSize (SecondString) != 0);
317
318 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
319 ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
320 }
321
322 while ((*FirstString != L'\0') &&
323 (*FirstString == *SecondString) &&
324 (Length > 1)) {
325 FirstString++;
326 SecondString++;
327 Length--;
328 }
329
330 return *FirstString - *SecondString;
331 }
332
333 /**
334 Concatenates one Null-terminated Unicode string to another Null-terminated
335 Unicode string, and returns the concatenated Unicode string.
336
337 This function concatenates two Null-terminated Unicode strings. The contents
338 of Null-terminated Unicode string Source are concatenated to the end of
339 Null-terminated Unicode string Destination. The Null-terminated concatenated
340 Unicode String is returned. If Source and Destination overlap, then the
341 results are undefined.
342
343 If Destination is NULL, then ASSERT().
344 If Destination is not aligned on a 16-bit boundary, then ASSERT().
345 If Source is NULL, then ASSERT().
346 If Source is not aligned on a 16-bit boundary, then ASSERT().
347 If Source and Destination overlap, then ASSERT().
348 If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
349 than PcdMaximumUnicodeStringLength Unicode characters, not including the
350 Null-terminator, then ASSERT().
351 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
352 PcdMaximumUnicodeStringLength Unicode characters, not including the
353 Null-terminator, then ASSERT().
354 If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
355 and Source results in a Unicode string with more than
356 PcdMaximumUnicodeStringLength Unicode characters, not including the
357 Null-terminator, then ASSERT().
358
359 @param Destination Pointer to a Null-terminated Unicode string.
360 @param Source Pointer to a Null-terminated Unicode string.
361
362 @return Destination.
363
364 **/
365 CHAR16 *
366 EFIAPI
367 StrCat (
368 IN OUT CHAR16 *Destination,
369 IN CONST CHAR16 *Source
370 )
371 {
372 StrCpy (Destination + StrLen (Destination), Source);
373
374 //
375 // Size of the resulting string should never be zero.
376 // PcdMaximumUnicodeStringLength is tested inside StrLen().
377 //
378 ASSERT (StrSize (Destination) != 0);
379 return Destination;
380 }
381
382 /**
383 Concatenates up to a specified length one Null-terminated Unicode to the end
384 of another Null-terminated Unicode string, and returns the concatenated
385 Unicode string.
386
387 This function concatenates two Null-terminated Unicode strings. The contents
388 of Null-terminated Unicode string Source are concatenated to the end of
389 Null-terminated Unicode string Destination, and Destination is returned. At
390 most, Length Unicode characters are concatenated from Source to the end of
391 Destination, and Destination is always Null-terminated. If Length is 0, then
392 Destination is returned unmodified. If Source and Destination overlap, then
393 the results are undefined.
394
395 If Destination is NULL, then ASSERT().
396 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
397 If Length > 0 and Source is NULL, then ASSERT().
398 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
399 If Source and Destination overlap, then ASSERT().
400 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
401 PcdMaximumUnicodeStringLength, then ASSERT().
402 If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
403 than PcdMaximumUnicodeStringLength Unicode characters, not including the
404 Null-terminator, then ASSERT().
405 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
406 PcdMaximumUnicodeStringLength Unicode characters, not including the
407 Null-terminator, then ASSERT().
408 If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
409 and Source results in a Unicode string with more than PcdMaximumUnicodeStringLength
410 Unicode characters, not including the Null-terminator, then ASSERT().
411
412 @param Destination Pointer to a Null-terminated Unicode string.
413 @param Source Pointer to a Null-terminated Unicode string.
414 @param Length Maximum number of Unicode characters to concatenate from
415 Source.
416
417 @return Destination.
418
419 **/
420 CHAR16 *
421 EFIAPI
422 StrnCat (
423 IN OUT CHAR16 *Destination,
424 IN CONST CHAR16 *Source,
425 IN UINTN Length
426 )
427 {
428 UINTN DestinationLen;
429
430 DestinationLen = StrLen (Destination);
431 StrnCpy (Destination + DestinationLen, Source, Length);
432 Destination[DestinationLen + Length] = L'\0';
433
434 //
435 // Size of the resulting string should never be zero.
436 // PcdMaximumUnicodeStringLength is tested inside StrLen().
437 //
438 ASSERT (StrSize (Destination) != 0);
439 return Destination;
440 }
441
442 /**
443 Returns the first occurrence of a Null-terminated Unicode sub-string
444 in a Null-terminated Unicode string.
445
446 This function scans the contents of the Null-terminated Unicode string
447 specified by String and returns the first occurrence of SearchString.
448 If SearchString is not found in String, then NULL is returned. If
449 the length of SearchString is zero, then String is
450 returned.
451
452 If String is NULL, then ASSERT().
453 If String is not aligned on a 16-bit boundary, then ASSERT().
454 If SearchString is NULL, then ASSERT().
455 If SearchString is not aligned on a 16-bit boundary, then ASSERT().
456
457 If PcdMaximumUnicodeStringLength is not zero, and SearchString
458 or String contains more than PcdMaximumUnicodeStringLength Unicode
459 characters, not including the Null-terminator, then ASSERT().
460
461 @param String Pointer to a Null-terminated Unicode string.
462 @param SearchString Pointer to a Null-terminated Unicode string to search for.
463
464 @retval NULL If the SearchString does not appear in String.
465 @return others If there is a match.
466
467 **/
468 CHAR16 *
469 EFIAPI
470 StrStr (
471 IN CONST CHAR16 *String,
472 IN CONST CHAR16 *SearchString
473 )
474 {
475 CONST CHAR16 *FirstMatch;
476 CONST CHAR16 *SearchStringTmp;
477
478 //
479 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
480 // Length tests are performed inside StrLen().
481 //
482 ASSERT (StrSize (String) != 0);
483 ASSERT (StrSize (SearchString) != 0);
484
485 if (*SearchString == L'\0') {
486 return (CHAR16 *) String;
487 }
488
489 while (*String != L'\0') {
490 SearchStringTmp = SearchString;
491 FirstMatch = String;
492
493 while ((*String == *SearchStringTmp)
494 && (*String != L'\0')) {
495 String++;
496 SearchStringTmp++;
497 }
498
499 if (*SearchStringTmp == L'\0') {
500 return (CHAR16 *) FirstMatch;
501 }
502
503 if (*String == L'\0') {
504 return NULL;
505 }
506
507 String = FirstMatch + 1;
508 }
509
510 return NULL;
511 }
512
513 /**
514 Check if a Unicode character is a decimal character.
515
516 This internal function checks if a Unicode character is a
517 decimal character. The valid decimal character is from
518 L'0' to L'9'.
519
520 @param Char The character to check against.
521
522 @retval TRUE If the Char is a decmial character.
523 @retval FALSE If the Char is not a decmial character.
524
525 **/
526 BOOLEAN
527 EFIAPI
528 InternalIsDecimalDigitCharacter (
529 IN CHAR16 Char
530 )
531 {
532 return (BOOLEAN) (Char >= L'0' && Char <= L'9');
533 }
534
535 /**
536 Convert a Unicode character to upper case only if
537 it maps to a valid small-case ASCII character.
538
539 This internal function only deal with Unicode character
540 which maps to a valid small-case ASCII character, i.e.
541 L'a' to L'z'. For other Unicode character, the input character
542 is returned directly.
543
544 @param Char The character to convert.
545
546 @retval LowerCharacter If the Char is with range L'a' to L'z'.
547 @retval Unchanged Otherwise.
548
549 **/
550 CHAR16
551 EFIAPI
552 InternalCharToUpper (
553 IN CHAR16 Char
554 )
555 {
556 if (Char >= L'a' && Char <= L'z') {
557 return (CHAR16) (Char - (L'a' - L'A'));
558 }
559
560 return Char;
561 }
562
563 /**
564 Convert a Unicode character to numerical value.
565
566 This internal function only deal with Unicode character
567 which maps to a valid hexadecimal ASII character, i.e.
568 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
569 Unicode character, the value returned does not make sense.
570
571 @param Char The character to convert.
572
573 @return The numerical value converted.
574
575 **/
576 UINTN
577 EFIAPI
578 InternalHexCharToUintn (
579 IN CHAR16 Char
580 )
581 {
582 if (InternalIsDecimalDigitCharacter (Char)) {
583 return Char - L'0';
584 }
585
586 return (UINTN) (10 + InternalCharToUpper (Char) - L'A');
587 }
588
589 /**
590 Check if a Unicode character is a hexadecimal character.
591
592 This internal function checks if a Unicode character is a
593 decimal character. The valid hexadecimal character is
594 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
595
596
597 @param Char The character to check against.
598
599 @retval TRUE If the Char is a hexadecmial character.
600 @retval FALSE If the Char is not a hexadecmial character.
601
602 **/
603 BOOLEAN
604 EFIAPI
605 InternalIsHexaDecimalDigitCharacter (
606 IN CHAR16 Char
607 )
608 {
609
610 return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
611 (Char >= L'A' && Char <= L'F') ||
612 (Char >= L'a' && Char <= L'f'));
613 }
614
615 /**
616 Convert a Null-terminated Unicode decimal string to a value of
617 type UINTN.
618
619 This function returns a value of type UINTN by interpreting the contents
620 of the Unicode string specified by String as a decimal number. The format
621 of the input Unicode string String is:
622
623 [spaces] [decimal digits].
624
625 The valid decimal digit character is in the range [0-9]. The
626 function will ignore the pad space, which includes spaces or
627 tab characters, before [decimal digits]. The running zero in the
628 beginning of [decimal digits] will be ignored. Then, the function
629 stops at the first character that is a not a valid decimal character
630 or a Null-terminator, whichever one comes first.
631
632 If String is NULL, then ASSERT().
633 If String is not aligned in a 16-bit boundary, then ASSERT().
634 If String has only pad spaces, then 0 is returned.
635 If String has no pad spaces or valid decimal digits,
636 then 0 is returned.
637 If the number represented by String overflows according
638 to the range defined by UINTN, then ASSERT().
639
640 If PcdMaximumUnicodeStringLength is not zero, and String contains
641 more than PcdMaximumUnicodeStringLength Unicode characters, not including
642 the Null-terminator, then ASSERT().
643
644 @param String Pointer to a Null-terminated Unicode string.
645
646 @retval Value translated from String.
647
648 **/
649 UINTN
650 EFIAPI
651 StrDecimalToUintn (
652 IN CONST CHAR16 *String
653 )
654 {
655 UINTN Result;
656
657 //
658 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
659 // Length tests are performed inside StrLen().
660 //
661 ASSERT (StrSize (String) != 0);
662
663 //
664 // Ignore the pad spaces (space or tab)
665 //
666 while ((*String == L' ') || (*String == L'\t')) {
667 String++;
668 }
669
670 //
671 // Ignore leading Zeros after the spaces
672 //
673 while (*String == L'0') {
674 String++;
675 }
676
677 Result = 0;
678
679 while (InternalIsDecimalDigitCharacter (*String)) {
680 //
681 // If the number represented by String overflows according
682 // to the range defined by UINTN, then ASSERT().
683 //
684 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_10) ||
685 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_10) &&
686 (*String - L'0') <= REMAINDER_MAX_UINTN_DIVIDED_BY_10)
687 );
688
689 Result = Result * 10 + (*String - L'0');
690 String++;
691 }
692
693 return Result;
694 }
695
696
697 /**
698 Convert a Null-terminated Unicode decimal string to a value of
699 type UINT64.
700
701 This function returns a value of type UINT64 by interpreting the contents
702 of the Unicode string specified by String as a decimal number. The format
703 of the input Unicode string String is:
704
705 [spaces] [decimal digits].
706
707 The valid decimal digit character is in the range [0-9]. The
708 function will ignore the pad space, which includes spaces or
709 tab characters, before [decimal digits]. The running zero in the
710 beginning of [decimal digits] will be ignored. Then, the function
711 stops at the first character that is a not a valid decimal character
712 or a Null-terminator, whichever one comes first.
713
714 If String is NULL, then ASSERT().
715 If String is not aligned in a 16-bit boundary, then ASSERT().
716 If String has only pad spaces, then 0 is returned.
717 If String has no pad spaces or valid decimal digits,
718 then 0 is returned.
719 If the number represented by String overflows according
720 to the range defined by UINT64, then ASSERT().
721
722 If PcdMaximumUnicodeStringLength is not zero, and String contains
723 more than PcdMaximumUnicodeStringLength Unicode characters, not including
724 the Null-terminator, then ASSERT().
725
726 @param String Pointer to a Null-terminated Unicode string.
727
728 @retval Value translated from String.
729
730 **/
731 UINT64
732 EFIAPI
733 StrDecimalToUint64 (
734 IN CONST CHAR16 *String
735 )
736 {
737 UINT64 Result;
738
739 //
740 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
741 // Length tests are performed inside StrLen().
742 //
743 ASSERT (StrSize (String) != 0);
744
745 //
746 // Ignore the pad spaces (space or tab)
747 //
748 while ((*String == L' ') || (*String == L'\t')) {
749 String++;
750 }
751
752 //
753 // Ignore leading Zeros after the spaces
754 //
755 while (*String == L'0') {
756 String++;
757 }
758
759 Result = 0;
760
761 while (InternalIsDecimalDigitCharacter (*String)) {
762 //
763 // If the number represented by String overflows according
764 // to the range defined by UINTN, then ASSERT().
765 //
766 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_10) ||
767 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_10) &&
768 (*String - L'0') <= REMAINDER_MAX_UINT64_DIVIDED_BY_10)
769 );
770
771 Result = MultU64x32 (Result, 10) + (*String - L'0');
772 String++;
773 }
774
775 return Result;
776 }
777
778 /**
779 Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.
780
781 This function returns a value of type UINTN by interpreting the contents
782 of the Unicode string specified by String as a hexadecimal number.
783 The format of the input Unicode string String is:
784
785 [spaces][zeros][x][hexadecimal digits].
786
787 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
788 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
789 If "x" appears in the input string, it must be prefixed with at least one 0.
790 The function will ignore the pad space, which includes spaces or tab characters,
791 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
792 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
793 first valid hexadecimal digit. Then, the function stops at the first character that is
794 a not a valid hexadecimal character or NULL, whichever one comes first.
795
796 If String is NULL, then ASSERT().
797 If String is not aligned in a 16-bit boundary, then ASSERT().
798 If String has only pad spaces, then zero is returned.
799 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
800 then zero is returned.
801 If the number represented by String overflows according to the range defined by
802 UINTN, then ASSERT().
803
804 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
805 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
806 then ASSERT().
807
808 @param String Pointer to a Null-terminated Unicode string.
809
810 @retval Value translated from String.
811
812 **/
813 UINTN
814 EFIAPI
815 StrHexToUintn (
816 IN CONST CHAR16 *String
817 )
818 {
819 UINTN Result;
820
821 //
822 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
823 // Length tests are performed inside StrLen().
824 //
825 ASSERT (StrSize (String) != 0);
826
827 //
828 // Ignore the pad spaces (space or tab)
829 //
830 while ((*String == L' ') || (*String == L'\t')) {
831 String++;
832 }
833
834 //
835 // Ignore leading Zeros after the spaces
836 //
837 while (*String == L'0') {
838 String++;
839 }
840
841 if (InternalCharToUpper (*String) == L'X') {
842 if (*(String - 1) != L'0') {
843 return 0;
844 }
845 //
846 // Skip the 'X'
847 //
848 String++;
849 }
850
851 Result = 0;
852
853 while (InternalIsHexaDecimalDigitCharacter (*String)) {
854 //
855 // If the Hex Number represented by String overflows according
856 // to the range defined by UINTN, then ASSERT().
857 //
858 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_16) ||
859 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_16) &&
860 (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINTN_DIVIDED_BY_16))
861 );
862
863 Result = (Result << 4) + InternalHexCharToUintn (*String);
864 String++;
865 }
866
867 return Result;
868 }
869
870
871 /**
872 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
873
874 This function returns a value of type UINT64 by interpreting the contents
875 of the Unicode string specified by String as a hexadecimal number.
876 The format of the input Unicode string String is
877
878 [spaces][zeros][x][hexadecimal digits].
879
880 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
881 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
882 If "x" appears in the input string, it must be prefixed with at least one 0.
883 The function will ignore the pad space, which includes spaces or tab characters,
884 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
885 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
886 first valid hexadecimal digit. Then, the function stops at the first character that is
887 a not a valid hexadecimal character or NULL, whichever one comes first.
888
889 If String is NULL, then ASSERT().
890 If String is not aligned in a 16-bit boundary, then ASSERT().
891 If String has only pad spaces, then zero is returned.
892 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
893 then zero is returned.
894 If the number represented by String overflows according to the range defined by
895 UINT64, then ASSERT().
896
897 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
898 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
899 then ASSERT().
900
901 @param String Pointer to a Null-terminated Unicode string.
902
903 @retval Value translated from String.
904
905 **/
906 UINT64
907 EFIAPI
908 StrHexToUint64 (
909 IN CONST CHAR16 *String
910 )
911 {
912 UINT64 Result;
913
914 //
915 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
916 // Length tests are performed inside StrLen().
917 //
918 ASSERT (StrSize (String) != 0);
919
920 //
921 // Ignore the pad spaces (space or tab)
922 //
923 while ((*String == L' ') || (*String == L'\t')) {
924 String++;
925 }
926
927 //
928 // Ignore leading Zeros after the spaces
929 //
930 while (*String == L'0') {
931 String++;
932 }
933
934 if (InternalCharToUpper (*String) == L'X') {
935 ASSERT (*(String - 1) == L'0');
936 if (*(String - 1) != L'0') {
937 return 0;
938 }
939 //
940 // Skip the 'X'
941 //
942 String++;
943 }
944
945 Result = 0;
946
947 while (InternalIsHexaDecimalDigitCharacter (*String)) {
948 //
949 // If the Hex Number represented by String overflows according
950 // to the range defined by UINTN, then ASSERT().
951 //
952 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_16)||
953 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_16) &&
954 (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINT64_DIVIDED_BY_16))
955 );
956
957 Result = LShiftU64 (Result, 4);
958 Result = Result + InternalHexCharToUintn (*String);
959 String++;
960 }
961
962 return Result;
963 }
964
965 /**
966 Check if a ASCII character is a decimal character.
967
968 This internal function checks if a Unicode character is a
969 decimal character. The valid decimal character is from
970 '0' to '9'.
971
972 @param Char The character to check against.
973
974 @retval TRUE If the Char is a decmial character.
975 @retval FALSE If the Char is not a decmial character.
976
977 **/
978 BOOLEAN
979 EFIAPI
980 InternalAsciiIsDecimalDigitCharacter (
981 IN CHAR8 Char
982 )
983 {
984 return (BOOLEAN) (Char >= '0' && Char <= '9');
985 }
986
987 /**
988 Check if a ASCII character is a hexadecimal character.
989
990 This internal function checks if a ASCII character is a
991 decimal character. The valid hexadecimal character is
992 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
993
994
995 @param Char The character to check against.
996
997 @retval TRUE If the Char is a hexadecmial character.
998 @retval FALSE If the Char is not a hexadecmial character.
999
1000 **/
1001 BOOLEAN
1002 EFIAPI
1003 InternalAsciiIsHexaDecimalDigitCharacter (
1004 IN CHAR8 Char
1005 )
1006 {
1007
1008 return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||
1009 (Char >= 'A' && Char <= 'F') ||
1010 (Char >= 'a' && Char <= 'f'));
1011 }
1012
1013 /**
1014 Convert a Null-terminated Unicode string to a Null-terminated
1015 ASCII string and returns the ASCII string.
1016
1017 This function converts the content of the Unicode string Source
1018 to the ASCII string Destination by copying the lower 8 bits of
1019 each Unicode character. It returns Destination.
1020
1021 If any Unicode characters in Source contain non-zero value in
1022 the upper 8 bits, then ASSERT().
1023
1024 If Destination is NULL, then ASSERT().
1025 If Source is NULL, then ASSERT().
1026 If Source is not aligned on a 16-bit boundary, then ASSERT().
1027 If Source and Destination overlap, then ASSERT().
1028
1029 If PcdMaximumUnicodeStringLength is not zero, and Source contains
1030 more than PcdMaximumUnicodeStringLength Unicode characters, not including
1031 the Null-terminator, then ASSERT().
1032
1033 If PcdMaximumAsciiStringLength is not zero, and Source contains more
1034 than PcdMaximumAsciiStringLength Unicode characters, not including the
1035 Null-terminator, then ASSERT().
1036
1037 @param Source Pointer to a Null-terminated Unicode string.
1038 @param Destination Pointer to a Null-terminated ASCII string.
1039
1040 @return Destination.
1041
1042 **/
1043 CHAR8 *
1044 EFIAPI
1045 UnicodeStrToAsciiStr (
1046 IN CONST CHAR16 *Source,
1047 OUT CHAR8 *Destination
1048 )
1049 {
1050 CHAR8 *ReturnValue;
1051
1052 ASSERT (Destination != NULL);
1053
1054 //
1055 // ASSERT if Source is long than PcdMaximumUnicodeStringLength.
1056 // Length tests are performed inside StrLen().
1057 //
1058 ASSERT (StrSize (Source) != 0);
1059
1060 //
1061 // Source and Destination should not overlap
1062 //
1063 ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source));
1064 ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));
1065
1066
1067 ReturnValue = Destination;
1068 while (*Source != '\0') {
1069 //
1070 // If any Unicode characters in Source contain
1071 // non-zero value in the upper 8 bits, then ASSERT().
1072 //
1073 ASSERT (*Source < 0x100);
1074 *(Destination++) = (CHAR8) *(Source++);
1075 }
1076
1077 *Destination = '\0';
1078
1079 //
1080 // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.
1081 // Length tests are performed inside AsciiStrLen().
1082 //
1083 ASSERT (AsciiStrSize (ReturnValue) != 0);
1084
1085 return ReturnValue;
1086 }
1087
1088
1089 /**
1090 Copies one Null-terminated ASCII string to another Null-terminated ASCII
1091 string and returns the new ASCII string.
1092
1093 This function copies the contents of the ASCII string Source to the ASCII
1094 string Destination, and returns Destination. If Source and Destination
1095 overlap, then the results are undefined.
1096
1097 If Destination is NULL, then ASSERT().
1098 If Source is NULL, then ASSERT().
1099 If Source and Destination overlap, then ASSERT().
1100 If PcdMaximumAsciiStringLength is not zero and Source contains more than
1101 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1102 then ASSERT().
1103
1104 @param Destination Pointer to a Null-terminated ASCII string.
1105 @param Source Pointer to a Null-terminated ASCII string.
1106
1107 @return Destination
1108
1109 **/
1110 CHAR8 *
1111 EFIAPI
1112 AsciiStrCpy (
1113 OUT CHAR8 *Destination,
1114 IN CONST CHAR8 *Source
1115 )
1116 {
1117 CHAR8 *ReturnValue;
1118
1119 //
1120 // Destination cannot be NULL
1121 //
1122 ASSERT (Destination != NULL);
1123
1124 //
1125 // Destination and source cannot overlap
1126 //
1127 ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
1128 ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));
1129
1130 ReturnValue = Destination;
1131 while (*Source != 0) {
1132 *(Destination++) = *(Source++);
1133 }
1134 *Destination = 0;
1135 return ReturnValue;
1136 }
1137
1138 /**
1139 Copies up to a specified length one Null-terminated ASCII string to another
1140 Null-terminated ASCII string and returns the new ASCII string.
1141
1142 This function copies the contents of the ASCII string Source to the ASCII
1143 string Destination, and returns Destination. At most, Length ASCII characters
1144 are copied from Source to Destination. If Length is 0, then Destination is
1145 returned unmodified. If Length is greater that the number of ASCII characters
1146 in Source, then Destination is padded with Null ASCII characters. If Source
1147 and Destination overlap, then the results are undefined.
1148
1149 If Destination is NULL, then ASSERT().
1150 If Source is NULL, then ASSERT().
1151 If Source and Destination overlap, then ASSERT().
1152 If PcdMaximumAsciiStringLength is not zero, and Length is greater than
1153 PcdMaximumAsciiStringLength, then ASSERT().
1154 If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1155 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1156 then ASSERT().
1157
1158 @param Destination Pointer to a Null-terminated ASCII string.
1159 @param Source Pointer to a Null-terminated ASCII string.
1160 @param Length Maximum number of ASCII characters to copy.
1161
1162 @return Destination
1163
1164 **/
1165 CHAR8 *
1166 EFIAPI
1167 AsciiStrnCpy (
1168 OUT CHAR8 *Destination,
1169 IN CONST CHAR8 *Source,
1170 IN UINTN Length
1171 )
1172 {
1173 CHAR8 *ReturnValue;
1174
1175 if (Length == 0) {
1176 return Destination;
1177 }
1178
1179 //
1180 // Destination cannot be NULL
1181 //
1182 ASSERT (Destination != NULL);
1183
1184 //
1185 // Destination and source cannot overlap
1186 //
1187 ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
1188 ASSERT ((UINTN)(Source - Destination) >= Length);
1189
1190 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1191 ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
1192 }
1193
1194 ReturnValue = Destination;
1195
1196 while (*Source != 0 && Length > 0) {
1197 *(Destination++) = *(Source++);
1198 Length--;
1199 }
1200
1201 ZeroMem (Destination, Length * sizeof (*Destination));
1202 return ReturnValue;
1203 }
1204
1205 /**
1206 Returns the length of a Null-terminated ASCII string.
1207
1208 This function returns the number of ASCII characters in the Null-terminated
1209 ASCII string specified by String.
1210
1211 If Length > 0 and Destination is NULL, then ASSERT().
1212 If Length > 0 and Source is NULL, then ASSERT().
1213 If PcdMaximumAsciiStringLength is not zero and String contains more than
1214 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1215 then ASSERT().
1216
1217 @param String Pointer to a Null-terminated ASCII string.
1218
1219 @return The length of String.
1220
1221 **/
1222 UINTN
1223 EFIAPI
1224 AsciiStrLen (
1225 IN CONST CHAR8 *String
1226 )
1227 {
1228 UINTN Length;
1229
1230 ASSERT (String != NULL);
1231
1232 for (Length = 0; *String != '\0'; String++, Length++) {
1233 //
1234 // If PcdMaximumUnicodeStringLength is not zero,
1235 // length should not more than PcdMaximumUnicodeStringLength
1236 //
1237 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1238 ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
1239 }
1240 }
1241 return Length;
1242 }
1243
1244 /**
1245 Returns the size of a Null-terminated ASCII string in bytes, including the
1246 Null terminator.
1247
1248 This function returns the size, in bytes, of the Null-terminated ASCII string
1249 specified by String.
1250
1251 If String is NULL, then ASSERT().
1252 If PcdMaximumAsciiStringLength is not zero and String contains more than
1253 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1254 then ASSERT().
1255
1256 @param String Pointer to a Null-terminated ASCII string.
1257
1258 @return The size of String.
1259
1260 **/
1261 UINTN
1262 EFIAPI
1263 AsciiStrSize (
1264 IN CONST CHAR8 *String
1265 )
1266 {
1267 return (AsciiStrLen (String) + 1) * sizeof (*String);
1268 }
1269
1270 /**
1271 Compares two Null-terminated ASCII strings, and returns the difference
1272 between the first mismatched ASCII characters.
1273
1274 This function compares the Null-terminated ASCII string FirstString to the
1275 Null-terminated ASCII string SecondString. If FirstString is identical to
1276 SecondString, then 0 is returned. Otherwise, the value returned is the first
1277 mismatched ASCII character in SecondString subtracted from the first
1278 mismatched ASCII character in FirstString.
1279
1280 If FirstString is NULL, then ASSERT().
1281 If SecondString is NULL, then ASSERT().
1282 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
1283 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1284 then ASSERT().
1285 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
1286 than PcdMaximumAsciiStringLength ASCII characters, not including the
1287 Null-terminator, then ASSERT().
1288
1289 @param FirstString Pointer to a Null-terminated ASCII string.
1290 @param SecondString Pointer to a Null-terminated ASCII string.
1291
1292 @retval ==0 FirstString is identical to SecondString.
1293 @retval !=0 FirstString is not identical to SecondString.
1294
1295 **/
1296 INTN
1297 EFIAPI
1298 AsciiStrCmp (
1299 IN CONST CHAR8 *FirstString,
1300 IN CONST CHAR8 *SecondString
1301 )
1302 {
1303 //
1304 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1305 //
1306 ASSERT (AsciiStrSize (FirstString));
1307 ASSERT (AsciiStrSize (SecondString));
1308
1309 while ((*FirstString != '\0') && (*FirstString == *SecondString)) {
1310 FirstString++;
1311 SecondString++;
1312 }
1313
1314 return *FirstString - *SecondString;
1315 }
1316
1317 /**
1318 Converts a lowercase Ascii character to upper one.
1319
1320 If Chr is lowercase Ascii character, then converts it to upper one.
1321
1322 If Value >= 0xA0, then ASSERT().
1323 If (Value & 0x0F) >= 0x0A, then ASSERT().
1324
1325 @param Chr one Ascii character
1326
1327 @return The uppercase value of Ascii character
1328
1329 **/
1330 CHAR8
1331 EFIAPI
1332 InternalBaseLibAsciiToUpper (
1333 IN CHAR8 Chr
1334 )
1335 {
1336 return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);
1337 }
1338
1339 /**
1340 Convert a ASCII character to numerical value.
1341
1342 This internal function only deal with Unicode character
1343 which maps to a valid hexadecimal ASII character, i.e.
1344 '0' to '9', 'a' to 'f' or 'A' to 'F'. For other
1345 ASCII character, the value returned does not make sense.
1346
1347 @param Char The character to convert.
1348
1349 @return The numerical value converted.
1350
1351 **/
1352 UINTN
1353 EFIAPI
1354 InternalAsciiHexCharToUintn (
1355 IN CHAR8 Char
1356 )
1357 {
1358 if (InternalIsDecimalDigitCharacter (Char)) {
1359 return Char - '0';
1360 }
1361
1362 return (UINTN) (10 + InternalBaseLibAsciiToUpper (Char) - 'A');
1363 }
1364
1365
1366 /**
1367 Performs a case insensitive comparison of two Null-terminated ASCII strings,
1368 and returns the difference between the first mismatched ASCII characters.
1369
1370 This function performs a case insensitive comparison of the Null-terminated
1371 ASCII string FirstString to the Null-terminated ASCII string SecondString. If
1372 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
1373 value returned is the first mismatched lower case ASCII character in
1374 SecondString subtracted from the first mismatched lower case ASCII character
1375 in FirstString.
1376
1377 If FirstString is NULL, then ASSERT().
1378 If SecondString is NULL, then ASSERT().
1379 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
1380 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1381 then ASSERT().
1382 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
1383 than PcdMaximumAsciiStringLength ASCII characters, not including the
1384 Null-terminator, then ASSERT().
1385
1386 @param FirstString Pointer to a Null-terminated ASCII string.
1387 @param SecondString Pointer to a Null-terminated ASCII string.
1388
1389 @retval ==0 FirstString is identical to SecondString using case insensitive
1390 comparisons.
1391 @retval !=0 FirstString is not identical to SecondString using case
1392 insensitive comparisons.
1393
1394 **/
1395 INTN
1396 EFIAPI
1397 AsciiStriCmp (
1398 IN CONST CHAR8 *FirstString,
1399 IN CONST CHAR8 *SecondString
1400 )
1401 {
1402 CHAR8 UpperFirstString;
1403 CHAR8 UpperSecondString;
1404
1405 //
1406 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1407 //
1408 ASSERT (AsciiStrSize (FirstString));
1409 ASSERT (AsciiStrSize (SecondString));
1410
1411 UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString);
1412 UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);
1413 while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {
1414 FirstString++;
1415 SecondString++;
1416 UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString);
1417 UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);
1418 }
1419
1420 return UpperFirstString - UpperSecondString;
1421 }
1422
1423 /**
1424 Compares two Null-terminated ASCII strings with maximum lengths, and returns
1425 the difference between the first mismatched ASCII characters.
1426
1427 This function compares the Null-terminated ASCII string FirstString to the
1428 Null-terminated ASCII string SecondString. At most, Length ASCII characters
1429 will be compared. If Length is 0, then 0 is returned. If FirstString is
1430 identical to SecondString, then 0 is returned. Otherwise, the value returned
1431 is the first mismatched ASCII character in SecondString subtracted from the
1432 first mismatched ASCII character in FirstString.
1433
1434 If Length > 0 and FirstString is NULL, then ASSERT().
1435 If Length > 0 and SecondString is NULL, then ASSERT().
1436 If PcdMaximumAsciiStringLength is not zero, and Length is greater than
1437 PcdMaximumAsciiStringLength, then ASSERT().
1438 If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than
1439 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1440 then ASSERT().
1441 If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than
1442 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1443 then ASSERT().
1444
1445 @param FirstString Pointer to a Null-terminated ASCII string.
1446 @param SecondString Pointer to a Null-terminated ASCII string.
1447 @param Length Maximum number of ASCII characters for compare.
1448
1449 @retval ==0 FirstString is identical to SecondString.
1450 @retval !=0 FirstString is not identical to SecondString.
1451
1452 **/
1453 INTN
1454 EFIAPI
1455 AsciiStrnCmp (
1456 IN CONST CHAR8 *FirstString,
1457 IN CONST CHAR8 *SecondString,
1458 IN UINTN Length
1459 )
1460 {
1461 if (Length == 0) {
1462 return 0;
1463 }
1464
1465 //
1466 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1467 //
1468 ASSERT (AsciiStrSize (FirstString));
1469 ASSERT (AsciiStrSize (SecondString));
1470
1471 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1472 ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
1473 }
1474
1475 while ((*FirstString != '\0') &&
1476 (*FirstString == *SecondString) &&
1477 (Length > 1)) {
1478 FirstString++;
1479 SecondString++;
1480 Length--;
1481 }
1482 return *FirstString - *SecondString;
1483 }
1484
1485 /**
1486 Concatenates one Null-terminated ASCII string to another Null-terminated
1487 ASCII string, and returns the concatenated ASCII string.
1488
1489 This function concatenates two Null-terminated ASCII strings. The contents of
1490 Null-terminated ASCII string Source are concatenated to the end of Null-
1491 terminated ASCII string Destination. The Null-terminated concatenated ASCII
1492 String is returned.
1493
1494 If Destination is NULL, then ASSERT().
1495 If Source is NULL, then ASSERT().
1496 If PcdMaximumAsciiStringLength is not zero and Destination contains more than
1497 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1498 then ASSERT().
1499 If PcdMaximumAsciiStringLength is not zero and Source contains more than
1500 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1501 then ASSERT().
1502 If PcdMaximumAsciiStringLength is not zero and concatenating Destination and
1503 Source results in a ASCII string with more than PcdMaximumAsciiStringLength
1504 ASCII characters, then ASSERT().
1505
1506 @param Destination Pointer to a Null-terminated ASCII string.
1507 @param Source Pointer to a Null-terminated ASCII string.
1508
1509 @return Destination
1510
1511 **/
1512 CHAR8 *
1513 EFIAPI
1514 AsciiStrCat (
1515 IN OUT CHAR8 *Destination,
1516 IN CONST CHAR8 *Source
1517 )
1518 {
1519 AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);
1520
1521 //
1522 // Size of the resulting string should never be zero.
1523 // PcdMaximumUnicodeStringLength is tested inside StrLen().
1524 //
1525 ASSERT (AsciiStrSize (Destination) != 0);
1526 return Destination;
1527 }
1528
1529 /**
1530 Concatenates up to a specified length one Null-terminated ASCII string to
1531 the end of another Null-terminated ASCII string, and returns the
1532 concatenated ASCII string.
1533
1534 This function concatenates two Null-terminated ASCII strings. The contents
1535 of Null-terminated ASCII string Source are concatenated to the end of Null-
1536 terminated ASCII string Destination, and Destination is returned. At most,
1537 Length ASCII characters are concatenated from Source to the end of
1538 Destination, and Destination is always Null-terminated. If Length is 0, then
1539 Destination is returned unmodified. If Source and Destination overlap, then
1540 the results are undefined.
1541
1542 If Length > 0 and Destination is NULL, then ASSERT().
1543 If Length > 0 and Source is NULL, then ASSERT().
1544 If Source and Destination overlap, then ASSERT().
1545 If PcdMaximumAsciiStringLength is not zero, and Length is greater than
1546 PcdMaximumAsciiStringLength, then ASSERT().
1547 If PcdMaximumAsciiStringLength is not zero, and Destination contains more than
1548 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1549 then ASSERT().
1550 If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1551 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1552 then ASSERT().
1553 If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and
1554 Source results in a ASCII string with more than PcdMaximumAsciiStringLength
1555 ASCII characters, not including the Null-terminator, then ASSERT().
1556
1557 @param Destination Pointer to a Null-terminated ASCII string.
1558 @param Source Pointer to a Null-terminated ASCII string.
1559 @param Length Maximum number of ASCII characters to concatenate from
1560 Source.
1561
1562 @return Destination
1563
1564 **/
1565 CHAR8 *
1566 EFIAPI
1567 AsciiStrnCat (
1568 IN OUT CHAR8 *Destination,
1569 IN CONST CHAR8 *Source,
1570 IN UINTN Length
1571 )
1572 {
1573 UINTN DestinationLen;
1574
1575 DestinationLen = AsciiStrLen (Destination);
1576 AsciiStrnCpy (Destination + DestinationLen, Source, Length);
1577 Destination[DestinationLen + Length] = '\0';
1578
1579 //
1580 // Size of the resulting string should never be zero.
1581 // PcdMaximumUnicodeStringLength is tested inside StrLen().
1582 //
1583 ASSERT (AsciiStrSize (Destination) != 0);
1584 return Destination;
1585 }
1586
1587 /**
1588 Returns the first occurrence of a Null-terminated ASCII sub-string
1589 in a Null-terminated ASCII string.
1590
1591 This function scans the contents of the ASCII string specified by String
1592 and returns the first occurrence of SearchString. If SearchString is not
1593 found in String, then NULL is returned. If the length of SearchString is zero,
1594 then String is returned.
1595
1596 If String is NULL, then ASSERT().
1597 If SearchString is NULL, then ASSERT().
1598
1599 If PcdMaximumAsciiStringLength is not zero, and SearchString or
1600 String contains more than PcdMaximumAsciiStringLength Unicode characters
1601 not including the Null-terminator, then ASSERT().
1602
1603 @param String Pointer to a Null-terminated ASCII string.
1604 @param SearchString Pointer to a Null-terminated ASCII string to search for.
1605
1606 @retval NULL If the SearchString does not appear in String.
1607 @retval others If there is a match return the first occurrence of SearchingString.
1608 If the length of SearchString is zero,return String.
1609
1610 **/
1611 CHAR8 *
1612 EFIAPI
1613 AsciiStrStr (
1614 IN CONST CHAR8 *String,
1615 IN CONST CHAR8 *SearchString
1616 )
1617 {
1618 CONST CHAR8 *FirstMatch;
1619 CONST CHAR8 *SearchStringTmp;
1620
1621 //
1622 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1623 //
1624 ASSERT (AsciiStrSize (String) != 0);
1625 ASSERT (AsciiStrSize (SearchString) != 0);
1626
1627 if (*SearchString == '\0') {
1628 return (CHAR8 *) String;
1629 }
1630
1631 while (*String != '\0') {
1632 SearchStringTmp = SearchString;
1633 FirstMatch = String;
1634
1635 while ((*String == *SearchStringTmp)
1636 && (*String != '\0')) {
1637 String++;
1638 SearchStringTmp++;
1639 }
1640
1641 if (*SearchStringTmp == '\0') {
1642 return (CHAR8 *) FirstMatch;
1643 }
1644
1645 if (*String == '\0') {
1646 return NULL;
1647 }
1648
1649 String = FirstMatch + 1;
1650 }
1651
1652 return NULL;
1653 }
1654
1655 /**
1656 Convert a Null-terminated ASCII decimal string to a value of type
1657 UINTN.
1658
1659 This function returns a value of type UINTN by interpreting the contents
1660 of the ASCII string String as a decimal number. The format of the input
1661 ASCII string String is:
1662
1663 [spaces] [decimal digits].
1664
1665 The valid decimal digit character is in the range [0-9]. The function will
1666 ignore the pad space, which includes spaces or tab characters, before the digits.
1667 The running zero in the beginning of [decimal digits] will be ignored. Then, the
1668 function stops at the first character that is a not a valid decimal character or
1669 Null-terminator, whichever on comes first.
1670
1671 If String has only pad spaces, then 0 is returned.
1672 If String has no pad spaces or valid decimal digits, then 0 is returned.
1673 If the number represented by String overflows according to the range defined by
1674 UINTN, then ASSERT().
1675 If String is NULL, then ASSERT().
1676 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1677 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1678 then ASSERT().
1679
1680 @param String Pointer to a Null-terminated ASCII string.
1681
1682 @retval Value translated from String.
1683
1684 **/
1685 UINTN
1686 EFIAPI
1687 AsciiStrDecimalToUintn (
1688 IN CONST CHAR8 *String
1689 )
1690 {
1691 UINTN Result;
1692
1693 //
1694 // ASSERT Strings is less long than PcdMaximumAsciiStringLength
1695 //
1696 ASSERT (AsciiStrSize (String) != 0);
1697
1698 //
1699 // Ignore the pad spaces (space or tab)
1700 //
1701 while ((*String == ' ') || (*String == '\t' )) {
1702 String++;
1703 }
1704
1705 //
1706 // Ignore leading Zeros after the spaces
1707 //
1708 while (*String == '0') {
1709 String++;
1710 }
1711
1712 Result = 0;
1713
1714 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
1715 //
1716 // If the number represented by String overflows according
1717 // to the range defined by UINTN, then ASSERT().
1718 //
1719 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_10) ||
1720 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_10) &&
1721 (*String - '0') <= REMAINDER_MAX_UINTN_DIVIDED_BY_10)
1722 );
1723
1724 Result = Result * 10 + (*String - '0');
1725 String++;
1726 }
1727
1728 return Result;
1729 }
1730
1731
1732 /**
1733 Convert a Null-terminated ASCII decimal string to a value of type
1734 UINT64.
1735
1736 This function returns a value of type UINT64 by interpreting the contents
1737 of the ASCII string String as a decimal number. The format of the input
1738 ASCII string String is:
1739
1740 [spaces] [decimal digits].
1741
1742 The valid decimal digit character is in the range [0-9]. The function will
1743 ignore the pad space, which includes spaces or tab characters, before the digits.
1744 The running zero in the beginning of [decimal digits] will be ignored. Then, the
1745 function stops at the first character that is a not a valid decimal character or
1746 Null-terminator, whichever on comes first.
1747
1748 If String has only pad spaces, then 0 is returned.
1749 If String has no pad spaces or valid decimal digits, then 0 is returned.
1750 If the number represented by String overflows according to the range defined by
1751 UINT64, then ASSERT().
1752 If String is NULL, then ASSERT().
1753 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1754 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1755 then ASSERT().
1756
1757 @param String Pointer to a Null-terminated ASCII string.
1758
1759 @retval Value translated from String.
1760
1761 **/
1762 UINT64
1763 EFIAPI
1764 AsciiStrDecimalToUint64 (
1765 IN CONST CHAR8 *String
1766 )
1767 {
1768 UINT64 Result;
1769
1770 //
1771 // ASSERT Strings is less long than PcdMaximumAsciiStringLength
1772 //
1773 ASSERT (AsciiStrSize (String) != 0);
1774
1775 //
1776 // Ignore the pad spaces (space or tab)
1777 //
1778 while ((*String == ' ') || (*String == '\t' )) {
1779 String++;
1780 }
1781
1782 //
1783 // Ignore leading Zeros after the spaces
1784 //
1785 while (*String == '0') {
1786 String++;
1787 }
1788
1789 Result = 0;
1790
1791 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
1792 //
1793 // If the number represented by String overflows according
1794 // to the range defined by UINTN, then ASSERT().
1795 //
1796 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_10) ||
1797 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_10) &&
1798 (*String - '0') <= REMAINDER_MAX_UINT64_DIVIDED_BY_10)
1799 );
1800
1801 Result = MultU64x32 (Result, 10) + (*String - '0');
1802 String++;
1803 }
1804
1805 return Result;
1806 }
1807
1808 /**
1809 Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
1810
1811 This function returns a value of type UINTN by interpreting the contents of
1812 the ASCII string String as a hexadecimal number. The format of the input ASCII
1813 string String is:
1814
1815 [spaces][zeros][x][hexadecimal digits].
1816
1817 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1818 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1819 appears in the input string, it must be prefixed with at least one 0. The function
1820 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1821 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1822 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1823 digit. Then, the function stops at the first character that is a not a valid
1824 hexadecimal character or Null-terminator, whichever on comes first.
1825
1826 If String has only pad spaces, then 0 is returned.
1827 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1828 0 is returned.
1829
1830 If the number represented by String overflows according to the range defined by UINTN,
1831 then ASSERT().
1832 If String is NULL, then ASSERT().
1833 If PcdMaximumAsciiStringLength is not zero,
1834 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1835 the Null-terminator, then ASSERT().
1836
1837 @param String Pointer to a Null-terminated ASCII string.
1838
1839 @retval Value translated from String.
1840
1841 **/
1842 UINTN
1843 EFIAPI
1844 AsciiStrHexToUintn (
1845 IN CONST CHAR8 *String
1846 )
1847 {
1848 UINTN Result;
1849
1850 //
1851 // ASSERT Strings is less long than PcdMaximumAsciiStringLength
1852 //
1853 ASSERT (AsciiStrSize (String) != 0);
1854
1855 //
1856 // Ignore the pad spaces (space or tab)
1857 //
1858 while ((*String == ' ') || (*String == '\t' )) {
1859 String++;
1860 }
1861
1862 //
1863 // Ignore leading Zeros after the spaces
1864 //
1865 while (*String == '0') {
1866 String++;
1867 }
1868
1869 if (InternalBaseLibAsciiToUpper (*String) == 'X') {
1870 ASSERT (*(String - 1) == '0');
1871 if (*(String - 1) != '0') {
1872 return 0;
1873 }
1874 //
1875 // Skip the 'X'
1876 //
1877 String++;
1878 }
1879
1880 Result = 0;
1881
1882 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
1883 //
1884 // If the Hex Number represented by String overflows according
1885 // to the range defined by UINTN, then ASSERT().
1886 //
1887 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_16) ||
1888 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_16) &&
1889 (InternalAsciiHexCharToUintn (*String) <= REMAINDER_MAX_UINTN_DIVIDED_BY_16))
1890 );
1891
1892 Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);
1893 String++;
1894 }
1895
1896 return Result;
1897 }
1898
1899
1900 /**
1901 Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
1902
1903 This function returns a value of type UINT64 by interpreting the contents of
1904 the ASCII string String as a hexadecimal number. The format of the input ASCII
1905 string String is:
1906
1907 [spaces][zeros][x][hexadecimal digits].
1908
1909 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1910 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1911 appears in the input string, it must be prefixed with at least one 0. The function
1912 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1913 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1914 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1915 digit. Then, the function stops at the first character that is a not a valid
1916 hexadecimal character or Null-terminator, whichever on comes first.
1917
1918 If String has only pad spaces, then 0 is returned.
1919 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1920 0 is returned.
1921
1922 If the number represented by String overflows according to the range defined by UINT64,
1923 then ASSERT().
1924 If String is NULL, then ASSERT().
1925 If PcdMaximumAsciiStringLength is not zero,
1926 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1927 the Null-terminator, then ASSERT().
1928
1929 @param String Pointer to a Null-terminated ASCII string.
1930
1931 @retval Value translated from String.
1932
1933 **/
1934 UINT64
1935 EFIAPI
1936 AsciiStrHexToUint64 (
1937 IN CONST CHAR8 *String
1938 )
1939 {
1940 UINT64 Result;
1941
1942 //
1943 // ASSERT Strings is less long than PcdMaximumAsciiStringLength
1944 //
1945 ASSERT (AsciiStrSize (String) != 0);
1946
1947 //
1948 // Ignore the pad spaces (space or tab) and leading Zeros
1949 //
1950 //
1951 // Ignore the pad spaces (space or tab)
1952 //
1953 while ((*String == ' ') || (*String == '\t' )) {
1954 String++;
1955 }
1956
1957 //
1958 // Ignore leading Zeros after the spaces
1959 //
1960 while (*String == '0') {
1961 String++;
1962 }
1963
1964 if (InternalBaseLibAsciiToUpper (*String) == 'X') {
1965 ASSERT (*(String - 1) == '0');
1966 if (*(String - 1) != '0') {
1967 return 0;
1968 }
1969 //
1970 // Skip the 'X'
1971 //
1972 String++;
1973 }
1974
1975 Result = 0;
1976
1977 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
1978 //
1979 // If the Hex Number represented by String overflows according
1980 // to the range defined by UINTN, then ASSERT().
1981 //
1982 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_16) ||
1983 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_16) &&
1984 (InternalAsciiHexCharToUintn (*String) <= REMAINDER_MAX_UINT64_DIVIDED_BY_16))
1985 );
1986
1987 Result = LShiftU64 (Result, 4);
1988 Result = Result + InternalAsciiHexCharToUintn (*String);
1989 String++;
1990 }
1991
1992 return Result;
1993 }
1994
1995
1996 /**
1997 Convert one Null-terminated ASCII string to a Null-terminated
1998 Unicode string and returns the Unicode string.
1999
2000 This function converts the contents of the ASCII string Source to the Unicode
2001 string Destination, and returns Destination. The function terminates the
2002 Unicode string Destination by appending a Null-terminator character at the end.
2003 The caller is responsible to make sure Destination points to a buffer with size
2004 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2005
2006 If Destination is NULL, then ASSERT().
2007 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2008 If Source is NULL, then ASSERT().
2009 If Source and Destination overlap, then ASSERT().
2010 If PcdMaximumAsciiStringLength is not zero, and Source contains more than
2011 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
2012 then ASSERT().
2013 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
2014 PcdMaximumUnicodeStringLength ASCII characters not including the
2015 Null-terminator, then ASSERT().
2016
2017 @param Source Pointer to a Null-terminated ASCII string.
2018 @param Destination Pointer to a Null-terminated Unicode string.
2019
2020 @return Destination.
2021
2022 **/
2023 CHAR16 *
2024 EFIAPI
2025 AsciiStrToUnicodeStr (
2026 IN CONST CHAR8 *Source,
2027 OUT CHAR16 *Destination
2028 )
2029 {
2030 CHAR16 *ReturnValue;
2031
2032 ASSERT (Destination != NULL);
2033
2034 //
2035 // ASSERT Source is less long than PcdMaximumAsciiStringLength
2036 //
2037 ASSERT (AsciiStrSize (Source) != 0);
2038
2039 //
2040 // Source and Destination should not overlap
2041 //
2042 ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));
2043 ASSERT ((UINTN) (Source - (CHAR8 *) Destination) > (AsciiStrLen (Source) * sizeof (CHAR16)));
2044
2045
2046 ReturnValue = Destination;
2047 while (*Source != '\0') {
2048 *(Destination++) = (CHAR16) *(Source++);
2049 }
2050 //
2051 // End the Destination with a NULL.
2052 //
2053 *Destination = '\0';
2054
2055 //
2056 // ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength
2057 //
2058 ASSERT (StrSize (ReturnValue) != 0);
2059
2060 return ReturnValue;
2061 }
2062
2063 /**
2064 Converts an 8-bit value to an 8-bit BCD value.
2065
2066 Converts the 8-bit value specified by Value to BCD. The BCD value is
2067 returned.
2068
2069 If Value >= 100, then ASSERT().
2070
2071 @param Value The 8-bit value to convert to BCD. Range 0..99.
2072
2073 @return The BCD value.
2074
2075 **/
2076 UINT8
2077 EFIAPI
2078 DecimalToBcd8 (
2079 IN UINT8 Value
2080 )
2081 {
2082 ASSERT (Value < 100);
2083 return (UINT8) (((Value / 10) << 4) | (Value % 10));
2084 }
2085
2086 /**
2087 Converts an 8-bit BCD value to an 8-bit value.
2088
2089 Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit
2090 value is returned.
2091
2092 If Value >= 0xA0, then ASSERT().
2093 If (Value & 0x0F) >= 0x0A, then ASSERT().
2094
2095 @param Value The 8-bit BCD value to convert to an 8-bit value.
2096
2097 @return The 8-bit value is returned.
2098
2099 **/
2100 UINT8
2101 EFIAPI
2102 BcdToDecimal8 (
2103 IN UINT8 Value
2104 )
2105 {
2106 ASSERT (Value < 0xa0);
2107 ASSERT ((Value & 0xf) < 0xa);
2108 return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));
2109 }