1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00
Files
OpenRCT2/src/core/FileStream.hpp
2016-01-23 18:58:31 +00:00

109 lines
2.3 KiB
C++

#pragma once
#include "../common.h"
#include <SDL.h>
#include "IStream.hpp"
enum
{
FILE_MODE_OPEN,
FILE_MODE_WRITE
};
/**
* A stream for reading and writing to files. Wraps an SDL_RWops, SDL2's cross platform file stream.
*/
class FileStream : public IStream
{
private:
SDL_RWops * _file;
bool _canRead;
bool _canWrite;
bool _disposed;
public:
FileStream(const utf8 * path, int fileMode)
{
const char * mode;
switch (fileMode) {
case FILE_MODE_OPEN:
mode = "rb";
_canRead = true;
_canWrite = false;
break;
case FILE_MODE_WRITE:
mode = "wb";
_canRead = false;
_canWrite = true;
break;
default:
throw;
}
_file = SDL_RWFromFile(path, mode);
if (_file == nullptr)
{
throw IOException(SDL_GetError());
}
_disposed = false;
}
~FileStream()
{
Dispose();
}
void Dispose() override
{
if (!_disposed)
{
_disposed = true;
SDL_RWclose(_file);
}
}
bool CanRead() const override { return _canRead; }
bool CanWrite() const override { return _canWrite; }
uint64 GetLength() const override { return SDL_RWsize(_file); }
uint64 GetPosition() const override { return SDL_RWtell(_file); }
void SetPosition(uint64 position) override
{
Seek(position, STREAM_SEEK_BEGIN);
}
void Seek(sint64 offset, int origin) override
{
switch (origin) {
case STREAM_SEEK_BEGIN:
SDL_RWseek(_file, offset, RW_SEEK_SET);
break;
case STREAM_SEEK_CURRENT:
SDL_RWseek(_file, offset, RW_SEEK_CUR);
break;
case STREAM_SEEK_END:
SDL_RWseek(_file, offset, RW_SEEK_END);
break;
}
}
void Read(void * buffer, uint64 length) override
{
if (SDL_RWread(_file, buffer, (size_t)length, 1) != 1)
{
throw IOException("Attempted to read past end of file.");
}
}
void Write(const void * buffer, uint64 length) override
{
if (SDL_RWwrite(_file, buffer, (size_t)length, 1) != 1)
{
throw IOException("Unable to write to file.");
}
}
};