// Copyright (C) 2003  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
#ifndef DLIB_SOCKSTrEAMBUF_UNBUFFERED_Hh_
#define DLIB_SOCKSTrEAMBUF_UNBUFFERED_Hh_

#include <iosfwd>
#include <streambuf>
#include "../sockets.h"
#include "sockstreambuf_abstract.h"

namespace dlib
{

// ---------------------------------------------------------------------------------------- 

    class sockstreambuf_unbuffered : public std::streambuf
    {
        /*!
            WHAT THIS OBJECT REPRESENTS
                This is an implementation of the interface defined in
                sockstreambuf_abstract.h except that it doesn't do any kind of buffering at
                all.  It just writes data directly to a connection.  However, note that we
                don't implement the flushes_output_on_read() routine as this object always
                flushes immediately (since it isn't buffers.  Moreover, it should be
                pointed out that this object is deprecated and only present for backwards
                compatibility with previous versions of dlib.  So you really should use the
                sockstreambuf object instead.  

            INITIAL VALUE
                con == a connection
                lastread_next == false
                peek == EOF

            CONVENTION
                if (peek != EOF) then
                    peek == the last character read from the connection object and
                            is used to store the char in the event the user peeks by
                            calling sgetc()
                if (lastread != EOF) then
                    lastread == the last character read and consumed by the user

                if (lastread_next) then
                    the next character to be returned to the user is lastread because
                    the user put it back into the buffer

        !*/

    public:


        sockstreambuf_unbuffered (
            connection* con_
        ) :
            con(*con_),
            peek(EOF),
            lastread_next(false)
        {}

        sockstreambuf_unbuffered (
            const std::unique_ptr<connection>& con_
        ) :
            con(*con_),
            peek(EOF),
            lastread_next(false)
        {}

        connection* get_connection (
        ) { return &con; }


    protected:

        // output functions
        int_type overflow (
            int_type c
        );

        std::streamsize xsputn (
            const char* s,
            std::streamsize num
        );

        // input functions
        int_type underflow( 
        );

        int_type uflow( 
        );

        int_type pbackfail(
            int_type c
        );

        std::streamsize xsgetn (
            char_type* s, 
            std::streamsize n
        );

    private:

        // member data
        connection&  con;
        int_type peek;
        int_type lastread;
        bool lastread_next;
    
    };

// ---------------------------------------------------------------------------------------- 

}

#ifdef NO_MAKEFILE
#include "sockstreambuf_unbuffered.cpp"
#endif

#endif // DLIB_SOCKSTrEAMBUF_UNBUFFERED_Hh_

