mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Core: FileMapping refactored
This commit is contained in:
parent
21f88fa4fd
commit
ac0504c1b7
7 changed files with 140 additions and 108 deletions
33
autotest/FileMapping/FileMapping.cpp
Normal file
33
autotest/FileMapping/FileMapping.cpp
Normal 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");
|
||||
}
|
||||
9
autotest/FileMapping/FileMapping.upp
Normal file
9
autotest/FileMapping/FileMapping.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
FileMapping.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
|
|
@ -318,6 +318,7 @@ class JsonIO;
|
|||
|
||||
#include "TimeDate.h"
|
||||
#include "Stream.h"
|
||||
#include "FileMapping.h"
|
||||
#include "Diag.h"
|
||||
|
||||
#include "Vcont.h"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
75
uppsrc/Core/FileMapping.h
Normal 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();
|
||||
};
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue