blob: 2ea1cec0ac736d35501103eda2ed06e8181574ec [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);
Yves Gerey665174f2018-06-19 15:03:05 +020031 socket_->SignalReadEvent.connect(this, &SocketStream::OnReadEvent);
32 socket_->SignalWriteEvent.connect(this, &SocketStream::OnWriteEvent);
33 socket_->SignalCloseEvent.connect(this, &SocketStream::OnCloseEvent);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000034 }
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
Yves Gerey665174f2018-06-19 15:03:05 +020062StreamResult SocketStream::Read(void* buffer,
63 size_t buffer_len,
64 size_t* read,
65 int* error) {
deadbeef37f5ecf2017-02-27 14:06:41 -080066 RTC_DCHECK(socket_ != nullptr);
Stefan Holmer9131efd2016-05-23 18:19:26 +020067 int result = socket_->Recv(buffer, buffer_len, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000068 if (result < 0) {
69 if (socket_->IsBlocking())
70 return SR_BLOCK;
71 if (error)
72 *error = socket_->GetError();
73 return SR_ERROR;
74 }
75 if ((result > 0) || (buffer_len == 0)) {
76 if (read)
77 *read = result;
78 return SR_SUCCESS;
79 }
80 return SR_EOS;
81}
82
Yves Gerey665174f2018-06-19 15:03:05 +020083StreamResult SocketStream::Write(const void* data,
84 size_t data_len,
85 size_t* written,
86 int* error) {
deadbeef37f5ecf2017-02-27 14:06:41 -080087 RTC_DCHECK(socket_ != nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000088 int result = socket_->Send(data, data_len);
89 if (result < 0) {
90 if (socket_->IsBlocking())
91 return SR_BLOCK;
92 if (error)
93 *error = socket_->GetError();
94 return SR_ERROR;
95 }
96 if (written)
97 *written = result;
98 return SR_SUCCESS;
99}
100
101void SocketStream::Close() {
deadbeef37f5ecf2017-02-27 14:06:41 -0800102 RTC_DCHECK(socket_ != nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000103 socket_->Close();
104}
105
106void SocketStream::OnConnectEvent(AsyncSocket* socket) {
nisseede5da42017-01-12 05:15:36 -0800107 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000108 SignalEvent(this, SE_OPEN | SE_READ | SE_WRITE, 0);
109}
110
111void SocketStream::OnReadEvent(AsyncSocket* socket) {
nisseede5da42017-01-12 05:15:36 -0800112 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000113 SignalEvent(this, SE_READ, 0);
114}
115
116void SocketStream::OnWriteEvent(AsyncSocket* socket) {
nisseede5da42017-01-12 05:15:36 -0800117 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000118 SignalEvent(this, SE_WRITE, 0);
119}
120
121void SocketStream::OnCloseEvent(AsyncSocket* socket, int err) {
nisseede5da42017-01-12 05:15:36 -0800122 RTC_DCHECK(socket == socket_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000123 SignalEvent(this, SE_CLOSE, err);
124}
125
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000126} // namespace rtc