Added close() method to stream classes.
[sockstream.git] / include / sockstream.h
1 /**************************************************************************
2 **  (c) Copyright 2012, Andromeda Technology & Automation
3 ***************************************************************************
4 ** MODULE INFORMATION *
5 ***********************
6 **      FILE NAME      : sockstream.h
7 **      SYSTEM NAME    : Socket stream classes
8 **      VERSION NUMBER : 0.1
9 **
10 **  DESCRIPTION      :  sockbuf and sockstream classes.
11 **
12 **                      Special thanks to Marc Groenewegen <marcg@dinkum.nl>
13 **
14 **  EXPORTED OBJECTS : class sockbuf, class isockstream,
15 **                     class osockstream, class sockstream
16 **  LOCAL    OBJECTS : 
17 **  MODULES  USED    :
18 ***************************************************************************
19 **  ADMINISTRATIVE INFORMATION *
20 ********************************
21 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
22 **      CREATION DATE   : Aug 16, 2012
23 **      LAST UPDATE     : Nov 13, 2012
24 **      MODIFICATIONS   : 
25 **************************************************************************/
26
27 #include <ios>
28 #include "socket.h"
29
30 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31 **  NAME           : basic_sockbuf - Template class that applies basic_streambuf to sockets.
32 **  MEMBERS        : sock       : Socket object that holds the network socket.
33 **  OPERATORS      : None
34 **  METHODS        : connect()        : Connect the sockbuf to a Socket object.
35 **                   close()          : Close the UNIX file descriptor in the Socket.
36 **                   overflow()       : Override the base class function overflow.
37 **                   underflow()      : Override the base class function underflow.
38 **
39 **  DESCRIPTION    : 
40 **
41 **
42 **  RELATIONS      : std::basic_streambuf, Socket
43 **  SEE ALSO       : 
44 **  LAST MODIFIED  : Oct 19, 2012
45 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 */
47
48 #define SOCKBUFSIZE  1500
49
50 template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
51    class basic_sockbuf : public std::basic_streambuf<_CharT, _Traits>
52 {
53 private:
54    StreamSocket sock;
55
56    _CharT gbuf[SOCKBUFSIZE];
57    _CharT pbuf[SOCKBUFSIZE];
58
59 public:
60
61    basic_sockbuf()
62    {
63       setg(gbuf,gbuf+SOCKBUFSIZE,gbuf+SOCKBUFSIZE);  // set get area
64       setp(pbuf,pbuf+SOCKBUFSIZE);                   // set put area
65    }
66
67    virtual ~basic_sockbuf()
68    {
69       sync();
70    }
71
72    void connect(StreamSocket s)
73    {
74       sock = s;
75    }
76
77    void close()
78    {
79       sock.Close();
80    }
81
82    virtual int underflow()
83    {
84       int bytes_read = sock.Read(gbuf, SOCKBUFSIZE);
85       if (bytes_read > 0)
86       {
87          setg(gbuf, gbuf, gbuf + bytes_read);
88          return 0;
89       }
90       else
91       {
92          return -1;
93       }
94    }
95
96    virtual int overflow(int c)
97    {
98       sync();
99       if (c != _Traits::eof() )
100       {
101          *this->pptr() = c;
102          this->pbump(1);
103       }
104       return c;
105    }
106
107    virtual int sync()
108    {
109       // check if there's data to flush
110       if (this->pptr() > this->pbase())
111       {
112          sock.Write(pbuf, this->pptr() - pbuf);
113          setp(pbuf, pbuf + SOCKBUFSIZE);       // reset put area
114       }
115       return 0;
116    }
117 };
118
119 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
120 **  NAME           : basic_isockstream
121 **  MEMBERS        : 
122 **  OPERATORS      : None
123 **  METHODS        : 
124 **
125 **  DESCRIPTION    : 
126 **
127 **
128 **  RELATIONS      : 
129 **  SEE ALSO       : 
130 **  LAST MODIFIED  : Nov 13, 2012
131 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
132 */
133
134 template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
135     class basic_isockstream : public std::basic_istream<_CharT, _Traits>
136 {
137 private:
138    basic_sockbuf<_CharT, _Traits>   _M_sockbuf;
139
140 public:
141    basic_isockstream(StreamSocket _s)
142    {
143       this->init(&_M_sockbuf);
144       _M_sockbuf.connect(_s);
145    }
146
147    void close()
148    {
149       _M_sockbuf.close();
150    }
151 };
152
153
154 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
155 **  NAME           : basic_osockstream
156 **  MEMBERS        : 
157 **  OPERATORS      : None
158 **  METHODS        : 
159 **
160 **  DESCRIPTION    : 
161 **
162 **
163 **  RELATIONS      : 
164 **  SEE ALSO       : 
165 **  LAST MODIFIED  : Nov 13, 2012
166 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
167 */
168
169 template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
170     class basic_osockstream : public std::basic_ostream<_CharT,_Traits>
171 {
172 private:
173    basic_sockbuf<_CharT, _Traits>   _M_sockbuf;
174
175 public:
176    basic_osockstream(StreamSocket _s)
177    {
178       this->init(&_M_sockbuf);
179       _M_sockbuf.connect(_s);
180    }
181
182    void close()
183    {
184       _M_sockbuf.close();
185    }
186 };
187
188 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
189 **  NAME           : basic_sockstream
190 **  MEMBERS        : 
191 **  OPERATORS      : None
192 **  METHODS        : 
193 **
194 **  DESCRIPTION    : 
195 **
196 **
197 **  RELATIONS      : 
198 **  SEE ALSO       : 
199 **  LAST MODIFIED  : Nov 13, 2012
200 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
201 */
202
203 template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
204     class basic_sockstream : public std::basic_iostream<_CharT, _Traits>
205 {
206 private:
207    basic_sockbuf<_CharT, _Traits>   _M_sockbuf;
208
209 public:
210    basic_sockstream(StreamSocket _s)
211    {
212       this->init(&_M_sockbuf);
213       _M_sockbuf.connect(_s);
214    }
215
216    void close()
217    {
218       _M_sockbuf.close();
219    }
220 };
221
222
223 //  Predefined buffer and stream types
224
225 typedef basic_sockbuf<char>          sockbuf;
226 typedef basic_isockstream<char>      isockstream;
227 typedef basic_osockstream<char>      osockstream;
228 typedef basic_sockstream<char>       sockstream;
229
230 typedef basic_sockbuf<wchar_t>       wsockbuf;
231 typedef basic_isockstream<wchar_t>   wisockstream;
232 typedef basic_osockstream<wchar_t>   wosockstream;
233 typedef basic_sockstream<wchar_t>    wsockstream;
234