+/**************************************************************************
+** (c) Copyright 2012, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+** FILE NAME : sockstream.h
+** SYSTEM NAME : Socket stream classes
+** VERSION NUMBER : 0.1
+**
+** DESCRIPTION : sockbuf and sockstream classes.
+**
+** EXPORTED OBJECTS : class sockbuf, class isockstream,
+** class osockstream, class sockstream
+** LOCAL OBJECTS :
+** MODULES USED :
+***************************************************************************
+** ADMINISTRATIVE INFORMATION *
+********************************
+** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+** CREATION DATE : Aug 16, 2012
+** LAST UPDATE : Oct 19, 2012
+** MODIFICATIONS :
+**************************************************************************/
+
+#include <ios>
+#include "socket.h"
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+** NAME : basic_sockbuf - Template class that applies basic_streambuf to sockets.
+** MEMBERS : sock : Socket object that holds the network socket.
+** OPERATORS : None
+** METHODS : connect() : Connect the sockbuf to a Socket object.
+** close() : Close the UNIX file descriptor in the Socket.
+** overflow() : Override the base class function overflow.
+** underflow() : Override the base class function underflow.
+**
+** DESCRIPTION :
+**
+**
+** RELATIONS : std::basic_streambuf, Socket
+** SEE ALSO :
+** LAST MODIFIED : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+#define SOCKBUFSIZE 1500
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+ class basic_sockbuf : public std::basic_streambuf<_CharT, _Traits>
+{
+private:
+ StreamSocket sock;
+
+ _CharT gbuf[SOCKBUFSIZE];
+ _CharT pbuf[SOCKBUFSIZE];
+
+public:
+
+ basic_sockbuf()
+ {
+ setg(gbuf,gbuf+SOCKBUFSIZE,gbuf+SOCKBUFSIZE); // set get area
+ setp(pbuf,pbuf+SOCKBUFSIZE); // set put area
+ }
+
+ virtual ~basic_sockbuf()
+ {
+ sync();
+ }
+
+ void connect(StreamSocket s)
+ {
+ sock = s;
+ }
+
+ void close()
+ {
+ sock.Close();
+ }
+
+ virtual int underflow()
+ {
+ int bytes_read = sock.Read(gbuf, SOCKBUFSIZE);
+ if (bytes_read > 0)
+ {
+ setg(gbuf, gbuf, gbuf + bytes_read);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ virtual int overflow(int c)
+ {
+ sync();
+ if (c != _Traits::eof() )
+ {
+ *this->pptr() = c;
+ this->pbump(1);
+ }
+ return c;
+ }
+
+ virtual int sync()
+ {
+ // check if there's data to flush
+ if (this->pptr() > this->pbase())
+ {
+ sock.Write(pbuf, this->pptr() - pbuf);
+ setp(pbuf, pbuf + SOCKBUFSIZE); // reset put area
+ }
+ return 0;
+ }
+};
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+** NAME : basic_isockstream
+** MEMBERS :
+** OPERATORS : None
+** METHODS :
+**
+** DESCRIPTION :
+**
+**
+** RELATIONS :
+** SEE ALSO :
+** LAST MODIFIED : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+ class basic_isockstream : public std::basic_istream<_CharT, _Traits>
+{
+private:
+ basic_sockbuf<_CharT, _Traits> _M_sockbuf;
+
+public:
+ basic_isockstream(StreamSocket _s)
+ {
+ this->init(&_M_sockbuf);
+ _M_sockbuf.connect(_s);
+ }
+};
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+** NAME : basic_osockstream
+** MEMBERS :
+** OPERATORS : None
+** METHODS :
+**
+** DESCRIPTION :
+**
+**
+** RELATIONS :
+** SEE ALSO :
+** LAST MODIFIED : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+ class basic_osockstream : public std::basic_ostream<_CharT,_Traits>
+{
+private:
+ basic_sockbuf<_CharT, _Traits> _M_sockbuf;
+
+public:
+ basic_osockstream(StreamSocket _s)
+ {
+ this->init(&_M_sockbuf);
+ _M_sockbuf.connect(_s);
+ }
+};
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+** NAME : basic_sockstream
+** MEMBERS :
+** OPERATORS : None
+** METHODS :
+**
+** DESCRIPTION :
+**
+**
+** RELATIONS :
+** SEE ALSO :
+** LAST MODIFIED : Oct 19, 2012
+**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+ class basic_sockstream : public std::basic_iostream<_CharT, _Traits>
+{
+private:
+ basic_sockbuf<_CharT, _Traits> _M_sockbuf;
+
+public:
+ basic_sockstream(StreamSocket _s)
+ {
+ this->init(&_M_sockbuf);
+ _M_sockbuf.connect(_s);
+ }
+};
+
+
+// Predefined buffer and stream types
+
+typedef basic_sockbuf<char> sockbuf;
+typedef basic_isockstream<char> isockstream;
+typedef basic_osockstream<char> osockstream;
+typedef basic_sockstream<char> sockstream;
+
+typedef basic_sockbuf<wchar_t> wsockbuf;
+typedef basic_isockstream<wchar_t> wisockstream;
+typedef basic_osockstream<wchar_t> wosockstream;
+typedef basic_sockstream<wchar_t> wsockstream;
+