Added wrapper to allow passing Mijin streams to functions that expect an STL stream.
This commit is contained in:
parent
a015ad54a7
commit
8e117e0f47
93
source/mijin/io/stlstream.hpp
Normal file
93
source/mijin/io/stlstream.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(MIJIN_IO_STLSTREAM_HPP_INCLUDED)
|
||||
#define MIJIN_IO_STLSTREAM_HPP_INCLUDED 1
|
||||
|
||||
#include <array>
|
||||
#include <streambuf>
|
||||
#include "./stream.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
|
||||
//
|
||||
// public defines
|
||||
//
|
||||
|
||||
//
|
||||
// public constants
|
||||
//
|
||||
|
||||
//
|
||||
// public types
|
||||
//
|
||||
|
||||
template<typename TChar, typename TTraits = std::char_traits<TChar>>
|
||||
class BasicStreambufAdapter : public std::basic_streambuf<TChar, TTraits>
|
||||
{
|
||||
private:
|
||||
using base_t = std::basic_streambuf<TChar, TTraits>;
|
||||
using char_type = base_t::char_type;
|
||||
using int_type = base_t::int_type;
|
||||
using traits_type = base_t::traits_type;
|
||||
|
||||
static const std::size_t BUFFER_SIZE = 4096;
|
||||
|
||||
Stream* stream_ = nullptr;
|
||||
std::array<TChar, BUFFER_SIZE> inBuffer_;
|
||||
std::array<TChar, BUFFER_SIZE> outBuffer_;
|
||||
public:
|
||||
explicit BasicStreambufAdapter(Stream& stream) noexcept : stream_(&stream)
|
||||
{
|
||||
base_t::setp(outBuffer_.data(), outBuffer_.data() + outBuffer_.size());
|
||||
}
|
||||
|
||||
int_type underflow() override
|
||||
{
|
||||
std::size_t bytesRead = 0;
|
||||
while (bytesRead == 0)
|
||||
{
|
||||
if (stream_->isAtEnd())
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
throwOnError(stream_->readRaw(inBuffer_, {.partial = true}, &bytesRead));
|
||||
}
|
||||
base_t::setg(inBuffer_.data(), inBuffer_.data(), inBuffer_.data() + bytesRead);
|
||||
return inBuffer_[0];
|
||||
}
|
||||
|
||||
int_type overflow(int_type c) override
|
||||
{
|
||||
if (base_t::pptr() - base_t::pbase() > 0)
|
||||
{
|
||||
throwOnError(stream_->writeRaw(base_t::pbase(), base_t::pptr() - base_t::pbase()));
|
||||
}
|
||||
outBuffer_[0] = traits_type::to_char_type(c);
|
||||
base_t::setp(outBuffer_.data() + 1, outBuffer_.data() + outBuffer_.size());
|
||||
return traits_type::not_eof(c);
|
||||
}
|
||||
|
||||
int sync() override
|
||||
{
|
||||
stream_->flush();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
using StreambufAdapter = BasicStreambufAdapter<char>;
|
||||
|
||||
template<typename TChar, typename TTraits = std::char_traits<TChar>>
|
||||
class BasicIOStreamAdapter : public std::basic_iostream<TChar, TTraits>
|
||||
{
|
||||
private:
|
||||
StreambufAdapter streambuf_;
|
||||
public:
|
||||
BasicIOStreamAdapter(Stream& stream) noexcept : std::basic_iostream<TChar, TTraits>(&streambuf_), streambuf_(stream) {}
|
||||
};
|
||||
|
||||
using IOStreamAdapter = BasicIOStreamAdapter<char>;
|
||||
} // namespace mijin
|
||||
|
||||
#endif // !defined(MIJIN_IO_STLSTREAM_HPP_INCLUDED)
|
Loading…
x
Reference in New Issue
Block a user