From e6429777e5090a5cc07c0fa1fe1fe91d42a772af Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 29 May 2024 20:02:57 +0200 Subject: [PATCH] sized_string (can we fix libc headers yet?) --- include/d/d_rawarchive.h | 9 ++- include/inline_string.h | 31 --------- include/sized_string.h | 69 +++++++++++++++++++ src/d/d_rawarchive.cpp | 8 +-- .../current_stage_arc_manager.cpp | 53 ++------------ src/toBeSorted/file_manager.cpp | 11 +-- 6 files changed, 88 insertions(+), 93 deletions(-) delete mode 100644 include/inline_string.h create mode 100644 include/sized_string.h diff --git a/include/d/d_rawarchive.h b/include/d/d_rawarchive.h index 43abc63c..61d048f4 100644 --- a/include/d/d_rawarchive.h +++ b/include/d/d_rawarchive.h @@ -3,6 +3,9 @@ #include #include +// clang-format off +#include +// clang-format on // TODO: loading status could be an enum (-2/-1/0/+1) @@ -28,8 +31,8 @@ public: return mRefCount != 0; } - inline const char *name() { - return mArcName; + inline const char *name() const { + return &mArcName; } inline bool isNotLoaded() { @@ -62,7 +65,7 @@ private: static void searchCallback2(void *, void *, const ARCDirEntry *, const char *); private: - /* 0x00 */ char mArcName[0x20]; + /* 0x00 */ SizedString<32> mArcName; /* 0x20 */ u16 mRefCount; /* 0x24 */ mDvd_mountMemArchive_c *mpDvdReq; /* 0x28 */ EGG::Archive *mpArc; diff --git a/include/inline_string.h b/include/inline_string.h deleted file mode 100644 index 3909422f..00000000 --- a/include/inline_string.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef INLINE_STRING_H -#define INLINE_STRING_H - -#include - -inline void inline_strncat(char *dest, const char *src, size_t destSize) { - if (src != nullptr) { - size_t destLen = strlen(dest); - size_t copyLen = strlen(src); - - // Make sure copy length isnt more than destination length - if (destLen + copyLen + 1 >= destSize) { - copyLen = destSize - destLen - 1; - } - - strncpy(dest + destLen, src, copyLen); - - // make sure string is null terminated - size_t offset = destLen + copyLen; - dest[offset] = '\0'; - } -} - -inline void inline_strncpy(char *dest, const char *src, size_t destSize) { - if (src != dest) { - dest[0] = '\0'; - inline_strncat(dest, src, destSize); - } -} - -#endif diff --git a/include/sized_string.h b/include/sized_string.h new file mode 100644 index 00000000..1d619dda --- /dev/null +++ b/include/sized_string.h @@ -0,0 +1,69 @@ +#ifndef SIZED_STRING_H +#define SIZED_STRING_H + +#include + +/** + * A statically sized string buffer used for resource + * identification where strings are guaranteed to be short. + * + * Note: We aren't aware of any other projects that use a similar + * class and given that SS has no debugging info anywhere it's hard + * to be certain about anything. + */ +template +struct SizedString { + SizedString() { + mChars[0] = '\0'; + } + + char mChars[Size]; + + char *operator&() { + return mChars; + } + + const char *operator&() const { + return mChars; + } + + void operator=(const char *src) { + if (src != mChars) { + mChars[0] = '\0'; + operator+=(src); + } + } + + void operator+=(const char *src) { + if (src != nullptr) { + size_t destLen = strlen(mChars); + size_t copyLen = strlen(src); + + // Make sure copy length isnt more than destination length + if (destLen + copyLen + 1 >= Size) { + size_t tmpLen = Size - destLen; + copyLen = tmpLen - 1; + } + + strncpy(mChars + destLen, src, copyLen); + + // make sure string is null terminated + size_t offset = destLen + copyLen; + mChars[offset] = '\0'; + } + } + + int sprintf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + + int printed = vsnprintf(this->mChars, Size, fmt, args); + if (printed != strlen(this->mChars)) { + this->mChars[0] = '\0'; + } + va_end(list); + return printed; + } +}; + +#endif diff --git a/src/d/d_rawarchive.cpp b/src/d/d_rawarchive.cpp index 7a1da9d5..9adc35b4 100644 --- a/src/d/d_rawarchive.cpp +++ b/src/d/d_rawarchive.cpp @@ -1,5 +1,4 @@ #include -#include #include class UnkManager { @@ -36,7 +35,6 @@ extern "C" void fn_80061BE0(UnkManager *mgr, const char *name, size_t len) { } dRawArcEntry_c::dRawArcEntry_c() { - mArcName[0] = '\0'; mRefCount = 0; mpDvdReq = nullptr; mpArc = nullptr; @@ -136,7 +134,7 @@ bool dRawArcEntry_c::loadArcFromDisk(const char *arcName, const char *arcPath, u if (mpDvdReq == nullptr) { return false; } - inline_strncpy(mArcName, arcName, sizeof(mArcName)); + mArcName = arcName; return true; } @@ -161,7 +159,7 @@ bool dRawArcEntry_c::checkArcExistsOnDiskInner(char *outBuf, const char *fileNam } int dRawArcEntry_c::mount(const char *name, void *data, void *callbackArg, u8 mountDirection, EGG::Heap *heap) { - inline_strncpy(mArcName, name, sizeof(mArcName)); + mArcName = name; mpArc = EGG::Archive::mount(data, heap, (mountDirection == 0 || mountDirection == 1) ? 4 : -4); if (mpArc == nullptr) { return -1; @@ -201,7 +199,7 @@ int dRawArcEntry_c::ensureLoadedMaybe(void *callbackArg) { if (mpArc == nullptr) { return -1; } - mpFrmHeap = mHeap::makeHeapOnCurrentGameHeap(-1, this->mArcName, 0x20, 0); + mpFrmHeap = mHeap::makeHeapOnCurrentGameHeap(-1, name(), 0x20, 0); if (mpFrmHeap == nullptr) { return -1; } diff --git a/src/toBeSorted/arc_managers/current_stage_arc_manager.cpp b/src/toBeSorted/arc_managers/current_stage_arc_manager.cpp index 6f0f33bd..87b1dd91 100644 --- a/src/toBeSorted/arc_managers/current_stage_arc_manager.cpp +++ b/src/toBeSorted/arc_managers/current_stage_arc_manager.cpp @@ -2,54 +2,9 @@ #include #include // clang-format off -#include +#include // clang-format on -template -struct SizedString { - SizedString() { - mChars[0] = '\0'; - } - - char mChars[Size]; - - char *operator&() { - return mChars; - } - - const char *operator&() const { - return mChars; - } - - inline void set(const char *src) { - if (src != mChars) { - mChars[0] = '\0'; - append(src); - } - } - - inline void append(const char *src) { - if (src != nullptr) { - size_t destLen = strlen(mChars); - size_t copyLen = strlen(src); - - // Make sure copy length isnt more than destination length - if (destLen + copyLen + 1 >= Size) { - size_t tmpLen = Size - destLen; - copyLen = tmpLen - 1; - } - - strncpy(mChars + destLen, src, copyLen); - - // make sure string is null terminated - size_t offset = destLen + copyLen; - mChars[offset] = '\0'; - } - } - - void sprintf(const char *fmt, ...); -}; - class CurrentStageArcManager { CurrentStageArcManager(); virtual ~CurrentStageArcManager(); @@ -103,7 +58,7 @@ void CurrentStageArcManager::init(EGG::Heap *heap) { extern "C" void fn_8001F820(char *str, const char *src, ...); bool CurrentStageArcManager::setStage(const char *newStage) { - mStageName.set(newStage); + mStageName = newStage; mCurrentLoadingStageArcName.sprintf("%s_stg_l0", mStageName); if (dRawArcEntry_c::checkArcExistsOnDisk(&mCurrentLoadingStageArcName, getCurrentStageDirectory())) { @@ -181,8 +136,8 @@ EGG::ExpHeap *getHeap() { const char *CurrentStageArcManager::getCurrentStageDirectory() { static SizedString<64> sStageDirTmp; - sStageDirTmp.set("Stage/"); - sStageDirTmp.append(&mStageName); + sStageDirTmp = "Stage/"; + sStageDirTmp += &mStageName; return &sStageDirTmp; } diff --git a/src/toBeSorted/file_manager.cpp b/src/toBeSorted/file_manager.cpp index 4a525a74..1f6ea9e4 100644 --- a/src/toBeSorted/file_manager.cpp +++ b/src/toBeSorted/file_manager.cpp @@ -1,7 +1,9 @@ #include "toBeSorted/file_manager.h" #include "f/f_base.h" #include -#include +// clang-format off +#include +// clang-format on // This class here makes no sense and the name might // be a total misnomer, but this gets the sinit section correct @@ -116,10 +118,9 @@ u16 *FileManager::getStoryFlagsMut() { file->selectedDowsingSlot = 0x8; file->lastUsedPouchItemSlot = 0x8; - char buf[0x20]; - buf[0] = '\0'; - inline_strncpy(buf, "F405", sizeof(buf)); - file->setAreaT1(buf); + SizedString<32> buf; + buf = "F405"; + file->setAreaT1(&buf); file->room_id_t1 = 0; file->forced_layer_t1 = 0; file->entrance_t1_load_flag = 1;