tlibc/include/tlibc/filesystem.h
2025-11-01 19:49:17 +05:00

138 lines
4.7 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);
/// 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);
}
//////////////////////////////////////////////////////////////////////////////
// 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);