]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/String.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BaseLib / String.c
CommitLineData
e1f414b6 1/** @file\r
3868d06d 2 Unicode and ASCII string primitives.\r
e1f414b6 3\r
5dbfa01e 4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e1f414b6 6\r
e1f414b6 7**/\r
8\r
e1f414b6 9#include "BaseLibInternals.h"\r
10\r
e1f414b6 11/**\r
12 Returns the length of a Null-terminated Unicode string.\r
13\r
14 This function returns the number of Unicode characters in the Null-terminated\r
15 Unicode string specified by String.\r
16\r
17 If String is NULL, then ASSERT().\r
18 If String is not aligned on a 16-bit boundary, then ASSERT().\r
19 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
dfbe9de9 20 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
e1f414b6 21 Null-terminator, then ASSERT().\r
22\r
127010dd 23 @param String A pointer to a Null-terminated Unicode string.\r
e1f414b6 24\r
25 @return The length of String.\r
26\r
27**/\r
28UINTN\r
29EFIAPI\r
30StrLen (\r
2f88bd3a 31 IN CONST CHAR16 *String\r
e1f414b6 32 )\r
33{\r
2f88bd3a 34 UINTN Length;\r
e1f414b6 35\r
36 ASSERT (String != NULL);\r
2f88bd3a 37 ASSERT (((UINTN)String & BIT0) == 0);\r
e1f414b6 38\r
39 for (Length = 0; *String != L'\0'; String++, Length++) {\r
40 //\r
41 // If PcdMaximumUnicodeStringLength is not zero,\r
42 // length should not more than PcdMaximumUnicodeStringLength\r
43 //\r
44 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {\r
45 ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));\r
46 }\r
47 }\r
2f88bd3a 48\r
e1f414b6 49 return Length;\r
50}\r
51\r
52/**\r
53 Returns the size of a Null-terminated Unicode string in bytes, including the\r
54 Null terminator.\r
55\r
9095d37b 56 This function returns the size, in bytes, of the Null-terminated Unicode string\r
9aa049d9 57 specified by String.\r
e1f414b6 58\r
59 If String is NULL, then ASSERT().\r
60 If String is not aligned on a 16-bit boundary, then ASSERT().\r
61 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
dfbe9de9 62 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
e1f414b6 63 Null-terminator, then ASSERT().\r
64\r
127010dd 65 @param String A pointer to a Null-terminated Unicode string.\r
e1f414b6 66\r
9aa049d9 67 @return The size of String.\r
e1f414b6 68\r
69**/\r
70UINTN\r
71EFIAPI\r
72StrSize (\r
2f88bd3a 73 IN CONST CHAR16 *String\r
e1f414b6 74 )\r
75{\r
76 return (StrLen (String) + 1) * sizeof (*String);\r
77}\r
78\r
79/**\r
80 Compares two Null-terminated Unicode strings, and returns the difference\r
81 between the first mismatched Unicode characters.\r
82\r
83 This function compares the Null-terminated Unicode string FirstString to the\r
84 Null-terminated Unicode string SecondString. If FirstString is identical to\r
85 SecondString, then 0 is returned. Otherwise, the value returned is the first\r
86 mismatched Unicode character in SecondString subtracted from the first\r
87 mismatched Unicode character in FirstString.\r
88\r
89 If FirstString is NULL, then ASSERT().\r
90 If FirstString is not aligned on a 16-bit boundary, then ASSERT().\r
91 If SecondString is NULL, then ASSERT().\r
92 If SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
93 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
dfbe9de9 94 than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
e1f414b6 95 Null-terminator, then ASSERT().\r
96 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
dfbe9de9 97 than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
e1f414b6 98 Null-terminator, then ASSERT().\r
99\r
127010dd 100 @param FirstString A pointer to a Null-terminated Unicode string.\r
101 @param SecondString A pointer to a Null-terminated Unicode string.\r
e1f414b6 102\r
1106ffe1 103 @retval 0 FirstString is identical to SecondString.\r
9aa049d9 104 @return others FirstString is not identical to SecondString.\r
e1f414b6 105\r
106**/\r
107INTN\r
108EFIAPI\r
109StrCmp (\r
2f88bd3a
MK
110 IN CONST CHAR16 *FirstString,\r
111 IN CONST CHAR16 *SecondString\r
e1f414b6 112 )\r
113{\r
114 //\r
115 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength\r
116 //\r
117 ASSERT (StrSize (FirstString) != 0);\r
118 ASSERT (StrSize (SecondString) != 0);\r
119\r
120 while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {\r
121 FirstString++;\r
122 SecondString++;\r
123 }\r
2f88bd3a 124\r
e1f414b6 125 return *FirstString - *SecondString;\r
126}\r
127\r
128/**\r
9aa049d9 129 Compares up to a specified length the contents of two Null-terminated Unicode strings,\r
130 and returns the difference between the first mismatched Unicode characters.\r
9095d37b 131\r
e1f414b6 132 This function compares the Null-terminated Unicode string FirstString to the\r
133 Null-terminated Unicode string SecondString. At most, Length Unicode\r
134 characters will be compared. If Length is 0, then 0 is returned. If\r
135 FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
136 value returned is the first mismatched Unicode character in SecondString\r
137 subtracted from the first mismatched Unicode character in FirstString.\r
138\r
139 If Length > 0 and FirstString is NULL, then ASSERT().\r
77f863ee 140 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().\r
e1f414b6 141 If Length > 0 and SecondString is NULL, then ASSERT().\r
77f863ee 142 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
53e96610 143 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than\r
144 PcdMaximumUnicodeStringLength, then ASSERT().\r
145 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than\r
146 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
147 then ASSERT().\r
148 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than\r
149 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
dfbe9de9 150 then ASSERT().\r
e1f414b6 151\r
127010dd 152 @param FirstString A pointer to a Null-terminated Unicode string.\r
153 @param SecondString A pointer to a Null-terminated Unicode string.\r
2fc59a00 154 @param Length The maximum number of Unicode characters to compare.\r
e1f414b6 155\r
1106ffe1 156 @retval 0 FirstString is identical to SecondString.\r
9aa049d9 157 @return others FirstString is not identical to SecondString.\r
e1f414b6 158\r
159**/\r
160INTN\r
161EFIAPI\r
162StrnCmp (\r
2f88bd3a
MK
163 IN CONST CHAR16 *FirstString,\r
164 IN CONST CHAR16 *SecondString,\r
165 IN UINTN Length\r
e1f414b6 166 )\r
167{\r
2bfb6009 168 if (Length == 0) {\r
e1f414b6 169 return 0;\r
170 }\r
171\r
172 //\r
173 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
174 // Length tests are performed inside StrLen().\r
175 //\r
176 ASSERT (StrSize (FirstString) != 0);\r
177 ASSERT (StrSize (SecondString) != 0);\r
178\r
dfbe9de9 179 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {\r
180 ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));\r
181 }\r
182\r
e1f414b6 183 while ((*FirstString != L'\0') &&\r
753a18f9 184 (*SecondString != L'\0') &&\r
e1f414b6 185 (*FirstString == *SecondString) &&\r
2f88bd3a
MK
186 (Length > 1))\r
187 {\r
e1f414b6 188 FirstString++;\r
189 SecondString++;\r
190 Length--;\r
191 }\r
192\r
193 return *FirstString - *SecondString;\r
194}\r
195\r
e1f414b6 196/**\r
9aa049d9 197 Returns the first occurrence of a Null-terminated Unicode sub-string\r
e1f414b6 198 in a Null-terminated Unicode string.\r
199\r
9aa049d9 200 This function scans the contents of the Null-terminated Unicode string\r
201 specified by String and returns the first occurrence of SearchString.\r
202 If SearchString is not found in String, then NULL is returned. If\r
203 the length of SearchString is zero, then String is\r
e1f414b6 204 returned.\r
9aa049d9 205\r
e1f414b6 206 If String is NULL, then ASSERT().\r
207 If String is not aligned on a 16-bit boundary, then ASSERT().\r
208 If SearchString is NULL, then ASSERT().\r
209 If SearchString is not aligned on a 16-bit boundary, then ASSERT().\r
210\r
9aa049d9 211 If PcdMaximumUnicodeStringLength is not zero, and SearchString\r
212 or String contains more than PcdMaximumUnicodeStringLength Unicode\r
dfbe9de9 213 characters, not including the Null-terminator, then ASSERT().\r
e1f414b6 214\r
127010dd 215 @param String A pointer to a Null-terminated Unicode string.\r
216 @param SearchString A pointer to a Null-terminated Unicode string to search for.\r
e1f414b6 217\r
9aa049d9 218 @retval NULL If the SearchString does not appear in String.\r
219 @return others If there is a match.\r
e1f414b6 220\r
221**/\r
222CHAR16 *\r
223EFIAPI\r
224StrStr (\r
2f88bd3a
MK
225 IN CONST CHAR16 *String,\r
226 IN CONST CHAR16 *SearchString\r
e1f414b6 227 )\r
228{\r
2f88bd3a
MK
229 CONST CHAR16 *FirstMatch;\r
230 CONST CHAR16 *SearchStringTmp;\r
e1f414b6 231\r
e1f414b6 232 //\r
4df26661 233 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
234 // Length tests are performed inside StrLen().\r
e1f414b6 235 //\r
4df26661 236 ASSERT (StrSize (String) != 0);\r
237 ASSERT (StrSize (SearchString) != 0);\r
e1f414b6 238\r
62e71e2f 239 if (*SearchString == L'\0') {\r
2f88bd3a 240 return (CHAR16 *)String;\r
62e71e2f 241 }\r
242\r
243 while (*String != L'\0') {\r
e1f414b6 244 SearchStringTmp = SearchString;\r
2f88bd3a 245 FirstMatch = String;\r
9095d37b 246\r
2f88bd3a
MK
247 while ( (*String == *SearchStringTmp)\r
248 && (*String != L'\0'))\r
249 {\r
e1f414b6 250 String++;\r
251 SearchStringTmp++;\r
9095d37b
LG
252 }\r
253\r
62e71e2f 254 if (*SearchStringTmp == L'\0') {\r
2f88bd3a 255 return (CHAR16 *)FirstMatch;\r
e1f414b6 256 }\r
257\r
62e71e2f 258 if (*String == L'\0') {\r
259 return NULL;\r
e1f414b6 260 }\r
62e71e2f 261\r
262 String = FirstMatch + 1;\r
e1f414b6 263 }\r
264\r
265 return NULL;\r
266}\r
267\r
268/**\r
269 Check if a Unicode character is a decimal character.\r
270\r
9095d37b 271 This internal function checks if a Unicode character is a\r
e1f414b6 272 decimal character. The valid decimal character is from\r
273 L'0' to L'9'.\r
274\r
e1f414b6 275 @param Char The character to check against.\r
276\r
277 @retval TRUE If the Char is a decmial character.\r
24dcb5e5 278 @retval FALSE If the Char is not a decmial character.\r
e1f414b6 279\r
280**/\r
e1f414b6 281BOOLEAN\r
42eedea9 282EFIAPI\r
e1f414b6 283InternalIsDecimalDigitCharacter (\r
2f88bd3a 284 IN CHAR16 Char\r
e1f414b6 285 )\r
286{\r
2f88bd3a 287 return (BOOLEAN)(Char >= L'0' && Char <= L'9');\r
e1f414b6 288}\r
289\r
290/**\r
9095d37b 291 Convert a Unicode character to upper case only if\r
e1f414b6 292 it maps to a valid small-case ASCII character.\r
293\r
294 This internal function only deal with Unicode character\r
24dcb5e5 295 which maps to a valid small-case ASCII character, i.e.\r
e1f414b6 296 L'a' to L'z'. For other Unicode character, the input character\r
297 is returned directly.\r
298\r
e1f414b6 299 @param Char The character to convert.\r
300\r
301 @retval LowerCharacter If the Char is with range L'a' to L'z'.\r
302 @retval Unchanged Otherwise.\r
303\r
304**/\r
e1f414b6 305CHAR16\r
42eedea9 306EFIAPI\r
5dbfa01e 307CharToUpper (\r
2f88bd3a 308 IN CHAR16 Char\r
e1f414b6 309 )\r
310{\r
2f88bd3a
MK
311 if ((Char >= L'a') && (Char <= L'z')) {\r
312 return (CHAR16)(Char - (L'a' - L'A'));\r
e1f414b6 313 }\r
314\r
315 return Char;\r
316}\r
317\r
318/**\r
319 Convert a Unicode character to numerical value.\r
320\r
321 This internal function only deal with Unicode character\r
322 which maps to a valid hexadecimal ASII character, i.e.\r
9095d37b 323 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
e1f414b6 324 Unicode character, the value returned does not make sense.\r
325\r
326 @param Char The character to convert.\r
327\r
24dcb5e5 328 @return The numerical value converted.\r
e1f414b6 329\r
330**/\r
e1f414b6 331UINTN\r
42eedea9 332EFIAPI\r
e1f414b6 333InternalHexCharToUintn (\r
2f88bd3a 334 IN CHAR16 Char\r
e1f414b6 335 )\r
336{\r
337 if (InternalIsDecimalDigitCharacter (Char)) {\r
338 return Char - L'0';\r
339 }\r
340\r
5dbfa01e 341 return (10 + CharToUpper (Char) - L'A');\r
e1f414b6 342}\r
343\r
344/**\r
345 Check if a Unicode character is a hexadecimal character.\r
346\r
9095d37b
LG
347 This internal function checks if a Unicode character is a\r
348 decimal character. The valid hexadecimal character is\r
e1f414b6 349 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
350\r
351\r
352 @param Char The character to check against.\r
353\r
354 @retval TRUE If the Char is a hexadecmial character.\r
24dcb5e5 355 @retval FALSE If the Char is not a hexadecmial character.\r
e1f414b6 356\r
357**/\r
e1f414b6 358BOOLEAN\r
42eedea9 359EFIAPI\r
e1f414b6 360InternalIsHexaDecimalDigitCharacter (\r
2f88bd3a 361 IN CHAR16 Char\r
e1f414b6 362 )\r
363{\r
2f88bd3a
MK
364 return (BOOLEAN)(InternalIsDecimalDigitCharacter (Char) ||\r
365 (Char >= L'A' && Char <= L'F') ||\r
366 (Char >= L'a' && Char <= L'f'));\r
e1f414b6 367}\r
368\r
369/**\r
9aa049d9 370 Convert a Null-terminated Unicode decimal string to a value of\r
e1f414b6 371 type UINTN.\r
372\r
9aa049d9 373 This function returns a value of type UINTN by interpreting the contents\r
374 of the Unicode string specified by String as a decimal number. The format\r
e1f414b6 375 of the input Unicode string String is:\r
9aa049d9 376\r
2fe241a2 377 [spaces] [decimal digits].\r
9aa049d9 378\r
379 The valid decimal digit character is in the range [0-9]. The\r
380 function will ignore the pad space, which includes spaces or\r
381 tab characters, before [decimal digits]. The running zero in the\r
382 beginning of [decimal digits] will be ignored. Then, the function\r
383 stops at the first character that is a not a valid decimal character\r
384 or a Null-terminator, whichever one comes first.\r
385\r
e1f414b6 386 If String is NULL, then ASSERT().\r
9aa049d9 387 If String is not aligned in a 16-bit boundary, then ASSERT().\r
e1f414b6 388 If String has only pad spaces, then 0 is returned.\r
9aa049d9 389 If String has no pad spaces or valid decimal digits,\r
e1f414b6 390 then 0 is returned.\r
9aa049d9 391 If the number represented by String overflows according\r
ea2e0921 392 to the range defined by UINTN, then MAX_UINTN is returned.\r
9aa049d9 393\r
394 If PcdMaximumUnicodeStringLength is not zero, and String contains\r
dfbe9de9 395 more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
e1f414b6 396 the Null-terminator, then ASSERT().\r
397\r
127010dd 398 @param String A pointer to a Null-terminated Unicode string.\r
e1f414b6 399\r
9aa049d9 400 @retval Value translated from String.\r
e1f414b6 401\r
402**/\r
403UINTN\r
404EFIAPI\r
405StrDecimalToUintn (\r
2f88bd3a 406 IN CONST CHAR16 *String\r
e1f414b6 407 )\r
408{\r
2f88bd3a 409 UINTN Result;\r
e1f414b6 410\r
2f88bd3a 411 StrDecimalToUintnS (String, (CHAR16 **)NULL, &Result);\r
e1f414b6 412 return Result;\r
413}\r
414\r
e1f414b6 415/**\r
9aa049d9 416 Convert a Null-terminated Unicode decimal string to a value of\r
e1f414b6 417 type UINT64.\r
418\r
9aa049d9 419 This function returns a value of type UINT64 by interpreting the contents\r
420 of the Unicode string specified by String as a decimal number. The format\r
e1f414b6 421 of the input Unicode string String is:\r
9aa049d9 422\r
2fe241a2 423 [spaces] [decimal digits].\r
9aa049d9 424\r
425 The valid decimal digit character is in the range [0-9]. The\r
426 function will ignore the pad space, which includes spaces or\r
427 tab characters, before [decimal digits]. The running zero in the\r
428 beginning of [decimal digits] will be ignored. Then, the function\r
429 stops at the first character that is a not a valid decimal character\r
430 or a Null-terminator, whichever one comes first.\r
431\r
e1f414b6 432 If String is NULL, then ASSERT().\r
9aa049d9 433 If String is not aligned in a 16-bit boundary, then ASSERT().\r
e1f414b6 434 If String has only pad spaces, then 0 is returned.\r
9aa049d9 435 If String has no pad spaces or valid decimal digits,\r
e1f414b6 436 then 0 is returned.\r
9aa049d9 437 If the number represented by String overflows according\r
ea2e0921 438 to the range defined by UINT64, then MAX_UINT64 is returned.\r
9aa049d9 439\r
440 If PcdMaximumUnicodeStringLength is not zero, and String contains\r
dfbe9de9 441 more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
e1f414b6 442 the Null-terminator, then ASSERT().\r
443\r
127010dd 444 @param String A pointer to a Null-terminated Unicode string.\r
e1f414b6 445\r
9aa049d9 446 @retval Value translated from String.\r
e1f414b6 447\r
448**/\r
449UINT64\r
450EFIAPI\r
451StrDecimalToUint64 (\r
2f88bd3a 452 IN CONST CHAR16 *String\r
e1f414b6 453 )\r
454{\r
2f88bd3a 455 UINT64 Result;\r
9095d37b 456\r
2f88bd3a 457 StrDecimalToUint64S (String, (CHAR16 **)NULL, &Result);\r
e1f414b6 458 return Result;\r
459}\r
460\r
461/**\r
462 Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.\r
463\r
9aa049d9 464 This function returns a value of type UINTN by interpreting the contents\r
465 of the Unicode string specified by String as a hexadecimal number.\r
e1f414b6 466 The format of the input Unicode string String is:\r
9aa049d9 467\r
468 [spaces][zeros][x][hexadecimal digits].\r
469\r
470 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
471 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
472 If "x" appears in the input string, it must be prefixed with at least one 0.\r
473 The function will ignore the pad space, which includes spaces or tab characters,\r
474 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
475 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
476 first valid hexadecimal digit. Then, the function stops at the first character that is\r
e1f414b6 477 a not a valid hexadecimal character or NULL, whichever one comes first.\r
478\r
479 If String is NULL, then ASSERT().\r
480 If String is not aligned in a 16-bit boundary, then ASSERT().\r
481 If String has only pad spaces, then zero is returned.\r
9aa049d9 482 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
e1f414b6 483 then zero is returned.\r
9aa049d9 484 If the number represented by String overflows according to the range defined by\r
ea2e0921 485 UINTN, then MAX_UINTN is returned.\r
e1f414b6 486\r
9aa049d9 487 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
dfbe9de9 488 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
e1f414b6 489 then ASSERT().\r
490\r
127010dd 491 @param String A pointer to a Null-terminated Unicode string.\r
e1f414b6 492\r
9aa049d9 493 @retval Value translated from String.\r
e1f414b6 494\r
495**/\r
496UINTN\r
497EFIAPI\r
498StrHexToUintn (\r
2f88bd3a 499 IN CONST CHAR16 *String\r
e1f414b6 500 )\r
501{\r
2f88bd3a 502 UINTN Result;\r
e1f414b6 503\r
2f88bd3a 504 StrHexToUintnS (String, (CHAR16 **)NULL, &Result);\r
e1f414b6 505 return Result;\r
506}\r
507\r
e1f414b6 508/**\r
509 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
510\r
9aa049d9 511 This function returns a value of type UINT64 by interpreting the contents\r
512 of the Unicode string specified by String as a hexadecimal number.\r
513 The format of the input Unicode string String is\r
514\r
515 [spaces][zeros][x][hexadecimal digits].\r
516\r
517 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
518 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
519 If "x" appears in the input string, it must be prefixed with at least one 0.\r
520 The function will ignore the pad space, which includes spaces or tab characters,\r
521 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
522 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
523 first valid hexadecimal digit. Then, the function stops at the first character that is\r
e1f414b6 524 a not a valid hexadecimal character or NULL, whichever one comes first.\r
525\r
526 If String is NULL, then ASSERT().\r
527 If String is not aligned in a 16-bit boundary, then ASSERT().\r
528 If String has only pad spaces, then zero is returned.\r
9aa049d9 529 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
e1f414b6 530 then zero is returned.\r
9aa049d9 531 If the number represented by String overflows according to the range defined by\r
ea2e0921 532 UINT64, then MAX_UINT64 is returned.\r
e1f414b6 533\r
9aa049d9 534 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
dfbe9de9 535 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
e1f414b6 536 then ASSERT().\r
537\r
127010dd 538 @param String A pointer to a Null-terminated Unicode string.\r
e1f414b6 539\r
9aa049d9 540 @retval Value translated from String.\r
e1f414b6 541\r
2fc60b70 542**/\r
e1f414b6 543UINT64\r
544EFIAPI\r
545StrHexToUint64 (\r
2f88bd3a 546 IN CONST CHAR16 *String\r
e1f414b6 547 )\r
548{\r
2f88bd3a 549 UINT64 Result;\r
e1f414b6 550\r
2f88bd3a 551 StrHexToUint64S (String, (CHAR16 **)NULL, &Result);\r
e1f414b6 552 return Result;\r
553}\r
554\r
555/**\r
556 Check if a ASCII character is a decimal character.\r
557\r
9095d37b 558 This internal function checks if a Unicode character is a\r
e1f414b6 559 decimal character. The valid decimal character is from\r
560 '0' to '9'.\r
561\r
562 @param Char The character to check against.\r
563\r
564 @retval TRUE If the Char is a decmial character.\r
24dcb5e5 565 @retval FALSE If the Char is not a decmial character.\r
e1f414b6 566\r
567**/\r
e1f414b6 568BOOLEAN\r
42eedea9 569EFIAPI\r
e1f414b6 570InternalAsciiIsDecimalDigitCharacter (\r
2f88bd3a 571 IN CHAR8 Char\r
e1f414b6 572 )\r
573{\r
2f88bd3a 574 return (BOOLEAN)(Char >= '0' && Char <= '9');\r
e1f414b6 575}\r
576\r
577/**\r
578 Check if a ASCII character is a hexadecimal character.\r
579\r
9095d37b
LG
580 This internal function checks if a ASCII character is a\r
581 decimal character. The valid hexadecimal character is\r
e1f414b6 582 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
583\r
584\r
585 @param Char The character to check against.\r
586\r
587 @retval TRUE If the Char is a hexadecmial character.\r
24dcb5e5 588 @retval FALSE If the Char is not a hexadecmial character.\r
e1f414b6 589\r
590**/\r
e1f414b6 591BOOLEAN\r
42eedea9 592EFIAPI\r
e1f414b6 593InternalAsciiIsHexaDecimalDigitCharacter (\r
2f88bd3a 594 IN CHAR8 Char\r
e1f414b6 595 )\r
596{\r
2f88bd3a
MK
597 return (BOOLEAN)(InternalAsciiIsDecimalDigitCharacter (Char) ||\r
598 (Char >= 'A' && Char <= 'F') ||\r
599 (Char >= 'a' && Char <= 'f'));\r
e1f414b6 600}\r
601\r
e1f414b6 602/**\r
603 Returns the length of a Null-terminated ASCII string.\r
604\r
605 This function returns the number of ASCII characters in the Null-terminated\r
606 ASCII string specified by String.\r
607\r
9aa049d9 608 If Length > 0 and Destination is NULL, then ASSERT().\r
609 If Length > 0 and Source is NULL, then ASSERT().\r
e1f414b6 610 If PcdMaximumAsciiStringLength is not zero and String contains more than\r
dfbe9de9 611 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
e1f414b6 612 then ASSERT().\r
613\r
127010dd 614 @param String A pointer to a Null-terminated ASCII string.\r
e1f414b6 615\r
616 @return The length of String.\r
617\r
618**/\r
619UINTN\r
620EFIAPI\r
621AsciiStrLen (\r
2f88bd3a 622 IN CONST CHAR8 *String\r
e1f414b6 623 )\r
624{\r
2f88bd3a 625 UINTN Length;\r
e1f414b6 626\r
627 ASSERT (String != NULL);\r
628\r
629 for (Length = 0; *String != '\0'; String++, Length++) {\r
630 //\r
631 // If PcdMaximumUnicodeStringLength is not zero,\r
632 // length should not more than PcdMaximumUnicodeStringLength\r
633 //\r
634 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
635 ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));\r
636 }\r
637 }\r
2f88bd3a 638\r
e1f414b6 639 return Length;\r
640}\r
641\r
642/**\r
643 Returns the size of a Null-terminated ASCII string in bytes, including the\r
644 Null terminator.\r
645\r
646 This function returns the size, in bytes, of the Null-terminated ASCII string\r
647 specified by String.\r
648\r
649 If String is NULL, then ASSERT().\r
650 If PcdMaximumAsciiStringLength is not zero and String contains more than\r
dfbe9de9 651 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
e1f414b6 652 then ASSERT().\r
653\r
127010dd 654 @param String A pointer to a Null-terminated ASCII string.\r
e1f414b6 655\r
656 @return The size of String.\r
657\r
658**/\r
659UINTN\r
660EFIAPI\r
661AsciiStrSize (\r
2f88bd3a 662 IN CONST CHAR8 *String\r
e1f414b6 663 )\r
664{\r
665 return (AsciiStrLen (String) + 1) * sizeof (*String);\r
666}\r
667\r
668/**\r
669 Compares two Null-terminated ASCII strings, and returns the difference\r
670 between the first mismatched ASCII characters.\r
671\r
672 This function compares the Null-terminated ASCII string FirstString to the\r
673 Null-terminated ASCII string SecondString. If FirstString is identical to\r
674 SecondString, then 0 is returned. Otherwise, the value returned is the first\r
675 mismatched ASCII character in SecondString subtracted from the first\r
676 mismatched ASCII character in FirstString.\r
677\r
678 If FirstString is NULL, then ASSERT().\r
679 If SecondString is NULL, then ASSERT().\r
680 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
dfbe9de9 681 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
e1f414b6 682 then ASSERT().\r
683 If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
dfbe9de9 684 than PcdMaximumAsciiStringLength ASCII characters, not including the\r
e1f414b6 685 Null-terminator, then ASSERT().\r
686\r
127010dd 687 @param FirstString A pointer to a Null-terminated ASCII string.\r
688 @param SecondString A pointer to a Null-terminated ASCII string.\r
e1f414b6 689\r
9aa049d9 690 @retval ==0 FirstString is identical to SecondString.\r
691 @retval !=0 FirstString is not identical to SecondString.\r
e1f414b6 692\r
693**/\r
694INTN\r
695EFIAPI\r
696AsciiStrCmp (\r
2f88bd3a
MK
697 IN CONST CHAR8 *FirstString,\r
698 IN CONST CHAR8 *SecondString\r
e1f414b6 699 )\r
700{\r
701 //\r
702 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
703 //\r
704 ASSERT (AsciiStrSize (FirstString));\r
705 ASSERT (AsciiStrSize (SecondString));\r
706\r
707 while ((*FirstString != '\0') && (*FirstString == *SecondString)) {\r
708 FirstString++;\r
709 SecondString++;\r
710 }\r
711\r
712 return *FirstString - *SecondString;\r
713}\r
714\r
715/**\r
24dcb5e5 716 Converts a lowercase Ascii character to upper one.\r
e1f414b6 717\r
718 If Chr is lowercase Ascii character, then converts it to upper one.\r
719\r
720 If Value >= 0xA0, then ASSERT().\r
721 If (Value & 0x0F) >= 0x0A, then ASSERT().\r
722\r
42eedea9 723 @param Chr one Ascii character\r
e1f414b6 724\r
9095d37b 725 @return The uppercase value of Ascii character\r
e1f414b6 726\r
727**/\r
e1f414b6 728CHAR8\r
42eedea9 729EFIAPI\r
5dbfa01e 730AsciiCharToUpper (\r
2f88bd3a 731 IN CHAR8 Chr\r
e1f414b6 732 )\r
733{\r
2f88bd3a 734 return (UINT8)((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);\r
e1f414b6 735}\r
736\r
737/**\r
738 Convert a ASCII character to numerical value.\r
739\r
740 This internal function only deal with Unicode character\r
741 which maps to a valid hexadecimal ASII character, i.e.\r
9095d37b 742 '0' to '9', 'a' to 'f' or 'A' to 'F'. For other\r
e1f414b6 743 ASCII character, the value returned does not make sense.\r
744\r
745 @param Char The character to convert.\r
746\r
24dcb5e5 747 @return The numerical value converted.\r
e1f414b6 748\r
749**/\r
e1f414b6 750UINTN\r
42eedea9 751EFIAPI\r
e1f414b6 752InternalAsciiHexCharToUintn (\r
2f88bd3a 753 IN CHAR8 Char\r
e1f414b6 754 )\r
755{\r
756 if (InternalIsDecimalDigitCharacter (Char)) {\r
757 return Char - '0';\r
758 }\r
759\r
5dbfa01e 760 return (10 + AsciiCharToUpper (Char) - 'A');\r
e1f414b6 761}\r
762\r
e1f414b6 763/**\r
764 Performs a case insensitive comparison of two Null-terminated ASCII strings,\r
765 and returns the difference between the first mismatched ASCII characters.\r
766\r
767 This function performs a case insensitive comparison of the Null-terminated\r
768 ASCII string FirstString to the Null-terminated ASCII string SecondString. If\r
769 FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
770 value returned is the first mismatched lower case ASCII character in\r
771 SecondString subtracted from the first mismatched lower case ASCII character\r
772 in FirstString.\r
773\r
774 If FirstString is NULL, then ASSERT().\r
775 If SecondString is NULL, then ASSERT().\r
776 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
dfbe9de9 777 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
e1f414b6 778 then ASSERT().\r
779 If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
dfbe9de9 780 than PcdMaximumAsciiStringLength ASCII characters, not including the\r
e1f414b6 781 Null-terminator, then ASSERT().\r
782\r
127010dd 783 @param FirstString A pointer to a Null-terminated ASCII string.\r
784 @param SecondString A pointer to a Null-terminated ASCII string.\r
e1f414b6 785\r
9aa049d9 786 @retval ==0 FirstString is identical to SecondString using case insensitive\r
1106ffe1 787 comparisons.\r
9aa049d9 788 @retval !=0 FirstString is not identical to SecondString using case\r
789 insensitive comparisons.\r
e1f414b6 790\r
791**/\r
792INTN\r
793EFIAPI\r
794AsciiStriCmp (\r
2f88bd3a
MK
795 IN CONST CHAR8 *FirstString,\r
796 IN CONST CHAR8 *SecondString\r
e1f414b6 797 )\r
798{\r
799 CHAR8 UpperFirstString;\r
800 CHAR8 UpperSecondString;\r
801\r
802 //\r
803 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
804 //\r
805 ASSERT (AsciiStrSize (FirstString));\r
806 ASSERT (AsciiStrSize (SecondString));\r
807\r
5dbfa01e
MT
808 UpperFirstString = AsciiCharToUpper (*FirstString);\r
809 UpperSecondString = AsciiCharToUpper (*SecondString);\r
c1f032cd 810 while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {\r
e1f414b6 811 FirstString++;\r
812 SecondString++;\r
5dbfa01e
MT
813 UpperFirstString = AsciiCharToUpper (*FirstString);\r
814 UpperSecondString = AsciiCharToUpper (*SecondString);\r
e1f414b6 815 }\r
816\r
817 return UpperFirstString - UpperSecondString;\r
818}\r
819\r
820/**\r
821 Compares two Null-terminated ASCII strings with maximum lengths, and returns\r
822 the difference between the first mismatched ASCII characters.\r
823\r
824 This function compares the Null-terminated ASCII string FirstString to the\r
825 Null-terminated ASCII string SecondString. At most, Length ASCII characters\r
826 will be compared. If Length is 0, then 0 is returned. If FirstString is\r
827 identical to SecondString, then 0 is returned. Otherwise, the value returned\r
828 is the first mismatched ASCII character in SecondString subtracted from the\r
829 first mismatched ASCII character in FirstString.\r
830\r
9aa049d9 831 If Length > 0 and FirstString is NULL, then ASSERT().\r
832 If Length > 0 and SecondString is NULL, then ASSERT().\r
9095d37b 833 If PcdMaximumAsciiStringLength is not zero, and Length is greater than\r
53e96610 834 PcdMaximumAsciiStringLength, then ASSERT().\r
835 If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than\r
dfbe9de9 836 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
e1f414b6 837 then ASSERT().\r
53e96610 838 If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than\r
dfbe9de9 839 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
53e96610 840 then ASSERT().\r
e1f414b6 841\r
127010dd 842 @param FirstString A pointer to a Null-terminated ASCII string.\r
843 @param SecondString A pointer to a Null-terminated ASCII string.\r
2fc59a00 844 @param Length The maximum number of ASCII characters for compare.\r
9095d37b 845\r
9aa049d9 846 @retval ==0 FirstString is identical to SecondString.\r
847 @retval !=0 FirstString is not identical to SecondString.\r
e1f414b6 848\r
849**/\r
850INTN\r
851EFIAPI\r
852AsciiStrnCmp (\r
2f88bd3a
MK
853 IN CONST CHAR8 *FirstString,\r
854 IN CONST CHAR8 *SecondString,\r
855 IN UINTN Length\r
e1f414b6 856 )\r
857{\r
2bfb6009 858 if (Length == 0) {\r
e1f414b6 859 return 0;\r
860 }\r
861\r
862 //\r
863 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
864 //\r
865 ASSERT (AsciiStrSize (FirstString));\r
866 ASSERT (AsciiStrSize (SecondString));\r
867\r
dfbe9de9 868 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
869 ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));\r
870 }\r
871\r
e1f414b6 872 while ((*FirstString != '\0') &&\r
753a18f9 873 (*SecondString != '\0') &&\r
e1f414b6 874 (*FirstString == *SecondString) &&\r
2f88bd3a
MK
875 (Length > 1))\r
876 {\r
e1f414b6 877 FirstString++;\r
878 SecondString++;\r
879 Length--;\r
880 }\r
2f88bd3a 881\r
e1f414b6 882 return *FirstString - *SecondString;\r
883}\r
884\r
e1f414b6 885/**\r
9aa049d9 886 Returns the first occurrence of a Null-terminated ASCII sub-string\r
e1f414b6 887 in a Null-terminated ASCII string.\r
888\r
9aa049d9 889 This function scans the contents of the ASCII string specified by String\r
890 and returns the first occurrence of SearchString. If SearchString is not\r
891 found in String, then NULL is returned. If the length of SearchString is zero,\r
e1f414b6 892 then String is returned.\r
9aa049d9 893\r
e1f414b6 894 If String is NULL, then ASSERT().\r
895 If SearchString is NULL, then ASSERT().\r
896\r
9aa049d9 897 If PcdMaximumAsciiStringLength is not zero, and SearchString or\r
898 String contains more than PcdMaximumAsciiStringLength Unicode characters\r
e1f414b6 899 not including the Null-terminator, then ASSERT().\r
900\r
127010dd 901 @param String A pointer to a Null-terminated ASCII string.\r
902 @param SearchString A pointer to a Null-terminated ASCII string to search for.\r
e1f414b6 903\r
904 @retval NULL If the SearchString does not appear in String.\r
9aa049d9 905 @retval others If there is a match return the first occurrence of SearchingString.\r
906 If the length of SearchString is zero,return String.\r
e1f414b6 907\r
908**/\r
909CHAR8 *\r
910EFIAPI\r
911AsciiStrStr (\r
2f88bd3a
MK
912 IN CONST CHAR8 *String,\r
913 IN CONST CHAR8 *SearchString\r
e1f414b6 914 )\r
915{\r
2f88bd3a
MK
916 CONST CHAR8 *FirstMatch;\r
917 CONST CHAR8 *SearchStringTmp;\r
e1f414b6 918\r
e1f414b6 919 //\r
4df26661 920 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
e1f414b6 921 //\r
4df26661 922 ASSERT (AsciiStrSize (String) != 0);\r
923 ASSERT (AsciiStrSize (SearchString) != 0);\r
e1f414b6 924\r
62e71e2f 925 if (*SearchString == '\0') {\r
2f88bd3a 926 return (CHAR8 *)String;\r
62e71e2f 927 }\r
928\r
e1f414b6 929 while (*String != '\0') {\r
930 SearchStringTmp = SearchString;\r
2f88bd3a 931 FirstMatch = String;\r
9095d37b 932\r
2f88bd3a
MK
933 while ( (*String == *SearchStringTmp)\r
934 && (*String != '\0'))\r
935 {\r
e1f414b6 936 String++;\r
937 SearchStringTmp++;\r
9095d37b
LG
938 }\r
939\r
e1f414b6 940 if (*SearchStringTmp == '\0') {\r
2f88bd3a 941 return (CHAR8 *)FirstMatch;\r
e1f414b6 942 }\r
943\r
62e71e2f 944 if (*String == '\0') {\r
945 return NULL;\r
e1f414b6 946 }\r
947\r
62e71e2f 948 String = FirstMatch + 1;\r
e1f414b6 949 }\r
950\r
951 return NULL;\r
952}\r
953\r
954/**\r
9aa049d9 955 Convert a Null-terminated ASCII decimal string to a value of type\r
e1f414b6 956 UINTN.\r
957\r
9aa049d9 958 This function returns a value of type UINTN by interpreting the contents\r
959 of the ASCII string String as a decimal number. The format of the input\r
e1f414b6 960 ASCII string String is:\r
9aa049d9 961\r
e1f414b6 962 [spaces] [decimal digits].\r
9aa049d9 963\r
964 The valid decimal digit character is in the range [0-9]. The function will\r
965 ignore the pad space, which includes spaces or tab characters, before the digits.\r
966 The running zero in the beginning of [decimal digits] will be ignored. Then, the\r
967 function stops at the first character that is a not a valid decimal character or\r
e1f414b6 968 Null-terminator, whichever on comes first.\r
9aa049d9 969\r
e1f414b6 970 If String has only pad spaces, then 0 is returned.\r
971 If String has no pad spaces or valid decimal digits, then 0 is returned.\r
9aa049d9 972 If the number represented by String overflows according to the range defined by\r
ea2e0921 973 UINTN, then MAX_UINTN is returned.\r
e1f414b6 974 If String is NULL, then ASSERT().\r
9aa049d9 975 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
976 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
e1f414b6 977 then ASSERT().\r
978\r
127010dd 979 @param String A pointer to a Null-terminated ASCII string.\r
e1f414b6 980\r
9aa049d9 981 @retval Value translated from String.\r
e1f414b6 982\r
983**/\r
984UINTN\r
985EFIAPI\r
986AsciiStrDecimalToUintn (\r
2f88bd3a 987 IN CONST CHAR8 *String\r
e1f414b6 988 )\r
989{\r
2f88bd3a 990 UINTN Result;\r
9095d37b 991\r
2f88bd3a 992 AsciiStrDecimalToUintnS (String, (CHAR8 **)NULL, &Result);\r
e1f414b6 993 return Result;\r
994}\r
995\r
e1f414b6 996/**\r
9aa049d9 997 Convert a Null-terminated ASCII decimal string to a value of type\r
e1f414b6 998 UINT64.\r
999\r
9aa049d9 1000 This function returns a value of type UINT64 by interpreting the contents\r
1001 of the ASCII string String as a decimal number. The format of the input\r
e1f414b6 1002 ASCII string String is:\r
9aa049d9 1003\r
e1f414b6 1004 [spaces] [decimal digits].\r
9aa049d9 1005\r
1006 The valid decimal digit character is in the range [0-9]. The function will\r
1007 ignore the pad space, which includes spaces or tab characters, before the digits.\r
1008 The running zero in the beginning of [decimal digits] will be ignored. Then, the\r
1009 function stops at the first character that is a not a valid decimal character or\r
e1f414b6 1010 Null-terminator, whichever on comes first.\r
9aa049d9 1011\r
e1f414b6 1012 If String has only pad spaces, then 0 is returned.\r
1013 If String has no pad spaces or valid decimal digits, then 0 is returned.\r
9aa049d9 1014 If the number represented by String overflows according to the range defined by\r
ea2e0921 1015 UINT64, then MAX_UINT64 is returned.\r
e1f414b6 1016 If String is NULL, then ASSERT().\r
9aa049d9 1017 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
1018 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
e1f414b6 1019 then ASSERT().\r
1020\r
127010dd 1021 @param String A pointer to a Null-terminated ASCII string.\r
e1f414b6 1022\r
9aa049d9 1023 @retval Value translated from String.\r
e1f414b6 1024\r
1025**/\r
1026UINT64\r
1027EFIAPI\r
1028AsciiStrDecimalToUint64 (\r
2f88bd3a 1029 IN CONST CHAR8 *String\r
e1f414b6 1030 )\r
1031{\r
2f88bd3a 1032 UINT64 Result;\r
9095d37b 1033\r
2f88bd3a 1034 AsciiStrDecimalToUint64S (String, (CHAR8 **)NULL, &Result);\r
e1f414b6 1035 return Result;\r
1036}\r
1037\r
1038/**\r
1039 Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.\r
1040\r
9aa049d9 1041 This function returns a value of type UINTN by interpreting the contents of\r
1042 the ASCII string String as a hexadecimal number. The format of the input ASCII\r
e1f414b6 1043 string String is:\r
9aa049d9 1044\r
e1f414b6 1045 [spaces][zeros][x][hexadecimal digits].\r
9aa049d9 1046\r
1047 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
1048 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"\r
1049 appears in the input string, it must be prefixed with at least one 0. The function\r
1050 will ignore the pad space, which includes spaces or tab characters, before [zeros],\r
1051 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]\r
1052 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal\r
1053 digit. Then, the function stops at the first character that is a not a valid\r
e1f414b6 1054 hexadecimal character or Null-terminator, whichever on comes first.\r
9aa049d9 1055\r
e1f414b6 1056 If String has only pad spaces, then 0 is returned.\r
1057 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then\r
1058 0 is returned.\r
1059\r
9aa049d9 1060 If the number represented by String overflows according to the range defined by UINTN,\r
ea2e0921 1061 then MAX_UINTN is returned.\r
e1f414b6 1062 If String is NULL, then ASSERT().\r
9aa049d9 1063 If PcdMaximumAsciiStringLength is not zero,\r
1064 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
e1f414b6 1065 the Null-terminator, then ASSERT().\r
1066\r
127010dd 1067 @param String A pointer to a Null-terminated ASCII string.\r
e1f414b6 1068\r
9aa049d9 1069 @retval Value translated from String.\r
e1f414b6 1070\r
1071**/\r
1072UINTN\r
1073EFIAPI\r
1074AsciiStrHexToUintn (\r
2f88bd3a 1075 IN CONST CHAR8 *String\r
e1f414b6 1076 )\r
1077{\r
2f88bd3a 1078 UINTN Result;\r
e1f414b6 1079\r
2f88bd3a 1080 AsciiStrHexToUintnS (String, (CHAR8 **)NULL, &Result);\r
e1f414b6 1081 return Result;\r
1082}\r
1083\r
e1f414b6 1084/**\r
1085 Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.\r
1086\r
9aa049d9 1087 This function returns a value of type UINT64 by interpreting the contents of\r
1088 the ASCII string String as a hexadecimal number. The format of the input ASCII\r
e1f414b6 1089 string String is:\r
9aa049d9 1090\r
e1f414b6 1091 [spaces][zeros][x][hexadecimal digits].\r
9aa049d9 1092\r
1093 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
1094 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"\r
1095 appears in the input string, it must be prefixed with at least one 0. The function\r
1096 will ignore the pad space, which includes spaces or tab characters, before [zeros],\r
1097 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]\r
1098 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal\r
1099 digit. Then, the function stops at the first character that is a not a valid\r
e1f414b6 1100 hexadecimal character or Null-terminator, whichever on comes first.\r
9aa049d9 1101\r
e1f414b6 1102 If String has only pad spaces, then 0 is returned.\r
1103 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then\r
1104 0 is returned.\r
1105\r
9aa049d9 1106 If the number represented by String overflows according to the range defined by UINT64,\r
ea2e0921 1107 then MAX_UINT64 is returned.\r
e1f414b6 1108 If String is NULL, then ASSERT().\r
9aa049d9 1109 If PcdMaximumAsciiStringLength is not zero,\r
1110 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
e1f414b6 1111 the Null-terminator, then ASSERT().\r
1112\r
127010dd 1113 @param String A pointer to a Null-terminated ASCII string.\r
e1f414b6 1114\r
9aa049d9 1115 @retval Value translated from String.\r
e1f414b6 1116\r
1117**/\r
1118UINT64\r
1119EFIAPI\r
1120AsciiStrHexToUint64 (\r
2f88bd3a 1121 IN CONST CHAR8 *String\r
e1f414b6 1122 )\r
1123{\r
2f88bd3a 1124 UINT64 Result;\r
e1f414b6 1125\r
2f88bd3a 1126 AsciiStrHexToUint64S (String, (CHAR8 **)NULL, &Result);\r
e1f414b6 1127 return Result;\r
1128}\r
1129\r
2f88bd3a 1130STATIC CHAR8 EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\r
1f7af69d
MT
1131 "abcdefghijklmnopqrstuvwxyz"\r
1132 "0123456789+/";\r
1133\r
1f7af69d
MT
1134/**\r
1135 Convert binary data to a Base64 encoded ascii string based on RFC4648.\r
1136\r
1137 Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.\r
1138 The Ascii string is produced by converting the data string specified by Source and SourceLength.\r
1139\r
1140 @param Source Input UINT8 data\r
1141 @param SourceLength Number of UINT8 bytes of data\r
1142 @param Destination Pointer to output string buffer\r
1143 @param DestinationSize Size of ascii buffer. Set to 0 to get the size needed.\r
1144 Caller is responsible for passing in buffer of DestinationSize\r
1145\r
1146 @retval RETURN_SUCCESS When ascii buffer is filled in.\r
1147 @retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is NULL.\r
1148 @retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).\r
1149 @retval RETURN_BUFFER_TOO_SMALL If SourceLength is 0 and DestinationSize is <1.\r
1150 @retval RETURN_BUFFER_TOO_SMALL If Destination is NULL or DestinationSize is smaller than required buffersize.\r
1151\r
1152**/\r
1153RETURN_STATUS\r
1154EFIAPI\r
1155Base64Encode (\r
1156 IN CONST UINT8 *Source,\r
2f88bd3a 1157 IN UINTN SourceLength,\r
1f7af69d
MT
1158 OUT CHAR8 *Destination OPTIONAL,\r
1159 IN OUT UINTN *DestinationSize\r
1160 )\r
1161{\r
2f88bd3a
MK
1162 UINTN RequiredSize;\r
1163 UINTN Left;\r
1f7af69d
MT
1164\r
1165 //\r
1166 // Check pointers, and SourceLength is valid\r
1167 //\r
1168 if ((Source == NULL) || (DestinationSize == NULL)) {\r
1169 return RETURN_INVALID_PARAMETER;\r
1170 }\r
1171\r
1172 //\r
1173 // Allow for RFC 4648 test vector 1\r
1174 //\r
1175 if (SourceLength == 0) {\r
1176 if (*DestinationSize < 1) {\r
1177 *DestinationSize = 1;\r
1178 return RETURN_BUFFER_TOO_SMALL;\r
1179 }\r
2f88bd3a 1180\r
1f7af69d 1181 *DestinationSize = 1;\r
2f88bd3a 1182 *Destination = '\0';\r
1f7af69d
MT
1183 return RETURN_SUCCESS;\r
1184 }\r
1185\r
1186 //\r
1187 // Check if SourceLength or DestinationSize is valid\r
1188 //\r
2f88bd3a 1189 if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))) {\r
1f7af69d
MT
1190 return RETURN_INVALID_PARAMETER;\r
1191 }\r
1192\r
1193 //\r
1194 // 4 ascii per 3 bytes + NULL\r
1195 //\r
1196 RequiredSize = ((SourceLength + 2) / 3) * 4 + 1;\r
2f88bd3a 1197 if ((Destination == NULL) || (*DestinationSize < RequiredSize)) {\r
1f7af69d
MT
1198 *DestinationSize = RequiredSize;\r
1199 return RETURN_BUFFER_TOO_SMALL;\r
1200 }\r
1201\r
1202 Left = SourceLength;\r
1203\r
1204 //\r
1205 // Encode 24 bits (three bytes) into 4 ascii characters\r
1206 //\r
1207 while (Left >= 3) {\r
2f88bd3a 1208 *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];\r
1f7af69d
MT
1209 *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
1210 *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2) + ((Source[2] & 0xc0) >> 6)];\r
2f88bd3a
MK
1211 *Destination++ = EncodingTable[(Source[2] & 0x3f)];\r
1212 Left -= 3;\r
1213 Source += 3;\r
1f7af69d
MT
1214 }\r
1215\r
1216 //\r
1217 // Handle the remainder, and add padding '=' characters as necessary.\r
1218 //\r
1219 switch (Left) {\r
1220 case 0:\r
1221\r
1222 //\r
1223 // No bytes Left, done.\r
1224 //\r
1225 break;\r
1226 case 1:\r
1227\r
1228 //\r
1229 // One more data byte, two pad characters\r
1230 //\r
2f88bd3a 1231 *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];\r
1f7af69d
MT
1232 *Destination++ = EncodingTable[((Source[0] & 0x03) << 4)];\r
1233 *Destination++ = '=';\r
1234 *Destination++ = '=';\r
1235 break;\r
1236 case 2:\r
1237\r
1238 //\r
1239 // Two more data bytes, and one pad character\r
1240 //\r
2f88bd3a 1241 *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];\r
1f7af69d
MT
1242 *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
1243 *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2)];\r
1244 *Destination++ = '=';\r
1245 break;\r
2f88bd3a
MK
1246 }\r
1247\r
1f7af69d
MT
1248 //\r
1249 // Add terminating NULL\r
1250 //\r
1251 *Destination = '\0';\r
1252 return RETURN_SUCCESS;\r
1253}\r
1254\r
1255/**\r
5d68fc67
LE
1256 Decode Base64 ASCII encoded data to 8-bit binary representation, based on\r
1257 RFC4648.\r
1258\r
1259 Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.\r
1260\r
1261 Whitespace is ignored at all positions:\r
1262 - 0x09 ('\t') horizontal tab\r
1263 - 0x0A ('\n') new line\r
1264 - 0x0B ('\v') vertical tab\r
1265 - 0x0C ('\f') form feed\r
1266 - 0x0D ('\r') carriage return\r
1267 - 0x20 (' ') space\r
1268\r
1269 The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated\r
1270 and enforced at the end of the Base64 ASCII encoded data, and only there.\r
1271\r
1272 Other characters outside of the encoding alphabet cause the function to\r
1273 reject the Base64 ASCII encoded data.\r
1274\r
1275 @param[in] Source Array of CHAR8 elements containing the Base64\r
1276 ASCII encoding. May be NULL if SourceSize is\r
1277 zero.\r
1278\r
1279 @param[in] SourceSize Number of CHAR8 elements in Source.\r
1280\r
1281 @param[out] Destination Array of UINT8 elements receiving the decoded\r
1282 8-bit binary representation. Allocated by the\r
1283 caller. May be NULL if DestinationSize is\r
1284 zero on input. If NULL, decoding is\r
1285 performed, but the 8-bit binary\r
1286 representation is not stored. If non-NULL and\r
1287 the function returns an error, the contents\r
1288 of Destination are indeterminate.\r
1289\r
1290 @param[in,out] DestinationSize On input, the number of UINT8 elements that\r
1291 the caller allocated for Destination. On\r
1292 output, if the function returns\r
1293 RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,\r
1294 the number of UINT8 elements that are\r
1295 required for decoding the Base64 ASCII\r
1296 representation. If the function returns a\r
1297 value different from both RETURN_SUCCESS and\r
1298 RETURN_BUFFER_TOO_SMALL, then DestinationSize\r
1299 is indeterminate on output.\r
1300\r
1301 @retval RETURN_SUCCESS SourceSize CHAR8 elements at Source have\r
1302 been decoded to on-output DestinationSize\r
1303 UINT8 elements at Destination. Note that\r
1304 RETURN_SUCCESS covers the case when\r
1305 DestinationSize is zero on input, and\r
1306 Source decodes to zero bytes (due to\r
1307 containing at most ignored whitespace).\r
1308\r
1309 @retval RETURN_BUFFER_TOO_SMALL The input value of DestinationSize is not\r
1310 large enough for decoding SourceSize CHAR8\r
1311 elements at Source. The required number of\r
1312 UINT8 elements has been stored to\r
1313 DestinationSize.\r
1314\r
1315 @retval RETURN_INVALID_PARAMETER DestinationSize is NULL.\r
1316\r
1317 @retval RETURN_INVALID_PARAMETER Source is NULL, but SourceSize is not zero.\r
1318\r
1319 @retval RETURN_INVALID_PARAMETER Destination is NULL, but DestinationSize is\r
1320 not zero on input.\r
1321\r
1322 @retval RETURN_INVALID_PARAMETER Source is non-NULL, and (Source +\r
1323 SourceSize) would wrap around MAX_ADDRESS.\r
1324\r
1325 @retval RETURN_INVALID_PARAMETER Destination is non-NULL, and (Destination +\r
1326 DestinationSize) would wrap around\r
1327 MAX_ADDRESS, as specified on input.\r
1328\r
1329 @retval RETURN_INVALID_PARAMETER None of Source and Destination are NULL,\r
1330 and CHAR8[SourceSize] at Source overlaps\r
1331 UINT8[DestinationSize] at Destination, as\r
1332 specified on input.\r
1333\r
1334 @retval RETURN_INVALID_PARAMETER Invalid CHAR8 element encountered in\r
1335 Source.\r
1336**/\r
1f7af69d
MT
1337RETURN_STATUS\r
1338EFIAPI\r
1339Base64Decode (\r
2f88bd3a
MK
1340 IN CONST CHAR8 *Source OPTIONAL,\r
1341 IN UINTN SourceSize,\r
1342 OUT UINT8 *Destination OPTIONAL,\r
1343 IN OUT UINTN *DestinationSize\r
1f7af69d
MT
1344 )\r
1345{\r
2f88bd3a
MK
1346 BOOLEAN PaddingMode;\r
1347 UINTN SixBitGroupsConsumed;\r
1348 UINT32 Accumulator;\r
1349 UINTN OriginalDestinationSize;\r
1350 UINTN SourceIndex;\r
1351 CHAR8 SourceChar;\r
1352 UINT32 Base64Value;\r
1353 UINT8 DestinationOctet;\r
35e242b6
LE
1354\r
1355 if (DestinationSize == NULL) {\r
1356 return RETURN_INVALID_PARAMETER;\r
1357 }\r
1358\r
1359 //\r
1360 // Check Source array validity.\r
1361 //\r
1362 if (Source == NULL) {\r
1363 if (SourceSize > 0) {\r
1364 //\r
1365 // At least one CHAR8 element at NULL Source.\r
1366 //\r
1367 return RETURN_INVALID_PARAMETER;\r
1368 }\r
1369 } else if (SourceSize > MAX_ADDRESS - (UINTN)Source) {\r
1370 //\r
1371 // Non-NULL Source, but it wraps around.\r
1372 //\r
1373 return RETURN_INVALID_PARAMETER;\r
1374 }\r
1375\r
1376 //\r
1377 // Check Destination array validity.\r
1378 //\r
1379 if (Destination == NULL) {\r
1380 if (*DestinationSize > 0) {\r
1381 //\r
1382 // At least one UINT8 element at NULL Destination.\r
1383 //\r
1384 return RETURN_INVALID_PARAMETER;\r
1385 }\r
1386 } else if (*DestinationSize > MAX_ADDRESS - (UINTN)Destination) {\r
1387 //\r
1388 // Non-NULL Destination, but it wraps around.\r
1389 //\r
1390 return RETURN_INVALID_PARAMETER;\r
1391 }\r
1392\r
1393 //\r
1394 // Check for overlap.\r
1395 //\r
2f88bd3a 1396 if ((Source != NULL) && (Destination != NULL)) {\r
35e242b6
LE
1397 //\r
1398 // Both arrays have been provided, and we know from earlier that each array\r
1399 // is valid in itself.\r
1400 //\r
1401 if ((UINTN)Source + SourceSize <= (UINTN)Destination) {\r
1402 //\r
1403 // Source array precedes Destination array, OK.\r
1404 //\r
1405 } else if ((UINTN)Destination + *DestinationSize <= (UINTN)Source) {\r
1406 //\r
1407 // Destination array precedes Source array, OK.\r
1408 //\r
1409 } else {\r
1410 //\r
1411 // Overlap.\r
1412 //\r
1413 return RETURN_INVALID_PARAMETER;\r
1414 }\r
1415 }\r
1416\r
1417 //\r
1418 // Decoding loop setup.\r
1419 //\r
1420 PaddingMode = FALSE;\r
1421 SixBitGroupsConsumed = 0;\r
1422 Accumulator = 0;\r
1423 OriginalDestinationSize = *DestinationSize;\r
1424 *DestinationSize = 0;\r
1425\r
1426 //\r
1427 // Decoding loop.\r
1428 //\r
1429 for (SourceIndex = 0; SourceIndex < SourceSize; SourceIndex++) {\r
35e242b6
LE
1430 SourceChar = Source[SourceIndex];\r
1431\r
1432 //\r
1433 // Whitespace is ignored at all positions (regardless of padding mode).\r
1434 //\r
2f88bd3a
MK
1435 if ((SourceChar == '\t') || (SourceChar == '\n') || (SourceChar == '\v') ||\r
1436 (SourceChar == '\f') || (SourceChar == '\r') || (SourceChar == ' '))\r
1437 {\r
35e242b6
LE
1438 continue;\r
1439 }\r
1440\r
1441 //\r
1442 // If we're in padding mode, accept another padding character, as long as\r
1443 // that padding character completes the quantum. This completes case (2)\r
1444 // from RFC4648, Chapter 4. "Base 64 Encoding":\r
1445 //\r
1446 // (2) The final quantum of encoding input is exactly 8 bits; here, the\r
1447 // final unit of encoded output will be two characters followed by two\r
1448 // "=" padding characters.\r
1449 //\r
1450 if (PaddingMode) {\r
2f88bd3a 1451 if ((SourceChar == '=') && (SixBitGroupsConsumed == 3)) {\r
35e242b6
LE
1452 SixBitGroupsConsumed = 0;\r
1453 continue;\r
1454 }\r
2f88bd3a 1455\r
35e242b6
LE
1456 return RETURN_INVALID_PARAMETER;\r
1457 }\r
1458\r
1459 //\r
1460 // When not in padding mode, decode Base64Value based on RFC4648, "Table 1:\r
1461 // The Base 64 Alphabet".\r
1462 //\r
2f88bd3a 1463 if (('A' <= SourceChar) && (SourceChar <= 'Z')) {\r
35e242b6 1464 Base64Value = SourceChar - 'A';\r
2f88bd3a 1465 } else if (('a' <= SourceChar) && (SourceChar <= 'z')) {\r
35e242b6 1466 Base64Value = 26 + (SourceChar - 'a');\r
2f88bd3a 1467 } else if (('0' <= SourceChar) && (SourceChar <= '9')) {\r
35e242b6
LE
1468 Base64Value = 52 + (SourceChar - '0');\r
1469 } else if (SourceChar == '+') {\r
1470 Base64Value = 62;\r
1471 } else if (SourceChar == '/') {\r
1472 Base64Value = 63;\r
1473 } else if (SourceChar == '=') {\r
1474 //\r
1475 // Enter padding mode.\r
1476 //\r
1477 PaddingMode = TRUE;\r
1478\r
1479 if (SixBitGroupsConsumed == 2) {\r
1480 //\r
1481 // If we have consumed two 6-bit groups from the current quantum before\r
1482 // encountering the first padding character, then this is case (2) from\r
1483 // RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,\r
1484 // and we'll enforce another padding character.\r
1485 //\r
1486 SixBitGroupsConsumed = 3;\r
1487 } else if (SixBitGroupsConsumed == 3) {\r
1488 //\r
1489 // If we have consumed three 6-bit groups from the current quantum\r
1490 // before encountering the first padding character, then this is case\r
1491 // (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now\r
1492 // complete.\r
1493 //\r
1494 SixBitGroupsConsumed = 0;\r
1495 } else {\r
1496 //\r
1497 // Padding characters are not allowed at the first two positions of a\r
1498 // quantum.\r
1499 //\r
1500 return RETURN_INVALID_PARAMETER;\r
1501 }\r
1502\r
1503 //\r
1504 // Wherever in a quantum we enter padding mode, we enforce the padding\r
1505 // bits pending in the accumulator -- from the last 6-bit group just\r
1506 // preceding the padding character -- to be zero. Refer to RFC4648,\r
1507 // Chapter 3.5. "Canonical Encoding".\r
1508 //\r
1509 if (Accumulator != 0) {\r
1510 return RETURN_INVALID_PARAMETER;\r
1511 }\r
1512\r
1513 //\r
1514 // Advance to the next source character.\r
1515 //\r
1516 continue;\r
1517 } else {\r
1518 //\r
1519 // Other characters outside of the encoding alphabet are rejected.\r
1520 //\r
1521 return RETURN_INVALID_PARAMETER;\r
1522 }\r
1523\r
1524 //\r
1525 // Feed the bits of the current 6-bit group of the quantum to the\r
1526 // accumulator.\r
1527 //\r
1528 Accumulator = (Accumulator << 6) | Base64Value;\r
1529 SixBitGroupsConsumed++;\r
1530 switch (SixBitGroupsConsumed) {\r
2f88bd3a
MK
1531 case 1:\r
1532 //\r
1533 // No octet to spill after consuming the first 6-bit group of the\r
1534 // quantum; advance to the next source character.\r
1535 //\r
1536 continue;\r
1537 case 2:\r
1538 //\r
1539 // 12 bits accumulated (6 pending + 6 new); prepare for spilling an\r
1540 // octet. 4 bits remain pending.\r
1541 //\r
1542 DestinationOctet = (UINT8)(Accumulator >> 4);\r
1543 Accumulator &= 0xF;\r
1544 break;\r
1545 case 3:\r
1546 //\r
1547 // 10 bits accumulated (4 pending + 6 new); prepare for spilling an\r
1548 // octet. 2 bits remain pending.\r
1549 //\r
1550 DestinationOctet = (UINT8)(Accumulator >> 2);\r
1551 Accumulator &= 0x3;\r
1552 break;\r
1553 default:\r
1554 ASSERT (SixBitGroupsConsumed == 4);\r
1555 //\r
1556 // 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.\r
1557 // The quantum is complete, 0 bits remain pending.\r
1558 //\r
1559 DestinationOctet = (UINT8)Accumulator;\r
1560 Accumulator = 0;\r
1561 SixBitGroupsConsumed = 0;\r
1562 break;\r
35e242b6
LE
1563 }\r
1564\r
1565 //\r
1566 // Store the decoded octet if there's room left. Increment\r
1567 // (*DestinationSize) unconditionally.\r
1568 //\r
1569 if (*DestinationSize < OriginalDestinationSize) {\r
1570 ASSERT (Destination != NULL);\r
1571 Destination[*DestinationSize] = DestinationOctet;\r
1572 }\r
2f88bd3a 1573\r
35e242b6
LE
1574 (*DestinationSize)++;\r
1575\r
1576 //\r
1577 // Advance to the next source character.\r
1578 //\r
1579 }\r
1580\r
1581 //\r
1582 // If Source terminates mid-quantum, then Source is invalid.\r
1583 //\r
1584 if (SixBitGroupsConsumed != 0) {\r
1585 return RETURN_INVALID_PARAMETER;\r
1586 }\r
1587\r
1588 //\r
1589 // Done.\r
1590 //\r
1591 if (*DestinationSize <= OriginalDestinationSize) {\r
1592 return RETURN_SUCCESS;\r
1593 }\r
2f88bd3a 1594\r
35e242b6 1595 return RETURN_BUFFER_TOO_SMALL;\r
1f7af69d
MT
1596}\r
1597\r
e1f414b6 1598/**\r
1599 Converts an 8-bit value to an 8-bit BCD value.\r
1600\r
1601 Converts the 8-bit value specified by Value to BCD. The BCD value is\r
1602 returned.\r
1603\r
1604 If Value >= 100, then ASSERT().\r
1605\r
1606 @param Value The 8-bit value to convert to BCD. Range 0..99.\r
1607\r
9aa049d9 1608 @return The BCD value.\r
e1f414b6 1609\r
1610**/\r
1611UINT8\r
1612EFIAPI\r
1613DecimalToBcd8 (\r
2f88bd3a 1614 IN UINT8 Value\r
e1f414b6 1615 )\r
1616{\r
1617 ASSERT (Value < 100);\r
2f88bd3a 1618 return (UINT8)(((Value / 10) << 4) | (Value % 10));\r
e1f414b6 1619}\r
1620\r
1621/**\r
1622 Converts an 8-bit BCD value to an 8-bit value.\r
1623\r
1624 Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit\r
1625 value is returned.\r
1626\r
1627 If Value >= 0xA0, then ASSERT().\r
1628 If (Value & 0x0F) >= 0x0A, then ASSERT().\r
1629\r
1630 @param Value The 8-bit BCD value to convert to an 8-bit value.\r
1631\r
9aa049d9 1632 @return The 8-bit value is returned.\r
e1f414b6 1633\r
1634**/\r
1635UINT8\r
1636EFIAPI\r
1637BcdToDecimal8 (\r
2f88bd3a 1638 IN UINT8 Value\r
e1f414b6 1639 )\r
1640{\r
1641 ASSERT (Value < 0xa0);\r
1642 ASSERT ((Value & 0xf) < 0xa);\r
2f88bd3a 1643 return (UINT8)((Value >> 4) * 10 + (Value & 0xf));\r
e1f414b6 1644}\r