From 835bc5e8349f0aab3fdad068549553670ad371bd Mon Sep 17 00:00:00 2001 From: timerix Date: Thu, 9 Feb 2023 01:42:10 +0600 Subject: [PATCH] filesystem rework --- src/Array/Array.c | 2 +- src/Filesystem/dir.c | 51 +++++++++++++++++++++++++++++++++++- src/Filesystem/dir.h | 18 ++++++++++--- src/Filesystem/file.c | 26 +++++++++++++++++- src/Filesystem/file.h | 12 +++++---- src/Filesystem/io_includes.h | 15 +++++++++++ src/Filesystem/path.c | 19 ++++++++++++++ src/Filesystem/path.h | 2 ++ src/base/cptr.c | 35 +++++++++++++++++++++++++ src/base/cptr.h | 9 +++++++ 10 files changed, 177 insertions(+), 12 deletions(-) create mode 100644 src/Filesystem/io_includes.h diff --git a/src/Array/Array.c b/src/Array/Array.c index f7d4030..e6b3069 100644 --- a/src/Array/Array.c +++ b/src/Array/Array.c @@ -16,7 +16,7 @@ Array_define(uint64) Array_define(Unitype) void Array_Unitype_free_(Array_Unitype* array, bool freeMembers){ - if(freeMembers) for (int32 i; ilength; i++) + if(freeMembers) for (int32 i=0; ilength; i++) Unitype_free(array->values[i]); if(array->allocatedOnHeap) free(array->values); diff --git a/src/Filesystem/dir.c b/src/Filesystem/dir.c index 840a3f3..a46164d 100644 --- a/src/Filesystem/dir.c +++ b/src/Filesystem/dir.c @@ -1 +1,50 @@ -#include "dir.h" \ No newline at end of file +#include "filesystem.h" +#include "io_includes.h" + +bool dir_exists(char* path){ +#if KFS_USE_WINDOWS_H + DWORD dwAttrib = GetFileAttributes(path); + return (bool)( + (dwAttrib != INVALID_FILE_ATTRIBUTES) & // file exists + (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is a directory +#else + struct stat stats; + int rez=stat(path, &stats); + return (bool)( + (rez!=-1) & // file exists + (S_ISDIR(stats.st_mode))); // file is a directory +#endif +} + +Maybe dir_create(char* path){ + if (dir_exists(path)) + return MaybeNull; + char* parentDir=path_parentDir(path); + dir_create(parentDir); + free(parentDir); + throw(ERR_NOTIMPLEMENTED); + return MaybeNull; +} + +Maybe dir_delete(char* path){ + throw(ERR_NOTIMPLEMENTED); + return MaybeNull; +} + +Maybe dir_getFiles(char* path, bool recursive){ + throw(ERR_NOTIMPLEMENTED); + return MaybeNull; +} +Maybe dir_getDirs(char* path, bool recursive){ + throw(ERR_NOTIMPLEMENTED); + return MaybeNull; +} + +Maybe dir_findFiles(char* path, char* searchPattern, bool recursive){ + throw(ERR_NOTIMPLEMENTED); + return MaybeNull; +} +Maybe dir_findDirs(char* path, char* searchPattern, bool recursive){ + throw(ERR_NOTIMPLEMENTED); + return MaybeNull; +} diff --git a/src/Filesystem/dir.h b/src/Filesystem/dir.h index 111e4ca..df9a664 100644 --- a/src/Filesystem/dir.h +++ b/src/Filesystem/dir.h @@ -7,11 +7,21 @@ extern "C" { #include "../base/base.h" #include "file.h" -typedef char* DirPath; -Array_declare(DirPath); +bool dir_exists(char* path); +///@return Maybe +Maybe dir_create(char* path); +///@return Maybe +Maybe dir_delete(char* path); -Array_FilePath dir_getFiles(DirPath path); -Array_FilePath dir_findFiles(DirPath path, FilePath searchPattern); +///@return Maybe +Maybe dir_getFiles(char* path, bool recursive); +///@return Maybe +Maybe dir_getDirs(char* path, bool recursive); + +///@return Maybe +Maybe dir_findFiles(char* path, char* searchPattern, bool recursive); +///@return Maybe +Maybe dir_findDirs(char* path, char* searchPattern, bool recursive); #if __cplusplus } diff --git a/src/Filesystem/file.c b/src/Filesystem/file.c index 1c56911..e368d85 100644 --- a/src/Filesystem/file.c +++ b/src/Filesystem/file.c @@ -1,8 +1,32 @@ #include "file.h" #include "../String/StringBuilder.h" +#include "io_includes.h" ktid_define(File); +bool file_exists(char* path){ + + // tryLast(path_throwIfEscapes(path)); + +#if KFS_USE_WINDOWS_H + DWORD dwAttrib = GetFileAttributes(path); + return (bool)( + (dwAttrib != INVALID_FILE_ATTRIBUTES) & // file exists + !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is not directory +#else + struct stat stats; + int rez=stat(path, &stats); + return (bool)( + (rez!=-1) & // file exists + !(S_ISDIR(stats.st_mode))); // file is not directory +#endif +} + +Maybe file_delete(char* path, bool recursive){ + throw(ERR_NOTIMPLEMENTED); + return MaybeNull; +} + char* FileOpenMode_toStr(FileOpenMode m){ char* p; switch(m){ @@ -18,7 +42,7 @@ char* FileOpenMode_toStr(FileOpenMode m){ return p; } -Maybe file_open(FilePath path, FileOpenMode mode){ +Maybe file_open(char* path, FileOpenMode mode){ File* file=fopen(path, FileOpenMode_toStr(mode)); if(!file) safethrow(cptr_concat("can't open file ", (char*)path),;); diff --git a/src/Filesystem/file.h b/src/Filesystem/file.h index da0f45a..8498b52 100644 --- a/src/Filesystem/file.h +++ b/src/Filesystem/file.h @@ -8,11 +8,14 @@ extern "C" { #include "../Array/Array.h" #include "../String/string.h" -typedef char* FilePath; -Array_declare(FilePath); typedef FILE File; ktid_declare(File); +bool file_exists(char* path); + +///@return Maybe +Maybe file_delete(char* path, bool recursive); + PACK_ENUM(FileOpenMode, // open a file for reading FileOpenMode_Read=1, @@ -24,14 +27,13 @@ PACK_ENUM(FileOpenMode, FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write, // opens file for readng/writing additional data to the end / creates new file FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append - ) - +) /// @brief opens file /// @param path path to file /// @param mode Read/Write/Append/ReadWrite/ReadAppend /// @return Maybe -Maybe file_open(FilePath path, FileOpenMode mode); +Maybe file_open(char* path, FileOpenMode mode); /// @brief closes file descriptor /// @return Maybe diff --git a/src/Filesystem/io_includes.h b/src/Filesystem/io_includes.h new file mode 100644 index 0000000..033adf6 --- /dev/null +++ b/src/Filesystem/io_includes.h @@ -0,0 +1,15 @@ +#include "../base/std.h" + +#if defined(_WIN64) || defined(_WIN32) +#define KFS_USE_WINDOWS_H 1 +#else +#define KFS_USE_WINDOWS_H 0 +#endif + +#if KFS_USE_WINDOWS_H +#include +#else +#include +#include +#include +#endif diff --git a/src/Filesystem/path.c b/src/Filesystem/path.c index 0a8757b..0ebf386 100644 --- a/src/Filesystem/path.c +++ b/src/Filesystem/path.c @@ -53,3 +53,22 @@ Maybe path_throwIfEscapes(char* path){ safethrow(cptr_concat("path <",path,"> uses <..>, that's not allowed"),); return MaybeNull; } + +char* path_parentDir(char* dir){ + throw(ERR_NOTIMPLEMENTED); + char* copy=cptr_copy(dir); + uint32 length=cptr_length(copy); + int i=cptr_lastIndexOfChar(copy,path_sep); + if(i==length-1){ + copy[length-1]=0; + i=cptr_lastIndexOfChar(copy,path_sep); + } + if(i==-1){ + free(copy); + copy=malloc(3); + copy[0]='.'; + copy[1]=path_sep; + copy[2]=0; + } + return copy; +} diff --git a/src/Filesystem/path.h b/src/Filesystem/path.h index 7c3b049..d39c97e 100644 --- a/src/Filesystem/path.h +++ b/src/Filesystem/path.h @@ -31,6 +31,8 @@ char* path_fixSeparators(char* path); /// @return Maybe Maybe path_throwIfEscapes(char* path); +char* path_parentDir(char* dir); + #if __cplusplus } #endif \ No newline at end of file diff --git a/src/base/cptr.c b/src/base/cptr.c index f098fdc..7042a9d 100644 --- a/src/base/cptr.c +++ b/src/base/cptr.c @@ -57,6 +57,41 @@ uint32 cptr_indexOf(char* ptr, char* fragment){ if(fragment[fi]==0) return si-fi+1; } + else fi=0; + } + return -1; +} +uint32 cptr_indexOfChar(char* ptr, char fragment){ + char sc=*ptr; + for(int si=0; sc!=0; si++){ + sc=ptr[si]; + if(sc==fragment){ + return si; + } + } + return -1; +} +uint32 cptr_lastIndexOf(char* ptr, char* fragment){ + char sc=*ptr; + int fi_last=cptr_length(fragment)-1; + for(int si=cptr_length(ptr)-1, fi=fi_last; si>=0; si--){ + sc=ptr[si]; + if(sc==fragment[fi]){ + if(fi==0) + return si; + fi--; + } + else fi=fi_last; + } + return -1; +} +uint32 cptr_lastIndexOfChar(char* ptr, char fragment){ + char sc=*ptr; + for(int si=cptr_length(ptr)-1; si>=0; si--){ + sc=ptr[si]; + if(sc==fragment){ + return si; + } } return -1; } diff --git a/src/base/cptr.h b/src/base/cptr.h index 255ee0a..9b7babb 100644 --- a/src/base/cptr.h +++ b/src/base/cptr.h @@ -25,6 +25,15 @@ bool cptr_endsWith(char* ptr, char* fragment); /// @brief search for in /// @return index of first inclusion or -1 if not found uint32 cptr_indexOf(char* ptr, char* fragment); +/// @brief search for in +/// @return index of first inclusion or -1 if not found +uint32 cptr_indexOfChar(char* ptr, char fragment); +/// @brief search for in +/// @return index of last inclusion or -1 if not found +uint32 cptr_lastIndexOf(char* ptr, char* fragment); +/// @brief search for in +/// @return index of last inclusion or -1 if not found +uint32 cptr_lastIndexOfChar(char* ptr, char fragment); static inline bool cptr_contains(char* ptr, char* fragment){ // if(cptr_indexOf(ptr, fragment)==-1)