Library/Base: Implement more StringUtil functions (#799)

This commit is contained in:
Narr the Reg 2025-11-24 04:32:13 -06:00 committed by GitHub
parent 0b6d26020c
commit fde6a21577
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 138 additions and 24 deletions

View file

@ -205969,7 +205969,7 @@ Util/YoshiUtil.o:
- offset: 0x75a2b8
size: 240
label: _ZN4sead15FixedSafeStringILi1024EEaSERKNS_14SafeStringBaseIcEE
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x75a3a8
size: 140
@ -224582,15 +224582,15 @@ Library/Base/StringUtil.o:
- offset: 0x817080
size: 72
label: _ZN2al16tryReplaceStringEPN4sead22BufferedSafeStringBaseIcEEPKcS5_
status: NotDecompiled
status: Matching
- offset: 0x8170c8
size: 748
label: _ZN2al16tryReplaceStringEPN4sead22BufferedSafeStringBaseIcEEPKcS5_S5_
status: NotDecompiled
status: Matching
- offset: 0x8173b4
size: 712
label: _ZN2al27tryReplaceStringNoRecursiveEPN4sead22BufferedSafeStringBaseIcEEPKcS5_S5_
status: NotDecompiled
status: Matching
- offset: 0x81767c
size: 44
label: _ZN2al13isEqualStringEPKDsS1_
@ -224614,7 +224614,7 @@ Library/Base/StringUtil.o:
- offset: 0x8177b0
size: 36
label: _ZN2al13isMatchStringEPKcRKNS_8MatchStrE
status: NotDecompiled
status: Matching
- offset: 0x8177d4
size: 4
label: _ZN2al23compareStringIgnoreCaseEPKcS1_
@ -224622,11 +224622,11 @@ Library/Base/StringUtil.o:
- offset: 0x8177d8
size: 276
label: _ZN2al19makeUrlEncodeStringEPcjPKc
status: NotDecompiled
status: NonMatchingMinor
- offset: 0x8178ec
size: 252
label: _ZN2al19makeUrlDecodeStringEPcjPKc
status: NotDecompiled
status: Matching
- offset: 0x8179e8
size: 8
label: _ZN2al10copyStringEPcPKcj
@ -224638,12 +224638,12 @@ Library/Base/StringUtil.o:
- offset: 0x817a00
size: 4
label: _ZN2al9StringTmpILi1024EED0Ev
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x817a04
size: 4
label: _ZN2al9isInStackEPKv
status: NotDecompiled
status: Matching
- offset: 0x817a08
size: 44
label: _ZN2al13isEqualStringEPKcS1_

View file

@ -132,10 +132,46 @@ void translateCharacters(char* string, const char* charmap, const char* newCharm
}
}
// void tryReplaceString(sead::BufferedSafeString*, const char*, const char*);
// void tryReplaceString(sead::BufferedSafeString*, const char*, const char*, const char*);
// void tryReplaceStringNoRecursive(sead::BufferedSafeString*, const char*, const char*,
// const char*);
bool tryReplaceString(sead::BufferedSafeString* out, const char* oldStr, const char* newStr) {
return tryReplaceString(out, out->cstr(), oldStr, newStr);
}
bool tryReplaceString(sead::BufferedSafeString* out, const char* targetStr, const char* oldStr,
const char* newStr) {
const char* subStr = searchSubString(targetStr, oldStr);
if (!subStr)
return false;
StringTmp<1024> before;
StringTmp<1024> after;
if (subStr != targetStr)
before.copy(targetStr, subStr - targetStr);
after.copy(subStr + std::strlen(oldStr));
tryReplaceString(&after, oldStr, newStr);
out->format("%s%s%s", before.cstr(), newStr, after.cstr());
return true;
}
bool tryReplaceStringNoRecursive(sead::BufferedSafeString* out, const char* targetStr,
const char* oldStr, const char* newStr) {
const char* subStr = searchSubString(targetStr, oldStr);
if (!subStr)
return false;
StringTmp<256> before;
StringTmp<256> after;
if (subStr != targetStr)
before.copy(targetStr, subStr - targetStr);
after.copy(subStr + std::strlen(oldStr));
out->format("%s%s%s", before.cstr(), newStr, after.cstr());
return true;
}
bool isEqualString(const char16* str1, const char16* str2) {
while (*str1 == *str2) {
@ -184,14 +220,85 @@ bool isEndWithString(const char* str, const char* end) {
return isEqualString(&str[lenStr - lenEnd], end);
}
// bool isMatchString(const char*, const MatchStr&);
bool isMatchString(const char* str, const MatchStr& matchStr) {
const char* subStr = getSubStringUnmatched(str, matchStr);
return subStr && subStr[0] == '\0';
}
s32 compareStringIgnoreCase(const char* str1, const char* str2) {
return strcasecmp(str1, str2);
}
// void makeUrlEncodeString(char*, u32, const char*);
// void makeUrlDecodeString(char*, u32, const char*);
inline bool isLetter(char ch) {
return ch - 'A' < 26u || ch - 'a' < 26u;
}
inline bool isDigit(char ch) {
return ch - '0' < 10u;
}
// NON_MATCHING: Using inverse sub operation https://decomp.me/scratch/rPdbr
void makeUrlEncodeString(char* out, u32 outLen, const char* str) {
out[0] = '\0';
for (; str[0] != '\0'; str++) {
char newSymbols[4] = {'\0', '\0', '\0', '\0'};
s64 bytesWritten = 1;
if (str[0] == ' ') {
newSymbols[0] = '+';
} else if (isLetter(str[0]) || isDigit(str[0])) {
newSymbols[0] = str[0];
} else {
char digit1 = (str[0] & 0xf0) >> 4;
char digit2 = (str[0] & 0x0f) >> 0;
newSymbols[0] = '%';
newSymbols[1] = digit1 < 10 ? digit1 + '0' : digit1 + 'A' - 10;
newSymbols[2] = digit2 < 10 ? digit2 + '0' : digit2 + 'A' - 10;
bytesWritten = 3;
}
if (strlen(out) + bytesWritten > outLen) {
out[outLen - 1] = '\0';
return;
}
strcat(out, newSymbols);
}
}
void makeUrlDecodeString(char* out, u32 outLen, const char* str) {
out[0] = '\0';
std::memset(out, 0, outLen);
s32 bytesRead = 1;
for (; str[0] != '\0'; str += bytesRead) {
char newSymbols[2] = {'\0', '\0'};
if (str[0] == '+') {
newSymbols[0] = ' ';
bytesRead = 1;
} else if (str[0] == '%') {
u8 val1 = str[1] < 'A' ? str[1] - '0' : str[1] - 'A' + 10;
u8 val2 = str[2] < 'A' ? str[2] - '0' : str[2] - 'A' + 10;
newSymbols[0] = (val1 << 4) | val2;
bytesRead = 3;
} else {
newSymbols[0] = str[0];
bytesRead = 1;
}
if (strlen(out) + bytesRead > outLen) {
out[outLen - 1] = '\0';
return;
}
strcat(out, newSymbols);
}
}
void copyString(char* out, const char* str, u32 len) {
strncpy(out, str, len);
@ -201,7 +308,12 @@ void copyStringW(char16* out, const char16* str, u32 len) {
sead::StringUtil::wcs16cpy(out, len, str);
}
// bool isInStack(const void*);
// Note: different cpp file from here?
// Attr required for createStringIfInStack
__attribute__((noinline)) bool isInStack(const void* element) {
return sead::MemUtil::isStack(element);
}
// Attr required for isEndWithString
__attribute__((noinline)) bool isEqualString(const char* str1, const char* str2) {

View file

@ -21,21 +21,23 @@ void extractBaseNameW(sead::WBufferedSafeString*, const sead::WSafeString&);
void removeExtensionString(char* out, u32 len, const char* str);
void removeStringFromEnd(char* out, u32 len, const char* end, const char* str);
void translateCharacters(char* string, const char* charmap, const char* newCharmap);
void tryReplaceString(sead::BufferedSafeString*, const char*, const char*);
void tryReplaceString(sead::BufferedSafeString*, const char*, const char*, const char*);
void tryReplaceStringNoRecursive(sead::BufferedSafeString*, const char*, const char*, const char*);
bool tryReplaceString(sead::BufferedSafeString* out, const char* oldStr, const char* newStr);
bool tryReplaceString(sead::BufferedSafeString* out, const char* targetStr, const char* oldStr,
const char* newStr);
bool tryReplaceStringNoRecursive(sead::BufferedSafeString* out, const char* targetStr,
const char* oldStr, const char* newStr);
bool isEqualString(const char16* str1, const char16* str2);
bool isEqualSubString(const char* str, const char* subStr);
bool isEqualSubString(const sead::SafeString& str, const sead::SafeString& subStr);
bool isStartWithString(const char* str, const char* start);
bool isEndWithString(const char* str, const char* end);
bool isMatchString(const char*, const MatchStr&);
bool isMatchString(const char* str, const MatchStr& matchStr);
s32 compareStringIgnoreCase(const char* str1, const char* str2);
void makeUrlEncodeString(char*, u32, const char*);
void makeUrlDecodeString(char*, u32, const char*);
void makeUrlEncodeString(char* out, u32 outLen, const char* str);
void makeUrlDecodeString(char* out, u32 outLen, const char* str);
void copyString(char* out, const char* str, u32 len);
void copyStringW(char16* out, const char16* str, u32 len);
bool isInStack(const void*);
bool isInStack(const void* element);
bool isEqualString(const char* str1, const char* str2);
bool isEqualString(const sead::SafeString& safestr1, const sead::SafeString& safestr2);
bool isEqualStringCase(const char* str1, const char* str2);