HelenOS sources

root/uspace/lib/cpp/include/__bits/io/streambuf.hpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pubimbue
  2. getloc
  3. pubsetbuf
  4. pubseekoff
  5. pubseekpos
  6. pubsync
  7. in_avail
  8. snextc
  9. sbumpc
  10. sgetc
  11. sgetn
  12. sputbackc
  13. sungetc
  14. sputc
  15. sputn
  16. swap
  17. eback
  18. gptr
  19. egptr
  20. gbump
  21. setg
  22. pbase
  23. pptr
  24. epptr
  25. pbump
  26. setp
  27. imbue
  28. setbuf
  29. seekoff
  30. seekpos
  31. sync
  32. showmanyc
  33. xsgetn
  34. underflow
  35. uflow
  36. pbackfail
  37. xsputn
  38. overflow
  39. write_avail_
  40. putback_avail_
  41. read_avail_

/*
 * Copyright (c) 2018 Jaroslav Jindrak
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef LIBCPP_BITS_IO_STREAMBUF
#define LIBCPP_BITS_IO_STREAMBUF

#include <ios>
#include <iosfwd>
#include <locale>

namespace std
{

    /**
     * 27.6.3, class template basic_streambuf:
     */

    template<class Char, class Traits>
    class basic_streambuf
    {
        public:
            using traits_type = Traits;
            using char_type   = Char;
            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()
            { /* DUMMY BODY */ }

            /**
             * 27.6.3.2.1, locales:
             */

            locale pubimbue(const locale& loc)
            {
                imbue(loc);

                return locale_;
            }

            locale getloc() const
            {
                return locale_;
            }

            /**
             * 27.6.3.2.2, buffer and positioning:
             */

            basic_streambuf<Char, Traits>* pubsetbuf(char_type* s, streamsize n)
            {
                return setbuf(s, n);
            }

            pos_type pubseekoff(off_type off, ios_base::seekdir way,
                                ios_base::openmode which = ios_base::in | ios_base::out)
            {
                return seekoff(off, way, 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();
            }

            /**
             * 27.6.3.2.3, get area:
             */

            streamsize in_avail()
            {
                if (read_avail_())
                    return egptr() - gptr();
                else
                    return showmanyc();
            }

            int_type snextc()
            {
                if (traits_type::eq(sbumpc(), traits_type::eof()))
                    return traits_type::eof();
                else
                    return sgetc();
            }

            int_type sbumpc()
            {
                if (read_avail_())
                    return traits_type::to_int_type(*input_next_++);
                else
                    return uflow();
            }

            int_type sgetc()
            {
                if (read_avail_())
                    return traits_type::to_int_type(*input_next_);
                else
                    return underflow();
            }

            streamsize sgetn(char_type* s, streamsize n)
            {
                return xsgetn(s, n);
            }

            /**
             * 27.6.2.4, putback:
             */

            int_type sputbackc(char_type c)
            {
                if (!putback_avail_() || traits_type::eq(c, gptr()[-1]))
                    return pbackfail(traits_type::to_int_type(c));
                else
                    return traits_type::to_int_type(*(--input_next_));
            }

            int_type sungetc()
            {
                if (!putback_avail_())
                    return pbackfail();
                else
                    return traits_type::to_int_type(*(--input_next_));
            }

            /**
             * 27.6.2.5, put area:
             */

            int_type sputc(char_type c)
            {
                if (!write_avail_())
                    return overflow(traits_type::to_int_type(c));
                else
                {
                    traits_type::assign(*output_next_++, c);

                    return traits_type::to_int_type(c);
                }
            }

            streamsize sputn(const char_type* s, streamsize n)
            {
                return xsputn(s, n);
            }

        protected:
            basic_streambuf()
                : input_begin_{}, input_next_{}, input_end_{},
                  output_begin_{}, output_next_{}, output_end_{},
                  locale_{locale()}
            { /* DUMMY BODY */ }

            basic_streambuf(const basic_streambuf& rhs)
            {
                input_begin_ = rhs.input_begin_;
                input_next_ = rhs.input_next_;
                input_end_ = rhs.input_end_;

                output_begin_ = rhs.output_begin_;
                output_next_ = rhs.output_next_;
                output_end_ = rhs.output_end_;

                locale_ = rhs.locale_;
            }

            basic_streambuf& operator=(const basic_streambuf& rhs)
            {
                input_begin_ = rhs.input_begin_;
                input_next_  = rhs.input_next_;
                input_end_   = rhs.input_end_;

                output_begin_ = rhs.output_begin_;
                output_next_  = rhs.output_next_;
                output_end_   = rhs.output_end_;

                locale_ = rhs.locale_;

                return *this;
            }

            void swap(basic_streambuf& rhs)
            {
                swap(input_begin_, rhs.input_begin_);
                swap(input_next_, rhs.input_next_);
                swap(input_end_, rhs.input_end_);

                swap(output_begin_, rhs.output_begin_);
                swap(output_next_, rhs.output_next_);
                swap(output_end_, rhs.output_end_);

                swap(locale_, rhs.locale_);
            }

            /**
             * 27.6.3.3.2, get area:
             */

            char_type* eback() const
            {
                return input_begin_;
            }

            char_type* gptr() const
            {
                return input_next_;
            }

            char_type* egptr() const
            {
                return input_end_;
            }

            void gbump(int n)
            {
                input_next_ += n;
            }

            void setg(char_type* gbeg, char_type* gnext, char_type* gend)
            {
                input_begin_ = gbeg;
                input_next_  = gnext;
                input_end_   = gend;
            }

            /**
             * 27.6.3.3.3, put area:
             */

            char_type* pbase() const
            {
                return output_begin_;
            }

            char_type* pptr() const
            {
                return output_next_;
            }

            char_type* epptr() const
            {
                return output_end_;
            }

            void pbump(int n)
            {
                output_next_ += n;
            }

            void setp(char_type* pbeg, char_type* pend)
            {
                output_begin_ = pbeg;
                output_next_  = pbeg;
                output_end_   = pend;
            }

            /**
             * 27.6.3.4.1, locales:
             */

            virtual void imbue(const locale& loc)
            { /* DUMMY BODY */ }

            /**
             * 27.6.3.4.2, buffer management and positioning:
             */

            virtual basic_streambuf<Char, Traits>*
            setbuf(char_type* s, streamsize n)
            {
                return this;
            }

            virtual pos_type seekoff(off_type off, ios_base::seekdir way,
                                     ios_base::openmode which = ios_base::in | ios_base::out)
            {
                return pos_type(off_type(-1));
            }

            virtual pos_type seekpos(pos_type pos, ios_base::openmode which =
                                     ios_base::in | ios_base::out)
            {
                return pos_type(off_type(-1));
            }

            virtual int sync()
            {
                return 0;
            }

            /**
             * 27.6.3.4.3, get area:
             */

            virtual streamsize showmanyc()
            {
                return 0;
            }

            virtual streamsize xsgetn(char_type* s, streamsize n)
            {
                if (!s || n == 0)
                    return 0;

                streamsize i{0};
                auto eof = traits_type::eof();
                for (; i <= n; ++i)
                {
                    if (!read_avail_() && traits_type::eq_int_type(uflow(), eof))
                        break;

                    *s++ = *input_next_++;
                }

                return i;
            }

            virtual int_type underflow()
            {
                return traits_type::eof();
            }

            virtual int_type uflow()
            {
                auto res = underflow();
                if (traits_type::eq_int_type(res, traits_type::eof()))
                    return traits_type::eof();
                else
                    return traits_type::to_int_type(*input_next_++);
            }

            /**
             * 27.6.3.4.4, putback:
             */

            virtual int_type pbackfail(int_type c = traits_type::eof())
            {
                return traits_type::eof();
            }

            /**
             * 27.6.3.4.5, put area:
             */

            virtual streamsize xsputn(const char_type* s, streamsize n)
            {
                if (!s || n == 0)
                    return 0;

                streamsize i{0};
                for (; i <= n; ++i)
                {
                    if (!write_avail_() && traits_type::eq_int_type(overflow(), traits_type::eof()))
                        break;

                    *output_next_++ = *s++;
                }

                return i;
            }

            virtual int_type overflow(int_type c = traits_type::eof())
            {
                return traits_type::eof();
            }

        protected:
            char_type* input_begin_;
            char_type* input_next_;
            char_type* input_end_;

            char_type* output_begin_;
            char_type* output_next_;
            char_type* output_end_;

            locale locale_;

            bool write_avail_() const
            {
                return output_next_ && output_next_ < output_end_;
            }

            bool putback_avail_() const
            {
                return input_next_ && input_begin_ < input_next_;
            }

            bool read_avail_() const
            {
                return input_next_ && input_next_ < input_end_;
            }
    };

    using streambuf  = basic_streambuf<char>;
    using wstreambuf = basic_streambuf<wchar_t>;
}

#endif

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub