blob: 7f6a3c147c83d7326142300ca6bb29480b33b496 [file] [log] [blame]
// 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_