Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Examples  

vpr::SocketImplNSPR Class Reference

#include <SocketImplNSPR.h>

Inheritance diagram for vpr::SocketImplNSPR:

Inheritance graph
[legend]
Collaboration diagram for vpr::SocketImplNSPR:

Collaboration graph
[legend]
List of all members.

Public Methods

const std::string & getName () const
 Gets the "name" of this socket. More...

vpr::ReturnStatus open ()
 Opens the socket. More...

vpr::ReturnStatus close ()
 Closes the socket. More...

bool isOpen () const
 Gets the open state of this socket. More...

bool isBound () const
vpr::ReturnStatus bind ()
 Binds this socket to the address in the host address member variable. More...

vpr::IOSys::Handle getHandle () const
 Return the contained handle. More...

bool isBlockingFixed () const
 Queries if the blocking state for this socket is fixed and can no longer be changed. More...

vpr::ReturnStatus setBlocking (bool blocking)
bool isBlocking () const
 Gets the current blocking state for the socket. More...

vpr::ReturnStatus connect (const vpr::Interval timeout=vpr::Interval::NoTimeout)
 Connects the socket on the client side to the server side. More...

bool isConnected () const
 Gets the status of a possibly connected socket. More...

const SocketTypes::TypegetType () const
 Gets the type of this socket (e.g., vpr::SocketTypes::STREAM). More...

const vpr::InetAddrgetLocalAddr () const
vpr::ReturnStatus setLocalAddr (const vpr::InetAddr &addr)
const vpr::InetAddrgetRemoteAddr () const
vpr::ReturnStatus setRemoteAddr (const vpr::InetAddr &addr)
vpr::ReturnStatus read_i (void *buffer, const vpr::Uint32 length, vpr::Uint32 &bytes_read, const vpr::Interval timeout=vpr::Interval::NoTimeout)
vpr::ReturnStatus readn_i (void *buffer, const vpr::Uint32 length, vpr::Uint32 &bytes_read, const vpr::Interval timeout=vpr::Interval::NoTimeout)
vpr::ReturnStatus write_i (const void *buffer, const vpr::Uint32 length, vpr::Uint32 &bytes_written, const vpr::Interval timeout=vpr::Interval::NoTimeout)
vpr::Uint32 availableBytes () const
vpr::ReturnStatus getOption (const vpr::SocketOptions::Types option, struct vpr::SocketOptions::Data &data) const
 Retrieves the value for the given option as set on the socket. More...

vpr::ReturnStatus setOption (const vpr::SocketOptions::Types option, const struct vpr::SocketOptions::Data &data)
 Sets a value for the given option on the socket using the given data block. More...

 ~SocketImplNSPR ()
 Destructor. More...


Protected Methods

 SocketImplNSPR (const SocketTypes::Type sock_type)
 Default constructor. More...

 SocketImplNSPR (const InetAddr &local_addr, const InetAddr &remote_addr, const SocketTypes::Type sock_type)
 Standard constructor. More...

 SocketImplNSPR (const SocketImplNSPR &sock)
 Copy constructor. More...


Protected Attributes

std::string mName
PRFileDesc * mHandle
 Handle to the socket. More...

vpr::InetAddr mLocalAddr
 The local site's address structure. More...

vpr::InetAddr mRemoteAddr
 The remote site's address structure. More...

vpr::SocketTypes::Type mType
 Socket type. More...

bool mOpen
bool mBound
 Is the socket bound to a port yet (connect and bind do this). More...

bool mConnected
bool mOpenBlocking
bool mBlocking
bool mBlockingFixed

Constructor & Destructor Documentation

vpr::SocketImplNSPR::~SocketImplNSPR  
 

Destructor.

Precondition:
None.
Postcondition:
Closes the socket, and deallocates and resources associated with the socket.

Definition at line 802 of file SocketImplNSPR.cpp.

References close, mHandle, vpr::ReturnStatus::success, and vprASSERT.

00803 {
00804    if ( mHandle != NULL )
00805    {
00806       vpr::ReturnStatus status = close();      // Close the socket
00807       vprASSERT(status.success() && "Failed to close socket in SocketImplNSPR destructor");
00808       mHandle = NULL;
00809    }
00810 }

vpr::SocketImplNSPR::SocketImplNSPR const SocketTypes::Type    sock_type [protected]
 

Default constructor.

This just initializes member variables to reasonable defaults.

Precondition:
None.
Postcondition:
The member variables are initialized accordingly to reasonable defaults.

Definition at line 767 of file SocketImplNSPR.cpp.

00768    : mHandle(NULL)
00769    , mType(sock_type)
00770    , mOpen(false)
00771    , mBound(false)
00772    , mConnected(false)
00773    , mOpenBlocking(true)
00774    , mBlocking(true)
00775    , mBlockingFixed(false)
00776 {
00777    /* Do nothing. */ ;
00778 }

vpr::SocketImplNSPR::SocketImplNSPR const InetAddr   local_addr,
const InetAddr   remote_addr,
const SocketTypes::Type    sock_type
[protected]
 

Standard constructor.

This takes two InetAddr objects, a local address and a remote address.

Precondition:
None.
Postcondition:
The member variables are initialized with the given values.
Parameters:
local_addr  The local address for the socket.
remote_addr  The remote address for the socket.

Definition at line 784 of file SocketImplNSPR.cpp.

References vpr::InetAddrBSD::getAddressString, mLocalAddr, and mName.

00787    : mHandle(NULL)
00788    , mLocalAddr(local_addr)
00789    , mRemoteAddr(remote_addr)
00790    , mType(sock_type)
00791    , mOpen(false)
00792    , mBound(false)
00793    , mConnected(false)
00794    , mOpenBlocking(true)
00795    , mBlocking(true)
00796    , mBlockingFixed(false)
00797 {
00798    mName = mLocalAddr.getAddressString();
00799 }

