Add strutil getlastbackslash

This commit is contained in:
Doyle Thai 2018-01-29 19:03:20 +11:00
parent 06b0f25f2a
commit f838cc79bf
2 changed files with 59 additions and 50 deletions

79
dqn.h
View File

@ -482,16 +482,17 @@ public:
bool Sprintf (char const *const fmt, ...);
bool VSprintf(char const *const fmt, va_list argList);
bool Append (DqnString const string);
bool Append (DqnString const *string);
bool Append (char const *const cstr, i32 bytesToCopy = -1);
void Clear ();
void Free ();
// return: -1 if invalid, or if bufSize is 0 the required buffer length in wchar_t characters
i32 ToWChar(wchar_t *const buf, i32 const bufSize);
i32 ToWChar(wchar_t *const buf, i32 const bufSize) const;
// return: String allocated using api.
wchar_t *ToWChar(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
wchar_t *ToWChar(DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR) const;
};
class DqnSmartString : public DqnString
@ -1671,6 +1672,10 @@ DQN_FILE_SCOPE char *DqnChar_GetNextLine (char *ptr, i32 *lineLength);
// return: 0 if equal. 0 < if a is before b, > 0 if a is after b
DQN_FILE_SCOPE i32 DqnStr_Cmp (char const *const a, char const *const b, i32 numBytesToCompare = -1, bool ignoreCase = false);
// strLen: Len of string, if -1, StrLen is used.
// return: Pointer in str to the last slash, if none then the original string.
DQN_FILE_SCOPE char *DqnStr_GetPtrToLastSlash (char const *str, i32 strLen = -1);
// return: String length not including the nullptr terminator. 0 if invalid args.
DQN_FILE_SCOPE i32 DqnStr_Len (char const *const a);
DQN_FILE_SCOPE i32 DqnStr_LenUTF8 (u32 const *const a, i32 *const lenInBytes = nullptr);
@ -2050,14 +2055,6 @@ struct DqnFile
void *handle;
size_t size;
// Initialisation API
// ==============================================================================================
// If raiiCleanup is true, close() is called in the destructor on scope exit. Can be changed at
// any point by user.
bool raiiCleanup = false;
DqnFile (bool const raiiCleanup = false);
~DqnFile();
// API
// ==============================================================================================
// NOTE: W(ide) versions of functions only work on Win32, since Unix is already UTF-8 compatible.
@ -2088,8 +2085,8 @@ struct DqnFile
// Buffer should be freed when done with.
// return: False if file access failure OR nullptr arguments.
static u8 *ReadEntireFileSimple(char const *const path, size_t *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
static u8 *ReadEntireFileSimple(wchar_t const *const path, size_t *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
static u8 *ReadEntireFile(char const *const path, size_t *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
static u8 *ReadEntireFile(wchar_t const *const path, size_t *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
// return: False if file access failure OR nullptr arguments.
static bool GetFileSize (char const *const path, size_t *const size);
@ -2114,6 +2111,12 @@ struct DqnFile
static void ListDirFree (char **fileList, i32 const numFiles);
};
class DqnSmartFile : public DqnFile
{
public:
~DqnSmartFile() { this->Close(); }
};
// XPlatform > #DqnTimer API
// =================================================================================================
DQN_FILE_SCOPE f64 DqnTimer_NowInMs();
@ -4553,7 +4556,7 @@ DQN_FILE_SCOPE char *DqnChar_TrimWhitespaceAround(char const *src, i32 srcLen, i
i32 charsSkipped = (i32)(start - src);
i32 updatedLen = srcLen - charsSkipped;
if (updatedLen == 0)
if (updatedLen <= 0)
{
if (newLen) *newLen = 0;
return nullptr;
@ -4694,6 +4697,22 @@ DQN_FILE_SCOPE i32 DqnStr_Cmp(const char *const a, const char *const b, i32 numB
return (((*aPtr) < (*bPtr)) ? -1 : 1);
}
DQN_FILE_SCOPE char *DqnStr_GetPtrToLastSlash(char const *str, i32 strLen)
{
char const *result = str;
if (strLen == -1) strLen = DqnStr_Len(str);
for (auto i = strLen - 1; i >= 0; i--)
{
if (result[i] == '\\' || result[i] == '/')
{
result = result + i + 1;
break;
}
}
return (char *)result;
}
DQN_FILE_SCOPE i32 DqnStr_Len(const char *const a)
{
i32 result = 0;
@ -5778,6 +5797,12 @@ bool DqnString::Append(DqnString const string)
return result;
}
bool DqnString::Append(DqnString const *string)
{
bool result = DqnStringInternal_Append(this, string->str, string->len);
return result;
}
void DqnString::Clear()
{
this->len = 0;
@ -5810,7 +5835,7 @@ void DqnString::Free()
}
}
i32 DqnString::ToWChar(wchar_t *const buf, i32 const bufSize)
i32 DqnString::ToWChar(wchar_t *const buf, i32 const bufSize) const
{
#if defined(DQN_IS_WIN32) && defined(DQN_WIN32_IMPLEMENTATION)
i32 result = DqnWin32_UTF8ToWChar(this->str, buf, bufSize);
@ -5822,7 +5847,7 @@ i32 DqnString::ToWChar(wchar_t *const buf, i32 const bufSize)
#endif
}
wchar_t *DqnString::ToWChar(DqnMemAPI *const api)
wchar_t *DqnString::ToWChar(DqnMemAPI *const api) const
{
// TODO(doyle): Should the "in" string allow specifyign len? probably
// Otherwise a c-string and a literal initiated string might have different lengths
@ -8029,22 +8054,6 @@ DQN_FILE_SCOPE char **DqnFileInternal_PlatformListDir(char const *const dir, u32
}
#endif // DQN_UNIX_PLATFORM
DqnFile::DqnFile(bool const raiiCleanup)
: flags(0)
, handle(nullptr)
, size(0)
, raiiCleanup(raiiCleanup)
{
}
DqnFile::~DqnFile()
{
if (raiiCleanup)
{
this->Close();
}
}
bool DqnFile::Open(char const *const path, u32 const flags_, Action const action)
{
if (!path) return false;
@ -8146,13 +8155,13 @@ size_t DqnFile::Read(u8 *const buf, size_t const numBytesToRead)
return numBytesRead;
}
u8 *DqnFile::ReadEntireFileSimple(wchar_t const *const path, size_t *const bufSize, DqnMemAPI *const api)
u8 *DqnFile::ReadEntireFile(wchar_t const *const path, size_t *const bufSize, DqnMemAPI *const api)
{
// TODO(doyle): Logging
if (!path || !bufSize) return false;
size_t requiredSize = 0;
if (!DqnFile::GetFileSize(path, &requiredSize)) return nullptr;
if (!DqnFile::GetFileSize(path, &requiredSize) || requiredSize == 0) return nullptr;
auto *buf = (u8 *)api->Alloc(requiredSize, /*zeroClear*/ false);
if (!buf) return nullptr;
@ -8169,12 +8178,12 @@ u8 *DqnFile::ReadEntireFileSimple(wchar_t const *const path, size_t *const bufSi
return nullptr;
}
u8 *DqnFile::ReadEntireFileSimple(char const *const path, size_t *const bufSize, DqnMemAPI *const api)
u8 *DqnFile::ReadEntireFile(char const *const path, size_t *const bufSize, DqnMemAPI *const api)
{
// TODO(doyle): Logging
size_t requiredSize = 0;
if (!DqnFile::GetFileSize(path, &requiredSize)) return nullptr;
if (!DqnFile::GetFileSize(path, &requiredSize) || requiredSize == 0) return nullptr;
auto *buf = (u8 *)api->Alloc(requiredSize, /*zeroClear*/ false);
if (!buf) return nullptr;

View File

@ -1462,7 +1462,7 @@ void DqnArray_TestRealDataInternal(DqnArray<char> *array)
{
#ifdef DQN_XPLATFORM_LAYER
size_t bufSize = 0;
u8 *buf = DqnFile::ReadEntireFileSimple("tests/google-10000-english.txt", &bufSize);
u8 *buf = DqnFile::ReadEntireFile("tests/google-10000-english.txt", &bufSize);
DQN_ASSERT(buf);
for (auto i = 0; i < bufSize; i++)
@ -2007,7 +2007,7 @@ void DqnFile_Test()
if (1)
{
DqnFile raiiFile = DqnFile(true);
DqnSmartFile raiiFile = {};
if (raiiFile.Open(FILE_TO_OPEN,
DqnFile::PermissionFlag::FileWrite | DqnFile::PermissionFlag::FileRead,
DqnFile::Action::OpenOnly))