1 // Copyright 2013 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 "chrome/browser/extensions/api/serial/serial_io_handler.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9
10 namespace {
11 #if defined(OS_WIN)
12 const base::PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE;
13 #elif defined(OS_POSIX)
14 const base::PlatformFile kInvalidPlatformFileValue = -1;
15 #endif
16 } // namespace
17
18 namespace extensions {
19
SerialIoHandler()20 SerialIoHandler::SerialIoHandler()
21 : file_(kInvalidPlatformFileValue),
22 pending_read_buffer_len_(0),
23 pending_write_buffer_len_(0) {
24 }
25
~SerialIoHandler()26 SerialIoHandler::~SerialIoHandler() {
27 DCHECK(CalledOnValidThread());
28 }
29
Initialize(base::PlatformFile file,const ReadCompleteCallback & read_callback,const WriteCompleteCallback & write_callback)30 void SerialIoHandler::Initialize(base::PlatformFile file,
31 const ReadCompleteCallback& read_callback,
32 const WriteCompleteCallback& write_callback) {
33 DCHECK(CalledOnValidThread());
34 DCHECK_EQ(file_, kInvalidPlatformFileValue);
35
36 file_ = file;
37 read_complete_ = read_callback;
38 write_complete_ = write_callback;
39
40 InitializeImpl();
41 }
42
Read(int max_bytes)43 void SerialIoHandler::Read(int max_bytes) {
44 DCHECK(CalledOnValidThread());
45 DCHECK(!IsReadPending());
46 pending_read_buffer_ = new net::IOBuffer(max_bytes);
47 pending_read_buffer_len_ = max_bytes;
48 read_canceled_ = false;
49 AddRef();
50 ReadImpl();
51 }
52
Write(const std::string & data)53 void SerialIoHandler::Write(const std::string& data) {
54 DCHECK(CalledOnValidThread());
55 DCHECK(!IsWritePending());
56 pending_write_buffer_ = new net::IOBuffer(data.length());
57 pending_write_buffer_len_ = data.length();
58 memcpy(pending_write_buffer_->data(), data.data(), pending_write_buffer_len_);
59 write_canceled_ = false;
60 AddRef();
61 WriteImpl();
62 }
63
ReadCompleted(int bytes_read,api::serial::ReceiveError error)64 void SerialIoHandler::ReadCompleted(int bytes_read,
65 api::serial::ReceiveError error) {
66 DCHECK(CalledOnValidThread());
67 DCHECK(IsReadPending());
68 read_complete_.Run(std::string(pending_read_buffer_->data(), bytes_read),
69 error);
70 pending_read_buffer_ = NULL;
71 pending_read_buffer_len_ = 0;
72 Release();
73 }
74
WriteCompleted(int bytes_written,api::serial::SendError error)75 void SerialIoHandler::WriteCompleted(int bytes_written,
76 api::serial::SendError error) {
77 DCHECK(CalledOnValidThread());
78 DCHECK(IsWritePending());
79 write_complete_.Run(bytes_written, error);
80 pending_write_buffer_ = NULL;
81 pending_write_buffer_len_ = 0;
82 Release();
83 }
84
IsReadPending() const85 bool SerialIoHandler::IsReadPending() const {
86 DCHECK(CalledOnValidThread());
87 return pending_read_buffer_ != NULL;
88 }
89
IsWritePending() const90 bool SerialIoHandler::IsWritePending() const {
91 DCHECK(CalledOnValidThread());
92 return pending_write_buffer_ != NULL;
93 }
94
CancelRead(api::serial::ReceiveError reason)95 void SerialIoHandler::CancelRead(api::serial::ReceiveError reason) {
96 DCHECK(CalledOnValidThread());
97 if (IsReadPending()) {
98 read_canceled_ = true;
99 read_cancel_reason_ = reason;
100 CancelReadImpl();
101 }
102 }
103
CancelWrite(api::serial::SendError reason)104 void SerialIoHandler::CancelWrite(api::serial::SendError reason) {
105 DCHECK(CalledOnValidThread());
106 if (IsWritePending()) {
107 write_canceled_ = true;
108 write_cancel_reason_ = reason;
109 CancelWriteImpl();
110 }
111 }
112
QueueReadCompleted(int bytes_read,api::serial::ReceiveError error)113 void SerialIoHandler::QueueReadCompleted(int bytes_read,
114 api::serial::ReceiveError error) {
115 base::MessageLoop::current()->PostTask(
116 FROM_HERE, base::Bind(&SerialIoHandler::ReadCompleted, this,
117 bytes_read, error));
118 }
119
QueueWriteCompleted(int bytes_written,api::serial::SendError error)120 void SerialIoHandler::QueueWriteCompleted(int bytes_written,
121 api::serial::SendError error) {
122 base::MessageLoop::current()->PostTask(
123 FROM_HERE, base::Bind(&SerialIoHandler::WriteCompleted, this,
124 bytes_written, error));
125 }
126
127 } // namespace extensions
128
129