vpr::SocketImplNSPR::SocketImplNSPR const SocketImplNSPR &    sock [inline, protected]
 

Copy constructor.

XXX: We need to have a reference count here

Definition at line 367 of file SocketImplNSPR.h.

00368       : mName(sock.mName)
00369       , mHandle(sock.mHandle)
00370       , mLocalAddr(sock.mLocalAddr)
00371       , mRemoteAddr(sock.mRemoteAddr)
00372       , mType(sock.mType)
00373       , mOpen(sock.mOpen)
00374       , mBound(sock.mBound)
00375       , mConnected(sock.mConnected)
00376       , mOpenBlocking(sock.mOpenBlocking)
00377       , mBlocking(sock.mBlocking)
00378       , mBlockingFixed(sock.mBlockingFixed)
00379    {
00380    }


Member Function Documentation

const std::string& vpr::SocketImplNSPR::getName   const [inline]
 

Gets the "name" of this socket.

It is typically the address of the peer host.

Precondition:
None.
Postcondition:
Returns:
An object containing the "name" of this socket.

Definition at line 80 of file SocketImplNSPR.h.

00081    {
00082       return mName;
00083    }

vpr::ReturnStatus vpr::SocketImplNSPR::open  
 

Opens the socket.

This creates a new socket using the domain and type options set through member variables.

Precondition:
mDomain and mType have been set to values recognized.
Postcondition:
A new socket is created.
Returns: true - The socket was opened successfully. false - The socket could not be opened for some reason (an error message is printed explaining why).

Definition at line 62 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, vpr::InetAddrBSD::getFamily, mHandle, mLocalAddr, mOpen, mOpenBlocking, setBlocking, and vpr::ReturnStatus::setCode.

00063 {
00064    vpr::ReturnStatus retval;
00065    PRFileDesc* new_sock = NULL;
00066 
00067    if(NULL != mHandle)
00068    {
00069       retval.setCode(vpr::ReturnStatus::Fail);
00070    }
00071    else
00072    {
00073       // NSPR has not concept of domain in socket creation
00074       // switch (mLocalAddr.getFamily())
00075 
00076       switch (mType)
00077       {
00078         case vpr::SocketTypes::STREAM:
00079           new_sock = PR_NewTCPSocket();
00080           break;
00081         case vpr::SocketTypes::DATAGRAM:
00082           new_sock = PR_NewUDPSocket();
00083           break;
00084         default:
00085           fprintf(stderr,
00086                   "[vpr::SocketImplNSPR] ERROR: Unknown socket type value %d\n",
00087                   mLocalAddr.getFamily());
00088           break;
00089       }
00090 
00091       // If socket(2) failed, print an error message and return error status.
00092       if ( new_sock == NULL )
00093       {
00094          vpr::Error::outputCurrentError(std::cerr, "[vpr::SocketImplNSPR] Could not create socket");
00095          retval.setCode(vpr::ReturnStatus::Fail);
00096       }
00097       // Otherwise, return success.
00098       else
00099       {
00100          mHandle = new_sock;
00101          mOpen = true;
00102 
00103          // Now that this socket is open, we can set the blocking state.
00104          setBlocking(mOpenBlocking);
00105 
00106          //vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) << "Socket open: handle:[" << mHandle << "]\n" << vprDEBUG_FLUSH;
00107       }
00108    }
00109 
00110    return retval;
00111 }

vpr::ReturnStatus vpr::SocketImplNSPR::close  
 

Closes the socket.

Precondition:
The socket is open.
Postcondition:
An attempt is made to close the socket. The resulting status is returned to the caller. If the socket is closed, mOpen is set to false.
Returns:
true if the socket was closed successfully. false if the socket could not be closed for some reason.

Definition at line 114 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, mBlockingFixed, mBound, mConnected, mHandle, mOpen, vpr::ReturnStatus::setCode, and vpr::ReturnStatus::Succeed.

Referenced by ~SocketImplNSPR.

00115 {
00116    vpr::ReturnStatus retval(vpr::ReturnStatus::Succeed);      // Default to success
00117    PRStatus status;
00118 
00119    if(NULL != mHandle)
00120    {
00121       //vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) << "Socket close: handle:[" << mHandle << "] (Socket now invalid)\n" << vprDEBUG_FLUSH;
00122 
00123       status = PR_Close(mHandle);
00124 
00125       mHandle = NULL;                // mHandle points to shrapnel now, so write over it
00126       mOpen = false;                 // Even if failed, we must scrap the socket and start over
00127       mBound = false;
00128       mConnected = false;
00129       mBlockingFixed = false;
00130 
00131       if (status == PR_SUCCESS)
00132       {
00133          //mOpen = false;
00134          //mBound = false;
00135          retval.setCode(vpr::ReturnStatus::Succeed);
00136       }
00137       else
00138       {
00139          retval.setCode(vpr::ReturnStatus::Fail);
00140       }
00141    }
00142 
00143    return retval;
00144 }

bool vpr::SocketImplNSPR::isOpen   const [inline]
 

Gets the open state of this socket.

Precondition:
None.
Postcondition:
The boolean value giving the open state is returned to the caller.
Returns:
true is returned if this socket is open; false otherwise.

Definition at line 121 of file SocketImplNSPR.h.

00122    {
00123       return mOpen;
00124    }

bool vpr::SocketImplNSPR::isBound   const [inline]
 

Definition at line 126 of file SocketImplNSPR.h.

00127    {
00128       return mBound;
00129    }

vpr::ReturnStatus vpr::SocketImplNSPR::bind  
 

Binds this socket to the address in the host address member variable.

Precondition:
The socket is open, and mLocalAddr has been initialized properly.
Postcondition:
The socket is bound to the address in mLocalAddr.
Returns: true - The socket was bound to the address successfully. false - The socket could not be bound to the address in mLocalAddr. An error message is printed explaining what went wrong.

