Add strutil getlastbackslash
This commit is contained in:
		
							parent
							
								
									06b0f25f2a
								
							
						
					
					
						commit
						f838cc79bf
					
				
							
								
								
									
										85
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								dqn.h
									
									
									
									
									
								
							| @ -482,16 +482,17 @@ public: | |||||||
| 	bool     Sprintf (char      const *const fmt, ...); | 	bool     Sprintf (char      const *const fmt, ...); | ||||||
| 	bool     VSprintf(char      const *const fmt, va_list argList); | 	bool     VSprintf(char      const *const fmt, va_list argList); | ||||||
| 	bool     Append  (DqnString const        string); | 	bool     Append  (DqnString const        string); | ||||||
|  | 	bool     Append  (DqnString const       *string); | ||||||
| 	bool     Append  (char      const *const cstr, i32 bytesToCopy = -1); | 	bool     Append  (char      const *const cstr, i32 bytesToCopy = -1); | ||||||
| 
 | 
 | ||||||
| 	void     Clear   (); | 	void     Clear   (); | ||||||
| 	void     Free    (); | 	void     Free    (); | ||||||
| 
 | 
 | ||||||
| 	// return: -1 if invalid, or if bufSize is 0 the required buffer length in wchar_t characters
 | 	// 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.
 | 	// 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 | 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
 | // 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); | 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.
 | // 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_Len               (char const *const a); | ||||||
| DQN_FILE_SCOPE i32   DqnStr_LenUTF8           (u32 const *const a, i32 *const lenInBytes = nullptr); | DQN_FILE_SCOPE i32   DqnStr_LenUTF8           (u32 const *const a, i32 *const lenInBytes = nullptr); | ||||||
| @ -2050,14 +2055,6 @@ struct DqnFile | |||||||
| 	void   *handle; | 	void   *handle; | ||||||
| 	size_t  size; | 	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
 | 	// API
 | ||||||
| 	// ==============================================================================================
 | 	// ==============================================================================================
 | ||||||
| 	// NOTE: W(ide) versions of functions only work on Win32, since Unix is already UTF-8 compatible.
 | 	// NOTE: W(ide) versions of functions only work on Win32, since Unix is already UTF-8 compatible.
 | ||||||
| @ -2065,7 +2062,7 @@ struct DqnFile | |||||||
| 	// Open a handle for file read and writing. Deleting files does not need a handle. Handles should be
 | 	// Open a handle for file read and writing. Deleting files does not need a handle. Handles should be
 | ||||||
| 	// closed before deleting files otherwise the OS may not be able to delete the file.
 | 	// closed before deleting files otherwise the OS may not be able to delete the file.
 | ||||||
| 	// return: FALSE if invalid args or failed to get handle (i.e. insufficient permissions)
 | 	// return: FALSE if invalid args or failed to get handle (i.e. insufficient permissions)
 | ||||||
| 	bool   Open (const char    *const path, u32 const flags_, Action const action); | 	bool   Open(const char    *const path, u32 const flags_, Action const action); | ||||||
| 	bool   Open(const wchar_t *const path, u32 const flags_, Action const action); | 	bool   Open(const wchar_t *const path, u32 const flags_, Action const action); | ||||||
| 
 | 
 | ||||||
| 	// fileOffset: The byte offset to starting writing from.
 | 	// fileOffset: The byte offset to starting writing from.
 | ||||||
| @ -2083,13 +2080,13 @@ struct DqnFile | |||||||
| 	// Read entire file into the given buffer. To determine required bufSize size, use GetFileSize.
 | 	// Read entire file into the given buffer. To determine required bufSize size, use GetFileSize.
 | ||||||
| 	// bytesRead: Pass in to get how many bytes of the buf was used. Basically the return value of Read
 | 	// bytesRead: Pass in to get how many bytes of the buf was used. Basically the return value of Read
 | ||||||
| 	// return:    False if insufficient bufSize OR file access failure OR nullptr arguments.
 | 	// return:    False if insufficient bufSize OR file access failure OR nullptr arguments.
 | ||||||
| 	static bool   ReadEntireFile      (char    const *const path, u8 *const buf, size_t const bufSize, size_t *const bytesRead); | 	static bool   ReadEntireFile(char    const *const path, u8 *const buf, size_t const bufSize, size_t *const bytesRead); | ||||||
| 	static bool   ReadEntireFile      (wchar_t const *const path, u8 *const buf, size_t const bufSize, size_t *const bytesRead); | 	static bool   ReadEntireFile(wchar_t const *const path, u8 *const buf, size_t const bufSize, size_t *const bytesRead); | ||||||
| 
 | 
 | ||||||
| 	// Buffer should be freed when done with.
 | 	// Buffer should be freed when done with.
 | ||||||
| 	// return: False if file access failure OR nullptr arguments.
 | 	// 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    *ReadEntireFile(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(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.
 | 	// return: False if file access failure OR nullptr arguments.
 | ||||||
