Added STLStream that wraps STL stream types for usage with functions that expect a Mijin stream.
This commit is contained in:
parent
f28cc04aa1
commit
5f0e6e9726
@ -88,6 +88,134 @@ public:
|
||||
};
|
||||
|
||||
using IOStreamAdapter = BasicIOStreamAdapter<char>;
|
||||
|
||||
template<typename TChar, typename TTraits = std::char_traits<TChar>>
|
||||
class BasicSTLStream : public Stream
|
||||
{
|
||||
private:
|
||||
std::basic_istream<TChar, TTraits>* istream_ = nullptr;
|
||||
std::basic_ostream<TChar, TTraits>* ostream_ = nullptr;
|
||||
public:
|
||||
explicit BasicSTLStream(std::basic_istream<TChar, TTraits>& istream) : istream_(&istream) {}
|
||||
explicit BasicSTLStream(std::basic_ostream<TChar, TTraits>& ostream) : ostream_(&ostream) {}
|
||||
explicit BasicSTLStream(std::basic_iostream<TChar, TTraits>& iostream) : istream_(&iostream), ostream_(&ostream_) {}
|
||||
StreamError readRaw(std::span<std::uint8_t> buffer, const ReadOptions& options = {}, std::size_t* outBytesRead = nullptr) override
|
||||
{
|
||||
(void) options;
|
||||
|
||||
if (istream_ != nullptr)
|
||||
{
|
||||
if (buffer.size() % sizeof(TChar) != 0)
|
||||
{
|
||||
// buffer size must be divisible by character size
|
||||
return StreamError::IO_ERROR;
|
||||
}
|
||||
|
||||
istream_->read(std::bit_cast<TChar*>(buffer.data()), buffer.size() / sizeof(TChar));
|
||||
if (!istream_->good())
|
||||
{
|
||||
return StreamError::IO_ERROR;
|
||||
}
|
||||
if (outBytesRead != nullptr)
|
||||
{
|
||||
*outBytesRead = buffer.size();
|
||||
}
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
return StreamError::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
StreamError writeRaw(std::span<const std::uint8_t> buffer) override
|
||||
{
|
||||
if (ostream_ != nullptr)
|
||||
{
|
||||
if (buffer.size() % sizeof(TChar) != 0)
|
||||
{
|
||||
// buffer size must be divisible by character size
|
||||
return StreamError::IO_ERROR;
|
||||
}
|
||||
|
||||
ostream_->write(std::bit_cast<const TChar*>(buffer.data()), buffer.size() / sizeof(TChar));
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
return StreamError::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
std::size_t tell() override
|
||||
{
|
||||
// kind of weird case, since the streams can have different positions
|
||||
// this is fine, I guess
|
||||
if (istream_ != nullptr)
|
||||
{
|
||||
return istream_->tellg();
|
||||
}
|
||||
if (ostream_ != nullptr)
|
||||
{
|
||||
return ostream_->tellp();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
StreamError seek(std::intptr_t pos, mijin::SeekMode seekMode = SeekMode::ABSOLUTE) override
|
||||
{
|
||||
std::ios_base::seekdir seekDir = std::ios_base::beg;
|
||||
switch (seekMode)
|
||||
{
|
||||
case mijin::SeekMode::ABSOLUTE:
|
||||
break;
|
||||
case mijin::SeekMode::RELATIVE:
|
||||
seekDir = std::ios_base::cur;
|
||||
break;
|
||||
case mijin::SeekMode::RELATIVE_TO_END:
|
||||
seekDir = std::ios_base::end;
|
||||
break;
|
||||
}
|
||||
if (istream_ != nullptr)
|
||||
{
|
||||
istream_->seekg(pos, seekDir);
|
||||
if (!istream_->good())
|
||||
{
|
||||
return StreamError::IO_ERROR;
|
||||
}
|
||||
}
|
||||
if (ostream_ != nullptr)
|
||||
{
|
||||
ostream_->seekp(pos, seekDir);
|
||||
if (!ostream_->good())
|
||||
{
|
||||
return StreamError::IO_ERROR;
|
||||
}
|
||||
}
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
bool isAtEnd() override
|
||||
{
|
||||
if (istream_ != nullptr)
|
||||
{
|
||||
return istream_->peek() == TTraits::eof();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
StreamFeatures getFeatures() override
|
||||
{
|
||||
return {
|
||||
.read = istream_ != nullptr,
|
||||
.write = ostream_ != nullptr,
|
||||
.tell = istream_ != nullptr || ostream_ != nullptr,
|
||||
.seek = istream_ != nullptr || ostream_ != nullptr,
|
||||
.async = false,
|
||||
.readOptions = {
|
||||
.partial = false,
|
||||
.peek = false,
|
||||
.noBlock = false
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
using STLStream = BasicSTLStream<char>;
|
||||
} // namespace mijin
|
||||
|
||||
#endif // !defined(MIJIN_IO_STLSTREAM_HPP_INCLUDED)
|
||||
|
Loading…
x
Reference in New Issue
Block a user