Kernel/include_std/streambuf
2024-05-18 07:42:01 +03:00

313 lines
6.0 KiB
Plaintext

/*
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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <algorithm>
#include <string>
#include <locale>
#include <ios>
namespace std
{
template <class CharT, class Traits = std::char_traits<CharT>>
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<CharT, Traits> *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<CharT, Traits> *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<char> streambuf;
typedef basic_streambuf<wchar_t> wstreambuf;
}