Definition at line 147 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, mBound, mHandle, mLocalAddr, mOpen, vpr::ReturnStatus::setCode, and vprASSERT.

00148 {
00149    vpr::ReturnStatus retval;
00150    PRStatus status;
00151 
00152    vprASSERT((true == mOpen) && "Trying to bind an un-opened socket");
00153    vprASSERT((mHandle != NULL) && "Trying to bind with NULL handle");
00154 
00155    // Bind the socket to the address in mLocalAddr.
00156    status = PR_Bind(mHandle, mLocalAddr.getPRNetAddr());
00157 
00158    // If that fails, print an error and return error status.
00159    if ( status == PR_FAILURE )
00160    {
00161       retval.setCode(vpr::ReturnStatus::Fail);
00162       vpr::Error::outputCurrentError(std::cerr, "SocketImplNSPR::bind: Failed to bind.");
00163    }
00164    // Otherwise, return success.
00165    else
00166    {
00167        mBound = true;
00168    }
00169 
00170    return retval;
00171 }

vpr::IOSys::Handle vpr::SocketImplNSPR::getHandle   const [inline]
 

Return the contained handle.

Definition at line 148 of file SocketImplNSPR.h.

00149    {
00150       return mHandle;
00151    }

bool vpr::SocketImplNSPR::isBlockingFixed   const [inline]
 

Queries if the blocking state for this socket is fixed and can no longer be changed.

Definition at line 157 of file SocketImplNSPR.h.

00158    {
00159       return mBlockingFixed;
00160    }

vpr::ReturnStatus vpr::SocketImplNSPR::setBlocking bool    blocking
 

Definition at line 173 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, mBlocking, mBlockingFixed, mHandle, mOpen, mOpenBlocking, vpr::ReturnStatus::setCode, and vprASSERT.

Referenced by open.

00174 {
00175    vprASSERT(! mBlockingFixed && "Can't change blocking state after blocking call");
00176 
00177    vpr::ReturnStatus retval;
00178 
00179    // If this socket has not been opened yet, set mOpenBlocking to the value
00180    // of blocking.  The actual change for the blocking state has to occur
00181    // after the socket has been opened.
00182    if ( ! mOpen )
00183    {
00184       mOpenBlocking = blocking;
00185    }
00186    // If this socket is already open, change the blocking state to match the
00187    // value of blocking.
00188    else
00189    {
00190       if ( ! mBlockingFixed )
00191       {
00192          PRStatus status;
00193          PRSocketOptionData option_data;
00194          option_data.option = PR_SockOpt_Nonblocking;
00195 
00196          if ( blocking )
00197          {
00198             option_data.value.non_blocking = false;
00199          }
00200          else
00201          {
00202             option_data.value.non_blocking = true;
00203          }
00204 
00205          status = PR_SetSocketOption(mHandle, &option_data);
00206 
00207          // If that fails, print an error and return error status.
00208          if ( status == PR_FAILURE )
00209          {
00210             vpr::Error::outputCurrentError(std::cerr,
00211                                            "SocketImplNSPR::setBlocking: Failed to set.");
00212             retval.setCode(vpr::ReturnStatus::Fail);
00213          }
00214          else
00215          {
00216             mBlocking = blocking;
00217          }
00218       }
00219       else
00220       {
00221          retval.setCode(vpr::ReturnStatus::Fail);
00222       }
00223    }
00224 
00225    return retval;
00226 }

bool vpr::SocketImplNSPR::isBlocking   const [inline]
 

Gets the current blocking state for the socket.

Returns:
true is returned if the socket is in blocking mode. Otherwise, false is returned.

Definition at line 170 of file SocketImplNSPR.h.

00171    {
00172       return mBlocking;
00173    }

vpr::ReturnStatus vpr::SocketImplNSPR::connect const vpr::Interval    timeout = vpr::Interval::NoTimeout
 

Connects the socket on the client side to the server side.

For a datagram socket, this makes the address given to the constructor the default destination for all packets. For a stream socket, this has the effect of establishing a connection with the destination.

Precondition:
The socket is open.
Postcondition:
The socket is connected to the address in mLocalAddr. For a stream socket, this means that a connection for future communication has been established. For a datagram socket, the default destination for all packets is now mLocalAddr.
Returns: true - The connection was made. false - The connect could not be made. An error message is printed explaining what happened.

Definition at line 232 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, vpr::ReturnStatus::InProgress, mBlockingFixed, mBound, mConnected, mHandle, mLocalAddr, mOpen, mRemoteAddr, vpr::Interval::NoWait, vpr::NSPR_getInterval, vpr::ReturnStatus::setCode, vpr::ReturnStatus::Timeout, vprASSERT, vprDBG_ALL, vprDBG_CRITICAL_LVL, vprDBG_WARNING_LVL, vprDEBUG, and vprDEBUG_FLUSH.

