2019-09-03 11:58:42 +02:00
|
|
|
/** @file
|
|
|
|
Unicode and ASCII string primitives.
|
|
|
|
|
|
|
|
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
|
2019-09-04 12:44:38 +02:00
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include "BaseLibInternals.h"
|
|
|
|
|
|
|
|
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Copies one Null-terminated Unicode string to another Null-terminated Unicode
|
|
|
|
string and returns the new Unicode string.
|
|
|
|
|
|
|
|
This function copies the contents of the Unicode string Source to the Unicode
|
|
|
|
string Destination, and returns Destination. If Source and Destination
|
|
|
|
overlap, then the results are undefined.
|
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Destination is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source is NULL, then ASSERT().
|
|
|
|
If Source is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Source A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@return Destination.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR16 *
|
|
|
|
EFIAPI
|
|
|
|
StrCpy (
|
|
|
|
OUT CHAR16 *Destination,
|
|
|
|
IN CONST CHAR16 *Source
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CHAR16 *ReturnValue;
|
2019-09-15 20:27:19 +02:00
|
|
|
// INTN DestMax;
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// Destination cannot be NULL
|
|
|
|
//
|
|
|
|
ASSERT (Destination != NULL);
|
|
|
|
ASSERT (((UINTN) Destination & BIT0) == 0);
|
2019-09-15 20:27:19 +02:00
|
|
|
if (!Destination || !Source) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// Destination and source cannot overlap
|
|
|
|
//
|
|
|
|
ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
|
|
|
|
ASSERT ((UINTN)(Source - Destination) > StrLen (Source));
|
|
|
|
|
2019-09-15 20:27:19 +02:00
|
|
|
// DestMax = StrLen (Destination);
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
ReturnValue = Destination;
|
|
|
|
while (*Source != 0) {
|
|
|
|
*(Destination++) = *(Source++);
|
|
|
|
}
|
|
|
|
*Destination = 0;
|
|
|
|
return ReturnValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Copies up to a specified length from one Null-terminated Unicode string to
|
|
|
|
another Null-terminated Unicode string and returns the new Unicode string.
|
|
|
|
|
|
|
|
This function copies the contents of the Unicode string Source to the Unicode
|
|
|
|
string Destination, and returns Destination. At most, Length Unicode
|
|
|
|
characters are copied from Source to Destination. If Length is 0, then
|
|
|
|
Destination is returned unmodified. If Length is greater that the number of
|
|
|
|
Unicode characters in Source, then Destination is padded with Null Unicode
|
|
|
|
characters. If Source and Destination overlap, then the results are
|
|
|
|
undefined.
|
|
|
|
|
|
|
|
If Length > 0 and Destination is NULL, then ASSERT().
|
|
|
|
If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Length > 0 and Source is NULL, then ASSERT().
|
|
|
|
If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
|
|
|
|
PcdMaximumUnicodeStringLength, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Source A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Length The maximum number of Unicode characters to copy.
|
|
|
|
|
2020-05-12 08:01:46 +02:00
|
|
|
@return Destination. //Slice - no sense to return same pointer as argument
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR16 *
|
|
|
|
EFIAPI
|
|
|
|
StrnCpy (
|
|
|
|
OUT CHAR16 *Destination,
|
|
|
|
IN CONST CHAR16 *Source,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CHAR16 *ReturnValue;
|
|
|
|
|
|
|
|
if (Length == 0) {
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2020-05-12 08:01:46 +02:00
|
|
|
// Destination cannot be NULL if Length is not zero //Slice - Source as null pointer deref
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2020-05-12 08:01:46 +02:00
|
|
|
if (!Destination || !Source) {
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
//ASSERT (Destination != NULL);
|
2019-09-03 11:58:42 +02:00
|
|
|
ASSERT (((UINTN) Destination & BIT0) == 0);
|
|
|
|
|
|
|
|
//
|
2020-05-12 08:01:46 +02:00
|
|
|
// Destination and source cannot overlap - //Slice - and what if this happen?
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
|
|
|
ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
|
|
|
|
ASSERT ((UINTN)(Source - Destination) >= Length);
|
|
|
|
|
|
|
|
// if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
|
|
|
|
// ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
|
|
|
|
// }
|
|
|
|
if (Length > 1000000) {
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue = Destination;
|
|
|
|
|
|
|
|
while ((*Source != L'\0') && (Length > 0)) {
|
|
|
|
*(Destination++) = *(Source++);
|
|
|
|
Length--;
|
|
|
|
}
|
2020-05-12 08:01:46 +02:00
|
|
|
//Slice - if Length == strlen(Source) then null will not be copied
|
|
|
|
//but this is not CopyMem, this is StrnCpy which MUST create NULL-terminating string
|
|
|
|
*Destination = L'\0';
|
|
|
|
|
|
|
|
//no sense to zero other bytes
|
|
|
|
//ZeroMem (Destination, Length * sizeof (*Destination));
|
2019-09-03 11:58:42 +02:00
|
|
|
return ReturnValue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the length of a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
This function returns the number of Unicode characters in the Null-terminated
|
|
|
|
Unicode string specified by String.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If String is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and String contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@return The length of String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
StrLen (
|
|
|
|
IN CONST CHAR16 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Length;
|
|
|
|
|
|
|
|
// ASSERT (String != NULL);
|
|
|
|
ASSERT (((UINTN) String & BIT0) == 0);
|
|
|
|
if (!String) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Length = 0; *String != L'\0'; String++, Length++) {
|
|
|
|
//
|
|
|
|
// If PcdMaximumUnicodeStringLength is not zero,
|
|
|
|
// length should not more than PcdMaximumUnicodeStringLength
|
|
|
|
//
|
|
|
|
// if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
|
|
|
|
// ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));
|
|
|
|
if (Length >= 100000000ull) {
|
|
|
|
break;
|
2019-09-04 12:44:38 +02:00
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
return Length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the size of a Null-terminated Unicode string in bytes, including the
|
|
|
|
Null terminator.
|
|
|
|
|
|
|
|
This function returns the size, in bytes, of the Null-terminated Unicode string
|
|
|
|
specified by String.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If String is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and String contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@return The size of String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
StrSize (
|
|
|
|
IN CONST CHAR16 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (!String) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return (StrLen (String) + 1) * sizeof (*String);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Compares two Null-terminated Unicode strings, and returns the difference
|
|
|
|
between the first mismatched Unicode characters.
|
|
|
|
|
|
|
|
This function compares the Null-terminated Unicode string FirstString to the
|
|
|
|
Null-terminated Unicode string SecondString. If FirstString is identical to
|
|
|
|
SecondString, then 0 is returned. Otherwise, the value returned is the first
|
|
|
|
mismatched Unicode character in SecondString subtracted from the first
|
|
|
|
mismatched Unicode character in FirstString.
|
|
|
|
|
|
|
|
If FirstString is NULL, then ASSERT().
|
|
|
|
If FirstString is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If SecondString is NULL, then ASSERT().
|
|
|
|
If SecondString is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
|
|
|
|
than PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
|
|
|
|
than PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param FirstString A pointer to a Null-terminated Unicode string.
|
|
|
|
@param SecondString A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@retval 0 FirstString is identical to SecondString.
|
|
|
|
@return others FirstString is not identical to SecondString.
|
|
|
|
|
|
|
|
**/
|
|
|
|
INTN
|
|
|
|
EFIAPI
|
|
|
|
StrCmp (
|
|
|
|
IN CONST CHAR16 *FirstString,
|
|
|
|
IN CONST CHAR16 *SecondString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// ASSERT both strings are less long than PcdMaximumUnicodeStringLength
|
|
|
|
//
|
|
|
|
// ASSERT (StrSize (FirstString) != 0);
|
|
|
|
// ASSERT (StrSize (SecondString) != 0);
|
|
|
|
if ((StrSize (FirstString) == 0) && (StrSize (SecondString) == 0)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (StrSize (FirstString) == 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (StrSize (SecondString) == 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
|
|
|
|
FirstString++;
|
|
|
|
SecondString++;
|
|
|
|
}
|
|
|
|
return *FirstString - *SecondString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Compares up to a specified length the contents of two Null-terminated Unicode strings,
|
|
|
|
and returns the difference between the first mismatched Unicode characters.
|
|
|
|
|
|
|
|
This function compares the Null-terminated Unicode string FirstString to the
|
|
|
|
Null-terminated Unicode string SecondString. At most, Length Unicode
|
|
|
|
characters will be compared. If Length is 0, then 0 is returned. If
|
|
|
|
FirstString is identical to SecondString, then 0 is returned. Otherwise, the
|
|
|
|
value returned is the first mismatched Unicode character in SecondString
|
|
|
|
subtracted from the first mismatched Unicode character in FirstString.
|
|
|
|
|
|
|
|
If Length > 0 and FirstString is NULL, then ASSERT().
|
|
|
|
If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Length > 0 and SecondString is NULL, then ASSERT().
|
|
|
|
If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
|
|
|
|
PcdMaximumUnicodeStringLength, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param FirstString A pointer to a Null-terminated Unicode string.
|
|
|
|
@param SecondString A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Length The maximum number of Unicode characters to compare.
|
|
|
|
|
|
|
|
@retval 0 FirstString is identical to SecondString.
|
|
|
|
@return others FirstString is not identical to SecondString.
|
|
|
|
|
|
|
|
**/
|
|
|
|
INTN
|
|
|
|
EFIAPI
|
|
|
|
StrnCmp (
|
|
|
|
IN CONST CHAR16 *FirstString,
|
|
|
|
IN CONST CHAR16 *SecondString,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Length == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
|
|
|
|
// Length tests are performed inside StrLen().
|
|
|
|
//
|
|
|
|
ASSERT (StrSize (FirstString) != 0);
|
|
|
|
ASSERT (StrSize (SecondString) != 0);
|
|
|
|
|
|
|
|
// if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
|
|
|
|
// ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
|
|
|
|
if (Length > 100000000ull) {
|
|
|
|
Length = 100000000ull;
|
2019-09-04 12:44:38 +02:00
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
while ((*FirstString != L'\0') &&
|
|
|
|
(*SecondString != L'\0') &&
|
|
|
|
(*FirstString == *SecondString) &&
|
|
|
|
(Length > 1)) {
|
|
|
|
FirstString++;
|
|
|
|
SecondString++;
|
|
|
|
Length--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *FirstString - *SecondString;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Concatenates one Null-terminated Unicode string to another Null-terminated
|
|
|
|
Unicode string, and returns the concatenated Unicode string.
|
|
|
|
|
|
|
|
This function concatenates two Null-terminated Unicode strings. The contents
|
|
|
|
of Null-terminated Unicode string Source are concatenated to the end of
|
|
|
|
Null-terminated Unicode string Destination. The Null-terminated concatenated
|
|
|
|
Unicode String is returned. If Source and Destination overlap, then the
|
|
|
|
results are undefined.
|
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Destination is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source is NULL, then ASSERT().
|
|
|
|
If Source is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
|
|
|
|
than PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
|
|
|
|
and Source results in a Unicode string with more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Source A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@return Destination.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR16 *
|
|
|
|
EFIAPI
|
|
|
|
StrCat (
|
|
|
|
IN OUT CHAR16 *Destination,
|
|
|
|
IN CONST CHAR16 *Source
|
|
|
|
)
|
|
|
|
{
|
|
|
|
StrCpy (Destination + StrLen (Destination), Source);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Size of the resulting string should never be zero.
|
|
|
|
// PcdMaximumUnicodeStringLength is tested inside StrLen().
|
|
|
|
//
|
|
|
|
ASSERT (StrSize (Destination) != 0);
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Concatenates up to a specified length one Null-terminated Unicode to the end
|
|
|
|
of another Null-terminated Unicode string, and returns the concatenated
|
|
|
|
Unicode string.
|
|
|
|
|
|
|
|
This function concatenates two Null-terminated Unicode strings. The contents
|
|
|
|
of Null-terminated Unicode string Source are concatenated to the end of
|
|
|
|
Null-terminated Unicode string Destination, and Destination is returned. At
|
|
|
|
most, Length Unicode characters are concatenated from Source to the end of
|
|
|
|
Destination, and Destination is always Null-terminated. If Length is 0, then
|
|
|
|
Destination is returned unmodified. If Source and Destination overlap, then
|
|
|
|
the results are undefined.
|
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Length > 0 and Source is NULL, then ASSERT().
|
|
|
|
If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
|
|
|
|
PcdMaximumUnicodeStringLength, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
|
|
|
|
than PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
|
|
|
|
and Source results in a Unicode string with more than PcdMaximumUnicodeStringLength
|
|
|
|
Unicode characters, not including the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Source A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Length The maximum number of Unicode characters to concatenate from
|
|
|
|
Source.
|
|
|
|
|
|
|
|
@return Destination.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR16 *
|
|
|
|
EFIAPI
|
|
|
|
StrnCat (
|
|
|
|
IN OUT CHAR16 *Destination,
|
|
|
|
IN CONST CHAR16 *Source,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN DestinationLen;
|
|
|
|
|
|
|
|
DestinationLen = StrLen (Destination);
|
|
|
|
StrnCpy (Destination + DestinationLen, Source, Length);
|
|
|
|
Destination[DestinationLen + Length] = L'\0';
|
|
|
|
|
|
|
|
//
|
|
|
|
// Size of the resulting string should never be zero.
|
|
|
|
// PcdMaximumUnicodeStringLength is tested inside StrLen().
|
|
|
|
//
|
|
|
|
ASSERT (StrSize (Destination) != 0);
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the first occurrence of a Null-terminated Unicode sub-string
|
|
|
|
in a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
This function scans the contents of the Null-terminated Unicode string
|
|
|
|
specified by String and returns the first occurrence of SearchString.
|
|
|
|
If SearchString is not found in String, then NULL is returned. If
|
|
|
|
the length of SearchString is zero, then String is
|
|
|
|
returned.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If String is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If SearchString is NULL, then ASSERT().
|
|
|
|
If SearchString is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and SearchString
|
|
|
|
or String contains more than PcdMaximumUnicodeStringLength Unicode
|
|
|
|
characters, not including the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated Unicode string.
|
|
|
|
@param SearchString A pointer to a Null-terminated Unicode string to search for.
|
|
|
|
|
|
|
|
@retval NULL If the SearchString does not appear in String.
|
|
|
|
@return others If there is a match.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR16 *
|
|
|
|
EFIAPI
|
|
|
|
StrStr (
|
|
|
|
IN CONST CHAR16 *String,
|
|
|
|
IN CONST CHAR16 *SearchString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CONST CHAR16 *FirstMatch;
|
|
|
|
CONST CHAR16 *SearchStringTmp;
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
|
|
|
|
// Length tests are performed inside StrLen().
|
|
|
|
//
|
|
|
|
// ASSERT (StrSize (String) != 0);
|
|
|
|
// ASSERT (StrSize (SearchString) != 0);
|
|
|
|
if (!StrSize (String) || !StrSize (SearchString)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*SearchString == L'\0') {
|
|
|
|
return (CHAR16 *) String;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*String != L'\0') {
|
|
|
|
SearchStringTmp = SearchString;
|
|
|
|
FirstMatch = String;
|
|
|
|
|
|
|
|
while ((*String == *SearchStringTmp)
|
|
|
|
&& (*String != L'\0')) {
|
|
|
|
String++;
|
|
|
|
SearchStringTmp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*SearchStringTmp == L'\0') {
|
|
|
|
return (CHAR16 *) FirstMatch;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*String == L'\0') {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
String = FirstMatch + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Check if a Unicode character is a decimal character.
|
|
|
|
|
|
|
|
This internal function checks if a Unicode character is a
|
|
|
|
decimal character. The valid decimal character is from
|
|
|
|
L'0' to L'9'.
|
|
|
|
|
|
|
|
@param Char The character to check against.
|
|
|
|
|
|
|
|
@retval TRUE If the Char is a decmial character.
|
|
|
|
@retval FALSE If the Char is not a decmial character.
|
|
|
|
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
EFIAPI
|
|
|
|
InternalIsDecimalDigitCharacter (
|
|
|
|
IN CHAR16 Char
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return (BOOLEAN) ((Char >= L'0') && (Char <= L'9'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Unicode character to upper case only if
|
|
|
|
it maps to a valid small-case ASCII character.
|
|
|
|
|
|
|
|
This internal function only deal with Unicode character
|
|
|
|
which maps to a valid small-case ASCII character, i.e.
|
|
|
|
L'a' to L'z'. For other Unicode character, the input character
|
|
|
|
is returned directly.
|
|
|
|
|
|
|
|
@param Char The character to convert.
|
|
|
|
|
|
|
|
@retval LowerCharacter If the Char is with range L'a' to L'z'.
|
|
|
|
@retval Unchanged Otherwise.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR16
|
|
|
|
EFIAPI
|
|
|
|
CharToUpper (
|
|
|
|
IN CHAR16 Char
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if ((Char >= L'a') && (Char <= L'z')) {
|
|
|
|
return (CHAR16) (Char - (L'a' - L'A'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Char;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Unicode character to numerical value.
|
|
|
|
|
|
|
|
This internal function only deal with Unicode character
|
|
|
|
which maps to a valid hexadecimal ASII character, i.e.
|
|
|
|
L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
|
|
|
|
Unicode character, the value returned does not make sense.
|
|
|
|
|
|
|
|
@param Char The character to convert.
|
|
|
|
|
|
|
|
@return The numerical value converted.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
InternalHexCharToUintn (
|
|
|
|
IN CHAR16 Char
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (InternalIsDecimalDigitCharacter (Char)) {
|
|
|
|
return Char - L'0';
|
|
|
|
}
|
|
|
|
|
|
|
|
return (10 + CharToUpper (Char) - L'A');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Check if a Unicode character is a hexadecimal character.
|
|
|
|
|
|
|
|
This internal function checks if a Unicode character is a
|
|
|
|
decimal character. The valid hexadecimal character is
|
|
|
|
L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
|
|
|
|
|
|
|
|
|
|
|
|
@param Char The character to check against.
|
|
|
|
|
|
|
|
@retval TRUE If the Char is a hexadecmial character.
|
|
|
|
@retval FALSE If the Char is not a hexadecmial character.
|
|
|
|
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
EFIAPI
|
|
|
|
InternalIsHexaDecimalDigitCharacter (
|
|
|
|
IN CHAR16 Char
|
|
|
|
)
|
|
|
|
{
|
|
|
|
|
|
|
|
return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
|
|
|
|
((Char >= L'A') && (Char <= L'F')) ||
|
|
|
|
((Char >= L'a') && (Char <= L'f')));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated Unicode decimal string to a value of
|
|
|
|
type UINTN.
|
|
|
|
|
|
|
|
This function returns a value of type UINTN by interpreting the contents
|
|
|
|
of the Unicode string specified by String as a decimal number. The format
|
|
|
|
of the input Unicode string String is:
|
|
|
|
|
|
|
|
[spaces] [decimal digits].
|
|
|
|
|
|
|
|
The valid decimal digit character is in the range [0-9]. The
|
|
|
|
function will ignore the pad space, which includes spaces or
|
|
|
|
tab characters, before [decimal digits]. The running zero in the
|
|
|
|
beginning of [decimal digits] will be ignored. Then, the function
|
|
|
|
stops at the first character that is a not a valid decimal character
|
|
|
|
or a Null-terminator, whichever one comes first.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If String is not aligned in a 16-bit boundary, then ASSERT().
|
|
|
|
If String has only pad spaces, then 0 is returned.
|
|
|
|
If String has no pad spaces or valid decimal digits,
|
|
|
|
then 0 is returned.
|
|
|
|
If the number represented by String overflows according
|
|
|
|
to the range defined by UINTN, then MAX_UINTN is returned.
|
|
|
|
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and String contains
|
|
|
|
more than PcdMaximumUnicodeStringLength Unicode characters, not including
|
|
|
|
the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
StrDecimalToUintn (
|
|
|
|
IN CONST CHAR16 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
Status = StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated Unicode decimal string to a value of
|
|
|
|
type UINT64.
|
|
|
|
|
|
|
|
This function returns a value of type UINT64 by interpreting the contents
|
|
|
|
of the Unicode string specified by String as a decimal number. The format
|
|
|
|
of the input Unicode string String is:
|
|
|
|
|
|
|
|
[spaces] [decimal digits].
|
|
|
|
|
|
|
|
The valid decimal digit character is in the range [0-9]. The
|
|
|
|
function will ignore the pad space, which includes spaces or
|
|
|
|
tab characters, before [decimal digits]. The running zero in the
|
|
|
|
beginning of [decimal digits] will be ignored. Then, the function
|
|
|
|
stops at the first character that is a not a valid decimal character
|
|
|
|
or a Null-terminator, whichever one comes first.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If String is not aligned in a 16-bit boundary, then ASSERT().
|
|
|
|
If String has only pad spaces, then 0 is returned.
|
|
|
|
If String has no pad spaces or valid decimal digits,
|
|
|
|
then 0 is returned.
|
|
|
|
If the number represented by String overflows according
|
|
|
|
to the range defined by UINT64, then MAX_UINT64 is returned.
|
|
|
|
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and String contains
|
|
|
|
more than PcdMaximumUnicodeStringLength Unicode characters, not including
|
|
|
|
the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT64
|
|
|
|
EFIAPI
|
|
|
|
StrDecimalToUint64 (
|
|
|
|
IN CONST CHAR16 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
Status = StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.
|
|
|
|
|
|
|
|
This function returns a value of type UINTN by interpreting the contents
|
|
|
|
of the Unicode string specified by String as a hexadecimal number.
|
|
|
|
The format of the input Unicode string String is:
|
|
|
|
|
|
|
|
[spaces][zeros][x][hexadecimal digits].
|
|
|
|
|
|
|
|
The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
|
|
|
|
The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
|
|
|
|
If "x" appears in the input string, it must be prefixed with at least one 0.
|
|
|
|
The function will ignore the pad space, which includes spaces or tab characters,
|
|
|
|
before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
|
|
|
|
[hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
|
|
|
|
first valid hexadecimal digit. Then, the function stops at the first character that is
|
|
|
|
a not a valid hexadecimal character or NULL, whichever one comes first.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If String is not aligned in a 16-bit boundary, then ASSERT().
|
|
|
|
If String has only pad spaces, then zero is returned.
|
|
|
|
If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
|
|
|
|
then zero is returned.
|
|
|
|
If the number represented by String overflows according to the range defined by
|
|
|
|
UINTN, then MAX_UINTN is returned.
|
|
|
|
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and String contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
StrHexToUintn (
|
|
|
|
IN CONST CHAR16 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
Status = StrHexToUintnS (String, (CHAR16 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
|
|
|
|
|
|
|
|
This function returns a value of type UINT64 by interpreting the contents
|
|
|
|
of the Unicode string specified by String as a hexadecimal number.
|
|
|
|
The format of the input Unicode string String is
|
|
|
|
|
|
|
|
[spaces][zeros][x][hexadecimal digits].
|
|
|
|
|
|
|
|
The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
|
|
|
|
The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
|
|
|
|
If "x" appears in the input string, it must be prefixed with at least one 0.
|
|
|
|
The function will ignore the pad space, which includes spaces or tab characters,
|
|
|
|
before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
|
|
|
|
[hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
|
|
|
|
first valid hexadecimal digit. Then, the function stops at the first character that is
|
|
|
|
a not a valid hexadecimal character or NULL, whichever one comes first.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If String is not aligned in a 16-bit boundary, then ASSERT().
|
|
|
|
If String has only pad spaces, then zero is returned.
|
|
|
|
If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
|
|
|
|
then zero is returned.
|
|
|
|
If the number represented by String overflows according to the range defined by
|
|
|
|
UINT64, then MAX_UINT64 is returned.
|
|
|
|
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and String contains more than
|
|
|
|
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
#if 1
|
|
|
|
UINT64
|
|
|
|
EFIAPI
|
|
|
|
StrHexToUint64 (
|
|
|
|
IN CONST CHAR16 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
Status = StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
UINT64
|
|
|
|
EFIAPI
|
|
|
|
StrHexToUint64 (
|
2019-09-04 12:44:38 +02:00
|
|
|
IN CONST CHAR16 *String
|
|
|
|
)
|
2019-09-03 11:58:42 +02:00
|
|
|
{
|
|
|
|
UINT64 Result;
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT String is less long than PcdMaximumUnicodeStringLength.
|
|
|
|
// Length tests are performed inside StrLen().
|
|
|
|
//
|
|
|
|
// ASSERT (StrSize (String) != 0);
|
|
|
|
if (!String) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Ignore the pad spaces (space or tab)
|
|
|
|
//
|
|
|
|
while ((*String == L' ') || (*String == L'\t')) {
|
|
|
|
String++;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Ignore leading Zeros after the spaces
|
|
|
|
//
|
|
|
|
while (*String == L'0') {
|
|
|
|
String++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (InternalCharToUpper (*String) == L'X') {
|
|
|
|
// ASSERT (*(String - 1) == L'0');
|
|
|
|
if (*(String - 1) != L'0') {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// Skip the 'X'
|
|
|
|
//
|
|
|
|
String++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result = 0;
|
|
|
|
|
|
|
|
while (InternalIsHexaDecimalDigitCharacter (*String)) {
|
|
|
|
//
|
|
|
|
// If the Hex Number represented by String overflows according
|
|
|
|
// to the range defined by UINTN, then ASSERT().
|
|
|
|
//
|
|
|
|
// ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4));
|
|
|
|
|
|
|
|
Result = LShiftU64 (Result, 4);
|
|
|
|
Result = Result + InternalHexCharToUintn (*String);
|
|
|
|
String++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Check if a ASCII character is a decimal character.
|
|
|
|
|
|
|
|
This internal function checks if a Unicode character is a
|
|
|
|
decimal character. The valid decimal character is from
|
|
|
|
'0' to '9'.
|
|
|
|
|
|
|
|
@param Char The character to check against.
|
|
|
|
|
|
|
|
@retval TRUE If the Char is a decmial character.
|
|
|
|
@retval FALSE If the Char is not a decmial character.
|
|
|
|
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
EFIAPI
|
|
|
|
InternalAsciiIsDecimalDigitCharacter (
|
|
|
|
IN CHAR8 Char
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return (BOOLEAN) ((Char >= '0') && (Char <= '9'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Check if a ASCII character is a hexadecimal character.
|
|
|
|
|
|
|
|
This internal function checks if a ASCII character is a
|
|
|
|
decimal character. The valid hexadecimal character is
|
|
|
|
L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
|
|
|
|
|
|
|
|
|
|
|
|
@param Char The character to check against.
|
|
|
|
|
|
|
|
@retval TRUE If the Char is a hexadecmial character.
|
|
|
|
@retval FALSE If the Char is not a hexadecmial character.
|
|
|
|
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
EFIAPI
|
|
|
|
InternalAsciiIsHexaDecimalDigitCharacter (
|
|
|
|
IN CHAR8 Char
|
|
|
|
)
|
|
|
|
{
|
|
|
|
|
|
|
|
return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||
|
|
|
|
((Char >= 'A') && (Char <= 'F')) ||
|
|
|
|
((Char >= 'a') && (Char <= 'f')));
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function is deprecated for security reason.
|
|
|
|
|
|
|
|
Convert a Null-terminated Unicode string to a Null-terminated
|
|
|
|
ASCII string and returns the ASCII string.
|
|
|
|
|
|
|
|
This function converts the content of the Unicode string Source
|
|
|
|
to the ASCII string Destination by copying the lower 8 bits of
|
|
|
|
each Unicode character. It returns Destination.
|
|
|
|
|
|
|
|
The caller is responsible to make sure Destination points to a buffer with size
|
|
|
|
equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
|
|
|
|
|
|
|
|
If any Unicode characters in Source contain non-zero value in
|
|
|
|
the upper 8 bits, then ASSERT().
|
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Source is NULL, then ASSERT().
|
|
|
|
If Source is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Source contains
|
|
|
|
more than PcdMaximumUnicodeStringLength Unicode characters, not including
|
|
|
|
the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Source contains more
|
|
|
|
than PcdMaximumAsciiStringLength Unicode characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param Source A pointer to a Null-terminated Unicode string.
|
|
|
|
@param Destination A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@return Destination.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR8 *
|
|
|
|
EFIAPI
|
|
|
|
UnicodeStrToAsciiStr (
|
|
|
|
IN CONST CHAR16 *Source,
|
|
|
|
OUT CHAR8 *Destination
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CHAR8 *ReturnValue;
|
|
|
|
|
|
|
|
ASSERT (Destination != NULL);
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT if Source is long than PcdMaximumUnicodeStringLength.
|
|
|
|
// Length tests are performed inside StrLen().
|
|
|
|
//
|
|
|
|
// ASSERT (StrSize (Source) != 0);
|
|
|
|
if (!StrSize (Source)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Source and Destination should not overlap
|
|
|
|
//
|
|
|
|
ASSERT ((UINTN) (Destination - (CHAR8 *) Source) >= StrSize (Source));
|
|
|
|
ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));
|
|
|
|
|
|
|
|
|
|
|
|
ReturnValue = Destination;
|
|
|
|
while (*Source != '\0') {
|
|
|
|
//
|
|
|
|
// If any Unicode characters in Source contain
|
|
|
|
// non-zero value in the upper 8 bits, then ASSERT().
|
|
|
|
//
|
|
|
|
//ASSERT (*Source < 0x100);
|
|
|
|
*(Destination++) = (CHAR8) (*(Source++) & 0xFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
*Destination = '\0';
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.
|
|
|
|
// Length tests are performed inside AsciiStrLen().
|
|
|
|
//
|
|
|
|
ASSERT (AsciiStrSize (ReturnValue) != 0);
|
|
|
|
|
|
|
|
return ReturnValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Copies one Null-terminated ASCII string to another Null-terminated ASCII
|
|
|
|
string and returns the new ASCII string.
|
|
|
|
|
|
|
|
This function copies the contents of the ASCII string Source to the ASCII
|
|
|
|
string Destination, and returns Destination. If Source and Destination
|
|
|
|
overlap, then the results are undefined.
|
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Source is NULL, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and Source contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Source A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@return Destination
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR8 *
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrCpy (
|
|
|
|
OUT CHAR8 *Destination,
|
|
|
|
IN CONST CHAR8 *Source
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CHAR8 *ReturnValue;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Destination cannot be NULL
|
|
|
|
//
|
|
|
|
//ASSERT (Destination != NULL);
|
|
|
|
if (!Destination || !Source) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Destination and source cannot overlap
|
|
|
|
//
|
2020-04-28 12:49:24 +02:00
|
|
|
ASSERT ((UINTN)(Destination - Source) > AsciiStrLen(Source));
|
|
|
|
ASSERT ((UINTN)(Source - Destination) > AsciiStrLen(Source));
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
ReturnValue = Destination;
|
|
|
|
while (*Source != 0) {
|
|
|
|
*(Destination++) = *(Source++);
|
|
|
|
}
|
|
|
|
*Destination = 0;
|
|
|
|
return ReturnValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Copies up to a specified length one Null-terminated ASCII string to another
|
|
|
|
Null-terminated ASCII string and returns the new ASCII string.
|
|
|
|
|
|
|
|
This function copies the contents of the ASCII string Source to the ASCII
|
|
|
|
string Destination, and returns Destination. At most, Length ASCII characters
|
|
|
|
are copied from Source to Destination. If Length is 0, then Destination is
|
|
|
|
returned unmodified. If Length is greater that the number of ASCII characters
|
|
|
|
in Source, then Destination is padded with Null ASCII characters. If Source
|
|
|
|
and Destination overlap, then the results are undefined.
|
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Source is NULL, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Length is greater than
|
|
|
|
PcdMaximumAsciiStringLength, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Source A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Length The maximum number of ASCII characters to copy.
|
|
|
|
|
|
|
|
@return Destination
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR8 *
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrnCpy (
|
|
|
|
OUT CHAR8 *Destination,
|
|
|
|
IN CONST CHAR8 *Source,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CHAR8 *ReturnValue;
|
|
|
|
|
|
|
|
if (Length == 0) {
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Destination cannot be NULL
|
|
|
|
//
|
|
|
|
//ASSERT (Destination != NULL);
|
|
|
|
if (!Destination || !Source) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Destination and source cannot overlap
|
|
|
|
//
|
2020-04-28 12:49:24 +02:00
|
|
|
ASSERT ((UINTN)(Destination - Source) > AsciiStrLen(Source));
|
2019-09-03 11:58:42 +02:00
|
|
|
ASSERT ((UINTN)(Source - Destination) >= Length);
|
|
|
|
|
|
|
|
// if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
|
|
|
|
// ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
|
|
|
|
if (Length <= 100000000ull) {
|
|
|
|
Length = 100000000ull;
|
2019-09-04 12:44:38 +02:00
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
ReturnValue = Destination;
|
|
|
|
|
|
|
|
while (*Source != 0 && Length > 0) {
|
|
|
|
*(Destination++) = *(Source++);
|
|
|
|
Length--;
|
|
|
|
}
|
|
|
|
|
|
|
|
ZeroMem (Destination, Length * sizeof (*Destination));
|
|
|
|
return ReturnValue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the length of a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
This function returns the number of ASCII characters in the Null-terminated
|
|
|
|
ASCII string specified by String.
|
|
|
|
|
|
|
|
If Length > 0 and Destination is NULL, then ASSERT().
|
|
|
|
If Length > 0 and Source is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and String contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@return The length of String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
2020-04-28 12:49:24 +02:00
|
|
|
AsciiStrLen(
|
2019-09-03 11:58:42 +02:00
|
|
|
IN CONST CHAR8 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Length;
|
|
|
|
|
|
|
|
// ASSERT (String != NULL);
|
|
|
|
if (!String) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Length = 0; *String != '\0'; String++, Length++) {
|
|
|
|
//
|
|
|
|
// If PcdMaximumUnicodeStringLength is not zero,
|
|
|
|
// length should not more than PcdMaximumUnicodeStringLength
|
|
|
|
//
|
|
|
|
// if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
|
|
|
|
// ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
|
|
|
|
if (Length == 100000000ull) {
|
|
|
|
break;
|
2019-09-04 12:44:38 +02:00
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
// }
|
|
|
|
}
|
|
|
|
return Length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the size of a Null-terminated ASCII string in bytes, including the
|
|
|
|
Null terminator.
|
|
|
|
|
|
|
|
This function returns the size, in bytes, of the Null-terminated ASCII string
|
|
|
|
specified by String.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and String contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@return The size of String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrSize (
|
|
|
|
IN CONST CHAR8 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (!String) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-28 12:49:24 +02:00
|
|
|
return (AsciiStrLen(String) + 1) * sizeof (*String);
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Compares two Null-terminated ASCII strings, and returns the difference
|
|
|
|
between the first mismatched ASCII characters.
|
|
|
|
|
|
|
|
This function compares the Null-terminated ASCII string FirstString to the
|
|
|
|
Null-terminated ASCII string SecondString. If FirstString is identical to
|
|
|
|
SecondString, then 0 is returned. Otherwise, the value returned is the first
|
|
|
|
mismatched ASCII character in SecondString subtracted from the first
|
|
|
|
mismatched ASCII character in FirstString.
|
|
|
|
|
|
|
|
If FirstString is NULL, then ASSERT().
|
|
|
|
If SecondString is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and SecondString contains more
|
|
|
|
than PcdMaximumAsciiStringLength ASCII characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param FirstString A pointer to a Null-terminated ASCII string.
|
|
|
|
@param SecondString A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@retval ==0 FirstString is identical to SecondString.
|
|
|
|
@retval !=0 FirstString is not identical to SecondString.
|
|
|
|
|
|
|
|
**/
|
|
|
|
INTN
|
|
|
|
EFIAPI
|
2020-04-23 11:08:10 +02:00
|
|
|
AsciiStrCmp(
|
2019-09-03 11:58:42 +02:00
|
|
|
IN CONST CHAR8 *FirstString,
|
|
|
|
IN CONST CHAR8 *SecondString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// ASSERT both strings are less long than PcdMaximumAsciiStringLength
|
|
|
|
//
|
|
|
|
// ASSERT (AsciiStrSize (FirstString));
|
|
|
|
// ASSERT (AsciiStrSize (SecondString));
|
|
|
|
if (!AsciiStrSize (FirstString) && !AsciiStrSize (SecondString)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!AsciiStrSize (FirstString)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!AsciiStrSize (SecondString)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((*FirstString != '\0') && (*FirstString == *SecondString)) {
|
|
|
|
FirstString++;
|
|
|
|
SecondString++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *FirstString - *SecondString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Converts a lowercase Ascii character to upper one.
|
|
|
|
|
|
|
|
If Chr is lowercase Ascii character, then converts it to upper one.
|
|
|
|
|
|
|
|
If Value >= 0xA0, then ASSERT().
|
|
|
|
If (Value & 0x0F) >= 0x0A, then ASSERT().
|
|
|
|
|
|
|
|
@param Chr one Ascii character
|
|
|
|
|
|
|
|
@return The uppercase value of Ascii character
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR8
|
|
|
|
EFIAPI
|
|
|
|
AsciiCharToUpper (
|
|
|
|
IN CHAR8 Chr
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return (UINT8) (((Chr >= 'a') && (Chr <= 'z')) ? Chr - ('a' - 'A') : Chr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a ASCII character to numerical value.
|
|
|
|
|
|
|
|
This internal function only deal with Unicode character
|
|
|
|
which maps to a valid hexadecimal ASII character, i.e.
|
|
|
|
'0' to '9', 'a' to 'f' or 'A' to 'F'. For other
|
|
|
|
ASCII character, the value returned does not make sense.
|
|
|
|
|
|
|
|
@param Char The character to convert.
|
|
|
|
|
|
|
|
@return The numerical value converted.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
InternalAsciiHexCharToUintn (
|
|
|
|
IN CHAR8 Char
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (InternalIsDecimalDigitCharacter (Char)) {
|
|
|
|
return Char - '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
return (10 + AsciiCharToUpper (Char) - 'A');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Performs a case insensitive comparison of two Null-terminated ASCII strings,
|
|
|
|
and returns the difference between the first mismatched ASCII characters.
|
|
|
|
|
|
|
|
This function performs a case insensitive comparison of the Null-terminated
|
|
|
|
ASCII string FirstString to the Null-terminated ASCII string SecondString. If
|
|
|
|
FirstString is identical to SecondString, then 0 is returned. Otherwise, the
|
|
|
|
value returned is the first mismatched lower case ASCII character in
|
|
|
|
SecondString subtracted from the first mismatched lower case ASCII character
|
|
|
|
in FirstString.
|
|
|
|
|
|
|
|
If FirstString is NULL, then ASSERT().
|
|
|
|
If SecondString is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and SecondString contains more
|
|
|
|
than PcdMaximumAsciiStringLength ASCII characters, not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param FirstString A pointer to a Null-terminated ASCII string.
|
|
|
|
@param SecondString A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@retval ==0 FirstString is identical to SecondString using case insensitive
|
|
|
|
comparisons.
|
|
|
|
@retval !=0 FirstString is not identical to SecondString using case
|
|
|
|
insensitive comparisons.
|
|
|
|
|
|
|
|
**/
|
|
|
|
INTN
|
|
|
|
EFIAPI
|
|
|
|
AsciiStriCmp (
|
|
|
|
IN CONST CHAR8 *FirstString,
|
|
|
|
IN CONST CHAR8 *SecondString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CHAR8 UpperFirstString;
|
|
|
|
CHAR8 UpperSecondString;
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT both strings are less long than PcdMaximumAsciiStringLength
|
|
|
|
//
|
|
|
|
// ASSERT (AsciiStrSize (FirstString));
|
|
|
|
// ASSERT (AsciiStrSize (SecondString));
|
|
|
|
if (!AsciiStrSize (FirstString) && !AsciiStrSize (SecondString)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!AsciiStrSize (FirstString)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!AsciiStrSize (SecondString)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
UpperFirstString = AsciiCharToUpper (*FirstString);
|
|
|
|
UpperSecondString = AsciiCharToUpper (*SecondString);
|
|
|
|
while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {
|
|
|
|
FirstString++;
|
|
|
|
SecondString++;
|
|
|
|
UpperFirstString = AsciiCharToUpper (*FirstString);
|
|
|
|
UpperSecondString = AsciiCharToUpper (*SecondString);
|
|
|
|
}
|
|
|
|
|
|
|
|
return UpperFirstString - UpperSecondString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Compares two Null-terminated ASCII strings with maximum lengths, and returns
|
|
|
|
the difference between the first mismatched ASCII characters.
|
|
|
|
|
|
|
|
This function compares the Null-terminated ASCII string FirstString to the
|
|
|
|
Null-terminated ASCII string SecondString. At most, Length ASCII characters
|
|
|
|
will be compared. If Length is 0, then 0 is returned. If FirstString is
|
|
|
|
identical to SecondString, then 0 is returned. Otherwise, the value returned
|
|
|
|
is the first mismatched ASCII character in SecondString subtracted from the
|
|
|
|
first mismatched ASCII character in FirstString.
|
|
|
|
|
|
|
|
If Length > 0 and FirstString is NULL, then ASSERT().
|
|
|
|
If Length > 0 and SecondString is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Length is greater than
|
|
|
|
PcdMaximumAsciiStringLength, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param FirstString A pointer to a Null-terminated ASCII string.
|
|
|
|
@param SecondString A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Length The maximum number of ASCII characters for compare.
|
|
|
|
|
|
|
|
@retval ==0 FirstString is identical to SecondString.
|
|
|
|
@retval !=0 FirstString is not identical to SecondString.
|
|
|
|
|
|
|
|
**/
|
|
|
|
INTN
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrnCmp (
|
|
|
|
IN CONST CHAR8 *FirstString,
|
|
|
|
IN CONST CHAR8 *SecondString,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Length == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT both strings are less long than PcdMaximumAsciiStringLength
|
|
|
|
//
|
|
|
|
// ASSERT (AsciiStrSize (FirstString));
|
|
|
|
// ASSERT (AsciiStrSize (SecondString));
|
|
|
|
if (!AsciiStrSize (FirstString) && !AsciiStrSize (SecondString)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!AsciiStrSize (FirstString)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!AsciiStrSize (SecondString)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
|
|
|
|
// ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
|
|
|
|
if (Length > 100000000ull) {
|
|
|
|
Length = 100000000ull;
|
2019-09-04 12:44:38 +02:00
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
while ((*FirstString != '\0') &&
|
|
|
|
(*SecondString != '\0') &&
|
|
|
|
(*FirstString == *SecondString) &&
|
|
|
|
(Length > 1)) {
|
|
|
|
FirstString++;
|
|
|
|
SecondString++;
|
|
|
|
Length--;
|
|
|
|
}
|
|
|
|
return *FirstString - *SecondString;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Concatenates one Null-terminated ASCII string to another Null-terminated
|
|
|
|
ASCII string, and returns the concatenated ASCII string.
|
|
|
|
|
|
|
|
This function concatenates two Null-terminated ASCII strings. The contents of
|
|
|
|
Null-terminated ASCII string Source are concatenated to the end of Null-
|
|
|
|
terminated ASCII string Destination. The Null-terminated concatenated ASCII
|
|
|
|
String is returned.
|
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Source is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and Destination contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and Source contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero and concatenating Destination and
|
|
|
|
Source results in a ASCII string with more than PcdMaximumAsciiStringLength
|
|
|
|
ASCII characters, then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Source A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@return Destination
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR8 *
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrCat (
|
|
|
|
IN OUT CHAR8 *Destination,
|
|
|
|
IN CONST CHAR8 *Source
|
|
|
|
)
|
|
|
|
{
|
2020-04-28 12:49:24 +02:00
|
|
|
AsciiStrCpy (Destination + AsciiStrLen(Destination), Source);
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// Size of the resulting string should never be zero.
|
|
|
|
// PcdMaximumUnicodeStringLength is tested inside StrLen().
|
|
|
|
//
|
|
|
|
ASSERT (AsciiStrSize (Destination) != 0);
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function will be deprecated for security reason.
|
|
|
|
|
|
|
|
Concatenates up to a specified length one Null-terminated ASCII string to
|
|
|
|
the end of another Null-terminated ASCII string, and returns the
|
|
|
|
concatenated ASCII string.
|
|
|
|
|
|
|
|
This function concatenates two Null-terminated ASCII strings. The contents
|
|
|
|
of Null-terminated ASCII string Source are concatenated to the end of Null-
|
|
|
|
terminated ASCII string Destination, and Destination is returned. At most,
|
|
|
|
Length ASCII characters are concatenated from Source to the end of
|
|
|
|
Destination, and Destination is always Null-terminated. If Length is 0, then
|
|
|
|
Destination is returned unmodified. If Source and Destination overlap, then
|
|
|
|
the results are undefined.
|
|
|
|
|
|
|
|
If Length > 0 and Destination is NULL, then ASSERT().
|
|
|
|
If Length > 0 and Source is NULL, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Length is greater than
|
|
|
|
PcdMaximumAsciiStringLength, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Destination contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and
|
|
|
|
Source results in a ASCII string with more than PcdMaximumAsciiStringLength
|
|
|
|
ASCII characters, not including the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param Destination A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Source A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Length The maximum number of ASCII characters to concatenate from
|
|
|
|
Source.
|
|
|
|
|
|
|
|
@return Destination
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR8 *
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrnCat (
|
|
|
|
IN OUT CHAR8 *Destination,
|
|
|
|
IN CONST CHAR8 *Source,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN DestinationLen;
|
|
|
|
|
2020-04-28 12:49:24 +02:00
|
|
|
DestinationLen = AsciiStrLen(Destination);
|
2019-09-03 11:58:42 +02:00
|
|
|
AsciiStrnCpy (Destination + DestinationLen, Source, Length);
|
|
|
|
Destination[DestinationLen + Length] = '\0';
|
|
|
|
|
|
|
|
//
|
|
|
|
// Size of the resulting string should never be zero.
|
|
|
|
// PcdMaximumUnicodeStringLength is tested inside StrLen().
|
|
|
|
//
|
|
|
|
ASSERT (AsciiStrSize (Destination) != 0);
|
|
|
|
return Destination;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the first occurrence of a Null-terminated ASCII sub-string
|
|
|
|
in a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
This function scans the contents of the ASCII string specified by String
|
|
|
|
and returns the first occurrence of SearchString. If SearchString is not
|
|
|
|
found in String, then NULL is returned. If the length of SearchString is zero,
|
|
|
|
then String is returned.
|
|
|
|
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If SearchString is NULL, then ASSERT().
|
|
|
|
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and SearchString or
|
|
|
|
String contains more than PcdMaximumAsciiStringLength Unicode characters
|
|
|
|
not including the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated ASCII string.
|
|
|
|
@param SearchString A pointer to a Null-terminated ASCII string to search for.
|
|
|
|
|
|
|
|
@retval NULL If the SearchString does not appear in String.
|
|
|
|
@retval others If there is a match return the first occurrence of SearchingString.
|
|
|
|
If the length of SearchString is zero,return String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR8 *
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrStr (
|
|
|
|
IN CONST CHAR8 *String,
|
|
|
|
IN CONST CHAR8 *SearchString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CONST CHAR8 *FirstMatch;
|
|
|
|
CONST CHAR8 *SearchStringTmp;
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT both strings are less long than PcdMaximumAsciiStringLength
|
|
|
|
//
|
|
|
|
// ASSERT (AsciiStrSize (String) != 0);
|
|
|
|
// ASSERT (AsciiStrSize (SearchString) != 0);
|
|
|
|
if (!String || !SearchString) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*SearchString == '\0') {
|
|
|
|
return (CHAR8 *) String;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*String != '\0') {
|
|
|
|
SearchStringTmp = SearchString;
|
|
|
|
FirstMatch = String;
|
|
|
|
|
|
|
|
while ((*String == *SearchStringTmp)
|
|
|
|
&& (*String != '\0')) {
|
|
|
|
String++;
|
|
|
|
SearchStringTmp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*SearchStringTmp == '\0') {
|
|
|
|
return (CHAR8 *) FirstMatch;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*String == '\0') {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
String = FirstMatch + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated ASCII decimal string to a value of type
|
|
|
|
UINTN.
|
|
|
|
|
|
|
|
This function returns a value of type UINTN by interpreting the contents
|
|
|
|
of the ASCII string String as a decimal number. The format of the input
|
|
|
|
ASCII string String is:
|
|
|
|
|
|
|
|
[spaces] [decimal digits].
|
|
|
|
|
|
|
|
The valid decimal digit character is in the range [0-9]. The function will
|
|
|
|
ignore the pad space, which includes spaces or tab characters, before the digits.
|
|
|
|
The running zero in the beginning of [decimal digits] will be ignored. Then, the
|
|
|
|
function stops at the first character that is a not a valid decimal character or
|
|
|
|
Null-terminator, whichever on comes first.
|
|
|
|
|
|
|
|
If String has only pad spaces, then 0 is returned.
|
|
|
|
If String has no pad spaces or valid decimal digits, then 0 is returned.
|
|
|
|
If the number represented by String overflows according to the range defined by
|
|
|
|
UINTN, then MAX_UINTN is returned.
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and String contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrDecimalToUintn (
|
|
|
|
IN CONST CHAR8 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
Status = AsciiStrDecimalToUintnS (String, (CHAR8 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated ASCII decimal string to a value of type
|
|
|
|
UINT64.
|
|
|
|
|
|
|
|
This function returns a value of type UINT64 by interpreting the contents
|
|
|
|
of the ASCII string String as a decimal number. The format of the input
|
|
|
|
ASCII string String is:
|
|
|
|
|
|
|
|
[spaces] [decimal digits].
|
|
|
|
|
|
|
|
The valid decimal digit character is in the range [0-9]. The function will
|
|
|
|
ignore the pad space, which includes spaces or tab characters, before the digits.
|
|
|
|
The running zero in the beginning of [decimal digits] will be ignored. Then, the
|
|
|
|
function stops at the first character that is a not a valid decimal character or
|
|
|
|
Null-terminator, whichever on comes first.
|
|
|
|
|
|
|
|
If String has only pad spaces, then 0 is returned.
|
|
|
|
If String has no pad spaces or valid decimal digits, then 0 is returned.
|
|
|
|
If the number represented by String overflows according to the range defined by
|
|
|
|
UINT64, then MAX_UINT64 is returned.
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and String contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT64
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrDecimalToUint64 (
|
|
|
|
IN CONST CHAR8 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
Status = AsciiStrDecimalToUint64S (String, (CHAR8 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
|
|
|
|
|
|
|
|
This function returns a value of type UINTN by interpreting the contents of
|
|
|
|
the ASCII string String as a hexadecimal number. The format of the input ASCII
|
|
|
|
string String is:
|
|
|
|
|
|
|
|
[spaces][zeros][x][hexadecimal digits].
|
|
|
|
|
|
|
|
The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
|
|
|
|
The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
|
|
|
|
appears in the input string, it must be prefixed with at least one 0. The function
|
|
|
|
will ignore the pad space, which includes spaces or tab characters, before [zeros],
|
|
|
|
[x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
|
|
|
|
will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
|
|
|
|
digit. Then, the function stops at the first character that is a not a valid
|
|
|
|
hexadecimal character or Null-terminator, whichever on comes first.
|
|
|
|
|
|
|
|
If String has only pad spaces, then 0 is returned.
|
|
|
|
If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
|
|
|
|
0 is returned.
|
|
|
|
|
|
|
|
If the number represented by String overflows according to the range defined by UINTN,
|
|
|
|
then MAX_UINTN is returned.
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero,
|
|
|
|
and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
|
|
|
|
the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINTN
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrHexToUintn (
|
|
|
|
IN CONST CHAR8 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
|
|
|
|
Status = AsciiStrHexToUintnS (String, (CHAR8 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
|
|
|
|
|
|
|
|
This function returns a value of type UINT64 by interpreting the contents of
|
|
|
|
the ASCII string String as a hexadecimal number. The format of the input ASCII
|
|
|
|
string String is:
|
|
|
|
|
|
|
|
[spaces][zeros][x][hexadecimal digits].
|
|
|
|
|
|
|
|
The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
|
|
|
|
The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
|
|
|
|
appears in the input string, it must be prefixed with at least one 0. The function
|
|
|
|
will ignore the pad space, which includes spaces or tab characters, before [zeros],
|
|
|
|
[x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
|
|
|
|
will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
|
|
|
|
digit. Then, the function stops at the first character that is a not a valid
|
|
|
|
hexadecimal character or Null-terminator, whichever on comes first.
|
|
|
|
|
|
|
|
If String has only pad spaces, then 0 is returned.
|
|
|
|
If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
|
|
|
|
0 is returned.
|
|
|
|
|
|
|
|
If the number represented by String overflows according to the range defined by UINT64,
|
|
|
|
then MAX_UINT64 is returned.
|
|
|
|
If String is NULL, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero,
|
|
|
|
and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
|
|
|
|
the Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param String A pointer to a Null-terminated ASCII string.
|
|
|
|
|
|
|
|
@retval Value translated from String.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT64
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrHexToUint64 (
|
|
|
|
IN CONST CHAR8 *String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 Result = 0;
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
Status = AsciiStrHexToUint64S (String, (CHAR8 **) NULL, &Result);
|
|
|
|
if (Status != RETURN_SUCCESS) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
|
|
|
|
|
|
|
/**
|
|
|
|
[ATTENTION] This function is deprecated for security reason.
|
|
|
|
|
|
|
|
Convert one Null-terminated ASCII string to a Null-terminated
|
|
|
|
Unicode string and returns the Unicode string.
|
|
|
|
|
|
|
|
This function converts the contents of the ASCII string Source to the Unicode
|
|
|
|
string Destination, and returns Destination. The function terminates the
|
|
|
|
Unicode string Destination by appending a Null-terminator character at the end.
|
|
|
|
The caller is responsible to make sure Destination points to a buffer with size
|
2020-04-28 12:49:24 +02:00
|
|
|
equal or greater than ((AsciiStrLen(Source) + 1) * sizeof (CHAR16)) in bytes.
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
If Destination is NULL, then ASSERT().
|
|
|
|
If Destination is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Source is NULL, then ASSERT().
|
|
|
|
If Source and Destination overlap, then ASSERT().
|
|
|
|
If PcdMaximumAsciiStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
|
|
|
|
then ASSERT().
|
|
|
|
If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
|
|
|
|
PcdMaximumUnicodeStringLength ASCII characters not including the
|
|
|
|
Null-terminator, then ASSERT().
|
|
|
|
|
|
|
|
@param Source A pointer to a Null-terminated ASCII string.
|
|
|
|
@param Destination A pointer to a Null-terminated Unicode string.
|
|
|
|
|
|
|
|
@return Destination.
|
|
|
|
|
|
|
|
**/
|
|
|
|
CHAR16 *
|
|
|
|
EFIAPI
|
|
|
|
AsciiStrToUnicodeStr (
|
|
|
|
IN CONST CHAR8 *Source,
|
|
|
|
OUT CHAR16 *Destination
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CHAR16 *ReturnValue;
|
|
|
|
|
|
|
|
// ASSERT (Destination != NULL);
|
|
|
|
if (!Destination) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT Source is less long than PcdMaximumAsciiStringLength
|
|
|
|
//
|
|
|
|
// ASSERT (AsciiStrSize (Source) != 0);
|
|
|
|
if (!AsciiStrSize (Source)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Source and Destination should not overlap
|
|
|
|
//
|
2020-04-28 12:49:24 +02:00
|
|
|
ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen(Source));
|
2019-09-03 11:58:42 +02:00
|
|
|
ASSERT ((UINTN) (Source - (CHAR8 *) Destination) >= (AsciiStrSize (Source) * sizeof (CHAR16)));
|
|
|
|
|
|
|
|
|
|
|
|
ReturnValue = Destination;
|
|
|
|
while (*Source != '\0') {
|
|
|
|
*(Destination++) = (CHAR16)(UINT8) *(Source++);
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// End the Destination with a NULL.
|
|
|
|
//
|
|
|
|
*Destination = '\0';
|
|
|
|
|
|
|
|
//
|
|
|
|
// ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength
|
|
|
|
//
|
|
|
|
ASSERT (StrSize (ReturnValue) != 0);
|
|
|
|
|
|
|
|
return ReturnValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
STATIC CHAR8 EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
"abcdefghijklmnopqrstuvwxyz"
|
|
|
|
"0123456789+/";
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert binary data to a Base64 encoded ascii string based on RFC4648.
|
|
|
|
|
|
|
|
Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.
|
|
|
|
The Ascii string is produced by converting the data string specified by Source and SourceLength.
|
|
|
|
|
|
|
|
@param Source Input UINT8 data
|
|
|
|
@param SourceLength Number of UINT8 bytes of data
|
|
|
|
@param Destination Pointer to output string buffer
|
|
|
|
@param DestinationSize Size of ascii buffer. Set to 0 to get the size needed.
|
|
|
|
Caller is responsible for passing in buffer of DestinationSize
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS When ascii buffer is filled in.
|
|
|
|
@retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is NULL.
|
|
|
|
@retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL If SourceLength is 0 and DestinationSize is <1.
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL If Destination is NULL or DestinationSize is smaller than required buffersize.
|
|
|
|
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
Base64Encode (
|
|
|
|
IN CONST UINT8 *Source,
|
|
|
|
IN UINTN SourceLength,
|
|
|
|
OUT CHAR8 *Destination OPTIONAL,
|
|
|
|
IN OUT UINTN *DestinationSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
|
|
|
|
UINTN RequiredSize;
|
|
|
|
UINTN Left;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check pointers, and SourceLength is valid
|
|
|
|
//
|
|
|
|
if ((Source == NULL) || (DestinationSize == NULL)) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Allow for RFC 4648 test vector 1
|
|
|
|
//
|
|
|
|
if (SourceLength == 0) {
|
|
|
|
if (*DestinationSize < 1) {
|
|
|
|
*DestinationSize = 1;
|
|
|
|
return RETURN_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
*DestinationSize = 1;
|
|
|
|
*Destination = '\0';
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check if SourceLength or DestinationSize is valid
|
|
|
|
//
|
|
|
|
if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// 4 ascii per 3 bytes + NULL
|
|
|
|
//
|
|
|
|
RequiredSize = ((SourceLength + 2) / 3) * 4 + 1;
|
|
|
|
if ((Destination == NULL) || *DestinationSize < RequiredSize) {
|
|
|
|
*DestinationSize = RequiredSize;
|
|
|
|
return RETURN_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Left = SourceLength;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Encode 24 bits (three bytes) into 4 ascii characters
|
|
|
|
//
|
|
|
|
while (Left >= 3) {
|
|
|
|
|
|
|
|
*Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2 ];
|
|
|
|
*Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];
|
|
|
|
*Destination++ = EncodingTable[((Source[1] & 0x0f) << 2) + ((Source[2] & 0xc0) >> 6)];
|
|
|
|
*Destination++ = EncodingTable[( Source[2] & 0x3f)];
|
|
|
|
Left -= 3;
|
|
|
|
Source += 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Handle the remainder, and add padding '=' characters as necessary.
|
|
|
|
//
|
|
|
|
switch (Left) {
|
|
|
|
case 0:
|
|
|
|
|
|
|
|
//
|
|
|
|
// No bytes Left, done.
|
|
|
|
//
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
//
|
|
|
|
// One more data byte, two pad characters
|
|
|
|
//
|
|
|
|
*Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];
|
|
|
|
*Destination++ = EncodingTable[((Source[0] & 0x03) << 4)];
|
|
|
|
*Destination++ = '=';
|
|
|
|
*Destination++ = '=';
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
|
|
|
|
//
|
|
|
|
// Two more data bytes, and one pad character
|
|
|
|
//
|
|
|
|
*Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];
|
|
|
|
*Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];
|
|
|
|
*Destination++ = EncodingTable[((Source[1] & 0x0f) << 2)];
|
|
|
|
*Destination++ = '=';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// Add terminating NULL
|
|
|
|
//
|
|
|
|
*Destination = '\0';
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-09-04 12:44:38 +02:00
|
|
|
Decode Base64 ASCII encoded data to 8-bit binary representation, based on
|
|
|
|
RFC4648.
|
|
|
|
|
|
|
|
Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.
|
|
|
|
|
|
|
|
Whitespace is ignored at all positions:
|
|
|
|
- 0x09 ('\t') horizontal tab
|
|
|
|
- 0x0A ('\n') new line
|
|
|
|
- 0x0B ('\v') vertical tab
|
|
|
|
- 0x0C ('\f') form feed
|
|
|
|
- 0x0D ('\r') carriage return
|
|
|
|
- 0x20 (' ') space
|
|
|
|
|
|
|
|
The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated
|
|
|
|
and enforced at the end of the Base64 ASCII encoded data, and only there.
|
|
|
|
|
|
|
|
Other characters outside of the encoding alphabet cause the function to
|
|
|
|
reject the Base64 ASCII encoded data.
|
|
|
|
|
|
|
|
@param[in] Source Array of CHAR8 elements containing the Base64
|
|
|
|
ASCII encoding. May be NULL if SourceSize is
|
|
|
|
zero.
|
|
|
|
|
|
|
|
@param[in] SourceSize Number of CHAR8 elements in Source.
|
|
|
|
|
|
|
|
@param[out] Destination Array of UINT8 elements receiving the decoded
|
|
|
|
8-bit binary representation. Allocated by the
|
|
|
|
caller. May be NULL if DestinationSize is
|
|
|
|
zero on input. If NULL, decoding is
|
|
|
|
performed, but the 8-bit binary
|
|
|
|
representation is not stored. If non-NULL and
|
|
|
|
the function returns an error, the contents
|
|
|
|
of Destination are indeterminate.
|
|
|
|
|
|
|
|
@param[in,out] DestinationSize On input, the number of UINT8 elements that
|
|
|
|
the caller allocated for Destination. On
|
|
|
|
output, if the function returns
|
|
|
|
RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,
|
|
|
|
the number of UINT8 elements that are
|
|
|
|
required for decoding the Base64 ASCII
|
|
|
|
representation. If the function returns a
|
|
|
|
value different from both RETURN_SUCCESS and
|
|
|
|
RETURN_BUFFER_TOO_SMALL, then DestinationSize
|
|
|
|
is indeterminate on output.
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS SourceSize CHAR8 elements at Source have
|
|
|
|
been decoded to on-output DestinationSize
|
|
|
|
UINT8 elements at Destination. Note that
|
|
|
|
RETURN_SUCCESS covers the case when
|
|
|
|
DestinationSize is zero on input, and
|
|
|
|
Source decodes to zero bytes (due to
|
|
|
|
containing at most ignored whitespace).
|
|
|
|
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL The input value of DestinationSize is not
|
|
|
|
large enough for decoding SourceSize CHAR8
|
|
|
|
elements at Source. The required number of
|
|
|
|
UINT8 elements has been stored to
|
|
|
|
DestinationSize.
|
|
|
|
|
|
|
|
@retval RETURN_INVALID_PARAMETER DestinationSize is NULL.
|
|
|
|
|
|
|
|
@retval RETURN_INVALID_PARAMETER Source is NULL, but SourceSize is not zero.
|
|
|
|
|
|
|
|
@retval RETURN_INVALID_PARAMETER Destination is NULL, but DestinationSize is
|
|
|
|
not zero on input.
|
|
|
|
|
|
|
|
@retval RETURN_INVALID_PARAMETER Source is non-NULL, and (Source +
|
|
|
|
SourceSize) would wrap around MAX_ADDRESS.
|
|
|
|
|
|
|
|
@retval RETURN_INVALID_PARAMETER Destination is non-NULL, and (Destination +
|
|
|
|
DestinationSize) would wrap around
|
|
|
|
MAX_ADDRESS, as specified on input.
|
|
|
|
|
|
|
|
@retval RETURN_INVALID_PARAMETER None of Source and Destination are NULL,
|
|
|
|
and CHAR8[SourceSize] at Source overlaps
|
|
|
|
UINT8[DestinationSize] at Destination, as
|
|
|
|
specified on input.
|
|
|
|
|
|
|
|
@retval RETURN_INVALID_PARAMETER Invalid CHAR8 element encountered in
|
|
|
|
Source.
|
|
|
|
**/
|
2020-07-09 21:06:48 +02:00
|
|
|
#if 1
|
2019-09-03 11:58:42 +02:00
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
Base64Decode (
|
2019-09-04 12:44:38 +02:00
|
|
|
IN CONST CHAR8 *Source OPTIONAL,
|
|
|
|
IN UINTN SourceSize,
|
|
|
|
OUT UINT8 *Destination OPTIONAL,
|
|
|
|
IN OUT UINTN *DestinationSize
|
2019-09-03 11:58:42 +02:00
|
|
|
)
|
|
|
|
{
|
2019-09-04 12:44:38 +02:00
|
|
|
BOOLEAN PaddingMode;
|
|
|
|
UINTN SixBitGroupsConsumed;
|
|
|
|
UINT32 Accumulator;
|
|
|
|
UINTN OriginalDestinationSize;
|
|
|
|
UINTN SourceIndex;
|
|
|
|
CHAR8 SourceChar;
|
|
|
|
UINT32 Base64Value;
|
|
|
|
UINT8 DestinationOctet;
|
|
|
|
|
|
|
|
if (DestinationSize == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Check Source array validity.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
if (Source == NULL) {
|
|
|
|
if (SourceSize > 0) {
|
|
|
|
//
|
|
|
|
// At least one CHAR8 element at NULL Source.
|
|
|
|
//
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
} else if (SourceSize > MAX_ADDRESS - (UINTN)Source) {
|
|
|
|
//
|
|
|
|
// Non-NULL Source, but it wraps around.
|
|
|
|
//
|
2019-09-03 11:58:42 +02:00
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Check Destination array validity.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
if (Destination == NULL) {
|
|
|
|
if (*DestinationSize > 0) {
|
|
|
|
//
|
|
|
|
// At least one UINT8 element at NULL Destination.
|
|
|
|
//
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
} else if (*DestinationSize > MAX_ADDRESS - (UINTN)Destination) {
|
|
|
|
//
|
|
|
|
// Non-NULL Destination, but it wraps around.
|
|
|
|
//
|
2019-09-03 11:58:42 +02:00
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2019-09-04 12:44:38 +02:00
|
|
|
//
|
|
|
|
// Check for overlap.
|
|
|
|
//
|
|
|
|
if (Source != NULL && Destination != NULL) {
|
|
|
|
//
|
|
|
|
// Both arrays have been provided, and we know from earlier that each array
|
|
|
|
// is valid in itself.
|
|
|
|
//
|
|
|
|
if ((UINTN)Source + SourceSize <= (UINTN)Destination) {
|
|
|
|
//
|
|
|
|
// Source array precedes Destination array, OK.
|
|
|
|
//
|
|
|
|
} else if ((UINTN)Destination + *DestinationSize <= (UINTN)Source) {
|
|
|
|
//
|
|
|
|
// Destination array precedes Source array, OK.
|
|
|
|
//
|
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// Overlap.
|
|
|
|
//
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Decoding loop setup.
|
|
|
|
//
|
|
|
|
PaddingMode = FALSE;
|
|
|
|
SixBitGroupsConsumed = 0;
|
|
|
|
Accumulator = 0;
|
|
|
|
OriginalDestinationSize = *DestinationSize;
|
|
|
|
*DestinationSize = 0;
|
|
|
|
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Decoding loop.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
for (SourceIndex = 0; SourceIndex < SourceSize; SourceIndex++) {
|
|
|
|
SourceChar = Source[SourceIndex];
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Whitespace is ignored at all positions (regardless of padding mode).
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
if (SourceChar == '\t' || SourceChar == '\n' || SourceChar == '\v' ||
|
|
|
|
SourceChar == '\f' || SourceChar == '\r' || SourceChar == ' ') {
|
|
|
|
continue;
|
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
2019-09-04 12:44:38 +02:00
|
|
|
//
|
|
|
|
// If we're in padding mode, accept another padding character, as long as
|
|
|
|
// that padding character completes the quantum. This completes case (2)
|
|
|
|
// from RFC4648, Chapter 4. "Base 64 Encoding":
|
|
|
|
//
|
|
|
|
// (2) The final quantum of encoding input is exactly 8 bits; here, the
|
|
|
|
// final unit of encoded output will be two characters followed by two
|
|
|
|
// "=" padding characters.
|
|
|
|
//
|
|
|
|
if (PaddingMode) {
|
|
|
|
if (SourceChar == '=' && SixBitGroupsConsumed == 3) {
|
|
|
|
SixBitGroupsConsumed = 0;
|
|
|
|
continue;
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
2019-09-04 12:44:38 +02:00
|
|
|
return RETURN_INVALID_PARAMETER;
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
|
2019-09-04 12:44:38 +02:00
|
|
|
//
|
|
|
|
// When not in padding mode, decode Base64Value based on RFC4648, "Table 1:
|
|
|
|
// The Base 64 Alphabet".
|
|
|
|
//
|
|
|
|
if ('A' <= SourceChar && SourceChar <= 'Z') {
|
|
|
|
Base64Value = SourceChar - 'A';
|
|
|
|
} else if ('a' <= SourceChar && SourceChar <= 'z') {
|
|
|
|
Base64Value = 26 + (SourceChar - 'a');
|
|
|
|
} else if ('0' <= SourceChar && SourceChar <= '9') {
|
|
|
|
Base64Value = 52 + (SourceChar - '0');
|
|
|
|
} else if (SourceChar == '+') {
|
|
|
|
Base64Value = 62;
|
|
|
|
} else if (SourceChar == '/') {
|
|
|
|
Base64Value = 63;
|
|
|
|
} else if (SourceChar == '=') {
|
|
|
|
//
|
|
|
|
// Enter padding mode.
|
|
|
|
//
|
|
|
|
PaddingMode = TRUE;
|
|
|
|
|
|
|
|
if (SixBitGroupsConsumed == 2) {
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// If we have consumed two 6-bit groups from the current quantum before
|
|
|
|
// encountering the first padding character, then this is case (2) from
|
|
|
|
// RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,
|
|
|
|
// and we'll enforce another padding character.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
SixBitGroupsConsumed = 3;
|
|
|
|
} else if (SixBitGroupsConsumed == 3) {
|
|
|
|
//
|
|
|
|
// If we have consumed three 6-bit groups from the current quantum
|
|
|
|
// before encountering the first padding character, then this is case
|
|
|
|
// (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now
|
|
|
|
// complete.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
SixBitGroupsConsumed = 0;
|
|
|
|
} else {
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Padding characters are not allowed at the first two positions of a
|
|
|
|
// quantum.
|
|
|
|
//
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
|
2019-09-04 12:44:38 +02:00
|
|
|
//
|
|
|
|
// Wherever in a quantum we enter padding mode, we enforce the padding
|
|
|
|
// bits pending in the accumulator -- from the last 6-bit group just
|
|
|
|
// preceding the padding character -- to be zero. Refer to RFC4648,
|
|
|
|
// Chapter 3.5. "Canonical Encoding".
|
|
|
|
//
|
|
|
|
if (Accumulator != 0) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
2019-09-04 12:44:38 +02:00
|
|
|
//
|
|
|
|
// Advance to the next source character.
|
|
|
|
//
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// Other characters outside of the encoding alphabet are rejected.
|
|
|
|
//
|
2019-09-03 11:58:42 +02:00
|
|
|
return RETURN_INVALID_PARAMETER;
|
2019-09-04 12:44:38 +02:00
|
|
|
}
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Feed the bits of the current 6-bit group of the quantum to the
|
|
|
|
// accumulator.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
Accumulator = (Accumulator << 6) | Base64Value;
|
|
|
|
SixBitGroupsConsumed++;
|
|
|
|
switch (SixBitGroupsConsumed) {
|
|
|
|
case 1:
|
|
|
|
//
|
|
|
|
// No octet to spill after consuming the first 6-bit group of the
|
|
|
|
// quantum; advance to the next source character.
|
|
|
|
//
|
|
|
|
continue;
|
|
|
|
case 2:
|
|
|
|
//
|
|
|
|
// 12 bits accumulated (6 pending + 6 new); prepare for spilling an
|
|
|
|
// octet. 4 bits remain pending.
|
|
|
|
//
|
|
|
|
DestinationOctet = (UINT8)(Accumulator >> 4);
|
|
|
|
Accumulator &= 0xF;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
//
|
|
|
|
// 10 bits accumulated (4 pending + 6 new); prepare for spilling an
|
|
|
|
// octet. 2 bits remain pending.
|
|
|
|
//
|
|
|
|
DestinationOctet = (UINT8)(Accumulator >> 2);
|
|
|
|
Accumulator &= 0x3;
|
|
|
|
break;
|
|
|
|
default:
|
2020-07-09 21:06:48 +02:00
|
|
|
// ASSERT (SixBitGroupsConsumed == 4);
|
2019-09-04 12:44:38 +02:00
|
|
|
//
|
|
|
|
// 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.
|
|
|
|
// The quantum is complete, 0 bits remain pending.
|
|
|
|
//
|
|
|
|
DestinationOctet = (UINT8)Accumulator;
|
|
|
|
Accumulator = 0;
|
|
|
|
SixBitGroupsConsumed = 0;
|
|
|
|
break;
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Store the decoded octet if there's room left. Increment
|
|
|
|
// (*DestinationSize) unconditionally.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
if (*DestinationSize < OriginalDestinationSize) {
|
2020-07-09 21:06:48 +02:00
|
|
|
// ASSERT (Destination != NULL);
|
2019-09-04 12:44:38 +02:00
|
|
|
Destination[*DestinationSize] = DestinationOctet;
|
|
|
|
}
|
|
|
|
(*DestinationSize)++;
|
2019-09-03 11:58:42 +02:00
|
|
|
|
|
|
|
//
|
2019-09-04 12:44:38 +02:00
|
|
|
// Advance to the next source character.
|
2019-09-03 11:58:42 +02:00
|
|
|
//
|
|
|
|
}
|
|
|
|
|
2019-09-04 12:44:38 +02:00
|
|
|
//
|
|
|
|
// If Source terminates mid-quantum, then Source is invalid.
|
|
|
|
//
|
|
|
|
if (SixBitGroupsConsumed != 0) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Done.
|
|
|
|
//
|
|
|
|
if (*DestinationSize <= OriginalDestinationSize) {
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
return RETURN_BUFFER_TOO_SMALL;
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Converts an 8-bit value to an 8-bit BCD value.
|
|
|
|
|
|
|
|
Converts the 8-bit value specified by Value to BCD. The BCD value is
|
|
|
|
returned.
|
|
|
|
|
|
|
|
If Value >= 100, then ASSERT().
|
|
|
|
|
|
|
|
@param Value The 8-bit value to convert to BCD. Range 0..99.
|
|
|
|
|
|
|
|
@return The BCD value.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT8
|
|
|
|
EFIAPI
|
|
|
|
DecimalToBcd8 (
|
|
|
|
IN UINT8 Value
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ASSERT (Value < 100);
|
|
|
|
return (UINT8) (((Value / 10) << 4) | (Value % 10));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Converts an 8-bit BCD value to an 8-bit value.
|
|
|
|
|
|
|
|
Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit
|
|
|
|
value is returned.
|
|
|
|
|
|
|
|
If Value >= 0xA0, then ASSERT().
|
|
|
|
If (Value & 0x0F) >= 0x0A, then ASSERT().
|
|
|
|
|
|
|
|
@param Value The 8-bit BCD value to convert to an 8-bit value.
|
|
|
|
|
|
|
|
@return The 8-bit value is returned.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT8
|
|
|
|
EFIAPI
|
|
|
|
BcdToDecimal8 (
|
|
|
|
IN UINT8 Value
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ASSERT (Value < 0xa0);
|
|
|
|
ASSERT ((Value & 0xf) < 0xa);
|
|
|
|
return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));
|
|
|
|
}
|