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