| // 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_CHROMEOS_DRIVE_DRIVE_FILE_STREAM_READER_H_ |
| #define CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_FILE_STREAM_READER_H_ |
| |
| #include <string> |
| |
| #include "base/basictypes.h" |
| #include "base/callback.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/scoped_vector.h" |
| #include "chrome/browser/chromeos/drive/file_errors.h" |
| #include "google_apis/drive/gdata_errorcode.h" |
| #include "net/base/completion_callback.h" |
| |
| namespace base { |
| class SequencedTaskRunner; |
| } // namespace base |
| |
| namespace net { |
| class HttpByteRange; |
| class IOBuffer; |
| } // namespace net |
| |
| namespace drive { |
| namespace util { |
| class LocalFileReader; |
| } // namespace util |
| |
| namespace internal { |
| |
| // An interface to dispatch the reading operation. If the file is locally |
| // cached, LocalReaderProxy defined below will be used. Otherwise (i.e. the |
| // file is being downloaded from the server), NetworkReaderProxy will be used. |
| class ReaderProxy { |
| public: |
| virtual ~ReaderProxy() {} |
| |
| // Called from DriveFileStreamReader::Read method. |
| virtual int Read(net::IOBuffer* buffer, int buffer_length, |
| const net::CompletionCallback& callback) = 0; |
| |
| // Called when the data from the server is received. |
| virtual void OnGetContent(scoped_ptr<std::string> data) = 0; |
| |
| // Called when the accessing to the file system is completed. |
| virtual void OnCompleted(FileError error) = 0; |
| }; |
| |
| // The read operation implementation for the locally cached files. |
| class LocalReaderProxy : public ReaderProxy { |
| public: |
| // The |file_reader| should be the instance which is already opened. |
| // This class takes its ownership. |
| // |length| is the number of bytes to be read. It must be equal or |
| // smaller than the remaining data size in the |file_reader|. |
| LocalReaderProxy( |
| scoped_ptr<util::LocalFileReader> file_reader, int64 length); |
| ~LocalReaderProxy() override; |
| |
| // ReaderProxy overrides. |
| int Read(net::IOBuffer* buffer, |
| int buffer_length, |
| const net::CompletionCallback& callback) override; |
| void OnGetContent(scoped_ptr<std::string> data) override; |
| void OnCompleted(FileError error) override; |
| |
| private: |
| scoped_ptr<util::LocalFileReader> file_reader_; |
| |
| // Callback for the LocalFileReader::Read. |
| void OnReadCompleted( |
| const net::CompletionCallback& callback, int read_result); |
| |
| // The number of remaining bytes to be read. |
| int64 remaining_length_; |
| |
| // This should remain the last member so it'll be destroyed first and |
| // invalidate its weak pointers before other members are destroyed. |
| base::WeakPtrFactory<LocalReaderProxy> weak_ptr_factory_; |
| DISALLOW_COPY_AND_ASSIGN(LocalReaderProxy); |
| }; |
| |
| // The read operation implementation for the file which is being downloaded. |
| class NetworkReaderProxy : public ReaderProxy { |
| public: |
| // If the instance is deleted during the download process, it is necessary |
| // to cancel the job. |job_canceller| should be the callback to run the |
| // cancelling. |full_content_length| is necessary for determining whether the |
| // deletion is done in the middle of download process. |
| NetworkReaderProxy( |
| int64 offset, int64 content_length, int64 full_content_length, |
| const base::Closure& job_canceller); |
| ~NetworkReaderProxy() override; |
| |
| // ReaderProxy overrides. |
| int Read(net::IOBuffer* buffer, |
| int buffer_length, |
| const net::CompletionCallback& callback) override; |
| void OnGetContent(scoped_ptr<std::string> data) override; |
| void OnCompleted(FileError error) override; |
| |
| private: |
| // The data received from the server, but not yet read. |
| ScopedVector<std::string> pending_data_; |
| |
| // The number of bytes to be skipped. |
| int64 remaining_offset_; |
| |
| // The number of bytes of remaining data (including the data not yet |
| // received from the server). |
| int64 remaining_content_length_; |
| |
| // Flag to remember whether this read request is for reading till the end of |
| // the file. |
| const bool is_full_download_; |
| |
| int error_code_; |
| |
| // To support pending Read(), it is necessary to keep its arguments. |
| scoped_refptr<net::IOBuffer> buffer_; |
| int buffer_length_; |
| net::CompletionCallback callback_; |
| |
| // Keeps the closure to cancel downloading job if necessary. |
| // Will be reset when the job is completed (regardless whether the job is |
| // successfully done or not). |
| base::Closure job_canceller_; |
| |
| DISALLOW_COPY_AND_ASSIGN(NetworkReaderProxy); |
| }; |
| |
| } // namespace internal |
| |
| class FileSystemInterface; |
| class ResourceEntry; |
| |
| // The stream reader for a file in FileSystem. Instances of this class |
| // should live on IO thread. |
| // Operations to communicate with a locally cached file will run on |
| // |file_task_runner| specified by the constructor. |
| class DriveFileStreamReader { |
| public: |
| // Callback to return the FileSystemInterface instance. This is an |
| // injecting point for testing. |
| // Note that the callback will be copied between threads (IO and UI), and |
| // will be called on UI thread. |
| typedef base::Callback<FileSystemInterface*()> FileSystemGetter; |
| |
| // Callback to return the result of Initialize(). |
| // |error| is net::Error code. |
| typedef base::Callback<void(int error, scoped_ptr<ResourceEntry> entry)> |
| InitializeCompletionCallback; |
| |
| DriveFileStreamReader(const FileSystemGetter& file_system_getter, |
| base::SequencedTaskRunner* file_task_runner); |
| ~DriveFileStreamReader(); |
| |
| // Returns true if the reader is initialized. |
| bool IsInitialized() const; |
| |
| // Initializes the stream for the |drive_file_path|. |
| // |callback| must not be null. |
| void Initialize(const base::FilePath& drive_file_path, |
| const net::HttpByteRange& byte_range, |
| const InitializeCompletionCallback& callback); |
| |
| // Reads the data into |buffer| at most |buffer_length|, and returns |
| // the number of bytes. If an error happened, returns an error code. |
| // If no data is available yet, returns net::ERR_IO_PENDING immediately, |
| // and when the data is available the actual Read operation is done |
| // and |callback| will be run with the result. |
| // The Read() method must not be called before the Initialize() is completed |
| // successfully, or if there is pending read operation. |
| // Neither |buffer| nor |callback| must be null. |
| int Read(net::IOBuffer* buffer, int buffer_length, |
| const net::CompletionCallback& callback); |
| |
| private: |
| // Used to store the cancel closure returned by FileSystemInterface. |
| void StoreCancelDownloadClosure(const base::Closure& cancel_download_closure); |
| |
| // Part of Initialize. Called after GetFileContent's initialization |
| // is done. |
| void InitializeAfterGetFileContentInitialized( |
| const net::HttpByteRange& byte_range, |
| const InitializeCompletionCallback& callback, |
| FileError error, |
| const base::FilePath& local_cache_file_path, |
| scoped_ptr<ResourceEntry> entry); |
| |
| // Part of Initialize. Called when the local file open process is done. |
| void InitializeAfterLocalFileOpen( |
| int64 length, |
| const InitializeCompletionCallback& callback, |
| scoped_ptr<ResourceEntry> entry, |
| scoped_ptr<util::LocalFileReader> file_reader, |
| int open_result); |
| |
| // Called when the data is received from the server. |
| void OnGetContent(google_apis::GDataErrorCode error_code, |
| scoped_ptr<std::string> data); |
| |
| // Called when GetFileContent is completed. |
| void OnGetFileContentCompletion( |
| const InitializeCompletionCallback& callback, |
| FileError error); |
| |
| const FileSystemGetter file_system_getter_; |
| scoped_refptr<base::SequencedTaskRunner> file_task_runner_; |
| base::Closure cancel_download_closure_; |
| scoped_ptr<internal::ReaderProxy> reader_proxy_; |
| |
| // This should remain the last member so it'll be destroyed first and |
| // invalidate its weak pointers before other members are destroyed. |
| base::WeakPtrFactory<DriveFileStreamReader> weak_ptr_factory_; |
| DISALLOW_COPY_AND_ASSIGN(DriveFileStreamReader); |
| }; |
| |
| } // namespace drive |
| |
| #endif // CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_FILE_STREAM_READER_H_ |