bsnes/nall/stream/stream.hpp

95 lines
2.2 KiB
C++

#pragma once
namespace nall {
struct stream {
stream() = default;
virtual ~stream() = default;
stream(const stream&) = delete;
auto operator=(const stream&) -> stream& = delete;
virtual auto seekable() const -> bool = 0;
virtual auto readable() const -> bool = 0;
virtual auto writable() const -> bool = 0;
virtual auto randomaccess() const -> bool = 0;
virtual auto data() const -> uint8_t* { return nullptr; }
virtual auto size() const -> uint = 0;
virtual auto offset() const -> uint = 0;
virtual auto seek(uint offset) const -> void = 0;
virtual auto read() const -> uint8_t = 0;
virtual auto write(uint8_t data) const -> void = 0;
virtual auto read(uint) const -> uint8_t { return 0; }
virtual auto write(uint, uint8_t) const -> void {}
explicit operator bool() const {
return size();
}
auto end() const -> bool {
return offset() >= size();
}
auto readl(uint length = 1) const -> uintmax {
uintmax data = 0, shift = 0;
while(length--) { data |= read() << shift; shift += 8; }
return data;
}
auto readm(uint length = 1) const -> uintmax {
uintmax data = 0;
while(length--) data = (data << 8) | read();
return data;
}
auto read(uint8_t* data, uint length) const -> void {
while(length--) *data++ = read();
}
auto text() const -> string {
string buffer;
buffer.resize(size());
seek(0);
read((uint8_t*)buffer.get(), size());
return buffer;
}
auto writel(uintmax data, uint length = 1) const -> void {
while(length--) {
write(data);
data >>= 8;
}
}
auto writem(uintmax data, uint length = 1) const -> void {
uintmax shift = 8 * length;
while(length--) {
shift -= 8;
write(data >> shift);
}
}
auto write(const uint8_t* data, uint length) const -> void {
while(length--) write(*data++);
}
struct byte {
byte(const stream& s, uint offset) : s(s), offset(offset) {}
operator uint8_t() const { return s.read(offset); }
auto operator=(uint8_t data) -> byte& { s.write(offset, data); return *this; }
private:
const stream& s;
const uint offset;
};
auto operator[](uint offset) const -> byte {
return byte(*this, offset);
}
};
}