/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #pragma once #include #include #include #include namespace std { template > class basic_streambuf { public: typedef CharT char_type; typedef Traits::char_type traits_type; typedef Traits::int_type int_type; typedef Traits::pos_type pos_type; typedef Traits::off_type off_type; private: char_type *_eback; char_type *_gptr; char_type *_egptr; char_type *_pbase; char_type *_pptr; char_type *_epptr; public: virtual ~basic_streambuf(); #pragma region Locales std::locale pubimbue(const std::locale &loc) { return imbue(loc); } std::locale getloc() const { return imbue(std::locale()); } #pragma endregion Locales #pragma region Positioning basic_streambuf *pubsetbuf(char_type *s, std::streamsize n) { return setbuf(s, n); } pos_type pubseekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = ios_base::in | ios_base::out) { return seekoff(off, dir, which); } pos_type pubseekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) { return seekpos(pos, which); } int pubsync() { return sync(); } #pragma endregion Positioning #pragma region Get Area std::streamsize in_avail() { return egptr() - gptr(); } int_type snextc() { return gptr() == egptr() ? Traits::eof() : Traits::to_int_type(*gptr()); } int_type sgetc() { return gptr() == egptr() ? underflow() : Traits::to_int_type(*gptr()); } std::streamsize sgetn(char_type *s, std::streamsize count) { std::streamsize copied = 0; while (copied < count) { if (gptr() == egptr()) { if (underflow() == Traits::eof()) { break; } } *s++ = *gptr(); ++copied; } return copied; } #pragma endregion Get Area #pragma region Put Area int_type sputc(char_type ch) { if (pptr() == epptr()) { if (overflow(Traits::to_int_type(ch)) == Traits::eof()) { return Traits::eof(); } } else { *pptr() = ch; pbump(1); } return Traits::to_int_type(ch); } std::streamsize sputn(const char_type *s, std::streamsize count) { return xsputn(s, count); } #pragma endregion Put Area #pragma region Putback int_type sputbackc(char_type c) { if (gptr() == eback() || !Traits::eq(c, gptr()[-1])) { return Traits::eof(); } gbump(-1); return Traits::to_int_type(c); } int_type sungetc() { if (gptr() == eback()) { return Traits::eof(); } gbump(-1); return Traits::to_int_type(*gptr()); } #pragma endregion Putback protected: basic_streambuf() : _eback(nullptr), _gptr(nullptr), _egptr(nullptr), _pbase(nullptr), _pptr(nullptr), _epptr(nullptr) { } basic_streambuf(const basic_streambuf &rhs) : _eback(rhs._eback), _gptr(rhs._gptr), _egptr(rhs._egptr), _pbase(rhs._pbase), _pptr(rhs._pptr), _epptr(rhs._epptr) { } basic_streambuf &operator=(const basic_streambuf &other) { if (this == &other) return *this; _eback = other._eback; _gptr = other._gptr; _egptr = other._egptr; _pbase = other._pbase; _pptr = other._pptr; _epptr = other._epptr; return *this; } void swap(basic_streambuf &other) { std::swap(_eback, other._eback); std::swap(_gptr, other._gptr); std::swap(_egptr, other._egptr); std::swap(_pbase, other._pbase); std::swap(_pptr, other._pptr); std::swap(_epptr, other._epptr); } #pragma region Locales virtual void imbue(const std::locale &loc) = 0; #pragma endregion Locales #pragma region Positioning virtual basic_streambuf *setbuf(char_type *s, std::streamsize n) = 0; virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = ios_base::in | ios_base::out) = 0; virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) = 0; virtual int sync() = 0; #pragma endregion Positioning #pragma region Get Area virtual std::streamsize showmanyc() = 0; virtual int_type underflow() = 0; virtual int_type uflow() = 0; virtual std::streamsize xsgetn(char_type *s, std::streamsize count) = 0; char_type *eback() const { return _eback; } char_type *gptr() const { return _gptr; } char_type *egptr() const { return _egptr; } void gbump(int count) { _gptr += count; } void setg(char_type *gbeg, char_type *gcurr, char_type *gend) { _eback = gbeg; _gptr = gcurr; _egptr = gend; } #pragma endregion Get Area #pragma region Put Area virtual std::streamsize xsputn(const char_type *s, std::streamsize count) = 0; virtual int_type overflow(int_type ch = Traits::eof()) = 0; char_type *pbase() const { return _pbase; } char_type *pptr() const { return _pptr; } char_type *epptr() const { return _epptr; } void pbump(int count) { _pptr += count; } void setp(char_type *pbeg, char_type *pend) { _pbase = pbeg; _pptr = pbeg; _epptr = pend; } #pragma endregion Put Area #pragma region Putback virtual int_type pbackfail(int_type c = Traits::eof()) = 0; #pragma endregion Putback }; typedef basic_streambuf streambuf; typedef basic_streambuf wstreambuf; }