| Index: storage/browser/blob/blob_reader.h
|
| diff --git a/storage/browser/blob/blob_reader.h b/storage/browser/blob/blob_reader.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..54b262f3ef3e910dfcf932c37a87d8b9e85ab8b7
|
| --- /dev/null
|
| +++ b/storage/browser/blob/blob_reader.h
|
| @@ -0,0 +1,190 @@
|
| +// Copyright 2015 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 STORAGE_BROWSER_BLOB_BLOB_READER_H_
|
| +#define STORAGE_BROWSER_BLOB_BLOB_READER_H_
|
| +
|
| +#include <stdint.h>
|
| +#include <map>
|
| +#include <vector>
|
| +
|
| +#include "base/macros.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "net/base/completion_callback.h"
|
| +#include "storage/browser/storage_browser_export.h"
|
| +
|
| +class GURL;
|
| +
|
| +namespace base {
|
| +class FilePath;
|
| +class SequencedTaskRunner;
|
| +class TaskRunner;
|
| +class Time;
|
| +}
|
| +
|
| +namespace net {
|
| +class DrainableIOBuffer;
|
| +class IOBuffer;
|
| +}
|
| +
|
| +namespace storage {
|
| +class BlobDataItem;
|
| +class BlobDataHandle;
|
| +class BlobDataSnapshot;
|
| +class FileStreamReader;
|
| +class FileSystemContext;
|
| +
|
| +// The blob reader is used to read a blob. This can only be used in the browser
|
| +// process, and we need to be on the IO thread.
|
| +// * There can only be one read happening at a time per reader.
|
| +// * If a status of Status::NET_ERROR is returned, that means there was an
|
| +// error and the net_error() variable contains the error code.
|
| +// Use a BlobDataHandle to create an instance.
|
| +class STORAGE_EXPORT BlobReader {
|
| + public:
|
| + class STORAGE_EXPORT FileStreamReaderProvider {
|
| + public:
|
| + virtual ~FileStreamReaderProvider();
|
| +
|
| + virtual scoped_ptr<FileStreamReader> CreateForLocalFile(
|
| + base::TaskRunner* task_runner,
|
| + const base::FilePath& file_path,
|
| + int64_t initial_offset,
|
| + const base::Time& expected_modification_time) = 0;
|
| +
|
| + virtual scoped_ptr<FileStreamReader> CreateFileStreamReader(
|
| + const GURL& filesystem_url,
|
| + int64_t offset,
|
| + int64_t max_bytes_to_read,
|
| + const base::Time& expected_modification_time) = 0;
|
| + };
|
| + enum class Status { NET_ERROR, IO_PENDING, DONE };
|
| + virtual ~BlobReader();
|
| +
|
| + // This calculates the total size of the blob, and initializes the reading
|
| + // cursor.
|
| + // * This should only be called once per reader.
|
| + // * Status::Done means that the total_size() value is populated and you can
|
| + // continue to SetReadRange or Read.
|
| + // * The 'done' callback is only called if Status::IO_PENDING is returned.
|
| + // The callback value contains the error code or net::OK. Please use the
|
| + // total_size() value to query the blob size, as it's uint64_t.
|
| + Status CalculateSize(const net::CompletionCallback& done);
|
| +
|
| + // Used to set the read position.
|
| + // * This should be called after CalculateSize and before Read.
|
| + // * Range can only be set once.
|
| + Status SetReadRange(uint64_t position, uint64_t length);
|
| +
|
| + // Reads a portion of the data.
|
| + // * CalculateSize (and optionally SetReadRange) must be called beforehand.
|
| + // * bytes_read is populated only if Status::DONE is returned. Otherwise the
|
| + // bytes read (or error code) is populated in the 'done' callback.
|
| + // * The done callback is only called if Status::IO_PENDING is returned.
|
| + // * This method can be called multiple times. A bytes_read value (either from
|
| + // the callback for Status::IO_PENDING or the bytes_read value for
|
| + // Status::DONE) of 0 means we're finished reading.
|
| + Status Read(net::IOBuffer* buffer,
|
| + size_t dest_size,
|
| + int* bytes_read,
|
| + net::CompletionCallback done);
|
| +
|
| + // Kills reading and invalidates all callbacks. The reader cannot be used
|
| + // after this call.
|
| + void Kill();
|
| +
|
| + // Returns if all of the blob's items are in memory.
|
| + bool IsInMemory() const;
|
| +
|
| + // Returns the remaining bytes to be read in the blob. This is populated
|
| + // after CalculateSize, and is modified by SetReadRange.
|
| + uint64_t remaining_bytes() const { return remaining_bytes_; }
|
| +
|
| + // Returns the net error code if there was an error. Defaults to net::OK.
|
| + int net_error() const { return net_error_; }
|
| +
|
| + // Returns the total size of the blob. This is populated after CalculateSize
|
| + // is called.
|
| + uint64_t total_size() const { return total_size_; }
|
| +
|
| + protected:
|
| + friend class BlobDataHandle;
|
| + friend class BlobReaderTest;
|
| +
|
| + BlobReader(const BlobDataHandle* blob_handle,
|
| + scoped_ptr<FileStreamReaderProvider> file_stream_provider,
|
| + base::SequencedTaskRunner* file_task_runner);
|
| +
|
| + bool total_size_calculated() const { return total_size_calculated_; }
|
| +
|
| + private:
|
| + Status ReportError(int net_error);
|
| + void InvalidateCallbacksAndDone(int net_error, net::CompletionCallback done);
|
| +
|
| + bool AddItemLength(size_t index, uint64_t length);
|
| + bool ResolveFileItemLength(const BlobDataItem& item,
|
| + int64_t total_length,
|
| + uint64_t* output_length);
|
| + void DidGetFileItemLength(size_t index, int64_t result);
|
| + void DidCountSize();
|
| +
|
| + // For reading the blob.
|
| + // Returns if we're done, PENDING_IO if we're waiting on async.
|
| + Status ReadLoop(int* bytes_read);
|
| + // Called from asynchronously called methods to continue the read loop.
|
| + void ContinueAsyncReadLoop();
|
| + // PENDING_IO means we're waiting on async.
|
| + Status ReadItem();
|
| + void AdvanceItem();
|
| + void AdvanceBytesRead(int result);
|
| + void ReadBytesItem(const BlobDataItem& item, int bytes_to_read);
|
| + BlobReader::Status ReadFileItem(FileStreamReader* reader, int bytes_to_read);
|
| + void DidReadFile(int result);
|
| + void DeleteCurrentFileReader();
|
| + Status ReadDiskCacheEntryItem(const BlobDataItem& item, int bytes_to_read);
|
| + void DidReadDiskCacheEntry(int result);
|
| + void DidReadItem(int result);
|
| + int ComputeBytesToRead() const;
|
| + int BytesReadCompleted();
|
| +
|
| + // Returns a FileStreamReader for a blob item at |index|.
|
| + // If the item at |index| is not of file this returns NULL.
|
| + FileStreamReader* GetOrCreateFileReaderAtIndex(size_t index);
|
| + // If the reader is null, then this basically performs a delete operation.
|
| + void SetFileReaderAtIndex(size_t index, scoped_ptr<FileStreamReader> reader);
|
| + // Creates a FileStreamReader for the item with additional_offset.
|
| + scoped_ptr<FileStreamReader> CreateFileStreamReader(
|
| + const BlobDataItem& item,
|
| + uint64_t additional_offset);
|
| +
|
| + scoped_ptr<BlobDataSnapshot> blob_data_;
|
| + scoped_ptr<FileStreamReaderProvider> file_stream_provider_;
|
| + scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
|
| +
|
| + int net_error_;
|
| + bool item_list_populated_ = false;
|
| + std::vector<uint64_t> item_length_list_;
|
| +
|
| + scoped_refptr<net::DrainableIOBuffer> read_buf_;
|
| +
|
| + bool total_size_calculated_ = false;
|
| + uint64_t total_size_ = 0;
|
| + uint64_t remaining_bytes_ = 0;
|
| + size_t pending_get_file_info_count_ = 0;
|
| + std::map<size_t, FileStreamReader*> index_to_reader_;
|
| + size_t current_item_index_ = 0;
|
| + uint64_t current_item_offset_ = 0;
|
| +
|
| + bool io_pending_ = false;
|
| +
|
| + net::CompletionCallback size_callback_;
|
| + net::CompletionCallback read_callback_;
|
| +
|
| + base::WeakPtrFactory<BlobReader> weak_factory_;
|
| + DISALLOW_COPY_AND_ASSIGN(BlobReader);
|
| +};
|
| +
|
| +} // namespace storage
|
| +#endif // STORAGE_BROWSER_BLOB_BLOB_READER_H_
|
|
|