00233 {
00234    vpr::ReturnStatus retval;
00235    PRStatus status;
00236 
00237    vprASSERT((true == mOpen) && "Trying to connect an un-opened socket");
00238    vprASSERT((mHandle != NULL) && "Trying to connect with NULL handle");
00239 
00240    if(mConnected)
00241    {
00242       vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) << "SocketImplNSPR::connect: Socket already connected.  Can't connect again"
00243                     << vprDEBUG_FLUSH;
00244       retval.setCode(vpr::ReturnStatus::Fail);
00245    }
00246    else
00247    {
00248       // Attempt to connect to the address in mAddr.
00249       status = PR_Connect(mHandle, mRemoteAddr.getPRNetAddr(),
00250                           NSPR_getInterval(timeout) );
00251 
00252       if ( status == PR_FAILURE )
00253       {
00254          PRInt32 err;
00255 
00256          err = PR_GetError();
00257 
00258          // This is a non-blocking connection.
00259          if ( err == PR_WOULD_BLOCK_ERROR || err == PR_IN_PROGRESS_ERROR  )
00260          {
00261             if ( vpr::Interval::NoWait == timeout )
00262             {
00263                retval.setCode( vpr::ReturnStatus::InProgress );
00264             }
00265             // Use the timeout to wait for the connection to complete.
00266             else
00267             {
00268                PRPollDesc poll_desc;
00269 
00270                poll_desc.fd       = mHandle;
00271                poll_desc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
00272 
00273                PR_Poll(&poll_desc, 1, NSPR_getInterval(timeout));
00274 
00275                // If the out flags don't have PR_POLL_WRITE, then we timed out.
00276                // Since we are a non-blocking socket, we tell the caller that
00277                // the connection is still in progress.
00278                if ( ! (poll_desc.out_flags & PR_POLL_WRITE) )
00279                {
00280                   retval.setCode(vpr::ReturnStatus::InProgress);
00281                }
00282             }
00283 
00284             mBound         = true;
00285             mConnected     = true;
00286             mBlockingFixed = true;
00287          }
00288          else if ( err == PR_IO_TIMEOUT_ERROR )
00289          {
00290             retval.setCode(vpr::ReturnStatus::Timeout);
00291          }
00292          else
00293          {
00294             vpr::Error::outputCurrentError(std::cerr, "SocketImplNSPR::connect: Failed to connect.");
00295             retval.setCode(vpr::ReturnStatus::Fail);
00296          }
00297       }
00298       // Otherwise, return success.
00299       else
00300       {
00301          mBound = true;
00302          mConnected = true;
00303          mBlockingFixed = true;
00304       }
00305    }
00306 
00307    // Fill in the local address if has not already been assigned.
00308    if ( mConnected && vpr::InetAddr::AnyAddr == mLocalAddr )
00309    {
00310       PRStatus status;
00311 
00312       status = PR_GetSockName(mHandle, mLocalAddr.getPRNetAddr());
00313 
00314       if ( status == PR_SUCCESS )
00315       {
00316 /* XXX: This doesn't compile on IRIX, and I don't know why.
00317           vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL) << "Connected, local address is "
00318                                         << mLocalAddr << std::endl
00319                                         << vprDEBUG_FLUSH;
00320 */
00321       }
00322       else
00323       {
00324           vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL) << "Failed to get local socket name\n"
00325                                           << vprDEBUG_FLUSH;
00326       }
00327    }
00328 
00329    return retval;
00330 }

bool vpr::SocketImplNSPR::isConnected   const [inline]
 

Gets the status of a possibly connected socket.

Precondition:
None
Returns:
true if the socket is connected to a remote addr. false if the socket is not currently connect (the other side may have disconnected).

Definition at line 206 of file SocketImplNSPR.h.

00207    {
00208       if ( mConnected )        // If it is not open, then it can't be connected
00209       {
00210          int num_avail = PR_Available(mHandle);
00211          if ( num_avail == 0 )
00212          {
00213             PRPollDesc poll_desc;
00214             poll_desc.fd = mHandle;
00215             poll_desc.in_flags = PR_POLL_READ;
00216 
00217             PR_Poll(&poll_desc, 1, PR_INTERVAL_NO_WAIT);
00218             if ( poll_desc.out_flags & PR_POLL_READ )
00219             {
00220                return false;             // Opened, but not connected
00221             }
00222          }
00223 
00224          return true;        // Either have data, or are waiting for it
00225       }
00226       else
00227       {
00228          return false;           // Not open --> not connected
00229       }
00230    }

const SocketTypes::Type& vpr::SocketImplNSPR::getType   const [inline]
 

Gets the type of this socket (e.g., vpr::SocketTypes::STREAM).

Precondition:
The socket implementation pointer is valid.
Postcondition:
The socket type for this socket is returned to the caller.
Returns:
A vpr::SocketTypes::Type value giving the socket type for this socket.

Definition at line 241 of file SocketImplNSPR.h.

00242    {
00243       return mType;
00244    }

const vpr::InetAddr& vpr::SocketImplNSPR::getLocalAddr   const [inline]
 

Definition at line 246 of file SocketImplNSPR.h.

00247    {
00248       return mLocalAddr;
00249    }

vpr::ReturnStatus vpr::SocketImplNSPR::setLocalAddr const vpr::InetAddr   addr [inline]
 

Definition at line 251 of file SocketImplNSPR.h.

References vpr::ReturnStatus::setCode, vprDBG_ALL, vprDBG_CRITICAL_LVL, vprDEBUG, and vprDEBUG_FLUSH.

00252    {
00253       vpr::ReturnStatus status;
00254 
00255       if ( mBound )
00256       {
00257          vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) << "SocketImplNSPR::setLocalAddr: Cant' set address of bound socket.\n" << vprDEBUG_FLUSH;
00258          status.setCode(ReturnStatus::Fail);
00259       }
00260       else
00261          mLocalAddr = addr;
00262 
00263       return status;
00264    }

const vpr::InetAddr& vpr::SocketImplNSPR::getRemoteAddr   const [inline]
 

Definition at line 266 of file SocketImplNSPR.h.

00267    {
00268       return mRemoteAddr;
00269    }

vpr::ReturnStatus vpr::SocketImplNSPR::setRemoteAddr const vpr::InetAddr   addr [inline]
 

Definition at line 271 of file SocketImplNSPR.h.

References vpr::ReturnStatus::Fail, vpr::ReturnStatus::setCode, vprDBG_ALL, vprDBG_CRITICAL_LVL, vprDEBUG, and vprDEBUG_FLUSH.

00272    {
00273       vpr::ReturnStatus status;
00274 
00275       if ( mConnected )
00276       {
00277          vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) << "SocketImplNSPR::setRemoteAddr: Cant' set address of bound socket.\n" << vprDEBUG_FLUSH;
00278          status.setCode(vpr::ReturnStatus::Fail);
00279       }
00280       else
00281       {
00282          mRemoteAddr = addr;
00283       }
00284 
00285       return status;
00286    }

