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