]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/SafeString.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BaseLib / SafeString.c
CommitLineData
c058d59f
JY
1/** @file\r
2 Safe String functions.\r
3\r
5dbfa01e 4 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
c058d59f
JY
6\r
7**/\r
8\r
d8af3301 9#include "BaseLibInternals.h"\r
c058d59f
JY
10\r
11#define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))\r
12\r
13#define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))\r
14\r
15#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \\r
16 do { \\r
c058d59f 17 if (!(Expression)) { \\r
09fe015a
VC
18 DEBUG ((DEBUG_VERBOSE, \\r
19 "%a(%d) %a: SAFE_STRING_CONSTRAINT_CHECK(%a) failed. Return %r\n", \\r
5948ec36 20 __FILE__, DEBUG_LINE_NUMBER, __FUNCTION__, DEBUG_EXPRESSION_STRING (Expression), Status)); \\r
c058d59f
JY
21 return Status; \\r
22 } \\r
23 } while (FALSE)\r
24\r
25/**\r
26 Returns if 2 memory blocks are overlapped.\r
27\r
28 @param Base1 Base address of 1st memory block.\r
29 @param Size1 Size of 1st memory block.\r
30 @param Base2 Base address of 2nd memory block.\r
31 @param Size2 Size of 2nd memory block.\r
32\r
33 @retval TRUE 2 memory blocks are overlapped.\r
34 @retval FALSE 2 memory blocks are not overlapped.\r
35**/\r
36BOOLEAN\r
37InternalSafeStringIsOverlap (\r
2f88bd3a
MK
38 IN VOID *Base1,\r
39 IN UINTN Size1,\r
40 IN VOID *Base2,\r
41 IN UINTN Size2\r
c058d59f
JY
42 )\r
43{\r
44 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||\r
2f88bd3a
MK
45 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1)))\r
46 {\r
c058d59f
JY
47 return TRUE;\r
48 }\r
2f88bd3a 49\r
c058d59f
JY
50 return FALSE;\r
51}\r
52\r
53/**\r
54 Returns if 2 Unicode strings are not overlapped.\r
55\r
56 @param Str1 Start address of 1st Unicode string.\r
57 @param Size1 The number of char in 1st Unicode string,\r
58 including terminating null char.\r
59 @param Str2 Start address of 2nd Unicode string.\r
60 @param Size2 The number of char in 2nd Unicode string,\r
61 including terminating null char.\r
62\r
63 @retval TRUE 2 Unicode strings are NOT overlapped.\r
64 @retval FALSE 2 Unicode strings are overlapped.\r
65**/\r
66BOOLEAN\r
67InternalSafeStringNoStrOverlap (\r
68 IN CHAR16 *Str1,\r
69 IN UINTN Size1,\r
70 IN CHAR16 *Str2,\r
71 IN UINTN Size2\r
72 )\r
73{\r
2f88bd3a 74 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof (CHAR16), Str2, Size2 * sizeof (CHAR16));\r
c058d59f
JY
75}\r
76\r
77/**\r
78 Returns if 2 Ascii strings are not overlapped.\r
79\r
80 @param Str1 Start address of 1st Ascii string.\r
81 @param Size1 The number of char in 1st Ascii string,\r
82 including terminating null char.\r
83 @param Str2 Start address of 2nd Ascii string.\r
84 @param Size2 The number of char in 2nd Ascii string,\r
85 including terminating null char.\r
86\r
87 @retval TRUE 2 Ascii strings are NOT overlapped.\r
88 @retval FALSE 2 Ascii strings are overlapped.\r
89**/\r
90BOOLEAN\r
91InternalSafeStringNoAsciiStrOverlap (\r
2f88bd3a
MK
92 IN CHAR8 *Str1,\r
93 IN UINTN Size1,\r
94 IN CHAR8 *Str2,\r
95 IN UINTN Size2\r
c058d59f
JY
96 )\r
97{\r
98 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);\r
99}\r
100\r
101/**\r
102 Returns the length of a Null-terminated Unicode string.\r
103\r
328f84b1
JY
104 This function is similar as strlen_s defined in C11.\r
105\r
c058d59f
JY
106 If String is not aligned on a 16-bit boundary, then ASSERT().\r
107\r
108 @param String A pointer to a Null-terminated Unicode string.\r
109 @param MaxSize The maximum number of Destination Unicode\r
110 char, including terminating null char.\r
111\r
112 @retval 0 If String is NULL.\r
113 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
114 @return The number of characters that percede the terminating null character.\r
115\r
116**/\r
117UINTN\r
118EFIAPI\r
119StrnLenS (\r
2f88bd3a
MK
120 IN CONST CHAR16 *String,\r
121 IN UINTN MaxSize\r
c058d59f
JY
122 )\r
123{\r
2f88bd3a 124 UINTN Length;\r
c058d59f 125\r
2f88bd3a 126 ASSERT (((UINTN)String & BIT0) == 0);\r
c058d59f
JY
127\r
128 //\r
cb867499 129 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.\r
c058d59f 130 //\r
cb867499 131 if ((String == NULL) || (MaxSize == 0)) {\r
c058d59f
JY
132 return 0;\r
133 }\r
134\r
135 //\r
136 // Otherwise, the StrnLenS function returns the number of characters that precede the\r
137 // terminating null character. If there is no null character in the first MaxSize characters of\r
138 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
139 // be accessed by StrnLenS.\r
140 //\r
c07c517c
HW
141 Length = 0;\r
142 while (String[Length] != 0) {\r
143 if (Length >= MaxSize - 1) {\r
144 return MaxSize;\r
145 }\r
2f88bd3a 146\r
c07c517c 147 Length++;\r
c058d59f 148 }\r
2f88bd3a 149\r
c058d59f
JY
150 return Length;\r
151}\r
152\r
b590e43a
HW
153/**\r
154 Returns the size of a Null-terminated Unicode string in bytes, including the\r
155 Null terminator.\r
156\r
157 This function returns the size of the Null-terminated Unicode string\r
158 specified by String in bytes, including the Null terminator.\r
159\r
160 If String is not aligned on a 16-bit boundary, then ASSERT().\r
161\r
162 @param String A pointer to a Null-terminated Unicode string.\r
163 @param MaxSize The maximum number of Destination Unicode\r
164 char, including the Null terminator.\r
165\r
166 @retval 0 If String is NULL.\r
167 @retval (sizeof (CHAR16) * (MaxSize + 1))\r
168 If there is no Null terminator in the first MaxSize characters of\r
169 String.\r
170 @return The size of the Null-terminated Unicode string in bytes, including\r
171 the Null terminator.\r
172\r
173**/\r
174UINTN\r
175EFIAPI\r
176StrnSizeS (\r
2f88bd3a
MK
177 IN CONST CHAR16 *String,\r
178 IN UINTN MaxSize\r
b590e43a
HW
179 )\r
180{\r
181 //\r
182 // If String is a null pointer, then the StrnSizeS function returns zero.\r
183 //\r
184 if (String == NULL) {\r
185 return 0;\r
186 }\r
187\r
188 //\r
189 // Otherwise, the StrnSizeS function returns the size of the Null-terminated\r
190 // Unicode string in bytes, including the Null terminator. If there is no\r
191 // Null terminator in the first MaxSize characters of String, then StrnSizeS\r
192 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with\r
193 // the StrnLenS function.\r
194 //\r
195 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
196}\r
197\r
c058d59f
JY
198/**\r
199 Copies the string pointed to by Source (including the terminating null char)\r
200 to the array pointed to by Destination.\r
201\r
328f84b1
JY
202 This function is similar as strcpy_s defined in C11.\r
203\r
c058d59f
JY
204 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
205 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
206\r
328f84b1
JY
207 If an error is returned, then the Destination is unmodified.\r
208\r
c058d59f
JY
209 @param Destination A pointer to a Null-terminated Unicode string.\r
210 @param DestMax The maximum number of Destination Unicode\r
211 char, including terminating null char.\r
212 @param Source A pointer to a Null-terminated Unicode string.\r
213\r
214 @retval RETURN_SUCCESS String is copied.\r
215 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
216 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
217 If Source is NULL.\r
218 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 219 and DestMax is greater than\r
c058d59f
JY
220 PcdMaximumUnicodeStringLength.\r
221 If DestMax is 0.\r
222 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
223**/\r
224RETURN_STATUS\r
225EFIAPI\r
226StrCpyS (\r
2f88bd3a
MK
227 OUT CHAR16 *Destination,\r
228 IN UINTN DestMax,\r
229 IN CONST CHAR16 *Source\r
c058d59f
JY
230 )\r
231{\r
2f88bd3a 232 UINTN SourceLen;\r
973f8862 233\r
2f88bd3a
MK
234 ASSERT (((UINTN)Destination & BIT0) == 0);\r
235 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
236\r
237 //\r
238 // 1. Neither Destination nor Source shall be a null pointer.\r
239 //\r
240 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
241 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
242\r
243 //\r
244 // 2. DestMax shall not be greater than RSIZE_MAX.\r
245 //\r
246 if (RSIZE_MAX != 0) {\r
247 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
248 }\r
249\r
250 //\r
251 // 3. DestMax shall not equal zero.\r
252 //\r
253 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
254\r
255 //\r
256 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).\r
257 //\r
258 SourceLen = StrnLenS (Source, DestMax);\r
259 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
260\r
261 //\r
262 // 5. Copying shall not take place between objects that overlap.\r
263 //\r
264 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
265\r
266 //\r
267 // The StrCpyS function copies the string pointed to by Source (including the terminating\r
268 // null character) into the array pointed to by Destination.\r
269 //\r
270 while (*Source != 0) {\r
271 *(Destination++) = *(Source++);\r
272 }\r
2f88bd3a 273\r
c058d59f
JY
274 *Destination = 0;\r
275\r
276 return RETURN_SUCCESS;\r
277}\r
278\r
279/**\r
280 Copies not more than Length successive char from the string pointed to by\r
281 Source to the array pointed to by Destination. If no null char is copied from\r
282 Source, then Destination[Length] is always set to null.\r
283\r
328f84b1
JY
284 This function is similar as strncpy_s defined in C11.\r
285\r
c058d59f
JY
286 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
287 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
288\r
328f84b1
JY
289 If an error is returned, then the Destination is unmodified.\r
290\r
c058d59f
JY
291 @param Destination A pointer to a Null-terminated Unicode string.\r
292 @param DestMax The maximum number of Destination Unicode\r
293 char, including terminating null char.\r
294 @param Source A pointer to a Null-terminated Unicode string.\r
295 @param Length The maximum number of Unicode characters to copy.\r
296\r
297 @retval RETURN_SUCCESS String is copied.\r
973f8862 298 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
c058d59f
JY
299 MIN(StrLen(Source), Length).\r
300 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
301 If Source is NULL.\r
302 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 303 and DestMax is greater than\r
c058d59f
JY
304 PcdMaximumUnicodeStringLength.\r
305 If DestMax is 0.\r
306 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
307**/\r
308RETURN_STATUS\r
309EFIAPI\r
310StrnCpyS (\r
2f88bd3a
MK
311 OUT CHAR16 *Destination,\r
312 IN UINTN DestMax,\r
313 IN CONST CHAR16 *Source,\r
314 IN UINTN Length\r
c058d59f
JY
315 )\r
316{\r
2f88bd3a 317 UINTN SourceLen;\r
c058d59f 318\r
2f88bd3a
MK
319 ASSERT (((UINTN)Destination & BIT0) == 0);\r
320 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
321\r
322 //\r
323 // 1. Neither Destination nor Source shall be a null pointer.\r
324 //\r
325 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
326 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
327\r
328 //\r
329 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX\r
330 //\r
331 if (RSIZE_MAX != 0) {\r
332 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
333 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
334 }\r
335\r
336 //\r
337 // 3. DestMax shall not equal zero.\r
338 //\r
339 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
340\r
341 //\r
342 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).\r
343 //\r
56658c22 344 SourceLen = StrnLenS (Source, MIN (DestMax, Length));\r
c058d59f
JY
345 if (Length >= DestMax) {\r
346 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
347 }\r
348\r
349 //\r
350 // 5. Copying shall not take place between objects that overlap.\r
351 //\r
352 if (SourceLen > Length) {\r
353 SourceLen = Length;\r
354 }\r
2f88bd3a 355\r
c058d59f
JY
356 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
357\r
358 //\r
359 // The StrnCpyS function copies not more than Length successive characters (characters that\r
360 // follow a null character are not copied) from the array pointed to by Source to the array\r
361 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
362 // character.\r
363 //\r
56658c22 364 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
365 *(Destination++) = *(Source++);\r
366 SourceLen--;\r
367 }\r
2f88bd3a 368\r
c058d59f
JY
369 *Destination = 0;\r
370\r
371 return RETURN_SUCCESS;\r
372}\r
373\r
374/**\r
375 Appends a copy of the string pointed to by Source (including the terminating\r
376 null char) to the end of the string pointed to by Destination.\r
377\r
328f84b1
JY
378 This function is similar as strcat_s defined in C11.\r
379\r
c058d59f
JY
380 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
381 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
382\r
328f84b1
JY
383 If an error is returned, then the Destination is unmodified.\r
384\r
c058d59f
JY
385 @param Destination A pointer to a Null-terminated Unicode string.\r
386 @param DestMax The maximum number of Destination Unicode\r
387 char, including terminating null char.\r
388 @param Source A pointer to a Null-terminated Unicode string.\r
389\r
390 @retval RETURN_SUCCESS String is appended.\r
973f8862 391 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
c058d59f
JY
392 StrLen(Destination).\r
393 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
394 greater than StrLen(Source).\r
395 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
396 If Source is NULL.\r
397 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 398 and DestMax is greater than\r
c058d59f
JY
399 PcdMaximumUnicodeStringLength.\r
400 If DestMax is 0.\r
401 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
402**/\r
403RETURN_STATUS\r
404EFIAPI\r
405StrCatS (\r
2f88bd3a
MK
406 IN OUT CHAR16 *Destination,\r
407 IN UINTN DestMax,\r
408 IN CONST CHAR16 *Source\r
c058d59f
JY
409 )\r
410{\r
2f88bd3a
MK
411 UINTN DestLen;\r
412 UINTN CopyLen;\r
413 UINTN SourceLen;\r
973f8862 414\r
2f88bd3a
MK
415 ASSERT (((UINTN)Destination & BIT0) == 0);\r
416 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
417\r
418 //\r
419 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.\r
420 //\r
421 DestLen = StrnLenS (Destination, DestMax);\r
422 CopyLen = DestMax - DestLen;\r
423\r
424 //\r
425 // 1. Neither Destination nor Source shall be a null pointer.\r
426 //\r
427 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
428 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
429\r
430 //\r
431 // 2. DestMax shall not be greater than RSIZE_MAX.\r
432 //\r
433 if (RSIZE_MAX != 0) {\r
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
435 }\r
436\r
437 //\r
438 // 3. DestMax shall not equal zero.\r
439 //\r
440 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
441\r
442 //\r
443 // 4. CopyLen shall not equal zero.\r
444 //\r
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
446\r
447 //\r
448 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
449 //\r
450 SourceLen = StrnLenS (Source, CopyLen);\r
451 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
452\r
453 //\r
454 // 6. Copying shall not take place between objects that overlap.\r
455 //\r
456 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
457\r
458 //\r
459 // The StrCatS function appends a copy of the string pointed to by Source (including the\r
460 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
461 // from Source overwrites the null character at the end of Destination.\r
462 //\r
463 Destination = Destination + DestLen;\r
464 while (*Source != 0) {\r
465 *(Destination++) = *(Source++);\r
466 }\r
2f88bd3a 467\r
c058d59f
JY
468 *Destination = 0;\r
469\r
470 return RETURN_SUCCESS;\r
471}\r
472\r
473/**\r
474 Appends not more than Length successive char from the string pointed to by\r
475 Source to the end of the string pointed to by Destination. If no null char is\r
476 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
477 set to null.\r
478\r
328f84b1
JY
479 This function is similar as strncat_s defined in C11.\r
480\r
c058d59f 481 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 482 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
c058d59f 483\r
328f84b1
JY
484 If an error is returned, then the Destination is unmodified.\r
485\r
c058d59f
JY
486 @param Destination A pointer to a Null-terminated Unicode string.\r
487 @param DestMax The maximum number of Destination Unicode\r
488 char, including terminating null char.\r
489 @param Source A pointer to a Null-terminated Unicode string.\r
490 @param Length The maximum number of Unicode characters to copy.\r
491\r
492 @retval RETURN_SUCCESS String is appended.\r
493 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
494 StrLen(Destination).\r
495 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
496 greater than MIN(StrLen(Source), Length).\r
497 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
498 If Source is NULL.\r
499 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 500 and DestMax is greater than\r
c058d59f
JY
501 PcdMaximumUnicodeStringLength.\r
502 If DestMax is 0.\r
503 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
504**/\r
505RETURN_STATUS\r
506EFIAPI\r
507StrnCatS (\r
2f88bd3a
MK
508 IN OUT CHAR16 *Destination,\r
509 IN UINTN DestMax,\r
510 IN CONST CHAR16 *Source,\r
511 IN UINTN Length\r
c058d59f
JY
512 )\r
513{\r
2f88bd3a
MK
514 UINTN DestLen;\r
515 UINTN CopyLen;\r
516 UINTN SourceLen;\r
973f8862 517\r
2f88bd3a
MK
518 ASSERT (((UINTN)Destination & BIT0) == 0);\r
519 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
520\r
521 //\r
522 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.\r
523 //\r
524 DestLen = StrnLenS (Destination, DestMax);\r
525 CopyLen = DestMax - DestLen;\r
526\r
527 //\r
528 // 1. Neither Destination nor Source shall be a null pointer.\r
529 //\r
530 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
531 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
532\r
533 //\r
534 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.\r
535 //\r
536 if (RSIZE_MAX != 0) {\r
537 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
538 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
539 }\r
540\r
541 //\r
542 // 3. DestMax shall not equal zero.\r
543 //\r
544 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
545\r
546 //\r
547 // 4. CopyLen shall not equal zero.\r
548 //\r
549 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
550\r
551 //\r
552 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
553 //\r
56658c22 554 SourceLen = StrnLenS (Source, MIN (CopyLen, Length));\r
c058d59f
JY
555 if (Length >= CopyLen) {\r
556 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
557 }\r
558\r
559 //\r
560 // 6. Copying shall not take place between objects that overlap.\r
561 //\r
562 if (SourceLen > Length) {\r
563 SourceLen = Length;\r
564 }\r
2f88bd3a 565\r
c058d59f
JY
566 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
567\r
568 //\r
569 // The StrnCatS function appends not more than Length successive characters (characters\r
570 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
571 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
572 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
573 // a null character.\r
574 //\r
575 Destination = Destination + DestLen;\r
56658c22 576 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
577 *(Destination++) = *(Source++);\r
578 SourceLen--;\r
579 }\r
2f88bd3a 580\r
c058d59f
JY
581 *Destination = 0;\r
582\r
583 return RETURN_SUCCESS;\r
584}\r
585\r
d8af3301
HW
586/**\r
587 Convert a Null-terminated Unicode decimal string to a value of type UINTN.\r
588\r
589 This function outputs a value of type UINTN by interpreting the contents of\r
590 the Unicode string specified by String as a decimal number. The format of the\r
591 input Unicode string String is:\r
592\r
593 [spaces] [decimal digits].\r
594\r
595 The valid decimal digit character is in the range [0-9]. The function will\r
596 ignore the pad space, which includes spaces or tab characters, before\r
597 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
598 be ignored. Then, the function stops at the first character that is a not a\r
599 valid decimal character or a Null-terminator, whichever one comes first.\r
600\r
d8af3301 601 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
602\r
603 If String has no valid decimal digits in the above format, then 0 is stored\r
604 at the location pointed to by Data.\r
605 If the number represented by String exceeds the range defined by UINTN, then\r
606 MAX_UINTN is stored at the location pointed to by Data.\r
607\r
608 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
609 is stored at the location pointed to by EndPointer. If String has no valid\r
610 decimal digits right after the optional pad spaces, the value of String is\r
611 stored at the location pointed to by EndPointer.\r
612\r
613 @param String Pointer to a Null-terminated Unicode string.\r
614 @param EndPointer Pointer to character that stops scan.\r
615 @param Data Pointer to the converted value.\r
616\r
617 @retval RETURN_SUCCESS Value is translated from String.\r
618 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
619 If Data is NULL.\r
620 If PcdMaximumUnicodeStringLength is not\r
621 zero, and String contains more than\r
622 PcdMaximumUnicodeStringLength Unicode\r
623 characters, not including the\r
624 Null-terminator.\r
625 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
626 the range defined by UINTN.\r
627\r
628**/\r
629RETURN_STATUS\r
630EFIAPI\r
631StrDecimalToUintnS (\r
2f88bd3a
MK
632 IN CONST CHAR16 *String,\r
633 OUT CHAR16 **EndPointer OPTIONAL,\r
634 OUT UINTN *Data\r
d8af3301
HW
635 )\r
636{\r
2f88bd3a 637 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
638\r
639 //\r
640 // 1. Neither String nor Data shall be a null pointer.\r
641 //\r
642 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
643 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
644\r
645 //\r
646 // 2. The length of String shall not be greater than RSIZE_MAX.\r
647 //\r
648 if (RSIZE_MAX != 0) {\r
649 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
650 }\r
651\r
652 if (EndPointer != NULL) {\r
2f88bd3a 653 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
654 }\r
655\r
656 //\r
657 // Ignore the pad spaces (space or tab)\r
658 //\r
659 while ((*String == L' ') || (*String == L'\t')) {\r
660 String++;\r
661 }\r
662\r
663 //\r
664 // Ignore leading Zeros after the spaces\r
665 //\r
666 while (*String == L'0') {\r
667 String++;\r
668 }\r
669\r
670 *Data = 0;\r
671\r
672 while (InternalIsDecimalDigitCharacter (*String)) {\r
673 //\r
674 // If the number represented by String overflows according to the range\r
675 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
676 // RETURN_UNSUPPORTED is returned.\r
677 //\r
678 if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {\r
679 *Data = MAX_UINTN;\r
680 if (EndPointer != NULL) {\r
2f88bd3a 681 *EndPointer = (CHAR16 *)String;\r
d8af3301 682 }\r
2f88bd3a 683\r
d8af3301
HW
684 return RETURN_UNSUPPORTED;\r
685 }\r
686\r
687 *Data = *Data * 10 + (*String - L'0');\r
688 String++;\r
689 }\r
690\r
691 if (EndPointer != NULL) {\r
2f88bd3a 692 *EndPointer = (CHAR16 *)String;\r
d8af3301 693 }\r
2f88bd3a 694\r
d8af3301
HW
695 return RETURN_SUCCESS;\r
696}\r
697\r
698/**\r
699 Convert a Null-terminated Unicode decimal string to a value of type UINT64.\r
700\r
701 This function outputs a value of type UINT64 by interpreting the contents of\r
702 the Unicode string specified by String as a decimal number. The format of the\r
703 input Unicode string String is:\r
704\r
705 [spaces] [decimal digits].\r
706\r
707 The valid decimal digit character is in the range [0-9]. The function will\r
708 ignore the pad space, which includes spaces or tab characters, before\r
709 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
710 be ignored. Then, the function stops at the first character that is a not a\r
711 valid decimal character or a Null-terminator, whichever one comes first.\r
712\r
d8af3301 713 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
714\r
715 If String has no valid decimal digits in the above format, then 0 is stored\r
716 at the location pointed to by Data.\r
717 If the number represented by String exceeds the range defined by UINT64, then\r
718 MAX_UINT64 is stored at the location pointed to by Data.\r
719\r
720 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
721 is stored at the location pointed to by EndPointer. If String has no valid\r
722 decimal digits right after the optional pad spaces, the value of String is\r
723 stored at the location pointed to by EndPointer.\r
724\r
725 @param String Pointer to a Null-terminated Unicode string.\r
726 @param EndPointer Pointer to character that stops scan.\r
727 @param Data Pointer to the converted value.\r
728\r
729 @retval RETURN_SUCCESS Value is translated from String.\r
730 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
731 If Data is NULL.\r
732 If PcdMaximumUnicodeStringLength is not\r
733 zero, and String contains more than\r
734 PcdMaximumUnicodeStringLength Unicode\r
735 characters, not including the\r
736 Null-terminator.\r
737 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
738 the range defined by UINT64.\r
739\r
740**/\r
741RETURN_STATUS\r
742EFIAPI\r
743StrDecimalToUint64S (\r
2f88bd3a
MK
744 IN CONST CHAR16 *String,\r
745 OUT CHAR16 **EndPointer OPTIONAL,\r
746 OUT UINT64 *Data\r
d8af3301
HW
747 )\r
748{\r
2f88bd3a 749 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
750\r
751 //\r
752 // 1. Neither String nor Data shall be a null pointer.\r
753 //\r
754 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
755 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
756\r
757 //\r
758 // 2. The length of String shall not be greater than RSIZE_MAX.\r
759 //\r
760 if (RSIZE_MAX != 0) {\r
761 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
762 }\r
763\r
764 if (EndPointer != NULL) {\r
2f88bd3a 765 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
766 }\r
767\r
768 //\r
769 // Ignore the pad spaces (space or tab)\r
770 //\r
771 while ((*String == L' ') || (*String == L'\t')) {\r
772 String++;\r
773 }\r
774\r
775 //\r
776 // Ignore leading Zeros after the spaces\r
777 //\r
778 while (*String == L'0') {\r
779 String++;\r
780 }\r
781\r
782 *Data = 0;\r
783\r
784 while (InternalIsDecimalDigitCharacter (*String)) {\r
785 //\r
786 // If the number represented by String overflows according to the range\r
787 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
788 // RETURN_UNSUPPORTED is returned.\r
789 //\r
790 if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) {\r
791 *Data = MAX_UINT64;\r
792 if (EndPointer != NULL) {\r
2f88bd3a 793 *EndPointer = (CHAR16 *)String;\r
d8af3301 794 }\r
2f88bd3a 795\r
d8af3301
HW
796 return RETURN_UNSUPPORTED;\r
797 }\r
798\r
799 *Data = MultU64x32 (*Data, 10) + (*String - L'0');\r
800 String++;\r
801 }\r
802\r
803 if (EndPointer != NULL) {\r
2f88bd3a 804 *EndPointer = (CHAR16 *)String;\r
d8af3301 805 }\r
2f88bd3a 806\r
d8af3301
HW
807 return RETURN_SUCCESS;\r
808}\r
809\r
810/**\r
811 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
812 UINTN.\r
813\r
814 This function outputs a value of type UINTN by interpreting the contents of\r
815 the Unicode string specified by String as a hexadecimal number. The format of\r
816 the input Unicode string String is:\r
817\r
818 [spaces][zeros][x][hexadecimal digits].\r
819\r
820 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
821 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
822 If "x" appears in the input string, it must be prefixed with at least one 0.\r
823 The function will ignore the pad space, which includes spaces or tab\r
824 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
825 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
826 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
827 the first character that is a not a valid hexadecimal character or NULL,\r
828 whichever one comes first.\r
829\r
d8af3301 830 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
831\r
832 If String has no valid hexadecimal digits in the above format, then 0 is\r
833 stored at the location pointed to by Data.\r
834 If the number represented by String exceeds the range defined by UINTN, then\r
835 MAX_UINTN is stored at the location pointed to by Data.\r
836\r
837 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
838 is stored at the location pointed to by EndPointer. If String has no valid\r
839 hexadecimal digits right after the optional pad spaces, the value of String\r
840 is stored at the location pointed to by EndPointer.\r
841\r
842 @param String Pointer to a Null-terminated Unicode string.\r
843 @param EndPointer Pointer to character that stops scan.\r
844 @param Data Pointer to the converted value.\r
845\r
846 @retval RETURN_SUCCESS Value is translated from String.\r
847 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
848 If Data is NULL.\r
849 If PcdMaximumUnicodeStringLength is not\r
850 zero, and String contains more than\r
851 PcdMaximumUnicodeStringLength Unicode\r
852 characters, not including the\r
853 Null-terminator.\r
854 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
855 the range defined by UINTN.\r
856\r
857**/\r
858RETURN_STATUS\r
859EFIAPI\r
860StrHexToUintnS (\r
2f88bd3a
MK
861 IN CONST CHAR16 *String,\r
862 OUT CHAR16 **EndPointer OPTIONAL,\r
863 OUT UINTN *Data\r
d8af3301
HW
864 )\r
865{\r
2f88bd3a 866 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
867\r
868 //\r
869 // 1. Neither String nor Data shall be a null pointer.\r
870 //\r
871 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
872 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
873\r
874 //\r
875 // 2. The length of String shall not be greater than RSIZE_MAX.\r
876 //\r
877 if (RSIZE_MAX != 0) {\r
878 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
879 }\r
880\r
881 if (EndPointer != NULL) {\r
2f88bd3a 882 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
883 }\r
884\r
885 //\r
886 // Ignore the pad spaces (space or tab)\r
887 //\r
888 while ((*String == L' ') || (*String == L'\t')) {\r
889 String++;\r
890 }\r
891\r
892 //\r
893 // Ignore leading Zeros after the spaces\r
894 //\r
895 while (*String == L'0') {\r
896 String++;\r
897 }\r
898\r
5dbfa01e 899 if (CharToUpper (*String) == L'X') {\r
d8af3301
HW
900 if (*(String - 1) != L'0') {\r
901 *Data = 0;\r
902 return RETURN_SUCCESS;\r
903 }\r
2f88bd3a 904\r
d8af3301
HW
905 //\r
906 // Skip the 'X'\r
907 //\r
908 String++;\r
909 }\r
910\r
911 *Data = 0;\r
912\r
913 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
914 //\r
915 // If the number represented by String overflows according to the range\r
916 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
917 // RETURN_UNSUPPORTED is returned.\r
918 //\r
919 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {\r
920 *Data = MAX_UINTN;\r
921 if (EndPointer != NULL) {\r
2f88bd3a 922 *EndPointer = (CHAR16 *)String;\r
d8af3301 923 }\r
2f88bd3a 924\r
d8af3301
HW
925 return RETURN_UNSUPPORTED;\r
926 }\r
927\r
928 *Data = (*Data << 4) + InternalHexCharToUintn (*String);\r
929 String++;\r
930 }\r
931\r
932 if (EndPointer != NULL) {\r
2f88bd3a 933 *EndPointer = (CHAR16 *)String;\r
d8af3301 934 }\r
2f88bd3a 935\r
d8af3301
HW
936 return RETURN_SUCCESS;\r
937}\r
938\r
939/**\r
940 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
941 UINT64.\r
942\r
943 This function outputs a value of type UINT64 by interpreting the contents of\r
944 the Unicode string specified by String as a hexadecimal number. The format of\r
945 the input Unicode string String is:\r
946\r
947 [spaces][zeros][x][hexadecimal digits].\r
948\r
949 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
950 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
951 If "x" appears in the input string, it must be prefixed with at least one 0.\r
952 The function will ignore the pad space, which includes spaces or tab\r
953 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
954 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
955 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
956 the first character that is a not a valid hexadecimal character or NULL,\r
957 whichever one comes first.\r
958\r
d8af3301 959 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
960\r
961 If String has no valid hexadecimal digits in the above format, then 0 is\r
962 stored at the location pointed to by Data.\r
963 If the number represented by String exceeds the range defined by UINT64, then\r
964 MAX_UINT64 is stored at the location pointed to by Data.\r
965\r
966 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
967 is stored at the location pointed to by EndPointer. If String has no valid\r
968 hexadecimal digits right after the optional pad spaces, the value of String\r
969 is stored at the location pointed to by EndPointer.\r
970\r
971 @param String Pointer to a Null-terminated Unicode string.\r
972 @param EndPointer Pointer to character that stops scan.\r
973 @param Data Pointer to the converted value.\r
974\r
975 @retval RETURN_SUCCESS Value is translated from String.\r
976 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
977 If Data is NULL.\r
978 If PcdMaximumUnicodeStringLength is not\r
979 zero, and String contains more than\r
980 PcdMaximumUnicodeStringLength Unicode\r
981 characters, not including the\r
982 Null-terminator.\r
983 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
984 the range defined by UINT64.\r
985\r
986**/\r
987RETURN_STATUS\r
988EFIAPI\r
989StrHexToUint64S (\r
2f88bd3a
MK
990 IN CONST CHAR16 *String,\r
991 OUT CHAR16 **EndPointer OPTIONAL,\r
992 OUT UINT64 *Data\r
d8af3301
HW
993 )\r
994{\r
2f88bd3a 995 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
996\r
997 //\r
998 // 1. Neither String nor Data shall be a null pointer.\r
999 //\r
1000 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1001 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1002\r
1003 //\r
1004 // 2. The length of String shall not be greater than RSIZE_MAX.\r
1005 //\r
1006 if (RSIZE_MAX != 0) {\r
1007 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1008 }\r
1009\r
1010 if (EndPointer != NULL) {\r
2f88bd3a 1011 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
1012 }\r
1013\r
1014 //\r
1015 // Ignore the pad spaces (space or tab)\r
1016 //\r
1017 while ((*String == L' ') || (*String == L'\t')) {\r
1018 String++;\r
1019 }\r
1020\r
1021 //\r
1022 // Ignore leading Zeros after the spaces\r
1023 //\r
1024 while (*String == L'0') {\r
1025 String++;\r
1026 }\r
1027\r
5dbfa01e 1028 if (CharToUpper (*String) == L'X') {\r
d8af3301
HW
1029 if (*(String - 1) != L'0') {\r
1030 *Data = 0;\r
1031 return RETURN_SUCCESS;\r
1032 }\r
2f88bd3a 1033\r
d8af3301
HW
1034 //\r
1035 // Skip the 'X'\r
1036 //\r
1037 String++;\r
1038 }\r
1039\r
1040 *Data = 0;\r
1041\r
1042 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
1043 //\r
1044 // If the number represented by String overflows according to the range\r
1045 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
1046 // RETURN_UNSUPPORTED is returned.\r
1047 //\r
1048 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {\r
1049 *Data = MAX_UINT64;\r
1050 if (EndPointer != NULL) {\r
2f88bd3a 1051 *EndPointer = (CHAR16 *)String;\r
d8af3301 1052 }\r
2f88bd3a 1053\r
d8af3301
HW
1054 return RETURN_UNSUPPORTED;\r
1055 }\r
1056\r
1057 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);\r
1058 String++;\r
1059 }\r
1060\r
1061 if (EndPointer != NULL) {\r
2f88bd3a 1062 *EndPointer = (CHAR16 *)String;\r
d8af3301 1063 }\r
2f88bd3a 1064\r
d8af3301
HW
1065 return RETURN_SUCCESS;\r
1066}\r
1067\r
36396ea2
RN
1068/**\r
1069 Convert a Null-terminated Unicode string to IPv6 address and prefix length.\r
1070\r
1071 This function outputs a value of type IPv6_ADDRESS and may output a value\r
1072 of type UINT8 by interpreting the contents of the Unicode string specified\r
1073 by String. The format of the input Unicode string String is as follows:\r
1074\r
1075 X:X:X:X:X:X:X:X[/P]\r
1076\r
1077 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and\r
1078 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low\r
1079 memory address and high byte is stored in high memory address. P contains decimal\r
1080 digit characters in the range [0-9]. The running zero in the beginning of P will\r
1081 be ignored. /P is optional.\r
1082\r
1083 When /P is not in the String, the function stops at the first character that is\r
1084 not a valid hexadecimal digit character after eight X's are converted.\r
1085\r
1086 When /P is in the String, the function stops at the first character that is not\r
1087 a valid decimal digit character after P is converted.\r
1088\r
1089 "::" can be used to compress one or more groups of X when X contains only 0.\r
1090 The "::" can only appear once in the String.\r
1091\r
36396ea2
RN
1092 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1093\r
36396ea2
RN
1094 If EndPointer is not NULL and Address is translated from String, a pointer\r
1095 to the character that stopped the scan is stored at the location pointed to\r
1096 by EndPointer.\r
1097\r
1098 @param String Pointer to a Null-terminated Unicode string.\r
1099 @param EndPointer Pointer to character that stops scan.\r
1100 @param Address Pointer to the converted IPv6 address.\r
1101 @param PrefixLength Pointer to the converted IPv6 address prefix\r
1102 length. MAX_UINT8 is returned when /P is\r
1103 not in the String.\r
1104\r
1105 @retval RETURN_SUCCESS Address is translated from String.\r
1106 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1107 If Data is NULL.\r
1108 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal\r
1109 digit characters.\r
1110 If String contains "::" and number of X\r
1111 is not less than 8.\r
1112 If P starts with character that is not a\r
1113 valid decimal digit character.\r
1114 If the decimal number converted from P\r
1115 exceeds 128.\r
1116\r
1117**/\r
1118RETURN_STATUS\r
1119EFIAPI\r
1120StrToIpv6Address (\r
2f88bd3a
MK
1121 IN CONST CHAR16 *String,\r
1122 OUT CHAR16 **EndPointer OPTIONAL,\r
1123 OUT IPv6_ADDRESS *Address,\r
1124 OUT UINT8 *PrefixLength OPTIONAL\r
36396ea2
RN
1125 )\r
1126{\r
2f88bd3a
MK
1127 RETURN_STATUS Status;\r
1128 UINTN AddressIndex;\r
1129 UINTN Uintn;\r
1130 IPv6_ADDRESS LocalAddress;\r
1131 UINT8 LocalPrefixLength;\r
1132 CONST CHAR16 *Pointer;\r
1133 CHAR16 *End;\r
1134 UINTN CompressStart;\r
1135 BOOLEAN ExpectPrefix;\r
36396ea2
RN
1136\r
1137 LocalPrefixLength = MAX_UINT8;\r
1138 CompressStart = ARRAY_SIZE (Address->Addr);\r
1139 ExpectPrefix = FALSE;\r
1140\r
2f88bd3a 1141 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1142\r
1143 //\r
1144 // 1. None of String or Guid shall be a null pointer.\r
1145 //\r
1146 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1147 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
1148\r
1149 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
1150 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
1151 if (*Pointer != L':') {\r
1152 //\r
1153 // ":" or "/" should be followed by digit characters.\r
1154 //\r
1155 return RETURN_UNSUPPORTED;\r
1156 }\r
1157\r
1158 //\r
1159 // Meet second ":" after previous ":" or "/"\r
1160 // or meet first ":" in the beginning of String.\r
1161 //\r
1162 if (ExpectPrefix) {\r
1163 //\r
1164 // ":" shall not be after "/"\r
1165 //\r
1166 return RETURN_UNSUPPORTED;\r
1167 }\r
1168\r
2f88bd3a 1169 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {\r
36396ea2
RN
1170 //\r
1171 // "::" can only appear once.\r
1172 // "::" can only appear when address is not full length.\r
1173 //\r
1174 return RETURN_UNSUPPORTED;\r
1175 } else {\r
1176 //\r
1177 // Remember the start of zero compressing.\r
1178 //\r
1179 CompressStart = AddressIndex;\r
1180 Pointer++;\r
1181\r
1182 if (CompressStart == 0) {\r
1183 if (*Pointer != L':') {\r
1184 //\r
1185 // Single ":" shall not be in the beginning of String.\r
1186 //\r
1187 return RETURN_UNSUPPORTED;\r
1188 }\r
2f88bd3a 1189\r
36396ea2
RN
1190 Pointer++;\r
1191 }\r
1192 }\r
1193 }\r
1194\r
1195 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
1196 if (*Pointer == L'/') {\r
1197 //\r
1198 // Might be optional "/P" after "::".\r
1199 //\r
1200 if (CompressStart != AddressIndex) {\r
1201 return RETURN_UNSUPPORTED;\r
1202 }\r
1203 } else {\r
1204 break;\r
1205 }\r
1206 } else {\r
1207 if (!ExpectPrefix) {\r
1208 //\r
1209 // Get X.\r
1210 //\r
1211 Status = StrHexToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 1212 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {\r
36396ea2
RN
1213 //\r
1214 // Number of hexadecimal digit characters is no more than 4.\r
1215 //\r
1216 return RETURN_UNSUPPORTED;\r
1217 }\r
2f88bd3a 1218\r
36396ea2
RN
1219 Pointer = End;\r
1220 //\r
1221 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.\r
1222 //\r
5b0ce08a 1223 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));\r
2f88bd3a
MK
1224 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);\r
1225 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;\r
1226 AddressIndex += 2;\r
36396ea2
RN
1227 } else {\r
1228 //\r
1229 // Get P, then exit the loop.\r
1230 //\r
1231 Status = StrDecimalToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 1232 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {\r
36396ea2
RN
1233 //\r
1234 // Prefix length should not exceed 128.\r
1235 //\r
1236 return RETURN_UNSUPPORTED;\r
1237 }\r
2f88bd3a
MK
1238\r
1239 LocalPrefixLength = (UINT8)Uintn;\r
1240 Pointer = End;\r
36396ea2
RN
1241 break;\r
1242 }\r
1243 }\r
1244\r
1245 //\r
1246 // Skip ':' or "/"\r
1247 //\r
1248 if (*Pointer == L'/') {\r
1249 ExpectPrefix = TRUE;\r
1250 } else if (*Pointer == L':') {\r
1251 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1252 //\r
1253 // Meet additional ":" after all 8 16-bit address\r
1254 //\r
1255 break;\r
1256 }\r
1257 } else {\r
1258 //\r
1259 // Meet other character that is not "/" or ":" after all 8 16-bit address\r
1260 //\r
1261 break;\r
1262 }\r
2f88bd3a 1263\r
36396ea2
RN
1264 Pointer++;\r
1265 }\r
1266\r
2f88bd3a
MK
1267 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||\r
1268 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))\r
1269 )\r
1270 {\r
36396ea2
RN
1271 //\r
1272 // Full length of address shall not have compressing zeros.\r
1273 // Non-full length of address shall have compressing zeros.\r
1274 //\r
1275 return RETURN_UNSUPPORTED;\r
1276 }\r
2f88bd3a 1277\r
36396ea2
RN
1278 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);\r
1279 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);\r
5b0ce08a
RN
1280 if (AddressIndex > CompressStart) {\r
1281 CopyMem (\r
1282 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],\r
1283 &LocalAddress.Addr[CompressStart],\r
1284 AddressIndex - CompressStart\r
1285 );\r
1286 }\r
36396ea2
RN
1287\r
1288 if (PrefixLength != NULL) {\r
1289 *PrefixLength = LocalPrefixLength;\r
1290 }\r
2f88bd3a 1291\r
36396ea2 1292 if (EndPointer != NULL) {\r
2f88bd3a 1293 *EndPointer = (CHAR16 *)Pointer;\r
36396ea2
RN
1294 }\r
1295\r
1296 return RETURN_SUCCESS;\r
1297}\r
1298\r
1299/**\r
1300 Convert a Null-terminated Unicode string to IPv4 address and prefix length.\r
1301\r
1302 This function outputs a value of type IPv4_ADDRESS and may output a value\r
1303 of type UINT8 by interpreting the contents of the Unicode string specified\r
1304 by String. The format of the input Unicode string String is as follows:\r
1305\r
1306 D.D.D.D[/P]\r
1307\r
1308 D and P are decimal digit characters in the range [0-9]. The running zero in\r
1309 the beginning of D and P will be ignored. /P is optional.\r
1310\r
1311 When /P is not in the String, the function stops at the first character that is\r
1312 not a valid decimal digit character after four D's are converted.\r
1313\r
1314 When /P is in the String, the function stops at the first character that is not\r
1315 a valid decimal digit character after P is converted.\r
1316\r
36396ea2
RN
1317 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1318\r
36396ea2
RN
1319 If EndPointer is not NULL and Address is translated from String, a pointer\r
1320 to the character that stopped the scan is stored at the location pointed to\r
1321 by EndPointer.\r
1322\r
1323 @param String Pointer to a Null-terminated Unicode string.\r
1324 @param EndPointer Pointer to character that stops scan.\r
1325 @param Address Pointer to the converted IPv4 address.\r
1326 @param PrefixLength Pointer to the converted IPv4 address prefix\r
1327 length. MAX_UINT8 is returned when /P is\r
1328 not in the String.\r
1329\r
1330 @retval RETURN_SUCCESS Address is translated from String.\r
1331 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1332 If Data is NULL.\r
1333 @retval RETURN_UNSUPPORTED If String is not in the correct format.\r
1334 If any decimal number converted from D\r
1335 exceeds 255.\r
1336 If the decimal number converted from P\r
1337 exceeds 32.\r
1338\r
1339**/\r
1340RETURN_STATUS\r
1341EFIAPI\r
1342StrToIpv4Address (\r
2f88bd3a
MK
1343 IN CONST CHAR16 *String,\r
1344 OUT CHAR16 **EndPointer OPTIONAL,\r
1345 OUT IPv4_ADDRESS *Address,\r
1346 OUT UINT8 *PrefixLength OPTIONAL\r
36396ea2
RN
1347 )\r
1348{\r
2f88bd3a
MK
1349 RETURN_STATUS Status;\r
1350 UINTN AddressIndex;\r
1351 UINTN Uintn;\r
1352 IPv4_ADDRESS LocalAddress;\r
1353 UINT8 LocalPrefixLength;\r
1354 CHAR16 *Pointer;\r
36396ea2
RN
1355\r
1356 LocalPrefixLength = MAX_UINT8;\r
1357\r
2f88bd3a 1358 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1359\r
1360 //\r
1361 // 1. None of String or Guid shall be a null pointer.\r
1362 //\r
1363 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1364 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
1365\r
2f88bd3a 1366 for (Pointer = (CHAR16 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
36396ea2
RN
1367 if (!InternalIsDecimalDigitCharacter (*Pointer)) {\r
1368 //\r
1369 // D or P contains invalid characters.\r
1370 //\r
1371 break;\r
1372 }\r
1373\r
1374 //\r
1375 // Get D or P.\r
1376 //\r
2f88bd3a 1377 Status = StrDecimalToUintnS ((CONST CHAR16 *)Pointer, &Pointer, &Uintn);\r
36396ea2
RN
1378 if (RETURN_ERROR (Status)) {\r
1379 return RETURN_UNSUPPORTED;\r
1380 }\r
2f88bd3a 1381\r
36396ea2
RN
1382 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1383 //\r
1384 // It's P.\r
1385 //\r
1386 if (Uintn > 32) {\r
1387 return RETURN_UNSUPPORTED;\r
1388 }\r
2f88bd3a
MK
1389\r
1390 LocalPrefixLength = (UINT8)Uintn;\r
36396ea2
RN
1391 } else {\r
1392 //\r
1393 // It's D.\r
1394 //\r
1395 if (Uintn > MAX_UINT8) {\r
1396 return RETURN_UNSUPPORTED;\r
1397 }\r
2f88bd3a
MK
1398\r
1399 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;\r
36396ea2
RN
1400 AddressIndex++;\r
1401 }\r
1402\r
1403 //\r
1404 // Check the '.' or '/', depending on the AddressIndex.\r
1405 //\r
1406 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1407 if (*Pointer == L'/') {\r
1408 //\r
1409 // '/P' is in the String.\r
1410 // Skip "/" and get P in next loop.\r
1411 //\r
1412 Pointer++;\r
1413 } else {\r
1414 //\r
1415 // '/P' is not in the String.\r
1416 //\r
1417 break;\r
1418 }\r
1419 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
1420 if (*Pointer == L'.') {\r
1421 //\r
1422 // D should be followed by '.'\r
1423 //\r
1424 Pointer++;\r
1425 } else {\r
1426 return RETURN_UNSUPPORTED;\r
1427 }\r
1428 }\r
1429 }\r
1430\r
1431 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
1432 return RETURN_UNSUPPORTED;\r
1433 }\r
1434\r
1435 CopyMem (Address, &LocalAddress, sizeof (*Address));\r
1436 if (PrefixLength != NULL) {\r
1437 *PrefixLength = LocalPrefixLength;\r
1438 }\r
2f88bd3a 1439\r
36396ea2
RN
1440 if (EndPointer != NULL) {\r
1441 *EndPointer = Pointer;\r
1442 }\r
1443\r
1444 return RETURN_SUCCESS;\r
1445}\r
1446\r
1447/**\r
1448 Convert a Null-terminated Unicode GUID string to a value of type\r
1449 EFI_GUID.\r
1450\r
1451 This function outputs a GUID value by interpreting the contents of\r
1452 the Unicode string specified by String. The format of the input\r
1453 Unicode string String consists of 36 characters, as follows:\r
1454\r
1455 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\r
1456\r
1457 The pairs aa - pp are two characters in the range [0-9], [a-f] and\r
1458 [A-F], with each pair representing a single byte hexadecimal value.\r
1459\r
1460 The mapping between String and the EFI_GUID structure is as follows:\r
1461 aa Data1[24:31]\r
1462 bb Data1[16:23]\r
1463 cc Data1[8:15]\r
1464 dd Data1[0:7]\r
1465 ee Data2[8:15]\r
1466 ff Data2[0:7]\r
1467 gg Data3[8:15]\r
1468 hh Data3[0:7]\r
1469 ii Data4[0:7]\r
1470 jj Data4[8:15]\r
1471 kk Data4[16:23]\r
1472 ll Data4[24:31]\r
1473 mm Data4[32:39]\r
1474 nn Data4[40:47]\r
1475 oo Data4[48:55]\r
1476 pp Data4[56:63]\r
1477\r
36396ea2
RN
1478 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1479\r
1480 @param String Pointer to a Null-terminated Unicode string.\r
1481 @param Guid Pointer to the converted GUID.\r
1482\r
1483 @retval RETURN_SUCCESS Guid is translated from String.\r
1484 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1485 If Data is NULL.\r
1486 @retval RETURN_UNSUPPORTED If String is not as the above format.\r
1487\r
1488**/\r
1489RETURN_STATUS\r
1490EFIAPI\r
1491StrToGuid (\r
2f88bd3a
MK
1492 IN CONST CHAR16 *String,\r
1493 OUT GUID *Guid\r
36396ea2
RN
1494 )\r
1495{\r
2f88bd3a
MK
1496 RETURN_STATUS Status;\r
1497 GUID LocalGuid;\r
36396ea2 1498\r
2f88bd3a 1499 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1500\r
1501 //\r
1502 // 1. None of String or Guid shall be a null pointer.\r
1503 //\r
1504 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1505 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);\r
1506\r
1507 //\r
1508 // Get aabbccdd in big-endian.\r
1509 //\r
2f88bd3a
MK
1510 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));\r
1511 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != L'-')) {\r
36396ea2
RN
1512 return RETURN_UNSUPPORTED;\r
1513 }\r
2f88bd3a 1514\r
36396ea2
RN
1515 //\r
1516 // Convert big-endian to little-endian.\r
1517 //\r
1518 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);\r
2f88bd3a 1519 String += 2 * sizeof (LocalGuid.Data1) + 1;\r
36396ea2
RN
1520\r
1521 //\r
1522 // Get eeff in big-endian.\r
1523 //\r
2f88bd3a
MK
1524 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));\r
1525 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != L'-')) {\r
36396ea2
RN
1526 return RETURN_UNSUPPORTED;\r
1527 }\r
2f88bd3a 1528\r
36396ea2
RN
1529 //\r
1530 // Convert big-endian to little-endian.\r
1531 //\r
1532 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);\r
2f88bd3a 1533 String += 2 * sizeof (LocalGuid.Data2) + 1;\r
36396ea2
RN
1534\r
1535 //\r
1536 // Get gghh in big-endian.\r
1537 //\r
2f88bd3a
MK
1538 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));\r
1539 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != L'-')) {\r
36396ea2
RN
1540 return RETURN_UNSUPPORTED;\r
1541 }\r
2f88bd3a 1542\r
36396ea2
RN
1543 //\r
1544 // Convert big-endian to little-endian.\r
1545 //\r
1546 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);\r
2f88bd3a 1547 String += 2 * sizeof (LocalGuid.Data3) + 1;\r
36396ea2
RN
1548\r
1549 //\r
1550 // Get iijj.\r
1551 //\r
1552 Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);\r
2f88bd3a 1553 if (RETURN_ERROR (Status) || (String[2 * 2] != L'-')) {\r
36396ea2
RN
1554 return RETURN_UNSUPPORTED;\r
1555 }\r
2f88bd3a 1556\r
36396ea2
RN
1557 String += 2 * 2 + 1;\r
1558\r
1559 //\r
1560 // Get kkllmmnnoopp.\r
1561 //\r
1562 Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);\r
1563 if (RETURN_ERROR (Status)) {\r
1564 return RETURN_UNSUPPORTED;\r
1565 }\r
1566\r
1567 CopyGuid (Guid, &LocalGuid);\r
1568 return RETURN_SUCCESS;\r
1569}\r
1570\r
1571/**\r
1572 Convert a Null-terminated Unicode hexadecimal string to a byte array.\r
1573\r
1574 This function outputs a byte array by interpreting the contents of\r
1575 the Unicode string specified by String in hexadecimal format. The format of\r
1576 the input Unicode string String is:\r
1577\r
1578 [XX]*\r
1579\r
1580 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].\r
1581 The function decodes every two hexadecimal digit characters as one byte. The\r
1582 decoding stops after Length of characters and outputs Buffer containing\r
1583 (Length / 2) bytes.\r
1584\r
1585 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1586\r
36396ea2
RN
1587 @param String Pointer to a Null-terminated Unicode string.\r
1588 @param Length The number of Unicode characters to decode.\r
1589 @param Buffer Pointer to the converted bytes array.\r
1590 @param MaxBufferSize The maximum size of Buffer.\r
1591\r
1592 @retval RETURN_SUCCESS Buffer is translated from String.\r
1593 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1594 If Data is NULL.\r
1595 If Length is not multiple of 2.\r
1596 If PcdMaximumUnicodeStringLength is not zero,\r
1597 and Length is greater than\r
1598 PcdMaximumUnicodeStringLength.\r
1599 @retval RETURN_UNSUPPORTED If Length of characters from String contain\r
1600 a character that is not valid hexadecimal\r
1601 digit characters, or a Null-terminator.\r
1602 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).\r
1603**/\r
1604RETURN_STATUS\r
1605EFIAPI\r
1606StrHexToBytes (\r
2f88bd3a
MK
1607 IN CONST CHAR16 *String,\r
1608 IN UINTN Length,\r
1609 OUT UINT8 *Buffer,\r
1610 IN UINTN MaxBufferSize\r
36396ea2
RN
1611 )\r
1612{\r
2f88bd3a 1613 UINTN Index;\r
36396ea2 1614\r
2f88bd3a 1615 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1616\r
1617 //\r
1618 // 1. None of String or Buffer shall be a null pointer.\r
1619 //\r
1620 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1621 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
1622\r
1623 //\r
1624 // 2. Length shall not be greater than RSIZE_MAX.\r
1625 //\r
1626 if (RSIZE_MAX != 0) {\r
1627 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1628 }\r
1629\r
1630 //\r
1631 // 3. Length shall not be odd.\r
1632 //\r
1633 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);\r
1634\r
1635 //\r
1636 // 4. MaxBufferSize shall equal to or greater than Length / 2.\r
1637 //\r
1638 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);\r
1639\r
1640 //\r
1641 // 5. String shall not contains invalid hexadecimal digits.\r
1642 //\r
1643 for (Index = 0; Index < Length; Index++) {\r
1644 if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {\r
1645 break;\r
1646 }\r
1647 }\r
2f88bd3a 1648\r
36396ea2
RN
1649 if (Index != Length) {\r
1650 return RETURN_UNSUPPORTED;\r
1651 }\r
1652\r
1653 //\r
1654 // Convert the hex string to bytes.\r
1655 //\r
2f88bd3a 1656 for (Index = 0; Index < Length; Index++) {\r
36396ea2
RN
1657 //\r
1658 // For even characters, write the upper nibble for each buffer byte,\r
1659 // and for even characters, the lower nibble.\r
1660 //\r
1661 if ((Index & BIT0) == 0) {\r
2f88bd3a 1662 Buffer[Index / 2] = (UINT8)InternalHexCharToUintn (String[Index]) << 4;\r
36396ea2 1663 } else {\r
2f88bd3a 1664 Buffer[Index / 2] |= (UINT8)InternalHexCharToUintn (String[Index]);\r
36396ea2
RN
1665 }\r
1666 }\r
2f88bd3a 1667\r
36396ea2
RN
1668 return RETURN_SUCCESS;\r
1669}\r
1670\r
c058d59f
JY
1671/**\r
1672 Returns the length of a Null-terminated Ascii string.\r
1673\r
328f84b1
JY
1674 This function is similar as strlen_s defined in C11.\r
1675\r
c058d59f
JY
1676 @param String A pointer to a Null-terminated Ascii string.\r
1677 @param MaxSize The maximum number of Destination Ascii\r
1678 char, including terminating null char.\r
1679\r
1680 @retval 0 If String is NULL.\r
1681 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
1682 @return The number of characters that percede the terminating null character.\r
1683\r
1684**/\r
1685UINTN\r
1686EFIAPI\r
1687AsciiStrnLenS (\r
2f88bd3a
MK
1688 IN CONST CHAR8 *String,\r
1689 IN UINTN MaxSize\r
c058d59f
JY
1690 )\r
1691{\r
2f88bd3a 1692 UINTN Length;\r
c058d59f
JY
1693\r
1694 //\r
cb867499 1695 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.\r
c058d59f 1696 //\r
cb867499 1697 if ((String == NULL) || (MaxSize == 0)) {\r
c058d59f
JY
1698 return 0;\r
1699 }\r
1700\r
1701 //\r
1702 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the\r
1703 // terminating null character. If there is no null character in the first MaxSize characters of\r
1704 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
1705 // be accessed by AsciiStrnLenS.\r
1706 //\r
c07c517c
HW
1707 Length = 0;\r
1708 while (String[Length] != 0) {\r
1709 if (Length >= MaxSize - 1) {\r
1710 return MaxSize;\r
1711 }\r
2f88bd3a 1712\r
c07c517c 1713 Length++;\r
c058d59f 1714 }\r
2f88bd3a 1715\r
c058d59f
JY
1716 return Length;\r
1717}\r
1718\r
b590e43a
HW
1719/**\r
1720 Returns the size of a Null-terminated Ascii string in bytes, including the\r
1721 Null terminator.\r
1722\r
1723 This function returns the size of the Null-terminated Ascii string specified\r
1724 by String in bytes, including the Null terminator.\r
1725\r
1726 @param String A pointer to a Null-terminated Ascii string.\r
1727 @param MaxSize The maximum number of Destination Ascii\r
1728 char, including the Null terminator.\r
1729\r
1730 @retval 0 If String is NULL.\r
1731 @retval (sizeof (CHAR8) * (MaxSize + 1))\r
1732 If there is no Null terminator in the first MaxSize characters of\r
1733 String.\r
1734 @return The size of the Null-terminated Ascii string in bytes, including the\r
1735 Null terminator.\r
1736\r
1737**/\r
1738UINTN\r
1739EFIAPI\r
1740AsciiStrnSizeS (\r
2f88bd3a
MK
1741 IN CONST CHAR8 *String,\r
1742 IN UINTN MaxSize\r
b590e43a
HW
1743 )\r
1744{\r
1745 //\r
1746 // If String is a null pointer, then the AsciiStrnSizeS function returns\r
1747 // zero.\r
1748 //\r
1749 if (String == NULL) {\r
1750 return 0;\r
1751 }\r
1752\r
1753 //\r
1754 // Otherwise, the AsciiStrnSizeS function returns the size of the\r
1755 // Null-terminated Ascii string in bytes, including the Null terminator. If\r
1756 // there is no Null terminator in the first MaxSize characters of String,\r
1757 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a\r
1758 // consistent map with the AsciiStrnLenS function.\r
1759 //\r
1760 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
1761}\r
1762\r
c058d59f
JY
1763/**\r
1764 Copies the string pointed to by Source (including the terminating null char)\r
1765 to the array pointed to by Destination.\r
1766\r
328f84b1
JY
1767 This function is similar as strcpy_s defined in C11.\r
1768\r
328f84b1
JY
1769 If an error is returned, then the Destination is unmodified.\r
1770\r
c058d59f
JY
1771 @param Destination A pointer to a Null-terminated Ascii string.\r
1772 @param DestMax The maximum number of Destination Ascii\r
1773 char, including terminating null char.\r
1774 @param Source A pointer to a Null-terminated Ascii string.\r
1775\r
1776 @retval RETURN_SUCCESS String is copied.\r
1777 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
1778 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1779 If Source is NULL.\r
1780 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1781 and DestMax is greater than\r
c058d59f
JY
1782 PcdMaximumAsciiStringLength.\r
1783 If DestMax is 0.\r
1784 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1785**/\r
1786RETURN_STATUS\r
1787EFIAPI\r
1788AsciiStrCpyS (\r
1789 OUT CHAR8 *Destination,\r
1790 IN UINTN DestMax,\r
1791 IN CONST CHAR8 *Source\r
1792 )\r
1793{\r
2f88bd3a 1794 UINTN SourceLen;\r
973f8862 1795\r
c058d59f
JY
1796 //\r
1797 // 1. Neither Destination nor Source shall be a null pointer.\r
1798 //\r
1799 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1800 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1801\r
1802 //\r
1803 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1804 //\r
1805 if (ASCII_RSIZE_MAX != 0) {\r
1806 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1807 }\r
1808\r
1809 //\r
1810 // 3. DestMax shall not equal zero.\r
1811 //\r
1812 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1813\r
1814 //\r
1815 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1816 //\r
1817 SourceLen = AsciiStrnLenS (Source, DestMax);\r
1818 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1819\r
1820 //\r
1821 // 5. Copying shall not take place between objects that overlap.\r
1822 //\r
1823 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1824\r
1825 //\r
1826 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating\r
1827 // null character) into the array pointed to by Destination.\r
1828 //\r
1829 while (*Source != 0) {\r
1830 *(Destination++) = *(Source++);\r
1831 }\r
2f88bd3a 1832\r
c058d59f
JY
1833 *Destination = 0;\r
1834\r
1835 return RETURN_SUCCESS;\r
1836}\r
1837\r
1838/**\r
1839 Copies not more than Length successive char from the string pointed to by\r
1840 Source to the array pointed to by Destination. If no null char is copied from\r
1841 Source, then Destination[Length] is always set to null.\r
1842\r
328f84b1
JY
1843 This function is similar as strncpy_s defined in C11.\r
1844\r
328f84b1
JY
1845 If an error is returned, then the Destination is unmodified.\r
1846\r
c058d59f
JY
1847 @param Destination A pointer to a Null-terminated Ascii string.\r
1848 @param DestMax The maximum number of Destination Ascii\r
1849 char, including terminating null char.\r
1850 @param Source A pointer to a Null-terminated Ascii string.\r
1851 @param Length The maximum number of Ascii characters to copy.\r
1852\r
1853 @retval RETURN_SUCCESS String is copied.\r
973f8862 1854 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
c058d59f
JY
1855 MIN(StrLen(Source), Length).\r
1856 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1857 If Source is NULL.\r
1858 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1859 and DestMax is greater than\r
c058d59f
JY
1860 PcdMaximumAsciiStringLength.\r
1861 If DestMax is 0.\r
1862 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1863**/\r
1864RETURN_STATUS\r
1865EFIAPI\r
1866AsciiStrnCpyS (\r
1867 OUT CHAR8 *Destination,\r
1868 IN UINTN DestMax,\r
1869 IN CONST CHAR8 *Source,\r
1870 IN UINTN Length\r
1871 )\r
1872{\r
2f88bd3a 1873 UINTN SourceLen;\r
c058d59f
JY
1874\r
1875 //\r
1876 // 1. Neither Destination nor Source shall be a null pointer.\r
1877 //\r
1878 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1879 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1880\r
1881 //\r
1882 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX\r
1883 //\r
1884 if (ASCII_RSIZE_MAX != 0) {\r
1885 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1886 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1887 }\r
1888\r
1889 //\r
1890 // 3. DestMax shall not equal zero.\r
1891 //\r
1892 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1893\r
1894 //\r
1895 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1896 //\r
56658c22 1897 SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length));\r
c058d59f
JY
1898 if (Length >= DestMax) {\r
1899 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1900 }\r
1901\r
1902 //\r
1903 // 5. Copying shall not take place between objects that overlap.\r
1904 //\r
1905 if (SourceLen > Length) {\r
1906 SourceLen = Length;\r
1907 }\r
2f88bd3a 1908\r
c058d59f
JY
1909 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1910\r
1911 //\r
1912 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that\r
1913 // follow a null character are not copied) from the array pointed to by Source to the array\r
1914 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
1915 // character.\r
1916 //\r
56658c22 1917 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
1918 *(Destination++) = *(Source++);\r
1919 SourceLen--;\r
1920 }\r
2f88bd3a 1921\r
c058d59f
JY
1922 *Destination = 0;\r
1923\r
1924 return RETURN_SUCCESS;\r
1925}\r
1926\r
1927/**\r
1928 Appends a copy of the string pointed to by Source (including the terminating\r
1929 null char) to the end of the string pointed to by Destination.\r
1930\r
328f84b1
JY
1931 This function is similar as strcat_s defined in C11.\r
1932\r
328f84b1
JY
1933 If an error is returned, then the Destination is unmodified.\r
1934\r
c058d59f
JY
1935 @param Destination A pointer to a Null-terminated Ascii string.\r
1936 @param DestMax The maximum number of Destination Ascii\r
1937 char, including terminating null char.\r
1938 @param Source A pointer to a Null-terminated Ascii string.\r
1939\r
1940 @retval RETURN_SUCCESS String is appended.\r
973f8862 1941 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
c058d59f
JY
1942 StrLen(Destination).\r
1943 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
1944 greater than StrLen(Source).\r
1945 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1946 If Source is NULL.\r
1947 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1948 and DestMax is greater than\r
c058d59f
JY
1949 PcdMaximumAsciiStringLength.\r
1950 If DestMax is 0.\r
1951 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1952**/\r
1953RETURN_STATUS\r
1954EFIAPI\r
1955AsciiStrCatS (\r
1956 IN OUT CHAR8 *Destination,\r
1957 IN UINTN DestMax,\r
1958 IN CONST CHAR8 *Source\r
1959 )\r
1960{\r
2f88bd3a
MK
1961 UINTN DestLen;\r
1962 UINTN CopyLen;\r
1963 UINTN SourceLen;\r
973f8862 1964\r
c058d59f
JY
1965 //\r
1966 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.\r
1967 //\r
1968 DestLen = AsciiStrnLenS (Destination, DestMax);\r
1969 CopyLen = DestMax - DestLen;\r
1970\r
1971 //\r
1972 // 1. Neither Destination nor Source shall be a null pointer.\r
1973 //\r
1974 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1975 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1976\r
1977 //\r
1978 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1979 //\r
1980 if (ASCII_RSIZE_MAX != 0) {\r
1981 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1982 }\r
1983\r
1984 //\r
1985 // 3. DestMax shall not equal zero.\r
1986 //\r
1987 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1988\r
1989 //\r
1990 // 4. CopyLen shall not equal zero.\r
1991 //\r
1992 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
1993\r
1994 //\r
1995 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
1996 //\r
1997 SourceLen = AsciiStrnLenS (Source, CopyLen);\r
1998 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1999\r
2000 //\r
2001 // 6. Copying shall not take place between objects that overlap.\r
2002 //\r
2003 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2004\r
2005 //\r
2006 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the\r
2007 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
2008 // from Source overwrites the null character at the end of Destination.\r
2009 //\r
2010 Destination = Destination + DestLen;\r
2011 while (*Source != 0) {\r
2012 *(Destination++) = *(Source++);\r
2013 }\r
2f88bd3a 2014\r
c058d59f
JY
2015 *Destination = 0;\r
2016\r
2017 return RETURN_SUCCESS;\r
2018}\r
2019\r
2020/**\r
2021 Appends not more than Length successive char from the string pointed to by\r
2022 Source to the end of the string pointed to by Destination. If no null char is\r
2023 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
2024 set to null.\r
2025\r
328f84b1
JY
2026 This function is similar as strncat_s defined in C11.\r
2027\r
328f84b1
JY
2028 If an error is returned, then the Destination is unmodified.\r
2029\r
c058d59f
JY
2030 @param Destination A pointer to a Null-terminated Ascii string.\r
2031 @param DestMax The maximum number of Destination Ascii\r
2032 char, including terminating null char.\r
2033 @param Source A pointer to a Null-terminated Ascii string.\r
2034 @param Length The maximum number of Ascii characters to copy.\r
2035\r
2036 @retval RETURN_SUCCESS String is appended.\r
2037 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
2038 StrLen(Destination).\r
2039 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
2040 greater than MIN(StrLen(Source), Length).\r
2041 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2042 If Source is NULL.\r
2043 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 2044 and DestMax is greater than\r
c058d59f
JY
2045 PcdMaximumAsciiStringLength.\r
2046 If DestMax is 0.\r
2047 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2048**/\r
2049RETURN_STATUS\r
2050EFIAPI\r
2051AsciiStrnCatS (\r
2052 IN OUT CHAR8 *Destination,\r
2053 IN UINTN DestMax,\r
2054 IN CONST CHAR8 *Source,\r
2055 IN UINTN Length\r
2056 )\r
2057{\r
2f88bd3a
MK
2058 UINTN DestLen;\r
2059 UINTN CopyLen;\r
2060 UINTN SourceLen;\r
973f8862 2061\r
c058d59f
JY
2062 //\r
2063 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.\r
2064 //\r
2065 DestLen = AsciiStrnLenS (Destination, DestMax);\r
2066 CopyLen = DestMax - DestLen;\r
2067\r
2068 //\r
2069 // 1. Neither Destination nor Source shall be a null pointer.\r
2070 //\r
2071 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2072 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2073\r
2074 //\r
2075 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.\r
2076 //\r
2077 if (ASCII_RSIZE_MAX != 0) {\r
2078 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2079 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2080 }\r
2081\r
2082 //\r
2083 // 3. DestMax shall not equal zero.\r
2084 //\r
2085 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2086\r
2087 //\r
2088 // 4. CopyLen shall not equal zero.\r
2089 //\r
2090 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
2091\r
2092 //\r
2093 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
2094 //\r
56658c22 2095 SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length));\r
c058d59f
JY
2096 if (Length >= CopyLen) {\r
2097 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2098 }\r
2099\r
2100 //\r
2101 // 6. Copying shall not take place between objects that overlap.\r
2102 //\r
2103 if (SourceLen > Length) {\r
2104 SourceLen = Length;\r
2105 }\r
2f88bd3a 2106\r
c058d59f
JY
2107 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2108\r
2109 //\r
2110 // The AsciiStrnCatS function appends not more than Length successive characters (characters\r
2111 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
2112 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
2113 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
2114 // a null character.\r
2115 //\r
2116 Destination = Destination + DestLen;\r
56658c22 2117 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
2118 *(Destination++) = *(Source++);\r
2119 SourceLen--;\r
2120 }\r
2f88bd3a 2121\r
c058d59f
JY
2122 *Destination = 0;\r
2123\r
d8af3301
HW
2124 return RETURN_SUCCESS;\r
2125}\r
2126\r
2127/**\r
2128 Convert a Null-terminated Ascii decimal string to a value of type UINTN.\r
2129\r
2130 This function outputs a value of type UINTN by interpreting the contents of\r
2131 the Ascii string specified by String as a decimal number. The format of the\r
2132 input Ascii string String is:\r
2133\r
2134 [spaces] [decimal digits].\r
2135\r
2136 The valid decimal digit character is in the range [0-9]. The function will\r
2137 ignore the pad space, which includes spaces or tab characters, before\r
2138 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
2139 be ignored. Then, the function stops at the first character that is a not a\r
2140 valid decimal character or a Null-terminator, whichever one comes first.\r
2141\r
d8af3301
HW
2142 If String has no valid decimal digits in the above format, then 0 is stored\r
2143 at the location pointed to by Data.\r
2144 If the number represented by String exceeds the range defined by UINTN, then\r
2145 MAX_UINTN is stored at the location pointed to by Data.\r
2146\r
2147 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2148 is stored at the location pointed to by EndPointer. If String has no valid\r
2149 decimal digits right after the optional pad spaces, the value of String is\r
2150 stored at the location pointed to by EndPointer.\r
2151\r
2152 @param String Pointer to a Null-terminated Ascii string.\r
2153 @param EndPointer Pointer to character that stops scan.\r
2154 @param Data Pointer to the converted value.\r
2155\r
2156 @retval RETURN_SUCCESS Value is translated from String.\r
2157 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2158 If Data is NULL.\r
2159 If PcdMaximumAsciiStringLength is not zero,\r
2160 and String contains more than\r
2161 PcdMaximumAsciiStringLength Ascii\r
2162 characters, not including the\r
2163 Null-terminator.\r
2164 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2165 the range defined by UINTN.\r
2166\r
2167**/\r
2168RETURN_STATUS\r
2169EFIAPI\r
2170AsciiStrDecimalToUintnS (\r
2f88bd3a
MK
2171 IN CONST CHAR8 *String,\r
2172 OUT CHAR8 **EndPointer OPTIONAL,\r
2173 OUT UINTN *Data\r
d8af3301
HW
2174 )\r
2175{\r
2176 //\r
2177 // 1. Neither String nor Data shall be a null pointer.\r
2178 //\r
2179 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2180 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2181\r
2182 //\r
2183 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2184 //\r
2185 if (ASCII_RSIZE_MAX != 0) {\r
2186 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2187 }\r
2188\r
2189 if (EndPointer != NULL) {\r
2f88bd3a 2190 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2191 }\r
2192\r
2193 //\r
2194 // Ignore the pad spaces (space or tab)\r
2195 //\r
2196 while ((*String == ' ') || (*String == '\t')) {\r
2197 String++;\r
2198 }\r
2199\r
2200 //\r
2201 // Ignore leading Zeros after the spaces\r
2202 //\r
2203 while (*String == '0') {\r
2204 String++;\r
2205 }\r
2206\r
2207 *Data = 0;\r
2208\r
2209 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
2210 //\r
2211 // If the number represented by String overflows according to the range\r
2212 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
2213 // RETURN_UNSUPPORTED is returned.\r
2214 //\r
2215 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {\r
2216 *Data = MAX_UINTN;\r
2217 if (EndPointer != NULL) {\r
2f88bd3a 2218 *EndPointer = (CHAR8 *)String;\r
d8af3301 2219 }\r
2f88bd3a 2220\r
d8af3301
HW
2221 return RETURN_UNSUPPORTED;\r
2222 }\r
2223\r
2224 *Data = *Data * 10 + (*String - '0');\r
2225 String++;\r
2226 }\r
2227\r
2228 if (EndPointer != NULL) {\r
2f88bd3a 2229 *EndPointer = (CHAR8 *)String;\r
d8af3301 2230 }\r
2f88bd3a 2231\r
d8af3301
HW
2232 return RETURN_SUCCESS;\r
2233}\r
2234\r
2235/**\r
2236 Convert a Null-terminated Ascii decimal string to a value of type UINT64.\r
2237\r
2238 This function outputs a value of type UINT64 by interpreting the contents of\r
2239 the Ascii string specified by String as a decimal number. The format of the\r
2240 input Ascii string String is:\r
2241\r
2242 [spaces] [decimal digits].\r
2243\r
2244 The valid decimal digit character is in the range [0-9]. The function will\r
2245 ignore the pad space, which includes spaces or tab characters, before\r
2246 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
2247 be ignored. Then, the function stops at the first character that is a not a\r
2248 valid decimal character or a Null-terminator, whichever one comes first.\r
2249\r
d8af3301
HW
2250 If String has no valid decimal digits in the above format, then 0 is stored\r
2251 at the location pointed to by Data.\r
2252 If the number represented by String exceeds the range defined by UINT64, then\r
2253 MAX_UINT64 is stored at the location pointed to by Data.\r
2254\r
2255 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2256 is stored at the location pointed to by EndPointer. If String has no valid\r
2257 decimal digits right after the optional pad spaces, the value of String is\r
2258 stored at the location pointed to by EndPointer.\r
2259\r
2260 @param String Pointer to a Null-terminated Ascii string.\r
2261 @param EndPointer Pointer to character that stops scan.\r
2262 @param Data Pointer to the converted value.\r
2263\r
2264 @retval RETURN_SUCCESS Value is translated from String.\r
2265 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2266 If Data is NULL.\r
2267 If PcdMaximumAsciiStringLength is not zero,\r
2268 and String contains more than\r
2269 PcdMaximumAsciiStringLength Ascii\r
2270 characters, not including the\r
2271 Null-terminator.\r
2272 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2273 the range defined by UINT64.\r
2274\r
2275**/\r
2276RETURN_STATUS\r
2277EFIAPI\r
2278AsciiStrDecimalToUint64S (\r
2f88bd3a
MK
2279 IN CONST CHAR8 *String,\r
2280 OUT CHAR8 **EndPointer OPTIONAL,\r
2281 OUT UINT64 *Data\r
d8af3301
HW
2282 )\r
2283{\r
2284 //\r
2285 // 1. Neither String nor Data shall be a null pointer.\r
2286 //\r
2287 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2288 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2289\r
2290 //\r
2291 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2292 //\r
2293 if (ASCII_RSIZE_MAX != 0) {\r
2294 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2295 }\r
2296\r
2297 if (EndPointer != NULL) {\r
2f88bd3a 2298 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2299 }\r
2300\r
2301 //\r
2302 // Ignore the pad spaces (space or tab)\r
2303 //\r
2304 while ((*String == ' ') || (*String == '\t')) {\r
2305 String++;\r
2306 }\r
2307\r
2308 //\r
2309 // Ignore leading Zeros after the spaces\r
2310 //\r
2311 while (*String == '0') {\r
2312 String++;\r
2313 }\r
2314\r
2315 *Data = 0;\r
2316\r
2317 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
2318 //\r
2319 // If the number represented by String overflows according to the range\r
2320 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
2321 // RETURN_UNSUPPORTED is returned.\r
2322 //\r
2323 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {\r
2324 *Data = MAX_UINT64;\r
2325 if (EndPointer != NULL) {\r
2f88bd3a 2326 *EndPointer = (CHAR8 *)String;\r
d8af3301 2327 }\r
2f88bd3a 2328\r
d8af3301
HW
2329 return RETURN_UNSUPPORTED;\r
2330 }\r
2331\r
2332 *Data = MultU64x32 (*Data, 10) + (*String - '0');\r
2333 String++;\r
2334 }\r
2335\r
2336 if (EndPointer != NULL) {\r
2f88bd3a 2337 *EndPointer = (CHAR8 *)String;\r
d8af3301 2338 }\r
2f88bd3a 2339\r
d8af3301
HW
2340 return RETURN_SUCCESS;\r
2341}\r
2342\r
2343/**\r
2344 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.\r
2345\r
2346 This function outputs a value of type UINTN by interpreting the contents of\r
2347 the Ascii string specified by String as a hexadecimal number. The format of\r
2348 the input Ascii string String is:\r
2349\r
2350 [spaces][zeros][x][hexadecimal digits].\r
2351\r
2352 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
2353 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
2354 "x" appears in the input string, it must be prefixed with at least one 0. The\r
2355 function will ignore the pad space, which includes spaces or tab characters,\r
2356 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
2357 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
2358 the first valid hexadecimal digit. Then, the function stops at the first\r
2359 character that is a not a valid hexadecimal character or Null-terminator,\r
2360 whichever on comes first.\r
2361\r
d8af3301
HW
2362 If String has no valid hexadecimal digits in the above format, then 0 is\r
2363 stored at the location pointed to by Data.\r
2364 If the number represented by String exceeds the range defined by UINTN, then\r
2365 MAX_UINTN is stored at the location pointed to by Data.\r
2366\r
2367 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2368 is stored at the location pointed to by EndPointer. If String has no valid\r
2369 hexadecimal digits right after the optional pad spaces, the value of String\r
2370 is stored at the location pointed to by EndPointer.\r
2371\r
2372 @param String Pointer to a Null-terminated Ascii string.\r
2373 @param EndPointer Pointer to character that stops scan.\r
2374 @param Data Pointer to the converted value.\r
2375\r
2376 @retval RETURN_SUCCESS Value is translated from String.\r
2377 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2378 If Data is NULL.\r
2379 If PcdMaximumAsciiStringLength is not zero,\r
2380 and String contains more than\r
2381 PcdMaximumAsciiStringLength Ascii\r
2382 characters, not including the\r
2383 Null-terminator.\r
2384 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2385 the range defined by UINTN.\r
2386\r
2387**/\r
2388RETURN_STATUS\r
2389EFIAPI\r
2390AsciiStrHexToUintnS (\r
2f88bd3a
MK
2391 IN CONST CHAR8 *String,\r
2392 OUT CHAR8 **EndPointer OPTIONAL,\r
2393 OUT UINTN *Data\r
d8af3301
HW
2394 )\r
2395{\r
2396 //\r
2397 // 1. Neither String nor Data shall be a null pointer.\r
2398 //\r
2399 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2400 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2401\r
2402 //\r
2403 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2404 //\r
2405 if (ASCII_RSIZE_MAX != 0) {\r
2406 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2407 }\r
2408\r
2409 if (EndPointer != NULL) {\r
2f88bd3a 2410 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2411 }\r
2412\r
2413 //\r
2414 // Ignore the pad spaces (space or tab)\r
2415 //\r
2416 while ((*String == ' ') || (*String == '\t')) {\r
2417 String++;\r
2418 }\r
2419\r
2420 //\r
2421 // Ignore leading Zeros after the spaces\r
2422 //\r
2423 while (*String == '0') {\r
2424 String++;\r
2425 }\r
2426\r
5dbfa01e 2427 if (AsciiCharToUpper (*String) == 'X') {\r
d8af3301
HW
2428 if (*(String - 1) != '0') {\r
2429 *Data = 0;\r
2430 return RETURN_SUCCESS;\r
2431 }\r
2f88bd3a 2432\r
d8af3301
HW
2433 //\r
2434 // Skip the 'X'\r
2435 //\r
2436 String++;\r
2437 }\r
2438\r
2439 *Data = 0;\r
2440\r
2441 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
2442 //\r
2443 // If the number represented by String overflows according to the range\r
2444 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
2445 // RETURN_UNSUPPORTED is returned.\r
2446 //\r
2447 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {\r
2448 *Data = MAX_UINTN;\r
2449 if (EndPointer != NULL) {\r
2f88bd3a 2450 *EndPointer = (CHAR8 *)String;\r
d8af3301 2451 }\r
2f88bd3a 2452\r
d8af3301
HW
2453 return RETURN_UNSUPPORTED;\r
2454 }\r
2455\r
2456 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);\r
2457 String++;\r
2458 }\r
2459\r
2460 if (EndPointer != NULL) {\r
2f88bd3a 2461 *EndPointer = (CHAR8 *)String;\r
d8af3301 2462 }\r
2f88bd3a 2463\r
d8af3301
HW
2464 return RETURN_SUCCESS;\r
2465}\r
2466\r
2467/**\r
2468 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.\r
2469\r
2470 This function outputs a value of type UINT64 by interpreting the contents of\r
2471 the Ascii string specified by String as a hexadecimal number. The format of\r
2472 the input Ascii string String is:\r
2473\r
2474 [spaces][zeros][x][hexadecimal digits].\r
2475\r
2476 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
2477 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
2478 "x" appears in the input string, it must be prefixed with at least one 0. The\r
2479 function will ignore the pad space, which includes spaces or tab characters,\r
2480 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
2481 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
2482 the first valid hexadecimal digit. Then, the function stops at the first\r
2483 character that is a not a valid hexadecimal character or Null-terminator,\r
2484 whichever on comes first.\r
2485\r
d8af3301
HW
2486 If String has no valid hexadecimal digits in the above format, then 0 is\r
2487 stored at the location pointed to by Data.\r
2488 If the number represented by String exceeds the range defined by UINT64, then\r
2489 MAX_UINT64 is stored at the location pointed to by Data.\r
2490\r
2491 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2492 is stored at the location pointed to by EndPointer. If String has no valid\r
2493 hexadecimal digits right after the optional pad spaces, the value of String\r
2494 is stored at the location pointed to by EndPointer.\r
2495\r
2496 @param String Pointer to a Null-terminated Ascii string.\r
2497 @param EndPointer Pointer to character that stops scan.\r
2498 @param Data Pointer to the converted value.\r
2499\r
2500 @retval RETURN_SUCCESS Value is translated from String.\r
2501 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2502 If Data is NULL.\r
2503 If PcdMaximumAsciiStringLength is not zero,\r
2504 and String contains more than\r
2505 PcdMaximumAsciiStringLength Ascii\r
2506 characters, not including the\r
2507 Null-terminator.\r
2508 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2509 the range defined by UINT64.\r
2510\r
2511**/\r
2512RETURN_STATUS\r
2513EFIAPI\r
2514AsciiStrHexToUint64S (\r
2f88bd3a
MK
2515 IN CONST CHAR8 *String,\r
2516 OUT CHAR8 **EndPointer OPTIONAL,\r
2517 OUT UINT64 *Data\r
d8af3301
HW
2518 )\r
2519{\r
2520 //\r
2521 // 1. Neither String nor Data shall be a null pointer.\r
2522 //\r
2523 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2524 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2525\r
2526 //\r
2527 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2528 //\r
2529 if (ASCII_RSIZE_MAX != 0) {\r
2530 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2531 }\r
2532\r
2533 if (EndPointer != NULL) {\r
2f88bd3a 2534 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2535 }\r
2536\r
2537 //\r
2538 // Ignore the pad spaces (space or tab)\r
2539 //\r
2540 while ((*String == ' ') || (*String == '\t')) {\r
2541 String++;\r
2542 }\r
2543\r
2544 //\r
2545 // Ignore leading Zeros after the spaces\r
2546 //\r
2547 while (*String == '0') {\r
2548 String++;\r
2549 }\r
2550\r
5dbfa01e 2551 if (AsciiCharToUpper (*String) == 'X') {\r
d8af3301
HW
2552 if (*(String - 1) != '0') {\r
2553 *Data = 0;\r
2554 return RETURN_SUCCESS;\r
2555 }\r
2f88bd3a 2556\r
d8af3301
HW
2557 //\r
2558 // Skip the 'X'\r
2559 //\r
2560 String++;\r
2561 }\r
2562\r
2563 *Data = 0;\r
2564\r
2565 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
2566 //\r
2567 // If the number represented by String overflows according to the range\r
2568 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
2569 // RETURN_UNSUPPORTED is returned.\r
2570 //\r
2571 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {\r
2572 *Data = MAX_UINT64;\r
2573 if (EndPointer != NULL) {\r
2f88bd3a 2574 *EndPointer = (CHAR8 *)String;\r
d8af3301 2575 }\r
2f88bd3a 2576\r
d8af3301
HW
2577 return RETURN_UNSUPPORTED;\r
2578 }\r
2579\r
2580 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);\r
2581 String++;\r
2582 }\r
2583\r
2584 if (EndPointer != NULL) {\r
2f88bd3a 2585 *EndPointer = (CHAR8 *)String;\r
d8af3301 2586 }\r
2f88bd3a 2587\r
c058d59f
JY
2588 return RETURN_SUCCESS;\r
2589}\r
3ab41b7a
JY
2590\r
2591/**\r
2592 Convert a Null-terminated Unicode string to a Null-terminated\r
2593 ASCII string.\r
2594\r
2595 This function is similar to AsciiStrCpyS.\r
2596\r
2597 This function converts the content of the Unicode string Source\r
2598 to the ASCII string Destination by copying the lower 8 bits of\r
2599 each Unicode character. The function terminates the ASCII string\r
2600 Destination by appending a Null-terminator character at the end.\r
2601\r
2602 The caller is responsible to make sure Destination points to a buffer with size\r
2603 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.\r
2604\r
2605 If any Unicode characters in Source contain non-zero value in\r
2606 the upper 8 bits, then ASSERT().\r
2607\r
2608 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
3ab41b7a
JY
2609\r
2610 If an error is returned, then the Destination is unmodified.\r
2611\r
2612 @param Source The pointer to a Null-terminated Unicode string.\r
2613 @param Destination The pointer to a Null-terminated ASCII string.\r
2614 @param DestMax The maximum number of Destination Ascii\r
2615 char, including terminating null char.\r
2616\r
2617 @retval RETURN_SUCCESS String is converted.\r
2618 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2619 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2620 If Source is NULL.\r
2621 If PcdMaximumAsciiStringLength is not zero,\r
2622 and DestMax is greater than\r
2623 PcdMaximumAsciiStringLength.\r
2624 If PcdMaximumUnicodeStringLength is not zero,\r
2625 and DestMax is greater than\r
2626 PcdMaximumUnicodeStringLength.\r
2627 If DestMax is 0.\r
2628 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2629\r
2630**/\r
2631RETURN_STATUS\r
2632EFIAPI\r
2633UnicodeStrToAsciiStrS (\r
2f88bd3a
MK
2634 IN CONST CHAR16 *Source,\r
2635 OUT CHAR8 *Destination,\r
2636 IN UINTN DestMax\r
3ab41b7a
JY
2637 )\r
2638{\r
2f88bd3a 2639 UINTN SourceLen;\r
3ab41b7a 2640\r
2f88bd3a 2641 ASSERT (((UINTN)Source & BIT0) == 0);\r
3ab41b7a
JY
2642\r
2643 //\r
2644 // 1. Neither Destination nor Source shall be a null pointer.\r
2645 //\r
2646 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2647 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2648\r
2649 //\r
2650 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.\r
2651 //\r
2652 if (ASCII_RSIZE_MAX != 0) {\r
2653 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2654 }\r
2f88bd3a 2655\r
3ab41b7a
JY
2656 if (RSIZE_MAX != 0) {\r
2657 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2658 }\r
2659\r
2660 //\r
2661 // 3. DestMax shall not equal zero.\r
2662 //\r
2663 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2664\r
2665 //\r
2666 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).\r
2667 //\r
2668 SourceLen = StrnLenS (Source, DestMax);\r
2669 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2670\r
2671 //\r
2672 // 5. Copying shall not take place between objects that overlap.\r
2673 //\r
2f88bd3a 2674 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);\r
3ab41b7a
JY
2675\r
2676 //\r
2677 // convert string\r
2678 //\r
2679 while (*Source != '\0') {\r
2680 //\r
2681 // If any Unicode characters in Source contain\r
2682 // non-zero value in the upper 8 bits, then ASSERT().\r
2683 //\r
2684 ASSERT (*Source < 0x100);\r
2f88bd3a 2685 *(Destination++) = (CHAR8)*(Source++);\r
3ab41b7a 2686 }\r
2f88bd3a 2687\r
3ab41b7a
JY
2688 *Destination = '\0';\r
2689\r
2690 return RETURN_SUCCESS;\r
2691}\r
2692\r
02263214
HW
2693/**\r
2694 Convert not more than Length successive characters from a Null-terminated\r
2695 Unicode string to a Null-terminated Ascii string. If no null char is copied\r
2696 from Source, then Destination[Length] is always set to null.\r
2697\r
2698 This function converts not more than Length successive characters from the\r
2699 Unicode string Source to the Ascii string Destination by copying the lower 8\r
2700 bits of each Unicode character. The function terminates the Ascii string\r
2701 Destination by appending a Null-terminator character at the end.\r
2702\r
2703 The caller is responsible to make sure Destination points to a buffer with\r
2704 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))\r
2705 in bytes.\r
2706\r
2707 If any Unicode characters in Source contain non-zero value in the upper 8\r
2708 bits, then ASSERT().\r
2709 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
02263214
HW
2710\r
2711 If an error is returned, then Destination and DestinationLength are\r
2712 unmodified.\r
2713\r
2714 @param Source The pointer to a Null-terminated Unicode string.\r
2715 @param Length The maximum number of Unicode characters to\r
2716 convert.\r
2717 @param Destination The pointer to a Null-terminated Ascii string.\r
2718 @param DestMax The maximum number of Destination Ascii char,\r
2719 including terminating null char.\r
2720 @param DestinationLength The number of Unicode characters converted.\r
2721\r
2722 @retval RETURN_SUCCESS String is converted.\r
2723 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2724 If Source is NULL.\r
2725 If DestinationLength is NULL.\r
2726 If PcdMaximumAsciiStringLength is not zero,\r
2727 and Length or DestMax is greater than\r
2728 PcdMaximumAsciiStringLength.\r
2729 If PcdMaximumUnicodeStringLength is not\r
2730 zero, and Length or DestMax is greater than\r
2731 PcdMaximumUnicodeStringLength.\r
2732 If DestMax is 0.\r
2733 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2734 MIN(StrLen(Source), Length).\r
2735 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2736\r
2737**/\r
2738RETURN_STATUS\r
2739EFIAPI\r
2740UnicodeStrnToAsciiStrS (\r
2f88bd3a
MK
2741 IN CONST CHAR16 *Source,\r
2742 IN UINTN Length,\r
2743 OUT CHAR8 *Destination,\r
2744 IN UINTN DestMax,\r
2745 OUT UINTN *DestinationLength\r
02263214
HW
2746 )\r
2747{\r
2f88bd3a 2748 UINTN SourceLen;\r
02263214 2749\r
2f88bd3a 2750 ASSERT (((UINTN)Source & BIT0) == 0);\r
02263214
HW
2751\r
2752 //\r
2753 // 1. None of Destination, Source or DestinationLength shall be a null\r
2754 // pointer.\r
2755 //\r
2756 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2757 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2758 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
2759\r
2760 //\r
2761 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
2762 // RSIZE_MAX.\r
2763 //\r
2764 if (ASCII_RSIZE_MAX != 0) {\r
2765 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2766 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2767 }\r
2f88bd3a 2768\r
02263214
HW
2769 if (RSIZE_MAX != 0) {\r
2770 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2771 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2772 }\r
2773\r
2774 //\r
2775 // 3. DestMax shall not equal zero.\r
2776 //\r
2777 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2778\r
2779 //\r
2780 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
2781 // StrnLenS(Source, DestMax).\r
2782 //\r
2783 SourceLen = StrnLenS (Source, DestMax);\r
2784 if (Length >= DestMax) {\r
2785 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2786 }\r
2787\r
2788 //\r
2789 // 5. Copying shall not take place between objects that overlap.\r
2790 //\r
2791 if (SourceLen > Length) {\r
2792 SourceLen = Length;\r
2793 }\r
2f88bd3a
MK
2794\r
2795 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);\r
02263214
HW
2796\r
2797 *DestinationLength = 0;\r
2798\r
2799 //\r
2800 // Convert string\r
2801 //\r
2802 while ((*Source != 0) && (SourceLen > 0)) {\r
2803 //\r
2804 // If any Unicode characters in Source contain non-zero value in the upper\r
2805 // 8 bits, then ASSERT().\r
2806 //\r
2807 ASSERT (*Source < 0x100);\r
2f88bd3a 2808 *(Destination++) = (CHAR8)*(Source++);\r
02263214
HW
2809 SourceLen--;\r
2810 (*DestinationLength)++;\r
2811 }\r
2f88bd3a 2812\r
02263214
HW
2813 *Destination = 0;\r
2814\r
2815 return RETURN_SUCCESS;\r
2816}\r
3ab41b7a
JY
2817\r
2818/**\r
2819 Convert one Null-terminated ASCII string to a Null-terminated\r
2820 Unicode string.\r
2821\r
2822 This function is similar to StrCpyS.\r
2823\r
2824 This function converts the contents of the ASCII string Source to the Unicode\r
2825 string Destination. The function terminates the Unicode string Destination by\r
2826 appending a Null-terminator character at the end.\r
2827\r
2828 The caller is responsible to make sure Destination points to a buffer with size\r
2829 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
2830\r
2831 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
3ab41b7a
JY
2832\r
2833 If an error is returned, then the Destination is unmodified.\r
2834\r
2835 @param Source The pointer to a Null-terminated ASCII string.\r
2836 @param Destination The pointer to a Null-terminated Unicode string.\r
2837 @param DestMax The maximum number of Destination Unicode\r
2838 char, including terminating null char.\r
2839\r
2840 @retval RETURN_SUCCESS String is converted.\r
2841 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2842 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2843 If Source is NULL.\r
2844 If PcdMaximumUnicodeStringLength is not zero,\r
2845 and DestMax is greater than\r
2846 PcdMaximumUnicodeStringLength.\r
2847 If PcdMaximumAsciiStringLength is not zero,\r
2848 and DestMax is greater than\r
2849 PcdMaximumAsciiStringLength.\r
2850 If DestMax is 0.\r
2851 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2852\r
2853**/\r
2854RETURN_STATUS\r
2855EFIAPI\r
2856AsciiStrToUnicodeStrS (\r
2f88bd3a
MK
2857 IN CONST CHAR8 *Source,\r
2858 OUT CHAR16 *Destination,\r
2859 IN UINTN DestMax\r
3ab41b7a
JY
2860 )\r
2861{\r
2f88bd3a 2862 UINTN SourceLen;\r
3ab41b7a 2863\r
2f88bd3a 2864 ASSERT (((UINTN)Destination & BIT0) == 0);\r
3ab41b7a
JY
2865\r
2866 //\r
2867 // 1. Neither Destination nor Source shall be a null pointer.\r
2868 //\r
2869 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2870 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2871\r
2872 //\r
2873 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.\r
2874 //\r
2875 if (RSIZE_MAX != 0) {\r
2876 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2877 }\r
2f88bd3a 2878\r
3ab41b7a
JY
2879 if (ASCII_RSIZE_MAX != 0) {\r
2880 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2881 }\r
2882\r
2883 //\r
2884 // 3. DestMax shall not equal zero.\r
2885 //\r
2886 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2887\r
2888 //\r
2889 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
2890 //\r
2891 SourceLen = AsciiStrnLenS (Source, DestMax);\r
2892 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2893\r
2894 //\r
2895 // 5. Copying shall not take place between objects that overlap.\r
2896 //\r
2f88bd3a 2897 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
3ab41b7a
JY
2898\r
2899 //\r
2900 // Convert string\r
2901 //\r
2902 while (*Source != '\0') {\r
0dab5770 2903 *(Destination++) = (CHAR16)(UINT8)*(Source++);\r
3ab41b7a 2904 }\r
2f88bd3a 2905\r
3ab41b7a
JY
2906 *Destination = '\0';\r
2907\r
2908 return RETURN_SUCCESS;\r
2909}\r
02263214
HW
2910\r
2911/**\r
2912 Convert not more than Length successive characters from a Null-terminated\r
2913 Ascii string to a Null-terminated Unicode string. If no null char is copied\r
2914 from Source, then Destination[Length] is always set to null.\r
2915\r
2916 This function converts not more than Length successive characters from the\r
2917 Ascii string Source to the Unicode string Destination. The function\r
2918 terminates the Unicode string Destination by appending a Null-terminator\r
2919 character at the end.\r
2920\r
2921 The caller is responsible to make sure Destination points to a buffer with\r
2922 size not smaller than\r
2923 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.\r
2924\r
2925 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
02263214
HW
2926\r
2927 If an error is returned, then Destination and DestinationLength are\r
2928 unmodified.\r
2929\r
2930 @param Source The pointer to a Null-terminated Ascii string.\r
2931 @param Length The maximum number of Ascii characters to convert.\r
2932 @param Destination The pointer to a Null-terminated Unicode string.\r
2933 @param DestMax The maximum number of Destination Unicode char,\r
2934 including terminating null char.\r
2935 @param DestinationLength The number of Ascii characters converted.\r
2936\r
2937 @retval RETURN_SUCCESS String is converted.\r
2938 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2939 If Source is NULL.\r
2940 If DestinationLength is NULL.\r
2941 If PcdMaximumUnicodeStringLength is not\r
2942 zero, and Length or DestMax is greater than\r
2943 PcdMaximumUnicodeStringLength.\r
2944 If PcdMaximumAsciiStringLength is not zero,\r
2945 and Length or DestMax is greater than\r
2946 PcdMaximumAsciiStringLength.\r
2947 If DestMax is 0.\r
2948 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2949 MIN(AsciiStrLen(Source), Length).\r
2950 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2951\r
2952**/\r
2953RETURN_STATUS\r
2954EFIAPI\r
2955AsciiStrnToUnicodeStrS (\r
2f88bd3a
MK
2956 IN CONST CHAR8 *Source,\r
2957 IN UINTN Length,\r
2958 OUT CHAR16 *Destination,\r
2959 IN UINTN DestMax,\r
2960 OUT UINTN *DestinationLength\r
02263214
HW
2961 )\r
2962{\r
2f88bd3a 2963 UINTN SourceLen;\r
02263214 2964\r
2f88bd3a 2965 ASSERT (((UINTN)Destination & BIT0) == 0);\r
02263214
HW
2966\r
2967 //\r
2968 // 1. None of Destination, Source or DestinationLength shall be a null\r
2969 // pointer.\r
2970 //\r
2971 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2972 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2973 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
2974\r
2975 //\r
2976 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
2977 // RSIZE_MAX.\r
2978 //\r
2979 if (RSIZE_MAX != 0) {\r
2980 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2981 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2982 }\r
2f88bd3a 2983\r
02263214
HW
2984 if (ASCII_RSIZE_MAX != 0) {\r
2985 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2986 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2987 }\r
2988\r
2989 //\r
2990 // 3. DestMax shall not equal zero.\r
2991 //\r
2992 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2993\r
2994 //\r
2995 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
2996 // AsciiStrnLenS(Source, DestMax).\r
2997 //\r
2998 SourceLen = AsciiStrnLenS (Source, DestMax);\r
2999 if (Length >= DestMax) {\r
3000 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
3001 }\r
3002\r
3003 //\r
3004 // 5. Copying shall not take place between objects that overlap.\r
3005 //\r
3006 if (SourceLen > Length) {\r
3007 SourceLen = Length;\r
3008 }\r
2f88bd3a
MK
3009\r
3010 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
02263214
HW
3011\r
3012 *DestinationLength = 0;\r
3013\r
3014 //\r
3015 // Convert string\r
3016 //\r
3017 while ((*Source != 0) && (SourceLen > 0)) {\r
0dab5770 3018 *(Destination++) = (CHAR16)(UINT8)*(Source++);\r
02263214
HW
3019 SourceLen--;\r
3020 (*DestinationLength)++;\r
3021 }\r
2f88bd3a 3022\r
02263214
HW
3023 *Destination = 0;\r
3024\r
3025 return RETURN_SUCCESS;\r
3026}\r
fb4dd857
RN
3027\r
3028/**\r
3029 Convert a Null-terminated ASCII string to IPv6 address and prefix length.\r
3030\r
3031 This function outputs a value of type IPv6_ADDRESS and may output a value\r
3032 of type UINT8 by interpreting the contents of the ASCII string specified\r
3033 by String. The format of the input ASCII string String is as follows:\r
3034\r
3035 X:X:X:X:X:X:X:X[/P]\r
3036\r
3037 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and\r
3038 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low\r
3039 memory address and high byte is stored in high memory address. P contains decimal\r
3040 digit characters in the range [0-9]. The running zero in the beginning of P will\r
3041 be ignored. /P is optional.\r
3042\r
3043 When /P is not in the String, the function stops at the first character that is\r
3044 not a valid hexadecimal digit character after eight X's are converted.\r
3045\r
3046 When /P is in the String, the function stops at the first character that is not\r
3047 a valid decimal digit character after P is converted.\r
3048\r
3049 "::" can be used to compress one or more groups of X when X contains only 0.\r
3050 The "::" can only appear once in the String.\r
3051\r
fb4dd857
RN
3052 If EndPointer is not NULL and Address is translated from String, a pointer\r
3053 to the character that stopped the scan is stored at the location pointed to\r
3054 by EndPointer.\r
3055\r
3056 @param String Pointer to a Null-terminated ASCII string.\r
3057 @param EndPointer Pointer to character that stops scan.\r
3058 @param Address Pointer to the converted IPv6 address.\r
3059 @param PrefixLength Pointer to the converted IPv6 address prefix\r
3060 length. MAX_UINT8 is returned when /P is\r
3061 not in the String.\r
3062\r
3063 @retval RETURN_SUCCESS Address is translated from String.\r
3064 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3065 If Data is NULL.\r
3066 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal\r
3067 digit characters.\r
3068 If String contains "::" and number of X\r
3069 is not less than 8.\r
3070 If P starts with character that is not a\r
3071 valid decimal digit character.\r
3072 If the decimal number converted from P\r
3073 exceeds 128.\r
3074\r
3075**/\r
3076RETURN_STATUS\r
3077EFIAPI\r
3078AsciiStrToIpv6Address (\r
2f88bd3a
MK
3079 IN CONST CHAR8 *String,\r
3080 OUT CHAR8 **EndPointer OPTIONAL,\r
3081 OUT IPv6_ADDRESS *Address,\r
3082 OUT UINT8 *PrefixLength OPTIONAL\r
fb4dd857
RN
3083 )\r
3084{\r
2f88bd3a
MK
3085 RETURN_STATUS Status;\r
3086 UINTN AddressIndex;\r
3087 UINTN Uintn;\r
3088 IPv6_ADDRESS LocalAddress;\r
3089 UINT8 LocalPrefixLength;\r
3090 CONST CHAR8 *Pointer;\r
3091 CHAR8 *End;\r
3092 UINTN CompressStart;\r
3093 BOOLEAN ExpectPrefix;\r
fb4dd857
RN
3094\r
3095 LocalPrefixLength = MAX_UINT8;\r
3096 CompressStart = ARRAY_SIZE (Address->Addr);\r
3097 ExpectPrefix = FALSE;\r
3098\r
3099 //\r
3100 // None of String or Address shall be a null pointer.\r
3101 //\r
3102 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3103 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
3104\r
3105 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
3106 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {\r
3107 if (*Pointer != ':') {\r
3108 //\r
3109 // ":" or "/" should be followed by digit characters.\r
3110 //\r
3111 return RETURN_UNSUPPORTED;\r
3112 }\r
3113\r
3114 //\r
3115 // Meet second ":" after previous ":" or "/"\r
3116 // or meet first ":" in the beginning of String.\r
3117 //\r
3118 if (ExpectPrefix) {\r
3119 //\r
3120 // ":" shall not be after "/"\r
3121 //\r
3122 return RETURN_UNSUPPORTED;\r
3123 }\r
3124\r
2f88bd3a 3125 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {\r
fb4dd857
RN
3126 //\r
3127 // "::" can only appear once.\r
3128 // "::" can only appear when address is not full length.\r
3129 //\r
3130 return RETURN_UNSUPPORTED;\r
3131 } else {\r
3132 //\r
3133 // Remember the start of zero compressing.\r
3134 //\r
3135 CompressStart = AddressIndex;\r
3136 Pointer++;\r
3137\r
3138 if (CompressStart == 0) {\r
3139 if (*Pointer != ':') {\r
3140 //\r
3141 // Single ":" shall not be in the beginning of String.\r
3142 //\r
3143 return RETURN_UNSUPPORTED;\r
3144 }\r
2f88bd3a 3145\r
fb4dd857
RN
3146 Pointer++;\r
3147 }\r
3148 }\r
3149 }\r
3150\r
3151 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {\r
3152 if (*Pointer == '/') {\r
3153 //\r
3154 // Might be optional "/P" after "::".\r
3155 //\r
3156 if (CompressStart != AddressIndex) {\r
3157 return RETURN_UNSUPPORTED;\r
3158 }\r
3159 } else {\r
3160 break;\r
3161 }\r
3162 } else {\r
3163 if (!ExpectPrefix) {\r
3164 //\r
3165 // Get X.\r
3166 //\r
3167 Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 3168 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {\r
fb4dd857
RN
3169 //\r
3170 // Number of hexadecimal digit characters is no more than 4.\r
3171 //\r
3172 return RETURN_UNSUPPORTED;\r
3173 }\r
2f88bd3a 3174\r
fb4dd857
RN
3175 Pointer = End;\r
3176 //\r
3177 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.\r
3178 //\r
5b0ce08a 3179 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));\r
2f88bd3a
MK
3180 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);\r
3181 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;\r
3182 AddressIndex += 2;\r
fb4dd857
RN
3183 } else {\r
3184 //\r
3185 // Get P, then exit the loop.\r
3186 //\r
3187 Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 3188 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {\r
fb4dd857
RN
3189 //\r
3190 // Prefix length should not exceed 128.\r
3191 //\r
3192 return RETURN_UNSUPPORTED;\r
3193 }\r
2f88bd3a
MK
3194\r
3195 LocalPrefixLength = (UINT8)Uintn;\r
3196 Pointer = End;\r
fb4dd857
RN
3197 break;\r
3198 }\r
3199 }\r
3200\r
3201 //\r
3202 // Skip ':' or "/"\r
3203 //\r
3204 if (*Pointer == '/') {\r
3205 ExpectPrefix = TRUE;\r
3206 } else if (*Pointer == ':') {\r
3207 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3208 //\r
3209 // Meet additional ":" after all 8 16-bit address\r
3210 //\r
3211 break;\r
3212 }\r
3213 } else {\r
3214 //\r
3215 // Meet other character that is not "/" or ":" after all 8 16-bit address\r
3216 //\r
3217 break;\r
3218 }\r
2f88bd3a 3219\r
fb4dd857
RN
3220 Pointer++;\r
3221 }\r
3222\r
2f88bd3a
MK
3223 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||\r
3224 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))\r
3225 )\r
3226 {\r
fb4dd857
RN
3227 //\r
3228 // Full length of address shall not have compressing zeros.\r
3229 // Non-full length of address shall have compressing zeros.\r
3230 //\r
3231 return RETURN_UNSUPPORTED;\r
3232 }\r
2f88bd3a 3233\r
fb4dd857
RN
3234 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);\r
3235 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);\r
5b0ce08a
RN
3236 if (AddressIndex > CompressStart) {\r
3237 CopyMem (\r
3238 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],\r
3239 &LocalAddress.Addr[CompressStart],\r
3240 AddressIndex - CompressStart\r
973f8862 3241 );\r
5b0ce08a 3242 }\r
fb4dd857
RN
3243\r
3244 if (PrefixLength != NULL) {\r
3245 *PrefixLength = LocalPrefixLength;\r
3246 }\r
2f88bd3a 3247\r
fb4dd857 3248 if (EndPointer != NULL) {\r
2f88bd3a 3249 *EndPointer = (CHAR8 *)Pointer;\r
fb4dd857
RN
3250 }\r
3251\r
3252 return RETURN_SUCCESS;\r
3253}\r
3254\r
3255/**\r
3256 Convert a Null-terminated ASCII string to IPv4 address and prefix length.\r
3257\r
3258 This function outputs a value of type IPv4_ADDRESS and may output a value\r
3259 of type UINT8 by interpreting the contents of the ASCII string specified\r
3260 by String. The format of the input ASCII string String is as follows:\r
3261\r
3262 D.D.D.D[/P]\r
3263\r
3264 D and P are decimal digit characters in the range [0-9]. The running zero in\r
3265 the beginning of D and P will be ignored. /P is optional.\r
3266\r
3267 When /P is not in the String, the function stops at the first character that is\r
3268 not a valid decimal digit character after four D's are converted.\r
3269\r
3270 When /P is in the String, the function stops at the first character that is not\r
3271 a valid decimal digit character after P is converted.\r
3272\r
fb4dd857
RN
3273 If EndPointer is not NULL and Address is translated from String, a pointer\r
3274 to the character that stopped the scan is stored at the location pointed to\r
3275 by EndPointer.\r
3276\r
3277 @param String Pointer to a Null-terminated ASCII string.\r
3278 @param EndPointer Pointer to character that stops scan.\r
3279 @param Address Pointer to the converted IPv4 address.\r
3280 @param PrefixLength Pointer to the converted IPv4 address prefix\r
3281 length. MAX_UINT8 is returned when /P is\r
3282 not in the String.\r
3283\r
3284 @retval RETURN_SUCCESS Address is translated from String.\r
3285 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3286 If Data is NULL.\r
3287 @retval RETURN_UNSUPPORTED If String is not in the correct format.\r
3288 If any decimal number converted from D\r
3289 exceeds 255.\r
3290 If the decimal number converted from P\r
3291 exceeds 32.\r
3292\r
3293**/\r
3294RETURN_STATUS\r
3295EFIAPI\r
3296AsciiStrToIpv4Address (\r
2f88bd3a
MK
3297 IN CONST CHAR8 *String,\r
3298 OUT CHAR8 **EndPointer OPTIONAL,\r
3299 OUT IPv4_ADDRESS *Address,\r
3300 OUT UINT8 *PrefixLength OPTIONAL\r
fb4dd857
RN
3301 )\r
3302{\r
2f88bd3a
MK
3303 RETURN_STATUS Status;\r
3304 UINTN AddressIndex;\r
3305 UINTN Uintn;\r
3306 IPv4_ADDRESS LocalAddress;\r
3307 UINT8 LocalPrefixLength;\r
3308 CHAR8 *Pointer;\r
fb4dd857
RN
3309\r
3310 LocalPrefixLength = MAX_UINT8;\r
3311\r
3312 //\r
3313 // None of String or Address shall be a null pointer.\r
3314 //\r
3315 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3316 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
3317\r
2f88bd3a 3318 for (Pointer = (CHAR8 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
fb4dd857
RN
3319 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {\r
3320 //\r
3321 // D or P contains invalid characters.\r
3322 //\r
3323 break;\r
3324 }\r
3325\r
3326 //\r
3327 // Get D or P.\r
3328 //\r
2f88bd3a 3329 Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *)Pointer, &Pointer, &Uintn);\r
fb4dd857
RN
3330 if (RETURN_ERROR (Status)) {\r
3331 return RETURN_UNSUPPORTED;\r
3332 }\r
2f88bd3a 3333\r
fb4dd857
RN
3334 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3335 //\r
3336 // It's P.\r
3337 //\r
3338 if (Uintn > 32) {\r
3339 return RETURN_UNSUPPORTED;\r
3340 }\r
2f88bd3a
MK
3341\r
3342 LocalPrefixLength = (UINT8)Uintn;\r
fb4dd857
RN
3343 } else {\r
3344 //\r
3345 // It's D.\r
3346 //\r
3347 if (Uintn > MAX_UINT8) {\r
3348 return RETURN_UNSUPPORTED;\r
3349 }\r
2f88bd3a
MK
3350\r
3351 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;\r
fb4dd857
RN
3352 AddressIndex++;\r
3353 }\r
3354\r
3355 //\r
3356 // Check the '.' or '/', depending on the AddressIndex.\r
3357 //\r
3358 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3359 if (*Pointer == '/') {\r
3360 //\r
3361 // '/P' is in the String.\r
3362 // Skip "/" and get P in next loop.\r
3363 //\r
3364 Pointer++;\r
3365 } else {\r
3366 //\r
3367 // '/P' is not in the String.\r
3368 //\r
3369 break;\r
3370 }\r
3371 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
3372 if (*Pointer == '.') {\r
3373 //\r
3374 // D should be followed by '.'\r
3375 //\r
3376 Pointer++;\r
3377 } else {\r
3378 return RETURN_UNSUPPORTED;\r
3379 }\r
3380 }\r
3381 }\r
3382\r
3383 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
3384 return RETURN_UNSUPPORTED;\r
3385 }\r
3386\r
3387 CopyMem (Address, &LocalAddress, sizeof (*Address));\r
3388 if (PrefixLength != NULL) {\r
3389 *PrefixLength = LocalPrefixLength;\r
3390 }\r
2f88bd3a 3391\r
fb4dd857
RN
3392 if (EndPointer != NULL) {\r
3393 *EndPointer = Pointer;\r
3394 }\r
3395\r
3396 return RETURN_SUCCESS;\r
3397}\r
3398\r
3399/**\r
3400 Convert a Null-terminated ASCII GUID string to a value of type\r
3401 EFI_GUID.\r
3402\r
3403 This function outputs a GUID value by interpreting the contents of\r
3404 the ASCII string specified by String. The format of the input\r
3405 ASCII string String consists of 36 characters, as follows:\r
3406\r
3407 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\r
3408\r
3409 The pairs aa - pp are two characters in the range [0-9], [a-f] and\r
3410 [A-F], with each pair representing a single byte hexadecimal value.\r
3411\r
3412 The mapping between String and the EFI_GUID structure is as follows:\r
3413 aa Data1[24:31]\r
3414 bb Data1[16:23]\r
3415 cc Data1[8:15]\r
3416 dd Data1[0:7]\r
3417 ee Data2[8:15]\r
3418 ff Data2[0:7]\r
3419 gg Data3[8:15]\r
3420 hh Data3[0:7]\r
3421 ii Data4[0:7]\r
3422 jj Data4[8:15]\r
3423 kk Data4[16:23]\r
3424 ll Data4[24:31]\r
3425 mm Data4[32:39]\r
3426 nn Data4[40:47]\r
3427 oo Data4[48:55]\r
3428 pp Data4[56:63]\r
3429\r
fb4dd857
RN
3430 @param String Pointer to a Null-terminated ASCII string.\r
3431 @param Guid Pointer to the converted GUID.\r
3432\r
3433 @retval RETURN_SUCCESS Guid is translated from String.\r
3434 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3435 If Data is NULL.\r
3436 @retval RETURN_UNSUPPORTED If String is not as the above format.\r
3437\r
3438**/\r
3439RETURN_STATUS\r
3440EFIAPI\r
3441AsciiStrToGuid (\r
2f88bd3a
MK
3442 IN CONST CHAR8 *String,\r
3443 OUT GUID *Guid\r
fb4dd857
RN
3444 )\r
3445{\r
2f88bd3a
MK
3446 RETURN_STATUS Status;\r
3447 GUID LocalGuid;\r
fb4dd857
RN
3448\r
3449 //\r
3450 // None of String or Guid shall be a null pointer.\r
3451 //\r
3452 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3453 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);\r
3454\r
3455 //\r
3456 // Get aabbccdd in big-endian.\r
3457 //\r
2f88bd3a
MK
3458 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));\r
3459 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != '-')) {\r
fb4dd857
RN
3460 return RETURN_UNSUPPORTED;\r
3461 }\r
2f88bd3a 3462\r
fb4dd857
RN
3463 //\r
3464 // Convert big-endian to little-endian.\r
3465 //\r
3466 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);\r
2f88bd3a 3467 String += 2 * sizeof (LocalGuid.Data1) + 1;\r
fb4dd857
RN
3468\r
3469 //\r
3470 // Get eeff in big-endian.\r
3471 //\r
2f88bd3a
MK
3472 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));\r
3473 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != '-')) {\r
fb4dd857
RN
3474 return RETURN_UNSUPPORTED;\r
3475 }\r
2f88bd3a 3476\r
fb4dd857
RN
3477 //\r
3478 // Convert big-endian to little-endian.\r
3479 //\r
3480 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);\r
2f88bd3a 3481 String += 2 * sizeof (LocalGuid.Data2) + 1;\r
fb4dd857
RN
3482\r
3483 //\r
3484 // Get gghh in big-endian.\r
3485 //\r
2f88bd3a
MK
3486 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));\r
3487 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != '-')) {\r
fb4dd857
RN
3488 return RETURN_UNSUPPORTED;\r
3489 }\r
2f88bd3a 3490\r
fb4dd857
RN
3491 //\r
3492 // Convert big-endian to little-endian.\r
3493 //\r
3494 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);\r
2f88bd3a 3495 String += 2 * sizeof (LocalGuid.Data3) + 1;\r
fb4dd857
RN
3496\r
3497 //\r
3498 // Get iijj.\r
3499 //\r
3500 Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);\r
2f88bd3a 3501 if (RETURN_ERROR (Status) || (String[2 * 2] != '-')) {\r
fb4dd857
RN
3502 return RETURN_UNSUPPORTED;\r
3503 }\r
2f88bd3a 3504\r
fb4dd857
RN
3505 String += 2 * 2 + 1;\r
3506\r
3507 //\r
3508 // Get kkllmmnnoopp.\r
3509 //\r
3510 Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);\r
3511 if (RETURN_ERROR (Status)) {\r
3512 return RETURN_UNSUPPORTED;\r
3513 }\r
3514\r
3515 CopyGuid (Guid, &LocalGuid);\r
3516 return RETURN_SUCCESS;\r
3517}\r
3518\r
3519/**\r
3520 Convert a Null-terminated ASCII hexadecimal string to a byte array.\r
3521\r
3522 This function outputs a byte array by interpreting the contents of\r
3523 the ASCII string specified by String in hexadecimal format. The format of\r
3524 the input ASCII string String is:\r
3525\r
3526 [XX]*\r
3527\r
3528 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].\r
3529 The function decodes every two hexadecimal digit characters as one byte. The\r
3530 decoding stops after Length of characters and outputs Buffer containing\r
3531 (Length / 2) bytes.\r
3532\r
fb4dd857
RN
3533 @param String Pointer to a Null-terminated ASCII string.\r
3534 @param Length The number of ASCII characters to decode.\r
3535 @param Buffer Pointer to the converted bytes array.\r
3536 @param MaxBufferSize The maximum size of Buffer.\r
3537\r
3538 @retval RETURN_SUCCESS Buffer is translated from String.\r
3539 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3540 If Data is NULL.\r
3541 If Length is not multiple of 2.\r
3542 If PcdMaximumAsciiStringLength is not zero,\r
3543 and Length is greater than\r
3544 PcdMaximumAsciiStringLength.\r
3545 @retval RETURN_UNSUPPORTED If Length of characters from String contain\r
3546 a character that is not valid hexadecimal\r
3547 digit characters, or a Null-terminator.\r
3548 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).\r
3549**/\r
3550RETURN_STATUS\r
3551EFIAPI\r
3552AsciiStrHexToBytes (\r
2f88bd3a
MK
3553 IN CONST CHAR8 *String,\r
3554 IN UINTN Length,\r
3555 OUT UINT8 *Buffer,\r
3556 IN UINTN MaxBufferSize\r
fb4dd857
RN
3557 )\r
3558{\r
2f88bd3a 3559 UINTN Index;\r
fb4dd857
RN
3560\r
3561 //\r
3562 // 1. None of String or Buffer shall be a null pointer.\r
3563 //\r
3564 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3565 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
3566\r
3567 //\r
3568 // 2. Length shall not be greater than ASCII_RSIZE_MAX.\r
3569 //\r
3570 if (ASCII_RSIZE_MAX != 0) {\r
3571 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3572 }\r
3573\r
3574 //\r
3575 // 3. Length shall not be odd.\r
3576 //\r
3577 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);\r
3578\r
3579 //\r
3580 // 4. MaxBufferSize shall equal to or greater than Length / 2.\r
3581 //\r
3582 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);\r
3583\r
3584 //\r
3585 // 5. String shall not contains invalid hexadecimal digits.\r
3586 //\r
3587 for (Index = 0; Index < Length; Index++) {\r
3588 if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {\r
3589 break;\r
3590 }\r
3591 }\r
2f88bd3a 3592\r
fb4dd857
RN
3593 if (Index != Length) {\r
3594 return RETURN_UNSUPPORTED;\r
3595 }\r
3596\r
3597 //\r
3598 // Convert the hex string to bytes.\r
3599 //\r
2f88bd3a 3600 for (Index = 0; Index < Length; Index++) {\r
fb4dd857
RN
3601 //\r
3602 // For even characters, write the upper nibble for each buffer byte,\r
3603 // and for even characters, the lower nibble.\r
3604 //\r
3605 if ((Index & BIT0) == 0) {\r
2f88bd3a 3606 Buffer[Index / 2] = (UINT8)InternalAsciiHexCharToUintn (String[Index]) << 4;\r
fb4dd857 3607 } else {\r
2f88bd3a 3608 Buffer[Index / 2] |= (UINT8)InternalAsciiHexCharToUintn (String[Index]);\r
fb4dd857
RN
3609 }\r
3610 }\r
2f88bd3a 3611\r
fb4dd857
RN
3612 return RETURN_SUCCESS;\r
3613}\r