mirror of
https://github.com/jakcron/nstool
synced 2024-11-14 17:56:39 +00:00
[fnd] Implement Windows 64bit size_t support in SimpleFile.
This commit is contained in:
parent
57d03b6076
commit
93509fac5a
2 changed files with 239 additions and 6 deletions
|
@ -1,7 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <fnd/IFile.h>
|
#include <fnd/IFile.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#else
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace fnd
|
namespace fnd
|
||||||
{
|
{
|
||||||
|
@ -34,9 +38,16 @@ namespace fnd
|
||||||
|
|
||||||
bool mOpen;
|
bool mOpen;
|
||||||
OpenMode mMode;
|
OpenMode mMode;
|
||||||
FILE* mFp;
|
|
||||||
|
|
||||||
const char* getOpenModeStr(OpenMode mMode);
|
#ifdef _WIN32
|
||||||
|
HANDLE mFileHandle;
|
||||||
|
DWORD getOpenModeFlag(OpenMode mode) const;
|
||||||
|
DWORD getShareModeFlag(OpenMode mode) const;
|
||||||
|
DWORD getCreationModeFlag(OpenMode mode) const;
|
||||||
|
#else
|
||||||
|
FILE* mFp;
|
||||||
|
const char* getOpenModeStr(OpenMode mode);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
#include <fnd/SimpleFile.h>
|
#include <fnd/SimpleFile.h>
|
||||||
|
#include <fnd/StringConv.h>
|
||||||
|
|
||||||
using namespace fnd;
|
using namespace fnd;
|
||||||
|
|
||||||
SimpleFile::SimpleFile() :
|
SimpleFile::SimpleFile() :
|
||||||
mOpen(false),
|
mOpen(false),
|
||||||
mMode(Read),
|
mMode(Read),
|
||||||
|
#ifdef _WIN32
|
||||||
|
mFileHandle()
|
||||||
|
#else
|
||||||
mFp(nullptr)
|
mFp(nullptr)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +21,29 @@ SimpleFile::~SimpleFile()
|
||||||
|
|
||||||
void SimpleFile::open(const std::string& path, OpenMode mode)
|
void SimpleFile::open(const std::string& path, OpenMode mode)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
// convert string to unicode
|
||||||
|
std::u16string unicodePath = fnd::StringConv::ConvertChar8ToChar16(path);
|
||||||
|
|
||||||
|
// save mode
|
||||||
|
mMode = mode;
|
||||||
|
|
||||||
|
// open file
|
||||||
|
mFileHandle = CreateFileW((LPCWSTR)unicodePath.c_str(),
|
||||||
|
getOpenModeFlag(mMode),
|
||||||
|
getShareModeFlag(mMode),
|
||||||
|
0,
|
||||||
|
getCreationModeFlag(mMode),
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
// check file handle
|
||||||
|
if (mFileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Failed to open file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
//close();
|
//close();
|
||||||
mMode = mode;
|
mMode = mode;
|
||||||
//printf("fopen(%s,%s);\n", path.c_str(), getOpenModeStr(mMode));
|
//printf("fopen(%s,%s);\n", path.c_str(), getOpenModeStr(mMode));
|
||||||
|
@ -23,46 +51,140 @@ void SimpleFile::open(const std::string& path, OpenMode mode)
|
||||||
if (mFp == nullptr)
|
if (mFp == nullptr)
|
||||||
throw fnd::Exception(kModuleName, "Failed to open file.");
|
throw fnd::Exception(kModuleName, "Failed to open file.");
|
||||||
mOpen = true;
|
mOpen = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
seek(0);
|
seek(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SimpleFile::isOpen() const
|
bool SimpleFile::isOpen() const
|
||||||
{
|
{
|
||||||
return mOpen == true && mFp != nullptr;
|
return mOpen == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleFile::close()
|
void SimpleFile::close()
|
||||||
{
|
{
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
CloseHandle(mFileHandle);
|
||||||
|
#else
|
||||||
fclose(mFp);
|
fclose(mFp);
|
||||||
}
|
|
||||||
mFp = nullptr;
|
mFp = nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
mOpen = false;
|
mOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SimpleFile::size()
|
size_t SimpleFile::size()
|
||||||
{
|
{
|
||||||
|
size_t fsize = 0;
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (mMode != Create)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER win_fsize;
|
||||||
|
if (GetFileSizeEx(mFileHandle, &win_fsize) == false)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Failed to check filesize");
|
||||||
|
}
|
||||||
|
|
||||||
|
fsize = win_fsize.QuadPart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fsize = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
size_t cur_pos = pos();
|
size_t cur_pos = pos();
|
||||||
fseek(mFp, 0, SEEK_END);
|
fseek(mFp, 0, SEEK_END);
|
||||||
size_t fsize = pos();
|
fsize = pos();
|
||||||
seek(cur_pos);
|
seek(cur_pos);
|
||||||
|
#endif
|
||||||
return fsize;
|
return fsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleFile::seek(size_t offset)
|
void SimpleFile::seek(size_t offset)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER win_pos, out;
|
||||||
|
win_pos.QuadPart = offset;
|
||||||
|
if (SetFilePointerEx(
|
||||||
|
mFileHandle,
|
||||||
|
win_pos,
|
||||||
|
&out,
|
||||||
|
FILE_BEGIN
|
||||||
|
) == false || out.QuadPart != win_pos.QuadPart)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Failed to change file offset");
|
||||||
|
}
|
||||||
|
#else
|
||||||
fseek(mFp, offset, SEEK_SET);
|
fseek(mFp, offset, SEEK_SET);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SimpleFile::pos()
|
size_t SimpleFile::pos()
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER win_pos, out;
|
||||||
|
win_pos.QuadPart = 0;
|
||||||
|
if (SetFilePointerEx(
|
||||||
|
mFileHandle,
|
||||||
|
win_pos,
|
||||||
|
&out,
|
||||||
|
FILE_CURRENT
|
||||||
|
) == false)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Failed to check file offset");
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.QuadPart;
|
||||||
|
#else
|
||||||
return ftell(mFp);
|
return ftell(mFp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleFile::read(byte_t* out, size_t len)
|
void SimpleFile::read(byte_t* out, size_t len)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER win_len;
|
||||||
|
win_len.QuadPart = len;
|
||||||
|
|
||||||
|
static const DWORD kDwordHalf = (MAXDWORD / (DWORD)2) + 1; // 0x80000000
|
||||||
|
static const size_t kDwordFull = (size_t)kDwordHalf * (size_t)2; // 0x100000000
|
||||||
|
|
||||||
|
// if the size is greater than a DWORD, read it in parts,
|
||||||
|
for (LONG i = 0; i < win_len.HighPart; i++)
|
||||||
|
{
|
||||||
|
// since kDwordFull isn't a valid DWORD value, read in two parts
|
||||||
|
ReadFile(
|
||||||
|
mFileHandle,
|
||||||
|
out + i * kDwordFull,
|
||||||
|
kDwordHalf,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
ReadFile(
|
||||||
|
mFileHandle,
|
||||||
|
out + i * kDwordFull + kDwordHalf,
|
||||||
|
kDwordHalf,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read remainding low part
|
||||||
|
if (win_len.LowPart > 0)
|
||||||
|
{
|
||||||
|
ReadFile(
|
||||||
|
mFileHandle,
|
||||||
|
out + win_len.HighPart * kDwordFull,
|
||||||
|
win_len.LowPart,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#else
|
||||||
fread(out, len, 1, mFp);
|
fread(out, len, 1, mFp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleFile::read(byte_t* out, size_t offset, size_t len)
|
void SimpleFile::read(byte_t* out, size_t offset, size_t len)
|
||||||
|
@ -73,7 +195,47 @@ void SimpleFile::read(byte_t* out, size_t offset, size_t len)
|
||||||
|
|
||||||
void SimpleFile::write(const byte_t* out, size_t len)
|
void SimpleFile::write(const byte_t* out, size_t len)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER win_len;
|
||||||
|
win_len.QuadPart = len;
|
||||||
|
|
||||||
|
static const DWORD kDwordHalf = ((DWORD)MAXDWORD / (DWORD)2) + 1; // 0x80000000
|
||||||
|
static const size_t kDwordFull = (size_t)kDwordHalf * (size_t)2; // 0x100000000
|
||||||
|
|
||||||
|
// if the size is greater than a DWORD, read it in parts,
|
||||||
|
for (LONG i = 0; i < win_len.HighPart; i++)
|
||||||
|
{
|
||||||
|
// since kDwordFull isn't a valid DWORD value, read in two parts
|
||||||
|
WriteFile(
|
||||||
|
mFileHandle,
|
||||||
|
out + i * kDwordFull,
|
||||||
|
kDwordHalf,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
WriteFile(
|
||||||
|
mFileHandle,
|
||||||
|
out + i * kDwordFull + kDwordHalf,
|
||||||
|
kDwordHalf,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read remainding low part
|
||||||
|
if (win_len.LowPart > 0)
|
||||||
|
{
|
||||||
|
WriteFile(
|
||||||
|
mFileHandle,
|
||||||
|
out + win_len.HighPart * kDwordFull,
|
||||||
|
win_len.LowPart,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#else
|
||||||
fwrite(out, len, 1, mFp);
|
fwrite(out, len, 1, mFp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleFile::write(const byte_t* out, size_t offset, size_t len)
|
void SimpleFile::write(const byte_t* out, size_t offset, size_t len)
|
||||||
|
@ -82,6 +244,65 @@ void SimpleFile::write(const byte_t* out, size_t offset, size_t len)
|
||||||
write(out, len);
|
write(out, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
DWORD SimpleFile::getOpenModeFlag(OpenMode mode) const
|
||||||
|
{
|
||||||
|
DWORD flag = 0;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case (Read):
|
||||||
|
flag = GENERIC_READ;
|
||||||
|
break;
|
||||||
|
case (Edit):
|
||||||
|
flag = GENERIC_READ | GENERIC_WRITE;
|
||||||
|
break;
|
||||||
|
case (Create):
|
||||||
|
flag = GENERIC_WRITE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw fnd::Exception(kModuleName, "Unknown open mode");
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
DWORD fnd::SimpleFile::getShareModeFlag(OpenMode mode) const
|
||||||
|
{
|
||||||
|
DWORD flag = 0;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case (Read):
|
||||||
|
flag = FILE_SHARE_READ;
|
||||||
|
break;
|
||||||
|
case (Edit):
|
||||||
|
flag = FILE_SHARE_READ;
|
||||||
|
break;
|
||||||
|
case (Create):
|
||||||
|
flag = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw fnd::Exception(kModuleName, "Unknown open mode");
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
DWORD fnd::SimpleFile::getCreationModeFlag(OpenMode mode) const
|
||||||
|
{
|
||||||
|
DWORD flag = 0;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case (Read):
|
||||||
|
flag = OPEN_EXISTING;
|
||||||
|
break;
|
||||||
|
case (Edit):
|
||||||
|
flag = OPEN_EXISTING;
|
||||||
|
break;
|
||||||
|
case (Create):
|
||||||
|
flag = CREATE_ALWAYS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw fnd::Exception(kModuleName, "Unknown open mode");
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
#else
|
||||||
const char* SimpleFile::getOpenModeStr(OpenMode mode)
|
const char* SimpleFile::getOpenModeStr(OpenMode mode)
|
||||||
{
|
{
|
||||||
const char* str = "";
|
const char* str = "";
|
||||||
|
@ -101,3 +322,4 @@ const char* SimpleFile::getOpenModeStr(OpenMode mode)
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
#endif
|
Loading…
Reference in a new issue