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 20 SerialIoHandler::SerialIoHandler() 21 : file_(kInvalidPlatformFileValue), 22 pending_read_buffer_len_(0), 23 pending_write_buffer_len_(0) { 24 } 25 26 SerialIoHandler::~SerialIoHandler() { 27 DCHECK(CalledOnValidThread()); 28 } 29 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 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 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 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 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 85 bool SerialIoHandler::IsReadPending() const { 86 DCHECK(CalledOnValidThread()); 87 return pending_read_buffer_ != NULL; 88 } 89 90 bool SerialIoHandler::IsWritePending() const { 91 DCHECK(CalledOnValidThread()); 92 return pending_write_buffer_ != NULL; 93 } 94 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 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 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 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