Files
Custom-Operating-System/libs/libcxx/include/streambuf

193 lines
5.4 KiB
Plaintext
Raw Normal View History

2025-02-12 09:54:05 -05:00
#pragma GCC system_header
#ifndef _LIBCXX_STREAMBUF
#define _LIBCXX_STREAMBUF
#include <__config>
#include <algorithm>
#include <cstdlib>
#include <ios>
#include <iosfwd>
#include <string>
_LIBCXX_BEGIN_NAMESPACE_STD
template <class CharT, class Traits>
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<streamsize>(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<streamsize>(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