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