root/chrome/browser/extensions/api/serial/serial_io_handler.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// 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_

/* [<][>][^][v][top][bottom][index][help] */