148 lines
4.9 KiB
C
148 lines
4.9 KiB
C
#pragma once
|
|
#include <stdio.h>
|
|
#include "std.h"
|
|
#include "errors.h"
|
|
#include "string/str.h"
|
|
#include "collections/Array.h"
|
|
|
|
#if !defined(TLIBC_FS_USE_WINDOWS_H)
|
|
#if defined(_WIN64) || defined(_WIN32)
|
|
#define TLIBC_FS_USE_WINDOWS_H 1
|
|
#else
|
|
#define TLIBC_FS_USE_WINDOWS_H 0
|
|
#endif
|
|
#endif
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// PATH //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if defined(_WIN64) || defined(_WIN32)
|
|
#define path_sep '\\'
|
|
#define path_seps "\\"
|
|
#define path_notsep '/'
|
|
#define path_notseps "/"
|
|
#else
|
|
#define path_sep '/'
|
|
#define path_seps "/"
|
|
#define path_notsep '\\'
|
|
#define path_notseps "\\"
|
|
#endif
|
|
|
|
/// @brief removes part of path after path_sep (including path_sep)
|
|
/// @return pointer to a segment of path.data or "." if no path_sep has been found
|
|
str path_dirname(str path);
|
|
|
|
/// @brief removes part of path before path_sep (including path_sep)
|
|
/// @return pointer to a segment of path.data or path itself if no path_sep has been found
|
|
str path_basename(str path, bool remove_ext);
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// FILE //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// open file for reading
|
|
#define FO_ReadExisting "rb"
|
|
/// (re)create file for writing
|
|
#define FO_WriteNew "wb"
|
|
/// open or create file for writing data to the end
|
|
#define FO_AppendOrCreate "ab"
|
|
/// open file for reading and writing
|
|
#define FO_ReadWriteExisting "rb+"
|
|
/// (re)create file for reading/writing
|
|
#define FO_ReadWriteNew "wb+"
|
|
/// open or create file for readng and writing data to the end
|
|
#define FO_ReadAppend "ab+"
|
|
|
|
Result(FILE*) file_open(cstr file_name, cstr fopen_mode);
|
|
|
|
static inline void file_close(FILE* f){
|
|
if(f == NULL)
|
|
return;
|
|
fclose(f);
|
|
}
|
|
|
|
/// if file exists, opens it with "rb+", else creates it with "wb+"
|
|
Result(FILE*) file_openOrCreateReadWrite(cstr file_name);
|
|
|
|
bool file_exists(cstr path);
|
|
|
|
///@return current position in file
|
|
Result(i64) file_tellPos(FILE* f);
|
|
///@return total size of file
|
|
Result(i64) file_getSize(FILE* f);
|
|
|
|
|
|
typedef enum SeekOrigin {
|
|
SeekOrigin_Start = SEEK_SET,
|
|
SeekOrigin_Current = SEEK_CUR,
|
|
SeekOrigin_End = SEEK_END,
|
|
} SeekOrigin;
|
|
|
|
/// @brief changes current position in file
|
|
Result(void) file_seek(FILE* f, i64 offset, SeekOrigin origin);
|
|
|
|
|
|
Result(void) file_writeByte(FILE* f, u8 b);
|
|
Result(void) file_writeStructs(FILE* f, const void* src, u64 struct_size, u64 count);
|
|
|
|
static inline Result(void) file_writeBytes(FILE* f, const void* src, u64 size){
|
|
return file_writeStructs(f, src, size, 1);
|
|
}
|
|
|
|
static inline Result(void) file_writeBytesArray(FILE* f, Array(u8) src){
|
|
return file_writeStructs(f, src.data, src.size, 1);
|
|
}
|
|
|
|
|
|
/// @param out_byte is not set on error or end of file
|
|
/// @return true if byte was read, false if end of file was reached
|
|
Result(bool) file_readByte(FILE* f, u8* out_byte);
|
|
|
|
|
|
/// @param max_count maximum number of structs to read
|
|
/// @return number of structs that were read (<=max_count)
|
|
Result(u64) file_readStructs(FILE* f, void* dst, u64 struct_size, u64 max_count);
|
|
|
|
/// @param max_count maximum number of bytes to read
|
|
/// @return number of bytes that were read (<=max_count)
|
|
static inline Result(u64) file_readBytes(FILE* f, void* dst, u64 max_count){
|
|
return file_readStructs(f, dst, 1, max_count);
|
|
}
|
|
|
|
/// @param dst array where .size is the maximum number of bytes to read
|
|
/// @return number of bytes that were read (<=max_count)
|
|
static inline Result(u64) file_readBytesArray(FILE* f, Array(u8) dst){
|
|
return file_readStructs(f, dst.data, 1, dst.size);
|
|
}
|
|
|
|
|
|
/// @param max_count exact number of structs to read
|
|
Result(void) file_readStructsExactly(FILE* f, void* dst, u64 struct_size, u64 exact_count);
|
|
|
|
/// @param exact_count exact number of bytes to read
|
|
static inline Result(void) file_readBytesExactly(FILE* f, void* dst, u64 exact_count){
|
|
return file_readStructsExactly(f, dst, 1, exact_count);
|
|
}
|
|
|
|
/// @param dst array where .size is the exact number of bytes to read
|
|
static inline Result(void) file_readBytesArrayExactly(FILE* f, Array(u8) dst){
|
|
return file_readStructsExactly(f, dst.data, 1, dst.size);
|
|
}
|
|
|
|
/// @brief allocates array of size equal `file_getSize()` and reads whole file
|
|
/// @param out_buf output array allocated on heap
|
|
Result(void) file_readWhole(FILE* f, Array(u8)* out_buf);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// DIRECTORY //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool dir_exists(cstr path);
|
|
|
|
/// @brief creates directories specified in path recursively
|
|
/// @return false if directory was present already, true if it has been created
|
|
Result(bool) dir_create(cstr path);
|