vpr::ReturnStatus vpr::SocketImplNSPR::read_i void *    buffer,
const vpr::Uint32    length,
vpr::Uint32   bytes_read,
const vpr::Interval    timeout = vpr::Interval::NoTimeout
 

Definition at line 332 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, mBlockingFixed, mHandle, vpr::ReturnStatus::NotConnected, vpr::NSPR_getInterval, vpr::ReturnStatus::setCode, vpr::ReturnStatus::Timeout, and vpr::ReturnStatus::WouldBlock.

00336 {
00337    if(mHandle == NULL)
00338       return vpr::ReturnStatus::Fail;
00339 
00340    vpr::ReturnStatus retval;
00341    PRInt32 bytes;
00342 
00343    mBlockingFixed = true;
00344 
00345    bytes = PR_Recv(mHandle, buffer, length, 0, NSPR_getInterval(timeout));
00346 
00347    if( bytes > 0)     // Successful read
00348    {
00349       bytes_read = bytes;
00350    }
00351    else if ( bytes == -1 )      // -1 indicates failure which includes PR_WOULD_BLOCK_ERROR.
00352    {
00353       PRErrorCode err_code = PR_GetError();
00354       vpr::Error::outputCurrentError(std::cerr, "SocketImplNSPR::read_i::Error -->");
00355 
00356       bytes_read = 0;
00357 
00358       if ( err_code == PR_WOULD_BLOCK_ERROR )
00359       {
00360          retval.setCode(vpr::ReturnStatus::WouldBlock);
00361       }
00362       else if ( err_code == PR_IO_TIMEOUT_ERROR )
00363       {
00364          retval.setCode(vpr::ReturnStatus::Timeout);
00365       }
00366       else if ( err_code == PR_CONNECT_RESET_ERROR ||
00367                 err_code == PR_SOCKET_SHUTDOWN_ERROR ||
00368                 err_code == PR_CONNECT_ABORTED_ERROR )
00369       {
00370          retval.setCode(vpr::ReturnStatus::NotConnected);
00371       }
00372       else
00373       {
00374          retval.setCode(vpr::ReturnStatus::Fail);
00375       }
00376    }
00377    else if( bytes == 0)    // Indicates that the network connection is closed
00378    {
00379       bytes_read = bytes;
00380       retval.setCode(vpr::ReturnStatus::NotConnected);    // Set status to indicate connection is closed
00381    }
00382 
00383    return retval;
00384 }

vpr::ReturnStatus vpr::SocketImplNSPR::readn_i void *    buffer,
const vpr::Uint32    length,
vpr::Uint32   bytes_read,
const vpr::Interval    timeout = vpr::Interval::NoTimeout
 

Definition at line 386 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, mBlockingFixed, mHandle, vpr::ReturnStatus::NotConnected, vpr::NSPR_getInterval, vpr::ReturnStatus::setCode, and vpr::ReturnStatus::Timeout.

00390 {
00391    if(mHandle == NULL)
00392       return vpr::ReturnStatus::Fail;
00393 
00394    vpr::ReturnStatus retval;
00395    PRInt32 bytes;            // Number of bytes read each time
00396    vpr::Uint32 bytes_left(length);
00397 
00398    bytes_read = 0;
00399    mBlockingFixed = true;
00400 
00401    while ( bytes_left > 0 )
00402    {
00403       bytes = PR_Recv(mHandle, buffer, bytes_left, 0,
00404                       NSPR_getInterval(timeout));
00405 
00406       // We are in an error state.
00407       if ( bytes > 0 )
00408       {
00409          buffer = (void*) ((char*) buffer + bytes);
00410          bytes_left -= bytes;
00411          bytes_read += bytes;
00412       }
00413       else if ( bytes < 0 )
00414       {
00415          PRErrorCode err_code = PR_GetError();
00416 
00417          // Non-blocking socket, but this is basically a blocking call.  We
00418          // just keep reading.
00419          if ( err_code == PR_WOULD_BLOCK_ERROR )
00420          {
00421             continue;
00422          }
00423          // The last read took longer than we wanted.
00424          else if ( err_code == PR_IO_TIMEOUT_ERROR )
00425          {
00426             retval.setCode(vpr::ReturnStatus::Timeout);
00427             return retval;
00428          }
00429          // We lost the connection.  We're done.
00430          else if ( err_code == PR_CONNECT_RESET_ERROR ||
00431                    err_code == PR_SOCKET_SHUTDOWN_ERROR ||
00432                    err_code == PR_CONNECT_ABORTED_ERROR )
00433          {
00434             retval.setCode(vpr::ReturnStatus::NotConnected);
00435             return retval;
00436          }
00437          // Unrecognized error.
00438          else
00439          {
00440             retval.setCode(vpr::ReturnStatus::Fail);
00441             return retval;
00442          }
00443       }
00444       // Read 0 bytes.
00445       else
00446       {
00447          retval.setCode(vpr::ReturnStatus::NotConnected);    // Set status to indicate connection is closed
00448          return retval;
00449       }
00450    }
00451 
00452    return retval;
00453 }

vpr::ReturnStatus vpr::SocketImplNSPR::write_i const void *    buffer,
const vpr::Uint32    length,
vpr::Uint32   bytes_written,
const vpr::Interval    timeout = vpr::Interval::NoTimeout
 

Definition at line 455 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, mBlockingFixed, mHandle, vpr::ReturnStatus::NotConnected, vpr::NSPR_getInterval, vpr::ReturnStatus::setCode, vpr::ReturnStatus::Timeout, and vpr::ReturnStatus::WouldBlock.

