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