#pragma GCC system_header #ifndef _LIBCXX_STREAMBUF #define _LIBCXX_STREAMBUF #include <__config> #include #include #include #include #include _LIBCXX_BEGIN_NAMESPACE_STD template class basic_streambuf { public: using char_type = CharT; using traits_type = Traits; using int_type = typename traits_type::int_type; using pos_type = typename traits_type::pos_type; using off_type = typename traits_type::off_type; virtual ~basic_streambuf() = default; // TODO: Add locales basic_streambuf* pubsetbuf(char_type* s, streamsize n) { return setbuf(s, n); } pos_type pubseekoff(off_type off, ios_base::seekdir dir, ios_base::openmode which = ios_base::in | ios_base::out) { return seekoff(off, dir, which); } pos_type pubseekpos(pos_type pos, ios_base::openmode which = ios_base::in | ios_base::out) { return seekpos(pos, which); } int pubsync() { return sync(); } streamsize in_avail() { if (egptr() - gptr() > 0) { return egptr() - gptr(); } return showmanyc(); } int_type snextc() { if (sbumpc() == traits_type::eof()) { return traits_type::eof(); } return sgetc(); } int_type sbumpc() { if (gptr() == egptr()) { return uflow(); } return Traits::to_int_type(*m_gptr++); } int_type sgetc() { if (gptr() == egptr()) { return underflow(); } return Traits::to_int_type(*gptr()); } streamsize sgetn(char_type* s, streamsize n) { return xsgetn(s, n); } int_type sputc(char_type c) { if (pptr() == epptr()) { return overflow(c); } *pptr() = c; m_pptr++; return Traits::to_int_type(c); } streamsize sputn(const char_type* s, streamsize n) { return xsputn(s, n); } int_type sputbackc(char_type c) { if (eback() == egptr() || traits_type::eq(c, egptr()[-1])) { return pbackfail(c); } return traits_type::to_int_type(*(--m_gptr)); } int_type sungetc() { if (eback() == egptr()) return pbackfail(); return traits_type::to_int_type(*(--m_gptr)); } protected: basic_streambuf() = default; virtual basic_streambuf* setbuf(char_type* s, streamsize n) { return this; } virtual pos_type seekoff(off_type off, ios_base::seekdir dir, ios_base::openmode which) { return pos_type(off_type(-1)); } virtual pos_type seekpos(pos_type pos, ios_base::openmode which) { return pos_type(off_type(-1)); } virtual int sync() { return 0; } virtual streamsize showmanyc() { return 0; } virtual int_type underflow() { return traits_type::eof(); } virtual int_type uflow() { if (underflow() == traits_type::eof()) { return traits_type::eof(); } return traits_type::to_int_type(*m_gptr++); } virtual streamsize xsgetn(char_type* s, streamsize count) { auto eof = traits_type::eof(); int_type tmpcint; for (streamsize i = 0; i < count;) { if (gptr() < egptr()) { streamsize can_get = std::min(static_cast(egptr() - gptr()), count); traits_type::copy(s, gptr(), can_get); this->gbump(can_get); s += can_get; i += can_get; } else if ((tmpcint = uflow()) != eof) { *s = traits_type::to_char_type(tmpcint); s++; i++; } else { return i; } } return count; } char_type* eback() const { return m_eback; } char_type* gptr() const { return m_gptr; } char_type* egptr() const { return m_egptr; } void gbump(int n) { m_gptr += n; } void setg(char_type* gbeg, char_type* gcurr, char_type* gend) { m_eback = gbeg; m_gptr = gcurr; m_egptr = gend; } virtual streamsize xsputn(const char_type* s, streamsize count) { auto eof = traits_type::eof(); int_type tmpcint; for (streamsize i = 0; i < count;) { if (pptr() < epptr()) { streamsize can_put = std::min(static_cast(egptr() - gptr()), count); traits_type::copy(pptr(), s, can_put); this->pbump(can_put); s += can_put; i += can_put; } else if ((tmpcint = overflow(*s)) != eof) { s++; i++; } else { return i; } } return count; } virtual int_type overflow(int_type ch = traits_type::eof()) { return traits_type::eof(); } char_type* pbase() const { return m_pbase; } char_type* pptr() const { return m_pptr; } char_type* epptr() const { return m_epptr; } void pbump(int n) { m_pptr += n; } void setg(char_type* pbeg, char_type* pend) { m_pbase = m_pptr = pbeg; m_epptr = pend; } virtual int_type pbackfail(int_type c = traits_type::eof()) { return traits_type::eof(); } private: char_type* m_eback { nullptr }; char_type* m_gptr { nullptr }; char_type* m_egptr { nullptr }; char_type* m_pbase { nullptr }; char_type* m_pptr { nullptr }; char_type* m_epptr { nullptr }; }; _LIBCXX_END_NAMESPACE_STD #endif // _LIBCXX_STREAMBUF