| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_EXTENSIONS_API_SERIAL_SERIAL_IO_HANDLER_H_ |
| #define CHROME_BROWSER_EXTENSIONS_API_SERIAL_SERIAL_IO_HANDLER_H_ |
| |
| #include "base/callback.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/platform_file.h" |
| #include "base/threading/non_thread_safe.h" |
| #include "chrome/common/extensions/api/serial.h" |
| #include "net/base/io_buffer.h" |
| |
| namespace extensions { |
| |
| // Provides a simplified interface for performing asynchronous I/O on serial |
| // devices by hiding platform-specific MessageLoop interfaces. Pending I/O |
| // operations hold a reference to this object until completion so that memory |
| // doesn't disappear out from under the OS. |
| class SerialIoHandler : public base::NonThreadSafe, |
| public base::RefCounted<SerialIoHandler> { |
| public: |
| // Constructs an instance of some platform-specific subclass. |
| static scoped_refptr<SerialIoHandler> Create(); |
| |
| // Called with a string of bytes read, and a result code. Note that an error |
| // result does not necessarily imply 0 bytes read. |
| typedef base::Callback<void(const std::string& data, |
| api::serial::ReceiveError error)> |
| ReadCompleteCallback; |
| |
| // Called with the number of bytes written and a result code. Note that an |
| // error result does not necessarily imply 0 bytes written. |
| typedef base::Callback<void(int bytes_written, api::serial::SendError error)> |
| WriteCompleteCallback; |
| |
| // Initializes the handler on the current message loop. Must be called exactly |
| // once before performing any I/O through the handler. |
| void Initialize(base::PlatformFile file, |
| const ReadCompleteCallback& read_callback, |
| const WriteCompleteCallback& write_callback); |
| |
| // Performs an async Read operation. Behavior is undefined if this is called |
| // while a Read is already pending. Otherwise, the ReadCompleteCallback |
| // (see above) will eventually be called with a result. |
| void Read(int max_bytes); |
| |
| // Performs an async Write operation. Behavior is undefined if this is called |
| // while a Write is already pending. Otherwise, the WriteCompleteCallback |
| // (see above) will eventually be called with a result. |
| void Write(const std::string& data); |
| |
| // Indicates whether or not a read is currently pending. |
| bool IsReadPending() const; |
| |
| // Indicates whether or not a write is currently pending. |
| bool IsWritePending() const; |
| |
| // Attempts to cancel a pending read operation. |
| void CancelRead(api::serial::ReceiveError reason); |
| |
| // Attempts to cancel a pending write operation. |
| void CancelWrite(api::serial::SendError reason); |
| |
| protected: |
| SerialIoHandler(); |
| virtual ~SerialIoHandler(); |
| |
| // Performs platform-specific initialization. |file_|, |read_complete_| and |
| // |write_complete_| all hold initialized values before this is called. |
| virtual void InitializeImpl() {} |
| |
| // Performs a platform-specific read operation. This must guarantee that |
| // ReadCompleted is called when the underlying async operation is completed |
| // or the SerialIoHandler instance will leak. |
| // NOTE: Implementations of ReadImpl should never call ReadCompleted directly. |
| // Use QueueReadCompleted instead to avoid reentrancy. |
| virtual void ReadImpl() = 0; |
| |
| // Performs a platform-specific write operation. This must guarantee that |
| // WriteCompleted is called when the underlying async operation is completed |
| // or the SerialIoHandler instance will leak. |
| // NOTE: Implementations of Writempl should never call WriteCompleted |
| // directly. Use QueueWriteCompleted instead to avoid reentrancy. |
| virtual void WriteImpl() = 0; |
| |
| // Platform-specific read cancelation. |
| virtual void CancelReadImpl() = 0; |
| |
| // Platform-specific write cancelation. |
| virtual void CancelWriteImpl() = 0; |
| |
| // Called by the implementation to signal that the active read has completed. |
| // WARNING: Calling this method can destroy the SerialIoHandler instance |
| // if the associated I/O operation was the only thing keeping it alive. |
| void ReadCompleted(int bytes_read, api::serial::ReceiveError error); |
| |
| // Called by the implementation to signal that the active write has completed. |
| // WARNING: Calling this method may destroy the SerialIoHandler instance |
| // if the associated I/O operation was the only thing keeping it alive. |
| void WriteCompleted(int bytes_written, api::serial::SendError error); |
| |
| // Queues a ReadCompleted call on the current thread. This is used to allow |
| // ReadImpl to immediately signal completion with 0 bytes and an error, |
| // without being reentrant. |
| void QueueReadCompleted(int bytes_read, api::serial::ReceiveError error); |
| |
| // Queues a WriteCompleted call on the current thread. This is used to allow |
| // WriteImpl to immediately signal completion with 0 bytes and an error, |
| // without being reentrant. |
| void QueueWriteCompleted(int bytes_written, api::serial::SendError error); |
| |
| base::PlatformFile file() const { |
| return file_; |
| } |
| |
| net::IOBuffer* pending_read_buffer() const { |
| return pending_read_buffer_.get(); |
| } |
| |
| int pending_read_buffer_len() const { |
| return pending_read_buffer_len_; |
| } |
| |
| api::serial::ReceiveError read_cancel_reason() const { |
| return read_cancel_reason_; |
| } |
| |
| bool read_canceled() const { |
| return read_canceled_; |
| } |
| |
| net::IOBuffer* pending_write_buffer() const { |
| return pending_write_buffer_.get(); |
| } |
| |
| int pending_write_buffer_len() const { |
| return pending_write_buffer_len_; |
| } |
| |
| api::serial::SendError write_cancel_reason() const { |
| return write_cancel_reason_; |
| } |
| |
| bool write_canceled() const { |
| return write_canceled_; |
| } |
| |
| private: |
| friend class base::RefCounted<SerialIoHandler>; |
| |
| base::PlatformFile file_; |
| |
| scoped_refptr<net::IOBuffer> pending_read_buffer_; |
| int pending_read_buffer_len_; |
| api::serial::ReceiveError read_cancel_reason_; |
| bool read_canceled_; |
| |
| scoped_refptr<net::IOBuffer> pending_write_buffer_; |
| int pending_write_buffer_len_; |
| api::serial::SendError write_cancel_reason_; |
| bool write_canceled_; |
| |
| ReadCompleteCallback read_complete_; |
| WriteCompleteCallback write_complete_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SerialIoHandler); |
| }; |
| |
| } // namespace extensions |
| |
| #endif // CHROME_BROWSER_EXTENSIONS_API_SERIAL_SERIAL_IO_HANDLER_H_ |