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