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