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 13namespace rtc { 14 15SocketStream::SocketStream(AsyncSocket* socket) : socket_(NULL) { 16 Attach(socket); 17} 18 19SocketStream::~SocketStream() { 20 delete socket_; 21} 22 23void 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 35AsyncSocket* 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 47StreamState 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 60StreamResult 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 79StreamResult 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 95void SocketStream::Close() { 96 ASSERT(socket_ != NULL); 97 socket_->Close(); 98} 99 100void SocketStream::OnConnectEvent(AsyncSocket* socket) { 101 ASSERT(socket == socket_); 102 SignalEvent(this, SE_OPEN | SE_READ | SE_WRITE, 0); 103} 104 105void SocketStream::OnReadEvent(AsyncSocket* socket) { 106 ASSERT(socket == socket_); 107 SignalEvent(this, SE_READ, 0); 108} 109 110void SocketStream::OnWriteEvent(AsyncSocket* socket) { 111 ASSERT(socket == socket_); 112 SignalEvent(this, SE_WRITE, 0); 113} 114 115void SocketStream::OnCloseEvent(AsyncSocket* socket, int err) { 116 ASSERT(socket == socket_); 117 SignalEvent(this, SE_CLOSE, err); 118} 119 120 121} // namespace rtc 122