basic_socketbuf.tpp

Go to the documentation of this file.
00001 /*
00002   CLAW - a C++ Library Absolutely Wonderful
00003 
00004   CLAW is a free library without any particular aim but being useful to 
00005   anyone.
00006 
00007   Copyright (C) 2005-2008 Julien Jorge
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023   contact: julien_jorge@yahoo.fr
00024 */
00030 #include <claw/assert.hpp>
00031 
00032 /*----------------------------------------------------------------------------*/
00033 template<typename CharT, typename Traits>
00034 const size_t claw::net::basic_socketbuf<CharT, Traits>::s_buffer_size = 256;
00035 
00036 /*----------------------------------------------------------------------------*/
00041 template<typename CharT, typename Traits>
00042 claw::net::basic_socketbuf<CharT, Traits>::basic_socketbuf()
00043   : m_input_buffer(NULL), m_input_buffer_size(0),
00044     m_output_buffer(NULL), m_output_buffer_size(0)
00045 {
00046   create_buffers();
00047 } // basic_socketbuf::basic_socketbuf()
00048 
00049 /*----------------------------------------------------------------------------*/
00053 template<typename CharT, typename Traits>
00054 claw::net::basic_socketbuf<CharT, Traits>::~basic_socketbuf()
00055 {
00056   close();
00057   destroy_buffers();
00058 } // basic_socketbuf::basic_socketbuf()
00059 
00060 /*----------------------------------------------------------------------------*/
00067 template<typename CharT, typename Traits>
00068 typename claw::net::basic_socketbuf<CharT, Traits>::self_type*
00069 claw::net::basic_socketbuf<CharT, Traits>::open
00070 ( const std::string& address, int port )
00071 {
00072   self_type* result = NULL;
00073 
00074   if (!this->is_open())
00075     if ( basic_socket::open() )
00076       {
00077         if ( connect( address, port ) )
00078           result = this;
00079         else
00080     close();
00081       }
00082 
00083   return result;
00084 } // basic_socketbuf::open()
00085 
00086 /*----------------------------------------------------------------------------*/
00095 template<typename CharT, typename Traits>
00096 typename claw::net::basic_socketbuf<CharT, Traits>::self_type*
00097 claw::net::basic_socketbuf<CharT, Traits>::open( socket_traits::descriptor d )
00098 {
00099   self_type* result = NULL;
00100 
00101   if ( socket_traits::is_open(d) )
00102     {
00103       if (this->is_open())
00104         {
00105           if ( close() )
00106             {
00107               result = this;
00108               m_descriptor = d;
00109             }
00110         }
00111       else
00112         {
00113           result = this;
00114           m_descriptor = d;
00115         }
00116     }
00117 
00118   return result;
00119 } // basic_socketbuf::open()
00120 
00121 /*----------------------------------------------------------------------------*/
00126 template<typename CharT, typename Traits>
00127 typename claw::net::basic_socketbuf<CharT, Traits>::self_type*
00128 claw::net::basic_socketbuf<CharT, Traits>::close()
00129 {
00130   if ( basic_socket::close() )
00131     return this;
00132   else
00133     return NULL;
00134 } // basic_socketbuf::close()
00135 
00136 /*----------------------------------------------------------------------------*/
00140 template<typename CharT, typename Traits>
00141 bool claw::net::basic_socketbuf<CharT, Traits>::is_open() const
00142 {
00143   return basic_socket::is_open();
00144 } // // basic_socketbuf::is_open()
00145 
00146 /*----------------------------------------------------------------------------*/
00151 template<typename CharT, typename Traits>
00152 int claw::net::basic_socketbuf<CharT, Traits>::sync()
00153 {
00154   CLAW_PRECOND( is_open() );
00155   CLAW_PRECOND( buffered() );
00156 
00157   ssize_t write_count = 0;
00158   ssize_t length = (this->pptr() - this->pbase()) * sizeof(char_type);
00159   int_type result = 0;
00160 
00161   if ( length > 0 )
00162     write_count = send(m_descriptor, static_cast<const char*>(this->pbase()),
00163            length, 0 );
00164 
00165   if ( write_count >= 0 )
00166     setp( m_output_buffer, m_output_buffer + m_output_buffer_size );
00167   else
00168     result = -1;
00169 
00170   return result;
00171 } // basic_socketbuf::sync()
00172 
00173 /*----------------------------------------------------------------------------*/
00180 template<typename CharT, typename Traits>
00181 typename claw::net::basic_socketbuf<CharT, Traits>::int_type
00182 claw::net::basic_socketbuf<CharT, Traits>::underflow()
00183 {
00184   CLAW_PRECOND( is_open() );
00185   CLAW_PRECOND( buffered() );
00186   CLAW_PRECOND( this->gptr() >= this->egptr() );
00187 
00188   ssize_t read_count;
00189   ssize_t length = m_input_buffer_size * sizeof(char_type);
00190   int_type result = traits_type::eof();
00191 
00192   if ( socket_traits::select_read(m_descriptor) )
00193     read_count = recv(m_descriptor, static_cast<char*>(m_input_buffer), length,
00194           0);
00195   else
00196     read_count = -1;
00197 
00198   if ( read_count > 0 )
00199     {
00200       setg( m_input_buffer, m_input_buffer, m_input_buffer + read_count);
00201       result = this->sgetc();
00202     }
00203   else
00204     setg( m_input_buffer, m_input_buffer + m_input_buffer_size,
00205           m_input_buffer + m_input_buffer_size );
00206 
00207   return result;
00208 } // basic_socketbuf::underflow()
00209 
00210 /*----------------------------------------------------------------------------*/
00215 template<typename CharT, typename Traits>
00216 typename claw::net::basic_socketbuf<CharT, Traits>::int_type
00217 claw::net::basic_socketbuf<CharT, Traits>::overflow( int_type c )
00218 {
00219   CLAW_PRECOND( is_open() );
00220   CLAW_PRECOND( buffered() );
00221 
00222   int_type result = traits_type::eof();
00223 
00224   if ( sync() == 0 )
00225     {
00226       result = traits_type::not_eof(c);
00227 
00228       if ( !traits_type::eq_int_type(c, traits_type::eof()) )
00229         sputc(c);
00230     }
00231 
00232   return result;
00233 } // basic_socketbuf::overflow()
00234 
00235 /*----------------------------------------------------------------------------*/
00243 template<typename CharT, typename Traits>
00244 bool claw::net::basic_socketbuf<CharT, Traits>::connect
00245 ( const std::string& addr, int port )
00246 {
00247   CLAW_PRECOND( socket_traits::valid_descriptor(m_descriptor) );
00248 
00249   return socket_traits::connect(m_descriptor, addr, port);
00250 } // basic_socketbuf::connect()
00251 
00252 /*----------------------------------------------------------------------------*/
00257 template<typename CharT, typename Traits>
00258 void claw::net::basic_socketbuf<CharT, Traits>::create_buffers()
00259 {
00260   CLAW_PRECOND( this->pbase() == NULL );
00261   CLAW_PRECOND( this->eback() == NULL );
00262 
00263   m_input_buffer_size = m_output_buffer_size = s_buffer_size;
00264 
00265   m_input_buffer  = new char_type[m_input_buffer_size];
00266   m_output_buffer = new char_type[m_output_buffer_size];
00267 
00268   this->setg( m_input_buffer, m_input_buffer + m_input_buffer_size, 
00269               m_input_buffer + m_input_buffer_size );
00270   this->setp( m_output_buffer, m_output_buffer + m_output_buffer_size );
00271 } // basic_socketbuf::create_buffers()
00272 
00273 /*----------------------------------------------------------------------------*/
00278 template<typename CharT, typename Traits>
00279 void claw::net::basic_socketbuf<CharT, Traits>::destroy_buffers()
00280 {
00281   if ( m_input_buffer )
00282     {
00283       delete[] m_input_buffer;
00284       m_input_buffer = NULL;
00285     }
00286 
00287   if ( m_output_buffer )
00288     {
00289       delete[] m_output_buffer;
00290       m_output_buffer = NULL;
00291     }
00292 
00293   this->setg( NULL, NULL, NULL );
00294   this->setp( NULL, NULL );
00295 } // basic_socketbuf::destroy_buffers()
00296 
00297 /*----------------------------------------------------------------------------*/
00302 template<typename CharT, typename Traits>
00303 bool claw::net::basic_socketbuf<CharT, Traits>::buffered() const
00304 {
00305   return this->pbase() && this->pptr() && this->epptr() 
00306     && this->eback() && this->gptr() && this->egptr();
00307 } // basic_socketbuf::buffered()

Generated on 9 Nov 2009 for CLAW Library (a C++ Library Absolutely Wonderful) by  doxygen 1.6.1