Claw  1.7.3
basic_socketbuf.tpp
Go to the documentation of this file.
1 /*
2  CLAW - a C++ Library Absolutely Wonderful
3 
4  CLAW is a free library without any particular aim but being useful to
5  anyone.
6 
7  Copyright (C) 2005-2011 Julien Jorge
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 
23  contact: julien.jorge@gamned.org
24 */
30 #include <claw/assert.hpp>
31 
32 /*----------------------------------------------------------------------------*/
33 template<typename CharT, typename Traits>
35 
36 /*----------------------------------------------------------------------------*/
43 template<typename CharT, typename Traits>
45  : m_read_limit(read_limit), m_input_buffer(NULL), m_input_buffer_size(0),
46  m_output_buffer(NULL), m_output_buffer_size(0)
47 {
48  create_buffers();
49 } // basic_socketbuf::basic_socketbuf()
50 
51 /*----------------------------------------------------------------------------*/
55 template<typename CharT, typename Traits>
57 {
58  close();
59  destroy_buffers();
60 } // basic_socketbuf::basic_socketbuf()
61 
62 /*----------------------------------------------------------------------------*/
69 template<typename CharT, typename Traits>
72 ( const std::string& address, int port )
73 {
74  self_type* result = NULL;
75 
76  if (!this->is_open())
77  if ( basic_socket::open() )
78  {
79  if ( connect( address, port ) )
80  result = this;
81  else
82  close();
83  }
84 
85  return result;
86 } // basic_socketbuf::open()
87 
88 /*----------------------------------------------------------------------------*/
97 template<typename CharT, typename Traits>
100 {
101  self_type* result = NULL;
102 
103  if ( socket_traits::is_open(d) )
104  {
105  if (this->is_open())
106  {
107  if ( close() )
108  {
109  result = this;
110  m_descriptor = d;
111  }
112  }
113  else
114  {
115  result = this;
116  m_descriptor = d;
117  }
118  }
119 
120  return result;
121 } // basic_socketbuf::open()
122 
123 /*----------------------------------------------------------------------------*/
128 template<typename CharT, typename Traits>
131 {
132  if ( basic_socket::close() )
133  return this;
134  else
135  return NULL;
136 } // basic_socketbuf::close()
137 
138 /*----------------------------------------------------------------------------*/
142 template<typename CharT, typename Traits>
144 {
145  return basic_socket::is_open();
146 } // // basic_socketbuf::is_open()
147 
148 /*----------------------------------------------------------------------------*/
154 template<typename CharT, typename Traits>
156 ( int read_limit )
157 {
158  m_read_limit = read_limit;
159 } // // basic_socketbuf::set_read_time_limit()
160 
161 /*----------------------------------------------------------------------------*/
166 template<typename CharT, typename Traits>
168 {
169  CLAW_PRECOND( is_open() );
170  CLAW_PRECOND( buffered() );
171 
172  ssize_t write_count = 0;
173  ssize_t length = (this->pptr() - this->pbase()) * sizeof(char_type);
174  int_type result = 0;
175 
176  if ( length > 0 )
177  write_count = send(m_descriptor, static_cast<const char*>(this->pbase()),
178  length, 0 );
179 
180  if ( write_count >= 0 )
181  this->setp( m_output_buffer, m_output_buffer + m_output_buffer_size );
182  else
183  result = -1;
184 
185  return result;
186 } // basic_socketbuf::sync()
187 
188 /*----------------------------------------------------------------------------*/
195 template<typename CharT, typename Traits>
198 {
199  CLAW_PRECOND( buffered() );
200  CLAW_PRECOND( this->gptr() >= this->egptr() );
201 
202  ssize_t read_count;
203  ssize_t length = m_input_buffer_size * sizeof(char_type);
204  int_type result = traits_type::eof();
205 
206  if( !is_open() )
207  return result;
208 
209  if ( socket_traits::select_read(m_descriptor, m_read_limit) )
210  read_count = recv(m_descriptor, static_cast<char*>(m_input_buffer), length,
211  0);
212  else
213  read_count = -1;
214 
215  if ( read_count > 0 )
216  {
217  this->setg( m_input_buffer, m_input_buffer, m_input_buffer + read_count);
218  result = this->sgetc();
219  }
220  else
221  this->setg( m_input_buffer, m_input_buffer + m_input_buffer_size,
222  m_input_buffer + m_input_buffer_size );
223 
224  return result;
225 } // basic_socketbuf::underflow()
226 
227 /*----------------------------------------------------------------------------*/
232 template<typename CharT, typename Traits>
235 {
236  CLAW_PRECOND( is_open() );
237  CLAW_PRECOND( buffered() );
238 
239  int_type result = traits_type::eof();
240 
241  if ( sync() == 0 )
242  {
243  result = traits_type::not_eof(c);
244 
245  if ( !traits_type::eq_int_type(c, traits_type::eof()) )
246  this->sputc(c);
247  }
248 
249  return result;
250 } // basic_socketbuf::overflow()
251 
252 /*----------------------------------------------------------------------------*/
260 template<typename CharT, typename Traits>
262 ( const std::string& addr, int port )
263 {
265 
266  return socket_traits::connect(m_descriptor, addr, port);
267 } // basic_socketbuf::connect()
268 
269 /*----------------------------------------------------------------------------*/
274 template<typename CharT, typename Traits>
276 {
277  CLAW_PRECOND( this->pbase() == NULL );
278  CLAW_PRECOND( this->eback() == NULL );
279 
280  m_input_buffer_size = m_output_buffer_size = s_buffer_size;
281 
282  m_input_buffer = new char_type[m_input_buffer_size];
283  m_output_buffer = new char_type[m_output_buffer_size];
284 
285  this->setg( m_input_buffer, m_input_buffer + m_input_buffer_size,
286  m_input_buffer + m_input_buffer_size );
287  this->setp( m_output_buffer, m_output_buffer + m_output_buffer_size );
288 } // basic_socketbuf::create_buffers()
289 
290 /*----------------------------------------------------------------------------*/
295 template<typename CharT, typename Traits>
297 {
298  if ( m_input_buffer )
299  {
300  delete[] m_input_buffer;
301  m_input_buffer = NULL;
302  }
303 
304  if ( m_output_buffer )
305  {
306  delete[] m_output_buffer;
307  m_output_buffer = NULL;
308  }
309 
310  this->setg( NULL, NULL, NULL );
311  this->setp( NULL, NULL );
312 } // basic_socketbuf::destroy_buffers()
313 
314 /*----------------------------------------------------------------------------*/
319 template<typename CharT, typename Traits>
321 {
322  return this->pbase() && this->pptr() && this->epptr()
323  && this->eback() && this->gptr() && this->egptr();
324 } // basic_socketbuf::buffered()