/** @file | |
Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "Edb.h" | |
/** | |
Convert hex string to uint. | |
@param Str - The string | |
**/ | |
UINTN | |
EFIAPI | |
Xtoi ( | |
CHAR16 *Str | |
) | |
{ | |
UINTN RetVal; | |
CHAR16 TempChar; | |
UINTN MaxVal; | |
ASSERT (Str != NULL); | |
MaxVal = (UINTN)-1 >> 4; | |
// | |
// skip preceeding white space | |
// | |
while (*Str != '\0' && *Str == ' ') { | |
Str += 1; | |
} | |
// | |
// skip preceeding zeros | |
// | |
while (*Str != '\0' && *Str == '0') { | |
Str += 1; | |
} | |
// | |
// skip preceeding white space | |
// | |
if ((*Str != '\0') && ((*Str == 'x') || (*Str == 'X'))) { | |
Str += 1; | |
} | |
// | |
// convert hex digits | |
// | |
RetVal = 0; | |
TempChar = *(Str++); | |
while (TempChar != '\0') { | |
if ((TempChar >= 'a') && (TempChar <= 'f')) { | |
TempChar -= 'a' - 'A'; | |
} | |
if (((TempChar >= '0') && (TempChar <= '9')) || ((TempChar >= 'A') && (TempChar <= 'F'))) { | |
if (RetVal > MaxVal) { | |
return (UINTN)-1; | |
} | |
RetVal = (RetVal << 4) | (TempChar - (TempChar >= 'A' ? 'A' - 10 : '0')); | |
} else { | |
break; | |
} | |
TempChar = *(Str++); | |
} | |
return RetVal; | |
} | |
/** | |
Convert hex string to uint. | |
@param Str - The string | |
**/ | |
UINT64 | |
EFIAPI | |
LXtoi ( | |
CHAR16 *Str | |
) | |
{ | |
UINT64 RetVal; | |
CHAR16 TempChar; | |
UINT64 MaxVal; | |
ASSERT (Str != NULL); | |
MaxVal = RShiftU64 ((UINT64)-1, 4); | |
// | |
// skip preceeding white space | |
// | |
while (*Str != '\0' && *Str == ' ') { | |
Str += 1; | |
} | |
// | |
// skip preceeding zeros | |
// | |
while (*Str != '\0' && *Str == '0') { | |
Str += 1; | |
} | |
// | |
// skip preceeding white space | |
// | |
if ((*Str != '\0') && ((*Str == 'x') || (*Str == 'X'))) { | |
Str += 1; | |
} | |
// | |
// convert hex digits | |
// | |
RetVal = 0; | |
TempChar = *(Str++); | |
while (TempChar != '\0') { | |
if ((TempChar >= 'a') && (TempChar <= 'f')) { | |
TempChar -= 'a' - 'A'; | |
} | |
if (((TempChar >= '0') && (TempChar <= '9')) || ((TempChar >= 'A') && (TempChar <= 'F'))) { | |
if (RetVal > MaxVal) { | |
return (UINT64)-1; | |
} | |
RetVal = LShiftU64 (RetVal, 4); | |
RetVal = RetVal + (TempChar - (TempChar >= 'A' ? 'A' - 10 : '0')); | |
} else { | |
break; | |
} | |
TempChar = *(Str++); | |
} | |
return RetVal; | |
} | |
/** | |
Convert hex string to uint. | |
@param Str - The string | |
**/ | |
UINTN | |
EFIAPI | |
Atoi ( | |
CHAR16 *Str | |
) | |
{ | |
UINTN RetVal; | |
CHAR16 TempChar; | |
UINTN MaxVal; | |
UINTN ResteVal; | |
ASSERT (Str != NULL); | |
MaxVal = (UINTN)-1 / 10; | |
ResteVal = (UINTN)-1 % 10; | |
// | |
// skip preceeding white space | |
// | |
while (*Str != '\0' && *Str == ' ') { | |
Str += 1; | |
} | |
// | |
// convert digits | |
// | |
RetVal = 0; | |
TempChar = *(Str++); | |
while (TempChar != '\0') { | |
if ((TempChar >= '0') && (TempChar <= '9')) { | |
if ((RetVal > MaxVal) || ((RetVal == MaxVal) && (TempChar - '0' > (INTN)ResteVal))) { | |
return (UINTN)-1; | |
} | |
RetVal = (RetVal * 10) + TempChar - '0'; | |
} else { | |
break; | |
} | |
TempChar = *(Str++); | |
} | |
return RetVal; | |
} | |
/** | |
Convert hex string to uint. | |
@param Str - The string | |
**/ | |
UINTN | |
EFIAPI | |
AsciiXtoi ( | |
CHAR8 *Str | |
) | |
{ | |
UINTN RetVal; | |
CHAR8 TempChar; | |
UINTN MaxVal; | |
ASSERT (Str != NULL); | |
MaxVal = (UINTN)-1 >> 4; | |
// | |
// skip preceeding white space | |
// | |
while (*Str != '\0' && *Str == ' ') { | |
Str += 1; | |
} | |
// | |
// skip preceeding zeros | |
// | |
while (*Str != '\0' && *Str == '0') { | |
Str += 1; | |
} | |
// | |
// skip preceeding white space | |
// | |
if ((*Str != '\0') && ((*Str == 'x') || (*Str == 'X'))) { | |
Str += 1; | |
} | |
// | |
// convert hex digits | |
// | |
RetVal = 0; | |
TempChar = *(Str++); | |
while (TempChar != '\0') { | |
if ((TempChar >= 'a') && (TempChar <= 'f')) { | |
TempChar -= 'a' - 'A'; | |
} | |
if (((TempChar >= '0') && (TempChar <= '9')) || ((TempChar >= 'A') && (TempChar <= 'F'))) { | |
if (RetVal > MaxVal) { | |
return (UINTN)-1; | |
} | |
RetVal = (RetVal << 4) | (TempChar - (TempChar >= 'A' ? 'A' - 10 : '0')); | |
} else { | |
break; | |
} | |
TempChar = *(Str++); | |
} | |
return RetVal; | |
} | |
/** | |
Convert hex string to uint. | |
@param Str - The string | |
**/ | |
UINTN | |
EFIAPI | |
AsciiAtoi ( | |
CHAR8 *Str | |
) | |
{ | |
UINTN RetVal; | |
CHAR8 TempChar; | |
UINTN MaxVal; | |
UINTN ResteVal; | |
ASSERT (Str != NULL); | |
MaxVal = (UINTN)-1 / 10; | |
ResteVal = (UINTN)-1 % 10; | |
// | |
// skip preceeding white space | |
// | |
while (*Str != '\0' && *Str == ' ') { | |
Str += 1; | |
} | |
// | |
// convert digits | |
// | |
RetVal = 0; | |
TempChar = *(Str++); | |
while (TempChar != '\0') { | |
if ((TempChar >= '0') && (TempChar <= '9')) { | |
if ((RetVal > MaxVal) || ((RetVal == MaxVal) && (TempChar - '0' > (INTN)ResteVal))) { | |
return (UINTN)-1; | |
} | |
RetVal = (RetVal * 10) + TempChar - '0'; | |
} else { | |
break; | |
} | |
TempChar = *(Str++); | |
} | |
return RetVal; | |
} | |
/** | |
Compare the Unicode and Ascii string pointed by String to the string pointed by String2. | |
@param String - Unicode String to process | |
@param String2 - Ascii string to process | |
@return Return a positive integer if String is lexicall greater than String2; Zero if | |
the two strings are identical; and a negative interger if String is lexically | |
less than String2. | |
**/ | |
INTN | |
EFIAPI | |
StrCmpUnicodeAndAscii ( | |
IN CHAR16 *String, | |
IN CHAR8 *String2 | |
) | |
{ | |
while (*String != '\0') { | |
if (*String != (CHAR16)*String2) { | |
break; | |
} | |
String += 1; | |
String2 += 1; | |
} | |
return (*String - (CHAR16)*String2); | |
} | |
/** | |
Compare the Unicode string pointed by String to the string pointed by String2. | |
@param String - Unicode String to process | |
@param String2 - Unicode string to process | |
@return Return a positive integer if String is lexically greater than String2; Zero if | |
the two strings are identical; and a negative integer if String is lexically | |
less than String2. | |
**/ | |
INTN | |
EFIAPI | |
StriCmp ( | |
IN CHAR16 *String, | |
IN CHAR16 *String2 | |
) | |
{ | |
while ((*String != L'\0') && | |
(CharToUpper (*String) == CharToUpper (*String2))) | |
{ | |
String++; | |
String2++; | |
} | |
return CharToUpper (*String) - CharToUpper (*String2); | |
} | |
/** | |
Compare the Unicode and Ascii string pointed by String to the string pointed by String2. | |
@param String - Unicode String to process | |
@param String2 - Ascii string to process | |
@return Return a positive integer if String is lexically greater than String2; Zero if | |
the two strings are identical; and a negative integer if String is lexically | |
less than String2. | |
**/ | |
INTN | |
EFIAPI | |
StriCmpUnicodeAndAscii ( | |
IN CHAR16 *String, | |
IN CHAR8 *String2 | |
) | |
{ | |
while ((*String != L'\0') && | |
(CharToUpper (*String) == (CHAR16)AsciiCharToUpper (*String2))) | |
{ | |
String++; | |
String2++; | |
} | |
return CharToUpper (*String) - (CHAR16)AsciiCharToUpper (*String2); | |
} | |
/** | |
Verify if the string is end with the sub string. | |
@param Str - The string where to search the sub string | |
@param SubStr - The substring. | |
**/ | |
BOOLEAN | |
EFIAPI | |
StrEndWith ( | |
IN CHAR16 *Str, | |
IN CHAR16 *SubStr | |
) | |
{ | |
CHAR16 *Temp; | |
if ((Str == NULL) || (SubStr == NULL) || (StrLen (Str) < StrLen (SubStr))) { | |
return FALSE; | |
} | |
Temp = Str + StrLen (Str) - StrLen (SubStr); | |
// | |
// Compare | |
// | |
if (StriCmp (Temp, SubStr) == 0) { | |
return TRUE; | |
} else { | |
return FALSE; | |
} | |
} | |
/** | |
Duplicate a string. | |
@param Src The string to be duplicated. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrDuplicate ( | |
IN CHAR16 *Src | |
) | |
{ | |
CHAR16 *Dest; | |
UINTN Size; | |
Size = (StrLen (Src) + 1) * sizeof (CHAR16); | |
Dest = AllocateZeroPool (Size); | |
if (Dest != NULL) { | |
CopyMem (Dest, Src, Size); | |
} | |
return Dest; | |
} | |
CHAR16 *mLineBuffer = NULL; | |
CHAR16 *mFieldBuffer = NULL; | |
/** | |
Find the first substring. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
UINTN | |
EFIAPI | |
StrSpn ( | |
IN CHAR16 *String, | |
IN CHAR16 *CharSet | |
) | |
{ | |
UINTN Count; | |
CHAR16 *Str1; | |
CHAR16 *Str2; | |
Count = 0; | |
for (Str1 = String; *Str1 != L'\0'; Str1++) { | |
for (Str2 = CharSet; *Str2 != L'\0'; Str2++) { | |
if (*Str1 == *Str2) { | |
break; | |
} | |
} | |
if (*Str2 == L'\0') { | |
return Count; | |
} | |
Count++; | |
} | |
return Count; | |
} | |
/** | |
Searches a string for the first occurrence of a character contained in a | |
specified buffer. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrBrk ( | |
IN CHAR16 *String, | |
IN CHAR16 *CharSet | |
) | |
{ | |
CHAR16 *Str1; | |
CHAR16 *Str2; | |
for (Str1 = String; *Str1 != L'\0'; Str1++) { | |
for (Str2 = CharSet; *Str2 != L'\0'; Str2++) { | |
if (*Str1 == *Str2) { | |
return (CHAR16 *)Str1; | |
} | |
} | |
} | |
return NULL; | |
} | |
/** | |
Find the next token after one or more specified characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrTokenLine ( | |
IN CHAR16 *String OPTIONAL, | |
IN CHAR16 *CharSet | |
) | |
{ | |
CHAR16 *Begin; | |
CHAR16 *End; | |
Begin = (String == NULL) ? mLineBuffer : String; | |
if (Begin == NULL) { | |
return NULL; | |
} | |
Begin += StrSpn (Begin, CharSet); | |
if (*Begin == L'\0') { | |
mLineBuffer = NULL; | |
return NULL; | |
} | |
End = StrBrk (Begin, CharSet); | |
if ((End != NULL) && (*End != L'\0')) { | |
*End = L'\0'; | |
End++; | |
} | |
mLineBuffer = End; | |
return Begin; | |
} | |
/** | |
Find the next token after one specificed characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrTokenField ( | |
IN CHAR16 *String OPTIONAL, | |
IN CHAR16 *CharSet | |
) | |
{ | |
CHAR16 *Begin; | |
CHAR16 *End; | |
Begin = (String == NULL) ? mFieldBuffer : String; | |
if (Begin == NULL) { | |
return NULL; | |
} | |
if (*Begin == L'\0') { | |
mFieldBuffer = NULL; | |
return NULL; | |
} | |
End = StrBrk (Begin, CharSet); | |
if ((End != NULL) && (*End != L'\0')) { | |
*End = L'\0'; | |
End++; | |
} | |
mFieldBuffer = End; | |
return Begin; | |
} | |
/** | |
Find the next token after one or more specified characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrGetNewTokenLine ( | |
IN CHAR16 *String, | |
IN CHAR16 *CharSet | |
) | |
{ | |
return StrTokenLine (String, CharSet); | |
} | |
/** | |
Find the next token after one or more specified characters. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrGetNextTokenLine ( | |
IN CHAR16 *CharSet | |
) | |
{ | |
return StrTokenLine (NULL, CharSet); | |
} | |
/** | |
Find the next token after one specificed characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrGetNewTokenField ( | |
IN CHAR16 *String, | |
IN CHAR16 *CharSet | |
) | |
{ | |
return StrTokenField (String, CharSet); | |
} | |
/** | |
Find the next token after one specificed characters. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR16 * | |
EFIAPI | |
StrGetNextTokenField ( | |
IN CHAR16 *CharSet | |
) | |
{ | |
return StrTokenField (NULL, CharSet); | |
} | |
/** | |
Patch a character to the end of a string. | |
@param Buffer The string to be patched. | |
@param Patch The patch character. | |
**/ | |
VOID | |
EFIAPI | |
PatchForStrTokenAfter ( | |
IN CHAR16 *Buffer, | |
IN CHAR16 Patch | |
) | |
{ | |
CHAR16 *Str; | |
if (Buffer == NULL) { | |
return; | |
} | |
Str = Buffer; | |
while (*Str != 0) { | |
Str++; | |
} | |
*Str = Patch; | |
while (*(Str++) != '\0') { | |
if (*Str == 0) { | |
*Str = Patch; | |
} else { | |
break; | |
} | |
} | |
return; | |
} | |
/** | |
Patch a character at the beginning of a string. | |
@param Buffer The string to be patched. | |
@param Patch The patch character. | |
**/ | |
VOID | |
EFIAPI | |
PatchForStrTokenBefore ( | |
IN CHAR16 *Buffer, | |
IN CHAR16 Patch | |
) | |
{ | |
CHAR16 *Str; | |
if (Buffer == NULL) { | |
return; | |
} | |
Str = Buffer; | |
while (*(Str--) != '\0') { | |
if ((*Str == 0) || (*Str == Patch)) { | |
*Str = Patch; | |
} else { | |
break; | |
} | |
} | |
return; | |
} | |
CHAR8 *mAsciiLineBuffer = NULL; | |
CHAR8 *mAsciiFieldBuffer = NULL; | |
/** | |
Find the first substring. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
UINTN | |
EFIAPI | |
AsciiStrSpn ( | |
IN CHAR8 *String, | |
IN CHAR8 *CharSet | |
) | |
{ | |
UINTN Count; | |
CHAR8 *Str1; | |
CHAR8 *Str2; | |
Count = 0; | |
for (Str1 = String; *Str1 != '\0'; Str1++) { | |
for (Str2 = CharSet; *Str2 != '\0'; Str2++) { | |
if (*Str1 == *Str2) { | |
break; | |
} | |
} | |
if (*Str2 == '\0') { | |
return Count; | |
} | |
Count++; | |
} | |
return Count; | |
} | |
/** | |
Searches a string for the first occurrence of a character contained in a | |
specified buffer. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR8 * | |
EFIAPI | |
AsciiStrBrk ( | |
IN CHAR8 *String, | |
IN CHAR8 *CharSet | |
) | |
{ | |
CHAR8 *Str1; | |
CHAR8 *Str2; | |
for (Str1 = String; *Str1 != '\0'; Str1++) { | |
for (Str2 = CharSet; *Str2 != '\0'; Str2++) { | |
if (*Str1 == *Str2) { | |
return (CHAR8 *)Str1; | |
} | |
} | |
} | |
return NULL; | |
} | |
/** | |
Find the next token after one or more specified characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR8 * | |
EFIAPI | |
AsciiStrTokenLine ( | |
IN CHAR8 *String OPTIONAL, | |
IN CHAR8 *CharSet | |
) | |
{ | |
CHAR8 *Begin; | |
CHAR8 *End; | |
Begin = (String == NULL) ? mAsciiLineBuffer : String; | |
if (Begin == NULL) { | |
return NULL; | |
} | |
Begin += AsciiStrSpn (Begin, CharSet); | |
if (*Begin == '\0') { | |
mAsciiLineBuffer = NULL; | |
return NULL; | |
} | |
End = AsciiStrBrk (Begin, CharSet); | |
if ((End != NULL) && (*End != '\0')) { | |
*End = '\0'; | |
End++; | |
} | |
mAsciiLineBuffer = End; | |
return Begin; | |
} | |
/** | |
Find the next token after one specificed characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR8 * | |
EFIAPI | |
AsciiStrTokenField ( | |
IN CHAR8 *String OPTIONAL, | |
IN CHAR8 *CharSet | |
) | |
{ | |
CHAR8 *Begin; | |
CHAR8 *End; | |
Begin = (String == NULL) ? mAsciiFieldBuffer : String; | |
if (Begin == NULL) { | |
return NULL; | |
} | |
if (*Begin == '\0') { | |
mAsciiFieldBuffer = NULL; | |
return NULL; | |
} | |
End = AsciiStrBrk (Begin, CharSet); | |
if ((End != NULL) && (*End != '\0')) { | |
*End = '\0'; | |
End++; | |
} | |
mAsciiFieldBuffer = End; | |
return Begin; | |
} | |
/** | |
Find the next token after one or more specified characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR8 * | |
EFIAPI | |
AsciiStrGetNewTokenLine ( | |
IN CHAR8 *String, | |
IN CHAR8 *CharSet | |
) | |
{ | |
return AsciiStrTokenLine (String, CharSet); | |
} | |
/** | |
Find the next token after one or more specified characters. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR8 * | |
EFIAPI | |
AsciiStrGetNextTokenLine ( | |
IN CHAR8 *CharSet | |
) | |
{ | |
return AsciiStrTokenLine (NULL, CharSet); | |
} | |
/** | |
Find the next token after one specificed characters. | |
@param String Point to the string where to find the substring. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR8 * | |
EFIAPI | |
AsciiStrGetNewTokenField ( | |
IN CHAR8 *String, | |
IN CHAR8 *CharSet | |
) | |
{ | |
return AsciiStrTokenField (String, CharSet); | |
} | |
/** | |
Find the next token after one specificed characters. | |
@param CharSet Point to the string to be found. | |
**/ | |
CHAR8 * | |
EFIAPI | |
AsciiStrGetNextTokenField ( | |
IN CHAR8 *CharSet | |
) | |
{ | |
return AsciiStrTokenField (NULL, CharSet); | |
} | |
/** | |
Patch a character to the end of a string. | |
@param Buffer The string to be patched. | |
@param Patch The patch character. | |
**/ | |
VOID | |
EFIAPI | |
PatchForAsciiStrTokenAfter ( | |
IN CHAR8 *Buffer, | |
IN CHAR8 Patch | |
) | |
{ | |
CHAR8 *Str; | |
if (Buffer == NULL) { | |
return; | |
} | |
Str = Buffer; | |
while (*Str != 0) { | |
Str++; | |
} | |
*Str = Patch; | |
while (*(Str++) != '\0') { | |
if (*Str == 0) { | |
*Str = Patch; | |
} else { | |
break; | |
} | |
} | |
return; | |
} | |
/** | |
Patch a character at the beginning of a string. | |
@param Buffer The string to be patched. | |
@param Patch The patch character. | |
**/ | |
VOID | |
EFIAPI | |
PatchForAsciiStrTokenBefore ( | |
IN CHAR8 *Buffer, | |
IN CHAR8 Patch | |
) | |
{ | |
CHAR8 *Str; | |
if (Buffer == NULL) { | |
return; | |
} | |
Str = Buffer; | |
while (*(Str--) != '\0') { | |
if ((*Str == 0) || (*Str == Patch)) { | |
*Str = Patch; | |
} else { | |
break; | |
} | |
} | |
return; | |
} |