ConnectableSocket.cpp

Go to the documentation of this file.
00001 
00014 // ConnectableSocket.cpp -- implementation for the ConnectableSocket class
00015 
00016 #include <errno.h>
00017 #include "ConnectableSocket.h"
00018 #include "SystemCall.h"
00019 
00020 
00022 // class Host
00023 
00024 // standard c++ iostream inserter
00025 std::ostream& ConnectableSocket::operator<<( std::ostream& stream) const
00026 {
00027         stream << "ConnectableSocket( ";
00028         if ( isOpen() ) {
00029                 stream << getDescriptor() << ", ";
00030                 if ( isConnected() )
00031                         peerAddress().operator <<(stream);
00032                 else
00033                         stream << "connection is not defined";
00034         }
00035         else {
00036                 stream << "connection is not currently opened";
00037         }
00038 
00039         stream << " )";
00040         return stream;
00041 }
00042 
00043 
00044 // Return true if the end of stream has been reached
00045 bool ConnectableSocket::isEof() const
00046 {
00047         return ( flags_ & state_eof ) != 0;
00048 }
00049 
00050 
00051 // Returns whether the end of stream will raise an event
00052 bool ConnectableSocket::eventOnEof() const
00053 {
00054         return ( flags_ & state_raise_event ) != 0;
00055 }
00056 
00057 
00058 // Sets the end of stream event
00059 void ConnectableSocket::eventOnEof( bool flag )
00060 {
00061         if ( flag )
00062                 flags_ |= state_raise_event;
00063         else
00064                 flags_ &= ~state_raise_event;
00065 }
00066 
00067 // Return success if the socket hasn't failed
00068 bool ConnectableSocket::isOk() const
00069 {
00070         return isOpen() && ( ( flags_ & state_failed ) == 0 );
00071 }
00072 
00073 
00074 // Return `true` if I'm in a good state, and not at eof.
00075 bool ConnectableSocket::isGood() const
00076 {
00077         return isOk() && !isEof();
00078 }
00079 
00080 
00081 // I'm if not broken, reset my eof and failed flags.
00082 void ConnectableSocket::clear()
00083 {
00084         flags_ &= state_raise_event;
00085 }
00086 
00087 
00088 // Return `true` if every flag in `mask` is in my I/O state.
00089 bool ConnectableSocket::getFlags( short mask ) const
00090 {
00091         return ( flags_ & mask ) == mask;
00092 }
00093 
00094 
00095 // Construct myself to reference the socket with descriptor
00096 ConnectableSocket::ConnectableSocket( SOCKET descriptor ) : Socket( descriptor )
00097 {
00098 }
00099 
00100 
00101 // Construct myself to be a new socket with type, domain, and protocol
00102 ConnectableSocket::ConnectableSocket(int type,int domain,int protocol) : Socket(type,domain,protocol)
00103 {
00104 }
00105 
00106 
00107 // Connect to the socket with IP socket address
00108 void ConnectableSocket::connectTo( const SocketAddress& address )
00109 {
00110         sockaddr_in in = address.operator sockaddr_in();
00111         connectTo(reinterpret_cast<sockaddr*>(&in),sizeof(sockaddr));
00112 }
00113 
00114 
00115 // Connect to the socket with address the given address
00116 void ConnectableSocket::connectTo( sockaddr* address, int size )
00117 {
00118         int result;
00119         SOCKET_CALL_3( result=(int),::connect,getDescriptor(),address,size)
00120         if ( result >= 0 )
00121                 clear();
00122 }
00123 
00124 
00125 // Receive up to bytes and place them into supplied buffer.
00126 // Return the number of bytes that were successfully read, and set address to the IP socket
00127 // address of the socket that the bytes were read from (`AF_INET` only).
00128 int ConnectableSocket::receiveFrom(SocketAddress& address,void* buffer,int bytes)
00129 {
00130         int result = -1 ;
00131     // not really ::accept(), but same idea applies
00132 #ifdef _MSC_VER
00133     int length = sizeof( sockaddr );
00134 #else
00135         socklen_t length = sizeof( sockaddr );
00136 #endif
00137 
00138         if ( isOk() ) {
00139                 SOCKET_CALL_6(result = (int),::recvfrom,getDescriptor(),(char*) buffer,
00140                         bytes,0,(sockaddr*) &(address.operator sockaddr_in()),&length)
00141 
00142         if ( result < 0 )
00143                 flags_ |= state_failed;
00144         }
00145         return result;
00146 }
00147 
00148 
00149 // Return `true` if I'm connected to another socket.
00150 bool ConnectableSocket::isConnected() const
00151 {
00152         bool connected = true;
00153         try {
00154                 peerAddress();
00155         }
00156         catch ( NetworkException& ) {
00157                 connected = false;
00158         }
00159         return connected;
00160 }
00161 
00162 
00163 // Write buffer (number given by parameter) to socket stream
00164 int ConnectableSocket::write( const void* buffer, int bytes )
00165 {
00166         int result = -1;
00167         if ( !( flags_ & state_failed ) ) {
00168                 result = ::send(socketHandle,reinterpret_cast<const char*>(buffer),bytes,0);
00169                 if (result < 0) {
00170                         flags_ |= state_failed;
00171                         NetworkException::throwNetworkException(NetworkException::write_failed,socket_error);
00172                 }
00173                 else {
00174                         flags_ &= ~state_eof;
00175                 }
00176         }
00177 
00178         return result;
00179 }
00180 
00181 
00182 
00183 // Read from the socket stream into the buffer
00184 int ConnectableSocket::read( void* buffer, int bytes )
00185 {
00186         int result = -1;
00187         if ( !( flags_ & state_failed ) ) {
00188                 result = ::recv(socketHandle,reinterpret_cast<char*>(buffer),bytes,0);
00189                 if (result < 0) {
00190                         flags_ |= state_failed;
00191                         NetworkException::throwNetworkException(NetworkException::read_failed,socket_error);
00192                 }
00193                 else if ( !result && !(flags_ & state_eof) ) {
00194                         flags_ |= state_eof;
00195                         if (( flags_ & state_raise_event) == state_raise_event)
00196                                 NetworkException::throwNetworkException(NetworkException::eof_encountered);
00197                 }
00198         }
00199         return result;
00200 }
00201 
00202 
00203 
00204 // Return an SocketAddress for the connected peer
00205 SocketAddress ConnectableSocket::peerAddress() const
00206 {
00207         SocketAddress address;
00208 #ifdef _MSC_VER
00209     int length = sizeof( sockaddr );
00210 #else
00211         socklen_t length = sizeof( sockaddr );
00212 #endif
00213     int dummy = 0;
00214         SOCKET_CALL_3(dummy =,::getpeername,getDescriptor(),
00215                 reinterpret_cast<sockaddr*>(&(address.operator sockaddr_in())),&length)
00216         return address;
00217 }

Generated on Tue Mar 28 09:10:14 2006 for Simple SOAP by  doxygen 1.4.6