/** @file Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
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 ; }