blob: 8b4c513ea8c99ab6fbe786438b92d5ae7f992c82 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_base/socketstream.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/checks.h"
nisseede5da42017-01-12 05:15:36 -080014
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000015namespace rtc {
16
deadbeef37f5ecf2017-02-27 14:06:41 -080017SocketStream::SocketStream(AsyncSocket* socket) : socket_(nullptr) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000018 Attach(socket);
19}
20
21SocketStream::~SocketStream() {
22 delete socket_;
23}
24
25void SocketStream::Attach(AsyncSocket* socket) {
26 if (socket_)
27 delete socket_;
28 socket_ = socket;
29 if (socket_) {
30 socket_->SignalConnectEvent.connect(this, &SocketStream::OnConnectEvent);
31 socket_->SignalReadEvent.connect(this, &SocketStream::OnReadEvent);
32 socket_->SignalWriteEvent.connect(this, &SocketStream::OnWriteEvent);
33 socket_->SignalCloseEvent.connect(this, &SocketStream::OnCloseEvent);
34 }
35}
36
37AsyncSocket* SocketStream::Detach() {
38 AsyncSocket* socket = socket_;
39 if (socket_) {
40 socket_->SignalConnectEvent.disconnect(this);
41 socket_->SignalReadEvent.disconnect(this);
42 socket_->SignalWriteEvent.disconnect(this);
43 socket_->SignalCloseEvent.disconnect(this);
deadbeef37f5ecf2017-02-27 14:06:41 -080044 socket_ = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000045 }
46 return socket;
47}
48
49StreamState SocketStream::GetState() const {
deadbeef37f5ecf2017-02-27 14:06:41 -080050 RTC_DCHECK(socket_ != nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000051 switch (socket_->GetState()) {
52 case Socket::CS_CONNECTED:
53 return SS_OPEN;
54 case Socket::CS_CONNECTING:
55 return SS_OPENING;
56 case Socket::CS_CLOSED:
57 default:
58 return SS_CLOSED;
59 }
60}
61
62StreamResult SocketStream::Read(void* buffer, size_t buffer_len,
63 size_t* read, int* error) {
deadbeef37f5ecf2017-02-27 14:06:41 -080064 RTC_DCHECK(socket_ != nullptr);
Stefan Holmer9131efd2016-05-23 18:19:26 +020065 int result = socket_->Recv(buffer, buffer_len, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000066 if (result < 0) {
67 if (socket_->IsBlocking())
68 return SR_BLOCK;
69 if (error)
70 *error = socket_->GetError();
71 return SR_ERROR;
72 }
73 if ((result > 0) || (buffer_len == 0)) {
74 if (read)
75 *read = result;
76 return SR_SUCCESS;
77 }
78 return SR_EOS;
79}
80
81StreamResult SocketStream::Write(const void* data, size_t data_len,
82 size_t* written, int* error) {
deadbeef37f5ecf2017-02-27 14:06:41 -080083 RTC_DCHECK(socket_ != nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000084 int result = socket_->Send(data, data_len);
85 if (result < 0) {
86 if (socket_->IsBlocking())
87 return SR_BLOCK;
88 if (error)
89 *error = socket_->GetError();
90 return SR_ERROR;
91 }
92 if (written)
93 *written = result;
94 return SR_SUCCESS;
95}
96
97void SocketStream::Close() {
deadbeef37f5ecf2017-02-27 14:06:41 -080098 RTC_DCHECK(socket_ != nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000099 socket_->Close();
100}
101
102void SocketStream::OnConnectEvent(AsyncSocket* socket) {
nisseede5da42017-01-12 05:15:36 -0800103 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000104 SignalEvent(this, SE_OPEN | SE_READ | SE_WRITE, 0);
105}
106
107void SocketStream::OnReadEvent(AsyncSocket* socket) {
nisseede5da42017-01-12 05:15:36 -0800108 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000109 SignalEvent(this, SE_READ, 0);
110}
111
112void SocketStream::OnWriteEvent(AsyncSocket* socket) {
nisseede5da42017-01-12 05:15:36 -0800113 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000114 SignalEvent(this, SE_WRITE, 0);
115}
116
117void SocketStream::OnCloseEvent(AsyncSocket* socket, int err) {
nisseede5da42017-01-12 05:15:36 -0800118 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000119 SignalEvent(this, SE_CLOSE, err);
120}
121
122
123} // namespace rtc