| 	static bool   GetFileSize   (char    const *const path, size_t *const size); | 	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); | 	static void   ListDirFree   (char **fileList,       i32 const numFiles); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | class DqnSmartFile : public DqnFile | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	~DqnSmartFile() { this->Close(); } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| // XPlatform > #DqnTimer API
 | // XPlatform > #DqnTimer API
 | ||||||
| // =================================================================================================
 | // =================================================================================================
 | ||||||
| DQN_FILE_SCOPE f64  DqnTimer_NowInMs(); | 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 charsSkipped = (i32)(start - src); | ||||||
| 	i32 updatedLen   = srcLen - charsSkipped; | 	i32 updatedLen   = srcLen - charsSkipped; | ||||||
| 	if (updatedLen == 0) | 	if (updatedLen <= 0) | ||||||
| 	{ | 	{ | ||||||
| 		if (newLen) *newLen = 0; | 		if (newLen) *newLen = 0; | ||||||
| 		return nullptr; | 		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); | 	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) | DQN_FILE_SCOPE i32 DqnStr_Len(const char *const a) | ||||||
| { | { | ||||||
| 	i32 result = 0; | 	i32 result = 0; | ||||||
| @ -5778,6 +5797,12 @@ bool DqnString::Append(DqnString const string) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool DqnString::Append(DqnString const *string) | ||||||
|  | { | ||||||
|  | 	bool result = DqnStringInternal_Append(this, string->str, string->len); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void DqnString::Clear() | void DqnString::Clear() | ||||||
| { | { | ||||||
| 	this->len = 0; | 	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) | #if defined(DQN_IS_WIN32) && defined(DQN_WIN32_IMPLEMENTATION) | ||||||
| 	i32 result = DqnWin32_UTF8ToWChar(this->str, buf, bufSize); | 	i32 result = DqnWin32_UTF8ToWChar(this->str, buf, bufSize); | ||||||
| @ -5822,7 +5847,7 @@ i32 DqnString::ToWChar(wchar_t *const buf, i32 const bufSize) | |||||||
| #endif | #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
 | 	// TODO(doyle): Should the "in" string allow specifyign len? probably
 | ||||||
| 	// Otherwise a c-string and a literal initiated string might have different lengths
 | 	// 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
 | #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) | bool DqnFile::Open(char const *const path, u32 const flags_, Action const action) | ||||||
| { | { | ||||||
| 	if (!path) return false; | 	if (!path) return false; | ||||||
| @ -8146,13 +8155,13 @@ size_t DqnFile::Read(u8 *const buf, size_t const numBytesToRead) | |||||||
| 	return numBytesRead; | 	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
 | 	// TODO(doyle): Logging
 | ||||||
| 	if (!path || !bufSize) return false; | 	if (!path || !bufSize) return false; | ||||||
| 
 | 
 | ||||||
| 	size_t requiredSize = 0; | 	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); | 	auto *buf = (u8 *)api->Alloc(requiredSize, /*zeroClear*/ false); | ||||||
| 	if (!buf) return nullptr; | 	if (!buf) return nullptr; | ||||||
| @ -8169,12 +8178,12 @@ u8 *DqnFile::ReadEntireFileSimple(wchar_t const *const path, size_t *const bufSi | |||||||
| 	return nullptr; | 	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
 | 	// TODO(doyle): Logging
 | ||||||
| 
 | 
 | ||||||
| 	size_t requiredSize = 0; | 	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); | 	auto *buf = (u8 *)api->Alloc(requiredSize, /*zeroClear*/ false); | ||||||
| 	if (!buf) return nullptr; | 	if (!buf) return nullptr; | ||||||
|  | |||||||
| @ -1462,7 +1462,7 @@ void DqnArray_TestRealDataInternal(DqnArray<char> *array) | |||||||
| { | { | ||||||
| #ifdef DQN_XPLATFORM_LAYER | #ifdef DQN_XPLATFORM_LAYER | ||||||
| 	size_t bufSize = 0; | 	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); | 	DQN_ASSERT(buf); | ||||||
| 
 | 
 | ||||||
| 	for (auto i = 0; i < bufSize; i++) | 	for (auto i = 0; i < bufSize; i++) | ||||||
| @ -2007,7 +2007,7 @@ void DqnFile_Test() | |||||||
| 
 | 
 | ||||||
| 			if (1) | 			if (1) | ||||||
| 			{ | 			{ | ||||||
| 				DqnFile raiiFile = DqnFile(true); | 				DqnSmartFile raiiFile = {}; | ||||||
| 				if (raiiFile.Open(FILE_TO_OPEN, | 				if (raiiFile.Open(FILE_TO_OPEN, | ||||||
| 				                  DqnFile::PermissionFlag::FileWrite | DqnFile::PermissionFlag::FileRead, | 				                  DqnFile::PermissionFlag::FileWrite | DqnFile::PermissionFlag::FileRead, | ||||||
| 				                  DqnFile::Action::OpenOnly)) | 				                  DqnFile::Action::OpenOnly)) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user