enderalse/SKSE/Plugins/fs_skse_plugin_functions/common/IFileStream.cpp
2021-10-06 02:45:46 +02:00

241 lines
4.5 KiB
C++

#include "IFileStream.h"
#include "IDebugLog.h"
#include "IErrors.h"
#include <direct.h>
IFileStream::IFileStream()
:theFile(INVALID_HANDLE_VALUE)
{
}
IFileStream::IFileStream(const char * name)
:theFile(INVALID_HANDLE_VALUE)
{
Open(name);
}
IFileStream::~IFileStream()
{
Close();
}
/**
* Opens a file for reading and attaches it to the stream
*/
bool IFileStream::Open(const char * name)
{
Close();
theFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(theFile != INVALID_HANDLE_VALUE)
{
LARGE_INTEGER temp;
GetFileSizeEx(theFile, &temp);
streamLength = temp.QuadPart;
streamOffset = 0;
}
return theFile != INVALID_HANDLE_VALUE;
}
static UINT_PTR CALLBACK BrowseEventProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
return 0;
}
bool IFileStream::BrowseOpen(void)
{
bool result = false;
OPENFILENAME info;
char path[4096];
path[0] = 0;
info.lStructSize = sizeof(info);
info.hwndOwner = NULL;
info.hInstance = NULL;
info.lpstrFilter = NULL;
info.lpstrCustomFilter = NULL;
info.nMaxCustFilter = 0;
info.nFilterIndex = 0;
info.lpstrFile = path;
info.nMaxFile = sizeof(path);
info.lpstrFileTitle = NULL;
info.nMaxFileTitle = 0;
info.lpstrInitialDir = NULL;
info.lpstrTitle = NULL;
info.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_ENABLEHOOK | OFN_NOCHANGEDIR;
info.lpstrDefExt = NULL;
info.lCustData = NULL;
info.lpfnHook = BrowseEventProc;
info.lpTemplateName = NULL;
// info.pvReserved = NULL;
// info.dwReserved = NULL;
// info.FlagsEx = 0;
if(GetOpenFileName(&info))
{
result = Open(path);
}
return result;
}
/**
* Creates a new file for writing, overwriting any previously-existing files,
* and attaches it to the stream
*/
bool IFileStream::Create(const char * name)
{
Close();
theFile = CreateFile(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(theFile != INVALID_HANDLE_VALUE)
{
streamLength = 0;
streamOffset = 0;
}
return theFile != INVALID_HANDLE_VALUE;
}
bool IFileStream::BrowseCreate(const char * defaultName, const char * defaultPath, const char * title)
{
bool result = false;
OPENFILENAME info;
char path[4096];
if(defaultName)
strcpy_s(path, sizeof(path), defaultName);
info.lStructSize = sizeof(info);
info.hwndOwner = NULL;
info.hInstance = NULL;
info.lpstrFilter = NULL;
info.lpstrCustomFilter = NULL;
info.nMaxCustFilter = 0;
info.nFilterIndex = 0;
info.lpstrFile = path;
info.nMaxFile = sizeof(path);
info.lpstrFileTitle = NULL;
info.nMaxFileTitle = 0;
info.lpstrInitialDir = defaultPath;
info.lpstrTitle = title;
info.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_ENABLEHOOK |
OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
info.lpstrDefExt = NULL;
info.lCustData = NULL;
info.lpfnHook = BrowseEventProc;
info.lpTemplateName = NULL;
// info.pvReserved = NULL;
// info.dwReserved = NULL;
// info.FlagsEx = 0;
if(GetSaveFileName(&info))
{
result = Create(path);
}
return result;
}
/**
* Closes the current file
*/
void IFileStream::Close(void)
{
if(theFile)
{
CloseHandle(theFile);
theFile = INVALID_HANDLE_VALUE;
}
}
void IFileStream::ReadBuf(void * buf, UInt32 inLength)
{
UInt32 bytesRead;
ReadFile(theFile, buf, inLength, &bytesRead, NULL);
streamOffset += bytesRead;
}
void IFileStream::WriteBuf(const void * buf, UInt32 inLength)
{
UInt32 bytesWritten;
// check for file expansion
if(streamOffset > streamLength)
SetEndOfFile(theFile);
WriteFile(theFile, buf, inLength, &bytesWritten, NULL);
streamOffset += bytesWritten;
if(streamLength < streamOffset)
streamLength = streamOffset;
}
void IFileStream::SetOffset(SInt64 inOffset)
{
LARGE_INTEGER temp;
temp.QuadPart = inOffset;
SetFilePointerEx(theFile, temp, NULL, FILE_BEGIN);
streamOffset = inOffset;
}
void IFileStream::SetLength(UInt64 length)
{
SetOffset(length);
SetEndOfFile(theFile);
streamLength = length;
}
// ### TODO: get rid of buf
void IFileStream::MakeAllDirs(const char * path)
{
char buf[1024];
char * traverse = buf;
while(1)
{
char data = *path++;
if(!data)
break;
if((data == '\\') || (data == '/'))
{
*traverse = 0;
_mkdir(buf);
}
*traverse++ = data;
}
}
char * IFileStream::ExtractFileName(char * path)
{
char * traverse = path;
char * lastSlash = NULL;
while(1)
{
char data = *traverse++;
if((data == '\\') || (data == '/'))
lastSlash = traverse;
if(!data)
break;
}
return lastSlash;
}