00459 {
00460    if(mHandle == NULL)
00461       return vpr::ReturnStatus::Fail;
00462 
00463    vpr::ReturnStatus retval;
00464    PRInt32 bytes;
00465 
00466    mBlockingFixed = true;
00467 
00468    bytes = PR_Send(mHandle, buffer, length, 0, NSPR_getInterval(timeout));
00469 
00470    if ( bytes == -1 )
00471    {
00472       PRErrorCode err_code = PR_GetError();
00473       vpr::Error::outputCurrentError(std::cerr, "SocketImplNspr::write_i: Error --> ");
00474 
00475       bytes_written = 0;
00476 
00477       if ( err_code == PR_WOULD_BLOCK_ERROR )
00478       {
00479          retval.setCode(vpr::ReturnStatus::WouldBlock);
00480       }
00481       else if ( err_code == PR_IO_TIMEOUT_ERROR )
00482       {
00483          retval.setCode(vpr::ReturnStatus::Timeout);
00484       }
00485       else if ( err_code == PR_NOT_CONNECTED_ERROR ||
00486                 err_code == PR_CONNECT_RESET_ERROR ||
00487                 err_code == PR_SOCKET_SHUTDOWN_ERROR ||
00488                 err_code == PR_CONNECT_ABORTED_ERROR )
00489       {
00490          retval.setCode(vpr::ReturnStatus::NotConnected);
00491       }
00492       else
00493       {
00494          retval.setCode(vpr::ReturnStatus::Fail);
00495       }
00496    }
00497    else
00498    {
00499       bytes_written = bytes;
00500    }
00501 
00502    return retval;
00503 }

vpr::Uint32 vpr::SocketImplNSPR::availableBytes   const [inline]
 

Definition at line 300 of file SocketImplNSPR.h.

00301    {
00302       return PR_Available(mHandle);
00303    }

vpr::ReturnStatus vpr::SocketImplNSPR::getOption const vpr::SocketOptions::Types    option,
struct vpr::SocketOptions::Data   data
const
 

Retrieves the value for the given option as set on the socket.

Parameters:
option  The option to be queried.
data  A data buffer that will be used to store the value of the given option.
Returns:
vpr::ReturnStatus::Succeed is returned if the value for the given option was retrieved successfully.
vpr::ReturnStatus;:Fail is returned otherwise.

Definition at line 505 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, vpr::SocketOptions::Data::ip_ttl, vpr::SocketOptions::Data::keep_alive, vpr::SocketOptions::Data::linger, vpr::SocketOptions::Data::max_segment, vpr::SocketOptions::Data::mcast_loopback, vpr::SocketOptions::Data::mcast_ttl, mHandle, vpr::SocketOptions::Data::no_delay, vpr::SocketOptions::Data::recv_buffer_size, vpr::SocketOptions::Data::reuse_addr, vpr::SocketOptions::Data::send_buffer_size, vpr::ReturnStatus::setCode, and vprASSERT.

00507 {
00508    vpr::ReturnStatus retval;
00509    PRSocketOptionData opt_data;
00510    bool get_opt;
00511 
00512    // If this is true, PR_GetSocketOption() will be called.
00513    get_opt = true;
00514 
00515    switch (option)
00516    {
00517       case vpr::SocketOptions::Linger:
00518          opt_data.option = PR_SockOpt_Linger;
00519          break;
00520       case vpr::SocketOptions::ReuseAddr:
00521          opt_data.option = PR_SockOpt_Reuseaddr;
00522          break;
00523       case vpr::SocketOptions::KeepAlive:
00524          opt_data.option = PR_SockOpt_Keepalive;
00525          break;
00526       case vpr::SocketOptions::RecvBufferSize:
00527          opt_data.option = PR_SockOpt_RecvBufferSize;
00528          break;
00529       case vpr::SocketOptions::SendBufferSize:
00530          opt_data.option = PR_SockOpt_SendBufferSize;
00531          break;
00532       case vpr::SocketOptions::IpTimeToLive:
00533          opt_data.option = PR_SockOpt_IpTimeToLive;
00534          break;
00535       case vpr::SocketOptions::IpTypeOfService:
00536          opt_data.option = PR_SockOpt_IpTypeOfService;
00537          break;
00538       case vpr::SocketOptions::AddMember:
00539       case vpr::SocketOptions::DropMember:
00540          fprintf(stderr,
00541                  "[vpr::SocketImplNSPR] Cannot get add/drop member socket option!\n");
00542          get_opt = false;
00543          break;
00544       case vpr::SocketOptions::McastInterface:
00545          opt_data.option = PR_SockOpt_McastInterface;
00546          break;
00547       case vpr::SocketOptions::McastTimeToLive:
00548          opt_data.option = PR_SockOpt_McastTimeToLive;
00549          break;
00550       case vpr::SocketOptions::McastLoopback:
00551          opt_data.option = PR_SockOpt_McastLoopback;
00552          break;
00553       case vpr::SocketOptions::NoDelay:
00554          opt_data.option = PR_SockOpt_NoDelay;
00555          break;
00556       case vpr::SocketOptions::MaxSegment:
00557          opt_data.option = PR_SockOpt_MaxSegment;
00558          break;
00559    }
00560 
00561    if ( get_opt )
00562    {
00563       PRStatus status;
00564 
00565       status = PR_GetSocketOption(mHandle, &opt_data);
00566 
00567       if ( status == PR_SUCCESS )
00568       {
00569          // This extracts the information from the union passed to
00570          // PR_GetSocketOption() and puts it in our friendly
00571          // vpr::SocketOptions::Data object.
00572          switch (option)
00573          {
00574             case vpr::SocketOptions::Linger:
00575                data.linger.enabled = opt_data.value.linger.polarity;
00576                data.linger.seconds = PR_IntervalToSeconds(opt_data.value.linger.linger);
00577                break;
00578             case vpr::SocketOptions::ReuseAddr:
00579                data.reuse_addr = (opt_data.value.reuse_addr != 0 ? true
00580                                                                  : false);
00581                break;
00582             case vpr::SocketOptions::KeepAlive:
00583                data.keep_alive = (opt_data.value.keep_alive != 0 ? true
00584                                                                  : false);
00585                break;
00586             case vpr::SocketOptions::RecvBufferSize:
00587                data.recv_buffer_size = opt_data.value.recv_buffer_size;
00588                break;
00589             case vpr::SocketOptions::SendBufferSize:
00590                data.send_buffer_size = opt_data.value.send_buffer_size;
00591                break;
00592             case vpr::SocketOptions::IpTimeToLive:
00593                data.ip_ttl = opt_data.value.ip_ttl;
00594                break;
00595             case vpr::SocketOptions::IpTypeOfService:
00596 /*
00597                switch (opt_data.value.ip_tos)
00598                {
00599                   case IPTOS_LOWDELAY:
00600                      data.type_of_service = vpr::SocketOptions::LowDelay;
00601                      break;
00602                   case IPTOS_THROUGHPUT:
00603                      data.type_of_service = vpr::SocketOptions::Throughput;
00604                      break;
00605                   case IPTOS_RELIABILITY:
00606                      data.type_of_service = vpr::SocketOptions::Reliability;
00607                      break;
00608 #ifdef IPTOS_LOWCOST
00609                   case IPTOS_LOWCOST:
00610                      data.type_of_service = vpr::SocketOptions::LowCost;
00611                      break;
00612 #endif
00613                }
00614 */
00615 
00616                break;
00617             case vpr::SocketOptions::McastInterface:
00618 //               data.mcast_if = vpr::InetAddr(opt_data.value.mcast_if);
00619                break;
00620             case vpr::SocketOptions::McastTimeToLive:
00621                data.mcast_ttl = opt_data.value.mcast_ttl;
00622                break;
00623             case vpr::SocketOptions::McastLoopback:
00624                data.mcast_loopback = opt_data.value.mcast_loopback;
00625                break;
00626             case vpr::SocketOptions::NoDelay:
00627                data.no_delay = (opt_data.value.no_delay != 0 ? true : false);
00628                break;
00629             case vpr::SocketOptions::MaxSegment:
00630                data.max_segment = opt_data.value.max_segment;
00631                break;
00632             case vpr::SocketOptions::AddMember:
00633             case vpr::SocketOptions::DropMember:
00634             default:
00635                vprASSERT(false && "Socket option handled incorrectly.");  // Should never get here
00636                break;
00637          }
00638       }
00639       else
00640       {
00641          retval.setCode(vpr::ReturnStatus::Fail);
00642          vpr::Error::outputCurrentError(std::cerr, "[vpr::SocketImplNSPR] ERROR: Could not get socket option for socket");
00643       }
00644    }
00645    else
00646    {
00647       retval.setCode(vpr::ReturnStatus::Fail);
00648    }
00649 
00650    return retval;
00651 }

