1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00
xn65/framework/csharp/stream.hpp
2024-03-26 17:22:00 -03:00

139 lines
3.8 KiB
C++

#ifndef XNA_CSHARP_STREAM_HPP
#define XNA_CSHARP_STREAM_HPP
#include "../types.hpp"
#include "../enums.hpp"
#include "../xnaerror.hpp"
#include <fstream>
#include <filesystem>
namespace xna {
class Stream {
public:
virtual Int Length() = 0;
virtual Long Position() = 0;
virtual void Close() = 0;
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_nullarg) = 0;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) = 0;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_nullarg) = 0;
virtual Int ReadByte(xna_error_nullarg) = 0;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_nullarg) = 0;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_nullarg) = 0;
virtual void WriteByte(Byte value, xna_error_nullarg) = 0;
};
class MemoryStream : public Stream {
public:
constexpr MemoryStream(Int capacity) :
_buffer(static_cast<size_t>(capacity)),
_length(capacity > 0 ? capacity : 0){}
virtual constexpr Int Length() override {
if (_closed)
return 0;
return _length;
}
virtual constexpr Long Position() override {
if (_closed)
return 0;
return _position;
}
virtual constexpr void Close() override {
_closed = true;
_buffer = std::vector<Byte>();
}
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) override;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int ReadByte(xna_error_ptr_arg) override;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
public:
Int _position{ 0 };
Int _origin{ 0 };
Int _length{ 0 };
std::vector<Byte> _buffer;
bool _closed{ false };
};
class FileStream : public Stream {
public:
FileStream(std::string const& path){
int flags = std::fstream::in
| std::fstream::out
| std::fstream::binary;
//| std::fstream::ate;
const auto exists = std::filesystem::exists(path);
if (!exists)
flags |= std::fstream::trunc;
_fstream.open(path.c_str(), flags);
if (!_fstream.is_open())
_closed = true;
}
~FileStream() {
Close();
}
virtual Int Length() override {
if (_closed)
return 0;
const auto end = endOfFile();
return end;
}
virtual Long Position() override {
if (_closed)
return 0;
return static_cast<Long>(_fstream.tellg());
}
virtual void Close() override {
_closed = true;
if(_fstream.is_open())
_fstream.close();
}
virtual Long Seek(Long offset, SeekOrigin const& origin, xna_error_ptr_arg) override;
virtual Int Read(Byte* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int Read(std::vector<Byte>& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual Int ReadByte(xna_error_ptr_arg) override;
virtual void Write(Byte const* buffer, Int bufferLength, Int offset, Int count, xna_error_ptr_arg) override;
virtual void Write(std::vector<Byte> const& buffer, Int offset, Int count, xna_error_ptr_arg) override;
virtual void WriteByte(Byte value, xna_error_ptr_arg) override;
public:
std::streampos _filesize{ 0 };
std::fstream _fstream;
bool _closed{ false };
Int endOfFile() {
if (_closed)
return 0;
const auto pos = _fstream.tellg();
_fstream.seekg(0, std::ios_base::end);
const auto end = _fstream.tellg();
_fstream.seekg(pos);
return static_cast<Int>(end);
}
};
}
#endif