1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-07 19:18:19 +02:00
Beef/BeefySysLib/FileStream.cpp
2025-03-28 08:08:33 -04:00

282 lines
5.1 KiB
C++

#include "FileStream.h"
#pragma warning(disable:4996)
USING_NS_BF;
FileStream::FileStream()
{
mFP = NULL;
mCacheBuffer = NULL;
mCacheReadPos = -0x3FFFFFFF;
mCacheSize = 0;
mVFilePos = 0;
mReadPastEnd = false;
}
FileStream::~FileStream()
{
delete mCacheBuffer;
if (mFP != NULL)
fclose(mFP);
}
bool FileStream::Open(const StringImpl& filePath, const char* fopenOptions)
{
#ifdef BF_PLATFORM_WINDOWS
mFP = _wfopen(UTF8Decode(filePath).c_str(), UTF8Decode(fopenOptions).c_str());
#else
mFP = fopen(filePath.c_str(), fopenOptions);
#endif
mReadPastEnd = false;
return mFP != NULL;
}
bool FileStream::IsOpen()
{
return mFP != NULL;
}
void FileStream::Close()
{
if (mFP != NULL)
{
fclose(mFP);
mFP = NULL;
}
}
void FileStream::SetCacheSize(int size)
{
size = (size + (4096-1)) & ~(4096-1);
mCacheReadPos = -0x3FFFFFFF;
delete mCacheBuffer;
if (size > 0)
mCacheBuffer = new uint8[size];
else
mCacheBuffer = NULL;
mCacheSize = size;
}
void FileStream::Seek(int size)
{
if (mCacheBuffer != NULL)
mVFilePos += size;
else
fseek(mFP, size, SEEK_CUR);
}
void FileStream::SetPos(int pos)
{
if (mCacheBuffer != NULL)
mVFilePos = pos;
else
fseek(mFP, pos, SEEK_SET);
}
bool FileStream::Eof()
{
if (mCacheBuffer != NULL)
{
fseek(mFP, 0, SEEK_END);
return mVFilePos >= ftell(mFP);
}
int aPos = (int)ftell(mFP);
fseek(mFP, 0, SEEK_END);
int aSize = (int)ftell(mFP);
fseek(mFP, aPos, SEEK_SET);
return aPos == aSize;
}
int FileStream::GetSize()
{
int aPos = (int)ftell(mFP);
fseek(mFP, 0, SEEK_END);
int aSize = (int)ftell(mFP);
fseek(mFP, aPos, SEEK_SET);
return aSize;
}
int FileStream::Read(void* ptr, int size)
{
if (mCacheBuffer != NULL)
{
int totalReadSize = 0;
while (true)
{
int buffOffset = mVFilePos - mCacheReadPos;
if ((buffOffset >= 0) && (buffOffset + size < mCacheSize))
{
// If inside
memcpy(ptr, mCacheBuffer + buffOffset, size);
mVFilePos += size;
return size;
}
else if ((buffOffset >= 0) && (buffOffset < mCacheSize))
{
int subSize = mCacheReadPos + mCacheSize - mVFilePos;
memcpy(ptr, mCacheBuffer + buffOffset, subSize);
mVFilePos += subSize;
ptr = (uint8*) ptr + subSize;
size -= subSize;
totalReadSize += subSize;
}
mCacheReadPos = mVFilePos & ~(4096-1);
fseek(mFP, mCacheReadPos, SEEK_SET);
int aSize = (int)fread(mCacheBuffer, 1, mCacheSize, mFP);
if (aSize != mCacheSize)
{
// Zero out underflow bytes
memset((uint8*) ptr + aSize, 0, mCacheSize - aSize);
}
totalReadSize += aSize;
}
return totalReadSize;
}
else
{
int aSize = (int)fread(ptr, 1, size, mFP);
if (aSize != size)
{
// Zero out underflow bytes
memset((uint8*) ptr + aSize, 0, size - aSize);
mReadPastEnd = true;
}
return aSize;
}
}
int FileStream::Write(void* ptr, int size)
{
return (int)fwrite(ptr, 1, size, mFP);
}
int FileStream::GetPos()
{
if (mCacheBuffer != NULL)
return mVFilePos;
return (int)ftell(mFP);
}
//////////////////////////////////////////////////////////////////////////
int FileSubStream::GetSize()
{
return mSize;
}
int FileSubStream::GetPos()
{
return FileStream::GetPos() - mOffset;
}
void FileSubStream::SetPos(int pos)
{
FileStream::SetPos(pos + mOffset);
}
//////////////////////////////////////////////////////////////////////////
SysFileStream::SysFileStream()
{
mFile = NULL;
}
SysFileStream::~SysFileStream()
{
if (mFile != NULL)
BfpFile_Release(mFile);
}
bool SysFileStream::Open(const StringImpl& filePath, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags)
{
mFile = BfpFile_Create(filePath.c_str(), createKind, createFlags, BfpFileAttribute_Normal, NULL);
return mFile != NULL;
//mHandle = ::CreateFileW(UTF8Decode(filePath).c_str(), access, 0, NULL, CREATE_ALWAYS, 0, 0);
//return mHandle != INVALID_HANDLE_VALUE;
}
bool SysFileStream::IsOpen()
{
return mFile != NULL;
}
void SysFileStream::Close()
{
if (mFile != NULL)
{
BfpFile_Release(mFile);
mFile = NULL;
}
}
void SysFileStream::SetSizeFast(int size)
{
int curSize = GetSize();
if (size == curSize)
return;
int curPos = GetPos();
SetPos(size);
BfpFileResult result = BfpFileResult_Ok;
BfpFile_Truncate(mFile, &result);
SetPos(curPos);
return;
}
void SysFileStream::Seek(int pos)
{
BfpFile_Seek(mFile, pos, BfpFileSeekKind_Relative);
}
void SysFileStream::SetPos(int pos)
{
BfpFile_Seek(mFile, pos, BfpFileSeekKind_Absolute);
}
bool SysFileStream::Eof()
{
char c;
int readSize = (int)BfpFile_Read(mFile, &c, 1, -1, NULL);
if (readSize == 0)
return true;
BfpFile_Seek(mFile, -1, BfpFileSeekKind_Relative);
return false;
}
int SysFileStream::GetSize()
{
return (int)BfpFile_GetFileSize(mFile);
}
int SysFileStream::Read(void* ptr, int size)
{
int readSize = (int)BfpFile_Read(mFile, ptr, size, -1, NULL);
if (readSize != size)
{
// Zero out underflow bytes
memset((uint8*)ptr + readSize, 0, size - readSize);
}
return readSize;
}
int SysFileStream::Write(void* ptr, int size)
{
return (int)BfpFile_Write(mFile, ptr, size, -1, NULL);
}
int SysFileStream::GetPos()
{
return (int)BfpFile_Seek(mFile, 0, BfpFileSeekKind_Relative);
}