Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2010 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/base/socketstream.h"
     12 
     13 namespace rtc {
     14 
     15 SocketStream::SocketStream(AsyncSocket* socket) : socket_(NULL) {
     16   Attach(socket);
     17 }
     18 
     19 SocketStream::~SocketStream() {
     20   delete socket_;
     21 }
     22 
     23 void SocketStream::Attach(AsyncSocket* socket) {
     24   if (socket_)
     25     delete socket_;
     26   socket_ = socket;
     27   if (socket_) {
     28     socket_->SignalConnectEvent.connect(this, &SocketStream::OnConnectEvent);
     29     socket_->SignalReadEvent.connect(this,    &SocketStream::OnReadEvent);
     30     socket_->SignalWriteEvent.connect(this,   &SocketStream::OnWriteEvent);
     31     socket_->SignalCloseEvent.connect(this,   &SocketStream::OnCloseEvent);
     32   }
     33 }
     34 
     35 AsyncSocket* SocketStream::Detach() {
     36   AsyncSocket* socket = socket_;
     37   if (socket_) {
     38     socket_->SignalConnectEvent.disconnect(this);
     39     socket_->SignalReadEvent.disconnect(this);
     40     socket_->SignalWriteEvent.disconnect(this);
     41     socket_->SignalCloseEvent.disconnect(this);
     42     socket_ = NULL;
     43   }
     44   return socket;
     45 }
     46 
     47 StreamState SocketStream::GetState() const {
     48   ASSERT(socket_ != NULL);
     49   switch (socket_->GetState()) {
     50     case Socket::CS_CONNECTED:
     51       return SS_OPEN;
     52     case Socket::CS_CONNECTING:
     53       return SS_OPENING;
     54     case Socket::CS_CLOSED:
     55     default:
     56       return SS_CLOSED;
     57   }
     58 }
     59 
     60 StreamResult SocketStream::Read(void* buffer, size_t buffer_len,
     61                                 size_t* read, int* error) {
     62   ASSERT(socket_ != NULL);
     63   int result = socket_->Recv(buffer, buffer_len);
     64   if (result < 0) {
     65     if (socket_->IsBlocking())
     66       return SR_BLOCK;
     67     if (error)
     68       *error = socket_->GetError();
     69     return SR_ERROR;
     70   }
     71   if ((result > 0) || (buffer_len == 0)) {
     72     if (read)
     73       *read = result;
     74     return SR_SUCCESS;
     75   }
     76   return SR_EOS;
     77 }
     78 
     79 StreamResult SocketStream::Write(const void* data, size_t data_len,
     80                                  size_t* written, int* error) {
     81   ASSERT(socket_ != NULL);
     82   int result = socket_->Send(data, data_len);
     83   if (result < 0) {
     84     if (socket_->IsBlocking())
     85       return SR_BLOCK;
     86     if (error)
     87       *error = socket_->GetError();
     88     return SR_ERROR;
     89   }
     90   if (written)
     91     *written = result;
     92   return SR_SUCCESS;
     93 }
     94 
     95 void SocketStream::Close() {
     96   ASSERT(socket_ != NULL);
     97   socket_->Close();
     98 }
     99 
    100 void SocketStream::OnConnectEvent(AsyncSocket* socket) {
    101   ASSERT(socket == socket_);
    102   SignalEvent(this, SE_OPEN | SE_READ | SE_WRITE, 0);
    103 }
    104 
    105 void SocketStream::OnReadEvent(AsyncSocket* socket) {
    106   ASSERT(socket == socket_);
    107   SignalEvent(this, SE_READ, 0);
    108 }
    109 
    110 void SocketStream::OnWriteEvent(AsyncSocket* socket) {
    111   ASSERT(socket == socket_);
    112   SignalEvent(this, SE_WRITE, 0);
    113 }
    114 
    115 void SocketStream::OnCloseEvent(AsyncSocket* socket, int err) {
    116   ASSERT(socket == socket_);
    117   SignalEvent(this, SE_CLOSE, err);
    118 }
    119 
    120 
    121 }  // namespace rtc
    122