vpr::ReturnStatus vpr::SocketImplNSPR::setOption const vpr::SocketOptions::Types    option,
const struct vpr::SocketOptions::Data   data
 

Sets a value for the given option on the socket using the given data block.

Parameters:
option  The option whose value will be set.
data  A data buffer containing the value to be used in setting the socket option.

Definition at line 653 of file SocketImplNSPR.cpp.

References vpr::ReturnStatus::Fail, vpr::SocketOptions::Data::ip_ttl, vpr::SocketOptions::Data::keep_alive, vpr::SocketOptions::Data::linger, vpr::SocketOptions::Data::max_segment, vpr::SocketOptions::Data::mcast_loopback, vpr::SocketOptions::Data::mcast_ttl, mHandle, vpr::SocketOptions::Data::no_delay, vpr::SocketOptions::Data::recv_buffer_size, vpr::SocketOptions::Data::reuse_addr, vpr::SocketOptions::Data::send_buffer_size, vpr::SocketOptions::Data::type_of_service, and vprASSERT.

00655 {
00656    PRSocketOptionData opt_data;
00657 
00658    switch (option)
00659    {
00660       case vpr::SocketOptions::Linger:
00661          opt_data.option                = PR_SockOpt_Linger;
00662          opt_data.value.linger.polarity = data.linger.enabled;
00663          opt_data.value.linger.linger   = PR_SecondsToInterval(data.linger.seconds);
00664          break;
00665       case vpr::SocketOptions::ReuseAddr:
00666          opt_data.option           = PR_SockOpt_Reuseaddr;
00667          opt_data.value.reuse_addr = (data.reuse_addr ? PR_TRUE : PR_FALSE);
00668          break;
00669       case vpr::SocketOptions::KeepAlive:
00670          opt_data.option           = PR_SockOpt_Keepalive;
00671          opt_data.value.keep_alive = (data.keep_alive ? PR_TRUE : PR_FALSE);
00672          break;
00673       case vpr::SocketOptions::RecvBufferSize:
00674          opt_data.option                 = PR_SockOpt_RecvBufferSize;
00675          opt_data.value.recv_buffer_size = data.recv_buffer_size;
00676          break;
00677       case vpr::SocketOptions::SendBufferSize:
00678          opt_data.option                 = PR_SockOpt_SendBufferSize;
00679          opt_data.value.send_buffer_size = data.send_buffer_size;
00680          break;
00681       case vpr::SocketOptions::IpTimeToLive:
00682          opt_data.option       = PR_SockOpt_IpTimeToLive;
00683          opt_data.value.ip_ttl = data.ip_ttl;
00684          break;
00685       case vpr::SocketOptions::IpTypeOfService:
00686          opt_data.option = PR_SockOpt_IpTypeOfService;
00687 
00688          switch (data.type_of_service)
00689          {
00690             case vpr::SocketOptions::LowDelay:
00691 //               opt_data.value.tos = ???;
00692                break;
00693             case vpr::SocketOptions::Throughput:
00694 //               opt_data.value.tos = ???;
00695                break;
00696             case vpr::SocketOptions::Reliability:
00697 //               opt_data.value.tos = ???;
00698                break;
00699             case vpr::SocketOptions::LowCost:
00700 #ifdef IPTOS_LOWCOST
00701 //               opt_data.value.tos = ???;
00702 #else
00703                fprintf(stderr,
00704                        "[vpr::SocketImplNSPR] WARNING: This subsystem does not "
00705                        "support LowCost type of service!\n");
00706 #endif
00707                break;
00708          }
00709 
00710          break;
00711       case vpr::SocketOptions::AddMember:
00712          opt_data.option = PR_SockOpt_AddMember;
00713 //         opt_data.value.mcast_req.mcaddr = data.mcast_add_member.getMulticastAddr().getAddressValue();
00714 //         opt_data.value.mcast_req.ifaddr = data.mcast_add_member.getInterfaceAddr().getAddressValue();
00715          break;
00716       case vpr::SocketOptions::DropMember:
00717          opt_data.option = PR_SockOpt_DropMember;
00718 //         opt_data.value.mcast_req.mcaddr = data.mcast_drop_member.getMulticastAddr().getAddressValue();
00719 //         opt_data.value.mcast_req.ifaddr = data.mcast_drop_member.getInterfaceAddr().getAddressValue();
00720          break;
00721       case vpr::SocketOptions::McastInterface:
00722          opt_data.option         = PR_SockOpt_McastInterface;
00723 //         opt_data.value.mcast_if = data.mcast_if.getAddressValue();
00724          break;
00725       case vpr::SocketOptions::McastTimeToLive:
00726          opt_data.option          = PR_SockOpt_McastTimeToLive;
00727          opt_data.value.mcast_ttl = data.mcast_ttl;
00728          break;
00729       case vpr::SocketOptions::McastLoopback:
00730          opt_data.option               = PR_SockOpt_McastLoopback;
00731          opt_data.value.mcast_loopback = data.mcast_loopback;
00732          break;
00733       case vpr::SocketOptions::NoDelay:
00734          opt_data.option         = PR_SockOpt_NoDelay;
00735          opt_data.value.no_delay = (data.no_delay ? PR_TRUE : PR_FALSE);
00736          break;
00737       case vpr::SocketOptions::MaxSegment:
00738          opt_data.option            = PR_SockOpt_MaxSegment;
00739          opt_data.value.max_segment = data.max_segment;
00740          break;
00741    }
00742 
00743    vprASSERT((mHandle != NULL) && "Trying to set option on NULL handle");
00744    if(mHandle == NULL)
00745    {
00746       return vpr::ReturnStatus(vpr::ReturnStatus::Fail);
00747    }
00748    else
00749    {
00750       if ( PR_SetSocketOption(mHandle, &opt_data) == PR_SUCCESS )
00751       {
00752          return vpr::ReturnStatus();
00753       }
00754       else
00755       {
00756          return vpr::ReturnStatus(vpr::ReturnStatus::Fail);
00757       }
00758    }
00759 }


