From 12edd1f0b21d69ab5be693e7345eea1eb9a7d107 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Tue, 9 Aug 2022 09:49:52 +0800 Subject: [PATCH] add streambuf for wrapping resources in IOStream --- ios/src/streambuf.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++ ios/src/streambuf.hpp | 27 ++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 ios/src/streambuf.cpp create mode 100644 ios/src/streambuf.hpp diff --git a/ios/src/streambuf.cpp b/ios/src/streambuf.cpp new file mode 100644 index 00000000..d2308b8f --- /dev/null +++ b/ios/src/streambuf.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include + +using namespace std; + +namespace polyvox { + +class streambuf : public std::streambuf +{ + public: + streambuf(const char *begin, const char *end); + ~streambuf() { + + } + streamsize size(); + + private: + int_type uflow() override; + int_type underflow() override; + int_type pbackfail(int_type ch) override; + streampos seekoff(streamoff off, ios_base::seekdir way, ios_base::openmode which) override; + streampos seekpos(streampos sp, ios_base::openmode which) override; + std::streamsize showmanyc() override; + +}; + +streambuf::streambuf(const char *begin, const char *end) +{ + setg((char*)begin, (char*)begin, (char*)end); +} + +streamsize streambuf::size() { + return egptr() - eback(); +} + +streambuf::int_type streambuf::underflow() +{ + if (gptr() == egptr()) { + return traits_type::eof(); + } + return *(gptr()); +} + +streambuf::int_type streambuf::uflow() +{ + if (gptr() == egptr()) { + return traits_type::eof(); + } + gbump(1); + + return *(gptr()); +} + +streambuf::int_type streambuf::pbackfail(int_type ch) +{ + if (gptr() == eback() || (ch != traits_type::eof() && ch != gptr()[-1])) + return traits_type::eof(); + gbump(-ch); + return *(gptr()); +} + +streamsize streambuf::showmanyc() +{ + return egptr() - gptr(); +} + +streampos streambuf::seekoff(streamoff off, ios_base::seekdir way, ios_base::openmode which = ios_base::in) { + if(way == ios_base::beg) { + setg(eback(), eback()+off, egptr()); + } else if(way == ios_base::cur) { + gbump(off); + } else { + setg(eback(), egptr()-off, egptr()); + } + return gptr() - eback(); +} + +streampos streambuf::seekpos(streampos sp, ios_base::openmode which = ios_base::in) { + return seekoff(sp - pos_type(off_type(0)), std::ios_base::beg, which); +} +} \ No newline at end of file diff --git a/ios/src/streambuf.hpp b/ios/src/streambuf.hpp new file mode 100644 index 00000000..5a593a24 --- /dev/null +++ b/ios/src/streambuf.hpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +namespace polyvox { + + class streambuf : public std::streambuf + { + public: + streambuf(const char *begin, const char *end); + ~streambuf() { + + } + streamsize size(); + + private: + int_type uflow() override; + int_type underflow() override; + int_type pbackfail(int_type ch) override; + streampos seekoff(streamoff off, ios_base::seekdir way, ios_base::openmode which) override; + streampos seekpos(streampos sp, ios_base::openmode which) override; + std::streamsize showmanyc() override; + + }; + +} \ No newline at end of file