Core: GetFileTime, GetFileLength, FileExists, DirectoryExists functions refactored, FileMapping improved

This commit is contained in:
Mirek Fidler 2024-03-25 12:10:20 +01:00
parent f7233ea69b
commit 4a99d79cb7
6 changed files with 135 additions and 61 deletions

View file

@ -0,0 +1,40 @@
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_COUT|LOG_FILE);
String testdir = GetHomeDirFile("path_test_dir__");
DirectoryCreate(testdir);
ASSERT(DirectoryExists(testdir));
ASSERT(!FileExists(testdir));
ASSERT(!DirectoryExists(testdir + "q24312"));
String path = AppendFileName(testdir, "test.txt");
Time tm0 = GetSysTime();
SaveFile(path, "test");
ASSERT(FileExists(path));
ASSERT(!DirectoryExists(path));
ASSERT(!FileExists(path + "1"));
ASSERT(GetFileLength(path) == 4);
ASSERT(GetFileLength(path + "1") < 0);
Time tm = GetFileTime(path);
DDUMP(tm);
ASSERT(tm >= tm0 && tm <= GetSysTime());
String newpath = AppendFileName(testdir, "test2.txt");
ASSERT(FileMove(path, newpath));
ASSERT(FileExists(newpath));
ASSERT(!FileExists(path));
ASSERT(!DirectoryExists(newpath));
DeleteFolderDeep(testdir);
ASSERT(!DirectoryExists(testdir));
LOG("================== OK");
}

View file

@ -0,0 +1,9 @@
uses
Core;
file
PathOps.cpp;
mainconfig
"" = "";

View file

