// Copyright 2024 The DMBMX2Tools Authors
// SPDX-License-Identifier: MIT
#pragma once
#include
#include
namespace dmtools::io {
enum class StreamSeekDirection : u8 {
Beg,
Cur,
End
};
using StreamDiff = i64;
// TODO: Communicate error conditions using ErrorOr<> instead of
// -1 values.
/// A abstract stream of bytes. We use a custom implementation
/// instead of C++ IO streams mostly for control reasons, and
/// also to avoid exceptions (we'll use ErrorOr for errors later on)
struct Stream {
Stream() = default;
virtual ~Stream() = default;
Stream(const Stream&) = delete;
Stream(Stream&&) = delete;
virtual void Flush() { return; }
virtual StreamDiff ReadSome(u8* buffer, usize length) = 0;
StreamDiff ReadSome(std::vector& buffer);
virtual StreamDiff WriteSome(const u8* buffer, usize length) {
// Default implementation disallows writes. Can be changed
return -1;
}
StreamDiff WriteSome(const std::vector& buffer);
/// Reads a single POD type from stream
template
inline bool ReadObject(T& obj) {
auto sz = ReadSome(std::bit_cast(&obj), sizeof(T));
if(sz != sizeof(T))
return false;
return true;
}
template
inline bool WriteObject(const T& obj) {
auto sz = WriteSome(std::bit_cast(&obj), sizeof(T));
if(sz != sizeof(T))
return false;
return true;
}
virtual StreamDiff Seek(StreamDiff where, StreamSeekDirection dir) = 0;
virtual StreamDiff Tell() const = 0;
virtual bool Ok() const = 0;
virtual bool Eof() const = 0;
inline operator bool() const {
return Ok() && !Eof();
}
};
} // namespace dmtools