#include "FileHandleStream.h" USING_NS_BF; FileHandleStream::FileHandleStream() { mFileHandle = NULL; mCacheBuffer = NULL; mCacheReadPos = -0x3FFFFFFF; mCacheSize = 0; mVFilePos = 0; } FileHandleStream::~FileHandleStream() { delete mCacheBuffer; if (mFileHandle != NULL) ::CloseHandle_File(mFileHandle); } void FileHandleStream::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 FileHandleStream::Seek(int pos) { if (mCacheBuffer != NULL) mVFilePos += pos; else ::SetFilePointer(mFileHandle, pos, 0, FILE_CURRENT); } void FileHandleStream::SetPos(int pos) { if (mCacheBuffer != NULL) mVFilePos = pos; else ::SetFilePointer(mFileHandle, pos, 0, FILE_BEGIN); } bool FileHandleStream::Eof() { if (mCacheBuffer != NULL) { ::SetFilePointer(mFileHandle, 0, 0, FILE_END); return mVFilePos >= (int)::SetFilePointer(mFileHandle, 0, 0, FILE_CURRENT); } return ::SetFilePointer(mFileHandle, 0, 0, FILE_CURRENT) >= ::GetFileSize(mFileHandle, NULL); } int FileHandleStream::GetSize() { return ::GetFileSize(mFileHandle, NULL); } void FileHandleStream::Read(void* ptr, int size) { if (mCacheBuffer != NULL) { while (true) { int buffOffset = mVFilePos - mCacheReadPos; if ((buffOffset >= 0) && (buffOffset + size < mCacheSize)) { // If inside memcpy(ptr, mCacheBuffer + buffOffset, size); mVFilePos += size; return; } else if ((buffOffset >= 0) && (buffOffset < mCacheSize)) { int subSize = mCacheReadPos + mCacheSize - mVFilePos; memcpy(ptr, mCacheBuffer + buffOffset, subSize); mVFilePos += subSize; ptr = (uint8*)ptr + subSize; size -= subSize; } mCacheReadPos = mVFilePos & ~(4096 - 1); ::SetFilePointer(mFileHandle, mCacheReadPos, 0, FILE_BEGIN); int aSize = 0; ::ReadFile(mFileHandle, mCacheBuffer, mCacheSize, (DWORD*)&aSize, NULL); if (aSize != mCacheSize) { // Zero out underflow bytes memset((uint8*)ptr + aSize, 0, mCacheSize - aSize); } } } else { int aSize = 0; ::ReadFile(mFileHandle, ptr, size, (DWORD*)&aSize, NULL); if (aSize != size) { // Zero out underflow bytes memset((uint8*)ptr + aSize, 0, size - aSize); } } } void FileHandleStream::Write(void* ptr, int size) { ::WriteFile(mFileHandle, ptr, size, NULL, NULL); } int FileHandleStream::GetPos() { if (mCacheBuffer != NULL) return mVFilePos; return ::SetFilePointer(mFileHandle, 0, 0, FILE_CURRENT); }