@ -6,22 +6,24 @@
namespace Upp {
static int sMappingGranularity_()
int FileMapping::MappingGranularity()
{
#ifdef PLATFORM_WIN32
static int mg = 0;
if(!mg) {
ONCELOCK {
SYSTEM_INFO info;
GetSystemInfo(&info);
mg = info.dwAllocationGranularity;
}
#else
static int mg = 4096;
ONCELOCK {
mg = getpagesize();
}
#endif
return mg;
}
FileMapping::FileMapping(const char *file_, bool delete_share_)
FileMapping::FileMapping(const char *file_)
{
#ifdef PLATFORM_WIN32
hfile = INVALID_HANDLE_VALUE;
@ -37,10 +39,10 @@ FileMapping::FileMapping(const char *file_, bool delete_share_)
filesize = -1;
write = false;
if(file_)
Open(file_, delete_share_);
Open(file_);
}
bool FileMapping::Open(const char *file, bool delete_share)
bool FileMapping::Open(const char *file)
{
Close();
write = false;
@ -96,45 +98,40 @@ bool FileMapping::Create(const char *file, int64 filesize_, bool delete_share)
return true;
}
bool FileMapping::Map(int64 mapoffset, size_t maplen)
byte *FileMapping::Map(int64 mapoffset, size_t maplen)
{
ASSERT(IsOpen());
if(maplen == 0)
return Unmap();
Unmap();
mapoffset = minmax<int64>(mapoffset, 0, filesize);
int gran = sMappingGranularity_();
int gran = MappingGranularity();
int64 rawoff = mapoffset & -gran;
maplen = (size_t)min<int64>(maplen, filesize - mapoffset);
size_t rawsz = (size_t)min<int64>((maplen + (size_t)(mapoffset - rawoff) + gran - 1) & -gran, filesize - rawoff);
if(rawbase && (mapoffset < rawoffset || mapoffset + maplen > rawoffset + rawsize))
Unmap();
if(!rawbase) {
rawoffset = rawoff;
rawsize = rawsz;
rawoffset = rawoff;
rawsize = rawsz;
#ifdef PLATFORM_WIN32
rawbase = (byte *)MapViewOfFile(hmap, write ? FILE_MAP_WRITE : FILE_MAP_READ,
(dword)(rawoffset >> 32), (dword)(rawoffset >> 0), rawsize);
rawbase = (byte *)MapViewOfFile(hmap, write ? FILE_MAP_WRITE : FILE_MAP_READ,
(dword)(rawoffset >> 32), (dword)(rawoffset >> 0), rawsize);
#else
rawbase = (byte *)mmap(0, rawsize,
PROT_READ | (write ? PROT_WRITE : 0),
rawbase = (byte *)mmap(0, rawsize,
PROT_READ | (write ? PROT_WRITE : 0),
#ifdef PLATFORM_FREEBSD
MAP_NOSYNC,
MAP_NOSYNC,
#else
MAP_SHARED,
MAP_SHARED,
#endif
hfile, rawoffset);
hfile, rawoffset);
#endif
#ifdef PLATFORM_POSIX
if(rawbase == (byte *)~0)
if(rawbase == (byte *)~0)
#else
if(!rawbase)
if(!rawbase)
#endif
return false;
}
return NULL;
offset = mapoffset;
size = maplen;
base = rawbase + (int)(offset - rawoffset);
return true;
return base;
}
bool FileMapping::Unmap()

View file

@ -638,23 +638,6 @@ String FindFile::GetPath() const
return AppendFileName(path, GetName());
}
bool FileExists(const char *name) {
FindFile ff(name);
return ff && ff.IsFile();
}
int64 GetFileLength(const char *name) {
FindFile ff(name);
return ff ? ff.GetLength() : -1;
}
bool DirectoryExists(const char *name) {
if(*name == '\0')
return false;
FindFile ff(name + String("/*"));
return ff;
}
String NormalizePath(const char *path) {
#ifdef PLATFORM_WINCE
return NormalizePath(path, "");
@ -756,16 +739,9 @@ Time FileGetTime(const char *filename)
FileTime GetFileTime(const char *filename)
{
#if defined(PLATFORM_WIN32)
HANDLE handle;
handle = CreateFileW(ToSystemCharsetW(filename), GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
WIN32_FILE_ATTRIBUTE_DATA wfad;
static FileTime ft0;
if(handle == INVALID_HANDLE_VALUE)
return ft0;
FileTime ft;
bool res = GetFileTime(handle, 0, 0, &ft);
CloseHandle(handle);
return res ? ft : ft0;
return GetFileAttributesEx(filename, GetFileExInfoStandard, &wfad) ? wfad.ftLastWriteTime : ft0;
#elif defined(PLATFORM_POSIX)
struct stat st;
if(stat(ToSystemCharset(filename), &st))
@ -776,6 +752,47 @@ FileTime GetFileTime(const char *filename)
#endif//PLATFORM
}
int64 GetFileLength(const char *path) {
#if defined(PLATFORM_WIN32)
WIN32_FILE_ATTRIBUTE_DATA wfad;
static FileTime ft0;
return GetFileAttributesEx(path, GetFileExInfoStandard, &wfad) ? MAKEQWORD(wfad.nFileSizeLow, wfad.nFileSizeHigh) : -1;
#elif defined(PLATFORM_POSIX)
struct stat st;
return stat(ToSystemCharset(filename), &st) ? -1 : st.st_size;
#else
#error
#endif//PLATFORM
}
bool FileExists(const char *path)
{
#if defined(PLATFORM_WIN32)
WIN32_FILE_ATTRIBUTE_DATA wfad;
static FileTime ft0;
return GetFileAttributesEx(path, GetFileExInfoStandard, &wfad) && !(wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
#elif defined(PLATFORM_POSIX)
struct stat st;
return stat(ToSystemCharset(filename), &st) ? false : S_ISREG(st.st_mode);
#else
#error
#endif//PLATFORM
}
bool DirectoryExists(const char *path)
{
#if defined(PLATFORM_WIN32)
WIN32_FILE_ATTRIBUTE_DATA wfad;
static FileTime ft0;
return GetFileAttributesEx(path, GetFileExInfoStandard, &wfad) && (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
#elif defined(PLATFORM_POSIX)
struct stat st;
return stat(ToSystemCharset(filename), &st) ? false : S_ISDIR(st.st_mode);
#else
#error
#endif//PLATFORM
}
bool SetFileTime(const char *filename, FileTime ft)
{
#if defined(PLATFORM_WIN32)

View file

@ -549,13 +549,14 @@ public:
class FileMapping
{
public:
FileMapping(const char *file = NULL, bool delete_share = false);
FileMapping(const char *file = NULL);
~FileMapping() { Close(); }
bool Open(const char *file, bool delete_share = false);
bool Open(const char *file);
bool Create(const char *file, int64 filesize, bool delete_share = false);
bool Expand(int64 filesize);
bool Map(int64 offset, size_t len);
byte *Map(int64 mapoffset, size_t maplen);
byte *Map() { return Map(0, GetFileSize()); }
bool Unmap();
bool Close();
@ -572,16 +573,22 @@ public:
size_t GetRawCount() const { return rawsize; }
const byte *operator ~ () const { ASSERT(IsOpen()); return base; }
const byte *Begin() const { ASSERT(IsOpen()); return base; }
const byte *End() const { ASSERT(IsOpen()); return base + size; }
const byte *GetIter(int i) const { ASSERT(IsOpen() && i >= 0 && (size_t)i <= size); return base + i; }
const byte *begin() const { ASSERT(IsOpen()); return base; }
const byte *end() const { ASSERT(IsOpen()); return base + size; }
const byte& operator [] (int i) const { ASSERT(IsOpen() && i >= 0 && (size_t)i < size); return base[i]; }
byte *operator ~ () { ASSERT(IsOpen()); return base; }
byte *begin() { ASSERT(IsOpen()); return base; }
byte *end() { ASSERT(IsOpen()); return base + size; }
byte& operator [] (int i) { ASSERT(IsOpen() && i >= 0 && (size_t)i < size); return base[i]; }
const byte *Begin() const { ASSERT(IsOpen()); return base; }
const byte *End() const { ASSERT(IsOpen()); return base + size; }
const byte *GetIter(int i) const { ASSERT(IsOpen() && i >= 0 && (size_t)i <= size); return base + i; }
byte *Begin() { ASSERT(IsOpen()); return base; }
byte *End() { ASSERT(IsOpen()); return base + size; }
byte *GetIter(int i) { ASSERT(IsOpen() && i >= 0 && (size_t)i <= size); return base + i; }
byte& operator [] (int i) { ASSERT(IsOpen() && i >= 0 && (size_t)i < size); return base[i]; }
private:
#ifdef PLATFORM_WIN32
@ -601,6 +608,9 @@ private:
size_t size;
size_t rawsize;
bool write;
static int MappingGranularity();
};

View file

@ -97,7 +97,8 @@ in Win32). Separator [*/ is not] included at the end of result.
If there is none, returns empty string.&]
[s2;%% Example (POSIX): GetFileFolder([@3 `"/home/user/test.ext`"])
returns [@3 `"/home/user`"].&]
[s3;%% &]
[s2;%% &]
[s3; &]
[s4;%% &]
[s5;:GetFileTitle`(const char`*`): [_^String^ String]_[* GetFileTitle]([@(0.0.255) const]_[@(0.0.255) c
har]_`*[*@3 path])&]