Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "remoting/base/socket_reader.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/location.h"
      9 #include "base/single_thread_task_runner.h"
     10 #include "base/thread_task_runner_handle.h"
     11 #include "net/base/io_buffer.h"
     12 #include "net/base/net_errors.h"
     13 #include "net/socket/socket.h"
     14 
     15 namespace remoting {
     16 
     17 namespace {
     18 int kReadBufferSize = 4096;
     19 }  // namespace
     20 
     21 SocketReader::SocketReader()
     22     : socket_(NULL),
     23       weak_factory_(this) {
     24 }
     25 
     26 SocketReader::~SocketReader() {
     27 }
     28 
     29 void SocketReader::Init(net::Socket* socket,
     30                         ReadResultCallback read_result_callback) {
     31   DCHECK(socket);
     32   DCHECK(!socket_);
     33 
     34   socket_ = socket;
     35   read_result_callback_ = read_result_callback;
     36   DoRead();
     37 }
     38 
     39 void SocketReader::DoRead() {
     40   while (true) {
     41     read_buffer_ = new net::IOBuffer(kReadBufferSize);
     42     int result = socket_->Read(
     43         read_buffer_.get(),
     44         kReadBufferSize,
     45         base::Bind(&SocketReader::OnRead, weak_factory_.GetWeakPtr()));
     46     HandleReadResult(result);
     47     if (result <= 0)
     48       break;
     49   }
     50 }
     51 
     52 void SocketReader::OnRead(int result) {
     53   HandleReadResult(result);
     54   if (result > 0)
     55     DoRead();
     56 }
     57 
     58 void SocketReader::HandleReadResult(int result) {
     59   if (result != net::ERR_IO_PENDING) {
     60     if (result < 0)
     61       read_buffer_ = NULL;
     62     base::ThreadTaskRunnerHandle::Get()->PostTask(
     63         FROM_HERE,
     64         base::Bind(&SocketReader::CallCallback, weak_factory_.GetWeakPtr(),
     65                    read_buffer_, result));
     66   }
     67 }
     68 
     69 void SocketReader::CallCallback(scoped_refptr<net::IOBuffer> data, int result) {
     70   read_result_callback_.Run(data, result);
     71 }
     72 
     73 }  // namespace remoting
     74