Core: FileMapping refactored

This commit is contained in:
Mirek Fidler 2024-04-10 10:29:08 +02:00
parent 21f88fa4fd
commit ac0504c1b7
7 changed files with 140 additions and 108 deletions

View file

@ -0,0 +1,33 @@
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_COUT|LOG_FILE);
String test;
for(int i = 0; i < 100; i++)
test << i << " " << i * 12345678 << "\n";
int sz = test.GetCount();
String path = GetHomeDirFile("mapped");
{
FileMapping m;
m.Create(path, sz);
memcpy(m.Map(), ~test, sz);
}
ASSERT(LoadFile(path) == test);
{
FileMapping m(path);
ASSERT(memcmp(m.Map(), ~test, sz) == 0);
}
DeleteFile(path);
LOG("============ OK");
}

View file

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

View file

@ -318,6 +318,7 @@ class JsonIO;
#include "TimeDate.h"
#include "Stream.h"
#include "FileMapping.h"
#include "Diag.h"
#include "Vcont.h"

View file

@ -74,9 +74,10 @@ file
Stream.h,
Stream.cpp,
BlockStream.cpp,
FileMapping.cpp,
FilterStream.h,
FilterStream.cpp,
FileMapping.h,
FileMapping.cpp,
Profile.h,
Diag.h,
Log.cpp,

View file

@ -42,60 +42,37 @@ FileMapping::FileMapping(const char *file_)
Open(file_);
}
bool FileMapping::Open(const char *file)
#ifdef PLATFORM_WIN32
bool FileMapping::Open(const char *filename, dword mode, int64 wsize)
#else
bool FileMapping::Open(const char *filename, dword mode, mode_t acm)
#endif
{
Close();
write = false;
write = (mode & FileStream::MODEMASK) != FileStream::READ;
#ifdef PLATFORM_WIN32
hfile = CreateFileW(ToSystemCharsetW(file), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(hfile == INVALID_HANDLE_VALUE)
if(!FileStream::OpenHandle(filename, mode, hfile, filesize))
return false;
filesize = ::GetFileSize(hfile, NULL);
hmap = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
if(write)
filesize = wsize;
else
wsize = 0;
hmap = CreateFileMapping(hfile, NULL, write ? PAGE_READWRITE : PAGE_READONLY, HIDWORD(wsize), LODWORD(wsize), NULL);
if(!hmap) {
Close();
return false;
}
#endif
#ifdef PLATFORM_POSIX
hfile = open(ToSystemCharset(file), O_RDONLY);
if(hfile == -1)
#else
if(!FileStream::OpenHandle(filename, mode, hfile, filesize, acm))
return false;
if(fstat(hfile, &hfstat) == -1) {
Close();
return false;
}
filesize = hfstat.st_size;
#endif
return true;
}
bool FileMapping::Create(const char *file, int64 filesize_, bool delete_share)
bool FileMapping::Create(const char *file, int64 filesize, bool delete_share)
{
Close();
write = true;
#ifdef PLATFORM_WIN32
hfile = CreateFileW(ToSystemCharsetW(file), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | (delete_share ? FILE_SHARE_DELETE : 0),
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(hfile == INVALID_HANDLE_VALUE)
return false;
long lo = (dword)filesize_, hi = (dword)(filesize_ >> 32);
hmap = CreateFileMapping(hfile, NULL, PAGE_READWRITE, hi, lo, NULL);
if(!hmap) {
Close();
return false;
}
#endif
#ifdef PLATFORM_POSIX
hfile = open(ToSystemCharset(file), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if(hfile == -1)
return false;
#endif
filesize = filesize_;
return true;
return Open(file, FileStream::CREATE | (delete_share ? FileStream::DELETESHARE : 0), filesize);
}
byte *FileMapping::Map(int64 mapoffset, size_t maplen)

75
uppsrc/Core/FileMapping.h Normal file
View file

@ -0,0 +1,75 @@
class FileMapping {
public:
FileMapping(const char *file = NULL);
~FileMapping() { Close(); }
#ifdef PLATFORM_WIN32
bool Open(const char *filename, dword mode = FileStream::READ, int64 filesize = 0);
#endif
#ifdef PLATFORM_POSIX
bool Open(const char *filename, dword mode = FileStream::READ, int64 filesize = 0, mode_t acm = 0644);
#endif
bool Create(const char *file, int64 filesize) { return Create(file, filesize, false); }
bool Expand(int64 filesize);
byte *Map(int64 mapoffset, size_t maplen);
byte *Map() { return Map(0, GetFileSize()); }
bool Unmap();
bool Close();
bool IsOpen() const { return hfile != INVALID_HANDLE_VALUE; }
int64 GetFileSize() const { return filesize; }
Time GetTime() const;
String GetData(int64 offset, int len);
int64 GetOffset() const { return offset; }
size_t GetCount() const { return size; }
int64 GetRawOffset() const { return rawoffset; }
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& 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]; }
// deprecated:
bool Create(const char *file, int64 filesize, bool delete_share);
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; }
private:
#ifdef PLATFORM_WIN32
HANDLE hfile;
HANDLE hmap;
#endif
#ifdef PLATFORM_POSIX
enum { INVALID_HANDLE_VALUE = -1 };
int hfile;
struct stat hfstat;
#endif
byte *base;
byte *rawbase;
int64 filesize;
int64 offset;
int64 rawoffset;
size_t size;
size_t rawsize;
bool write;
static int MappingGranularity();
};

View file

@ -365,6 +365,7 @@ protected:
public:
enum {
READ, CREATE, APPEND, READWRITE,
MODEMASK = 0x3,
NOWRITESHARE = 0x10,
SHAREMASK = 0x70,
@ -406,6 +407,8 @@ protected:
void SetPos(int64 pos);
void Init(int64 size);
friend class FileMapping;
public:
operator bool() const { return IsOpen(); }
@ -547,73 +550,6 @@ public:
~TeeStream() { Close(); }
};
class FileMapping {
public:
FileMapping(const char *file = NULL);
~FileMapping() { Close(); }
bool Open(const char *file);
bool Create(const char *file, int64 filesize, bool delete_share = false);
bool Expand(int64 filesize);
byte *Map(int64 mapoffset, size_t maplen);
byte *Map() { return Map(0, GetFileSize()); }
bool Unmap();
bool Close();
bool IsOpen() const { return hfile != INVALID_HANDLE_VALUE; }
int64 GetFileSize() const { return filesize; }
Time GetTime() const;
String GetData(int64 offset, int len);
int64 GetOffset() const { return offset; }
size_t GetCount() const { return size; }
int64 GetRawOffset() const { return rawoffset; }
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& 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; }
private:
#ifdef PLATFORM_WIN32
HANDLE hfile;
HANDLE hmap;
#endif
#ifdef PLATFORM_POSIX
enum { INVALID_HANDLE_VALUE = -1 };
int hfile;
struct stat hfstat;
#endif
byte *base;
byte *rawbase;
int64 filesize;
int64 offset;
int64 rawoffset;
size_t size;
size_t rawsize;
bool write;
static int MappingGranularity();
};
String LoadStream(Stream& in);
bool SaveStream(Stream& out, const String& data);