Member Data Documentation

std::string vpr::SocketImplNSPR::mName [protected]
 

Definition at line 382 of file SocketImplNSPR.h.

Referenced by SocketImplNSPR.

PRFileDesc* vpr::SocketImplNSPR::mHandle [protected]
 

Handle to the socket.

Definition at line 383 of file SocketImplNSPR.h.

Referenced by vpr::SocketStreamImplNSPR::accept, bind, close, connect, getOption, vpr::SocketStreamImplNSPR::listen, open, read_i, readn_i, vpr::SocketDatagramImplNSPR::recvfrom, vpr::SocketDatagramImplNSPR::sendto, setBlocking, setOption, write_i, and ~SocketImplNSPR.

vpr::InetAddr vpr::SocketImplNSPR::mLocalAddr [protected]
 

The local site's address structure.

Definition at line 384 of file SocketImplNSPR.h.

Referenced by bind, connect, open, and SocketImplNSPR.

vpr::InetAddr vpr::SocketImplNSPR::mRemoteAddr [protected]
 

The remote site's address structure.

Definition at line 385 of file SocketImplNSPR.h.

Referenced by connect.

vpr::SocketTypes::Type vpr::SocketImplNSPR::mType [protected]
 

Socket type.

Definition at line 387 of file SocketImplNSPR.h.

bool vpr::SocketImplNSPR::mOpen [protected]
 

Definition at line 389 of file SocketImplNSPR.h.

Referenced by bind, close, connect, open, and setBlocking.

bool vpr::SocketImplNSPR::mBound [protected]
 

Is the socket bound to a port yet (connect and bind do this).

Definition at line 390 of file SocketImplNSPR.h.

Referenced by vpr::SocketStreamImplNSPR::accept, bind, close, connect, and vpr::SocketStreamImplNSPR::listen.

bool vpr::SocketImplNSPR::mConnected [protected]
 

Definition at line 392 of file SocketImplNSPR.h.

Referenced by close, and connect.

bool vpr::SocketImplNSPR::mOpenBlocking [protected]
 

Definition at line 393 of file SocketImplNSPR.h.

Referenced by open, and setBlocking.

bool vpr::SocketImplNSPR::mBlocking [protected]
 

Definition at line 394 of file SocketImplNSPR.h.

Referenced by vpr::SocketStreamImplNSPR::accept, and setBlocking.

bool vpr::SocketImplNSPR::mBlockingFixed [protected]
 

Definition at line 395 of file SocketImplNSPR.h.

Referenced by vpr::SocketStreamImplNSPR::accept, close, connect, read_i, readn_i, setBlocking, and write_i.


The documentation for this class was generated from the following files:
Generated on Sun May 2 14:47:00 2004 for VR Juggler Portable Runtime by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002