summaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
authordmurph <dmurph@chromium.org>2015-01-23 01:18:56 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-23 09:20:02 +0000
commitbff2e53fb3e210be45d264797036ec59005ebdd6 (patch)
tree6715a49048fd85d94b341ea4a3f474e567135e3c /storage
parent98d7ef56b969695d1f185881e3eed845a3221136 (diff)
downloadchromium_src-bff2e53fb3e210be45d264797036ec59005ebdd6.zip
chromium_src-bff2e53fb3e210be45d264797036ec59005ebdd6.tar.gz
chromium_src-bff2e53fb3e210be45d264797036ec59005ebdd6.tar.bz2
[Storage] Blob Storage Refactoring pt 1:
* Renaming classes to be more descriptive. * Changing smart pointers to reflect strict ownership model. * Adding pointers to facilitate future resource swapping. * Remove renderer-side dependency on blob_data.h This patch makes all of the far-reaching changes that effect everyone that uses the blob storage context. Subsequent changes should only effect the blob infrastructure. https://bit.ly/AutoBlobToDisk BUG=375297 Review URL: https://codereview.chromium.org/810403004 Cr-Commit-Position: refs/heads/master@{#312800}
Diffstat (limited to 'storage')
-rw-r--r--storage/browser/BUILD.gn10
-rw-r--r--storage/browser/blob/blob_data_builder.cc82
-rw-r--r--storage/browser/blob/blob_data_builder.h118
-rw-r--r--storage/browser/blob/blob_data_handle.cc30
-rw-r--r--storage/browser/blob/blob_data_handle.h38
-rw-r--r--storage/browser/blob/blob_data_item.cc18
-rw-r--r--storage/browser/blob/blob_data_item.h63
-rw-r--r--storage/browser/blob/blob_data_snapshot.cc39
-rw-r--r--storage/browser/blob/blob_data_snapshot.h54
-rw-r--r--storage/browser/blob/blob_storage_context.cc201
-rw-r--r--storage/browser/blob/blob_storage_context.h46
-rw-r--r--storage/browser/blob/blob_url_request_job.cc53
-rw-r--r--storage/browser/blob/blob_url_request_job.h8
-rw-r--r--storage/browser/blob/blob_url_request_job_factory.cc11
-rw-r--r--storage/browser/blob/blob_url_request_job_factory.h5
-rw-r--r--storage/browser/blob/scoped_file.cc (renamed from storage/common/blob/scoped_file.cc)2
-rw-r--r--storage/browser/blob/scoped_file.h (renamed from storage/common/blob/scoped_file.h)10
-rw-r--r--storage/browser/blob/shareable_file_reference.cc (renamed from storage/common/blob/shareable_file_reference.cc)2
-rw-r--r--storage/browser/blob/shareable_file_reference.h (renamed from storage/common/blob/shareable_file_reference.h)11
-rw-r--r--storage/browser/blob/view_blob_internals_job.cc24
-rw-r--r--storage/browser/blob/view_blob_internals_job.h4
-rw-r--r--storage/browser/fileapi/async_file_util_adapter.cc2
-rw-r--r--storage/browser/fileapi/copy_or_move_operation_delegate.cc2
-rw-r--r--storage/browser/fileapi/dragged_file_util.cc2
-rw-r--r--storage/browser/fileapi/file_system_file_stream_reader.h2
-rw-r--r--storage/browser/fileapi/file_system_file_util.h2
-rw-r--r--storage/browser/fileapi/file_system_operation_impl.cc2
-rw-r--r--storage/browser/fileapi/file_system_operation_impl.h2
-rw-r--r--storage/browser/fileapi/file_system_operation_runner.cc2
-rw-r--r--storage/browser/fileapi/obfuscated_file_util.h2
-rw-r--r--storage/browser/fileapi/sandbox_file_stream_writer.h2
-rw-r--r--storage/common/BUILD.gn6
-rw-r--r--storage/common/blob/blob_data.cc63
-rw-r--r--storage/common/blob/blob_data.h98
-rw-r--r--storage/storage_browser.gyp10
-rw-r--r--storage/storage_common.gyp6
36 files changed, 657 insertions, 375 deletions
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn
index 3ca92d7..02bd84e 100644
--- a/storage/browser/BUILD.gn
+++ b/storage/browser/BUILD.gn
@@ -7,8 +7,14 @@ component("browser") {
output_name = "storage_browser"
sources = [
"storage_browser_export.h",
+ "blob/blob_data_builder.cc",
+ "blob/blob_data_builder.h",
"blob/blob_data_handle.cc",
"blob/blob_data_handle.h",
+ "blob/blob_data_item.cc",
+ "blob/blob_data_item.h",
+ "blob/blob_data_snapshot.cc",
+ "blob/blob_data_snapshot.h",
"blob/blob_storage_context.cc",
"blob/blob_storage_context.h",
"blob/blob_url_request_job.cc",
@@ -19,6 +25,10 @@ component("browser") {
"blob/file_stream_reader.h",
"blob/local_file_stream_reader.cc",
"blob/local_file_stream_reader.h",
+ "blob/scoped_file.cc",
+ "blob/scoped_file.h",
+ "blob/shareable_file_reference.cc",
+ "blob/shareable_file_reference.h",
"blob/view_blob_internals_job.cc",
"blob/view_blob_internals_job.h",
"database/database_quota_client.cc",
diff --git a/storage/browser/blob/blob_data_builder.cc b/storage/browser/blob/blob_data_builder.cc
new file mode 100644
index 0000000..120bc44
--- /dev/null
+++ b/storage/browser/blob/blob_data_builder.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 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.
+
+#include <storage/browser/blob/blob_data_builder.h>
+#include "base/time/time.h"
+
+namespace storage {
+
+BlobDataBuilder::BlobDataBuilder(const std::string& uuid) : uuid_(uuid) {
+}
+BlobDataBuilder::~BlobDataBuilder() {
+}
+
+void BlobDataBuilder::AppendData(const char* data, size_t length) {
+ DCHECK(length > 0);
+ scoped_ptr<DataElement> element(new DataElement());
+ element->SetToBytes(data, length);
+ items_.push_back(new BlobDataItem(element.Pass()));
+}
+
+void BlobDataBuilder::AppendFile(const base::FilePath& file_path,
+ uint64 offset,
+ uint64 length,
+ const base::Time& expected_modification_time) {
+ DCHECK(length > 0);
+ scoped_ptr<DataElement> element(new DataElement());
+ element->SetToFilePathRange(file_path, offset, length,
+ expected_modification_time);
+ items_.push_back(new BlobDataItem(element.Pass()));
+}
+
+void BlobDataBuilder::AppendFile(
+ const base::FilePath& file_path,
+ uint64 offset,
+ uint64 length,
+ const base::Time& expected_modification_time,
+ scoped_refptr<ShareableFileReference> shareable_file) {
+ DCHECK(length > 0);
+ scoped_ptr<DataElement> element(new DataElement());
+ element->SetToFilePathRange(file_path, offset, length,
+ expected_modification_time);
+ items_.push_back(new BlobDataItem(element.Pass(), shareable_file));
+}
+
+void BlobDataBuilder::AppendBlob(const std::string& uuid,
+ uint64 offset,
+ uint64 length) {
+ DCHECK_GT(length, 0ul);
+ scoped_ptr<DataElement> element(new DataElement());
+ element->SetToBlobRange(uuid, offset, length);
+ items_.push_back(new BlobDataItem(element.Pass()));
+}
+
+void BlobDataBuilder::AppendFileSystemFile(
+ const GURL& url,
+ uint64 offset,
+ uint64 length,
+ const base::Time& expected_modification_time) {
+ DCHECK(length > 0);
+ scoped_ptr<DataElement> element(new DataElement());
+ element->SetToFileSystemUrlRange(url, offset, length,
+ expected_modification_time);
+ items_.push_back(new BlobDataItem(element.Pass()));
+}
+
+size_t BlobDataBuilder::GetMemoryUsage() const {
+ int64 memory = 0;
+ for (const auto& data_item : items_) {
+ if (data_item->type() == DataElement::TYPE_BYTES)
+ memory += data_item->length();
+ }
+ return memory;
+}
+
+scoped_ptr<BlobDataSnapshot> BlobDataBuilder::BuildSnapshot() {
+ return scoped_ptr<BlobDataSnapshot>(new BlobDataSnapshot(uuid_, content_type_,
+ content_disposition_,
+ items_)).Pass();
+}
+
+} // namespace storage
diff --git a/storage/browser/blob/blob_data_builder.h b/storage/browser/blob/blob_data_builder.h
new file mode 100644
index 0000000..3c42640
--- /dev/null
+++ b/storage/browser/blob/blob_data_builder.h
@@ -0,0 +1,118 @@
+// 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_DATA_BUILDER_H_
+#define STORAGE_BROWSER_BLOB_BLOB_DATA_BUILDER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "storage/browser/blob/blob_data_item.h"
+#include "storage/browser/blob/blob_data_snapshot.h"
+#include "storage/browser/storage_browser_export.h"
+
+namespace storage {
+class BlobStorageContext;
+
+class STORAGE_EXPORT BlobDataBuilder {
+ public:
+ explicit BlobDataBuilder(const std::string& uuid);
+ virtual ~BlobDataBuilder();
+
+ const std::string& uuid() const { return uuid_; }
+
+ void AppendData(const std::string& data) {
+ AppendData(data.c_str(), data.size());
+ }
+
+ void AppendData(const char* data, size_t length);
+
+ void AppendFile(const base::FilePath& file_path,
+ uint64 offset,
+ uint64 length,
+ const base::Time& expected_modification_time);
+
+ void AppendFile(const base::FilePath& file_path,
+ uint64 offset,
+ uint64 length,
+ const base::Time& expected_modification_time,
+ scoped_refptr<ShareableFileReference> shareable_file);
+
+ void AppendBlob(const std::string& uuid, uint64 offset, uint64 length);
+ void AppendFileSystemFile(const GURL& url,
+ uint64 offset,
+ uint64 length,
+ const base::Time& expected_modification_time);
+
+ void set_content_type(const std::string& content_type) {
+ content_type_ = content_type;
+ }
+
+ void set_content_disposition(const std::string& content_disposition) {
+ content_disposition_ = content_disposition;
+ }
+
+ size_t GetMemoryUsage() const;
+
+ scoped_ptr<BlobDataSnapshot> BuildSnapshot();
+
+ private:
+ friend class BlobStorageContext;
+ friend bool operator==(const BlobDataBuilder& a, const BlobDataBuilder& b);
+ friend bool operator==(const BlobDataSnapshot& a, const BlobDataBuilder& b);
+
+ std::string uuid_;
+ std::string content_type_;
+ std::string content_disposition_;
+ std::vector<scoped_refptr<BlobDataItem>> items_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlobDataBuilder);
+};
+
+#if defined(UNIT_TEST)
+inline bool operator==(const BlobDataBuilder& a, const BlobDataBuilder& b) {
+ if (a.content_type_ != b.content_type_)
+ return false;
+ if (a.content_disposition_ != b.content_disposition_)
+ return false;
+ if (a.items_.size() != b.items_.size())
+ return false;
+ for (size_t i = 0; i < a.items_.size(); ++i) {
+ if (a.items_[i] != b.items_[i])
+ return false;
+ }
+ return true;
+}
+
+inline bool operator==(const BlobDataSnapshot& a, const BlobDataBuilder& b) {
+ if (a.content_type() != b.content_type_) {
+ return false;
+ }
+ if (a.content_disposition() != b.content_disposition_) {
+ return false;
+ }
+ if (a.items().size() != b.items_.size()) {
+ return false;
+ }
+ for (size_t i = 0; i < a.items().size(); ++i) {
+ if (*(a.items()[i]) != *(b.items_[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline bool operator!=(const BlobDataSnapshot& a, const BlobDataBuilder& b) {
+ return !(a == b);
+}
+
+inline bool operator!=(const BlobDataBuilder& a, const BlobDataBuilder& b) {
+ return !(a == b);
+}
+#endif // defined(UNIT_TEST)
+
+} // namespace storage
+#endif // STORAGE_BROWSER_BLOB_BLOB_DATA_BUILDER_H_
diff --git a/storage/browser/blob/blob_data_handle.cc b/storage/browser/blob/blob_data_handle.cc
index cf647b4..e3a4be9 100644
--- a/storage/browser/blob/blob_data_handle.cc
+++ b/storage/browser/blob/blob_data_handle.cc
@@ -8,38 +8,38 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
+#include "storage/browser/blob/blob_data_snapshot.h"
#include "storage/browser/blob/blob_storage_context.h"
-#include "storage/common/blob/blob_data.h"
namespace storage {
BlobDataHandle::BlobDataHandleShared::BlobDataHandleShared(
- BlobData* blob_data,
+ const std::string& uuid,
BlobStorageContext* context,
base::SequencedTaskRunner* task_runner)
- : blob_data_(blob_data),
- context_(context->AsWeakPtr()) {
- context_->IncrementBlobRefCount(blob_data->uuid());
+ : uuid_(uuid), context_(context->AsWeakPtr()) {
+ context_->IncrementBlobRefCount(uuid);
}
-BlobData* BlobDataHandle::BlobDataHandleShared::data() const {
- return blob_data_.get();
+scoped_ptr<BlobDataSnapshot>
+BlobDataHandle::BlobDataHandleShared::CreateSnapshot() const {
+ return context_->CreateSnapshot(uuid_).Pass();
}
const std::string& BlobDataHandle::BlobDataHandleShared::uuid() const {
- return blob_data_->uuid();
+ return uuid_;
}
BlobDataHandle::BlobDataHandleShared::~BlobDataHandleShared() {
if (context_.get())
- context_->DecrementBlobRefCount(blob_data_->uuid());
+ context_->DecrementBlobRefCount(uuid_);
}
-BlobDataHandle::BlobDataHandle(BlobData* blob_data,
+BlobDataHandle::BlobDataHandle(const std::string& uuid,
BlobStorageContext* context,
base::SequencedTaskRunner* task_runner)
: io_task_runner_(task_runner),
- shared_(new BlobDataHandleShared(blob_data, context, task_runner)) {
+ shared_(new BlobDataHandleShared(uuid, context, task_runner)) {
DCHECK(io_task_runner_.get());
DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
}
@@ -52,16 +52,16 @@ BlobDataHandle::BlobDataHandle(const BlobDataHandle& other) {
BlobDataHandle::~BlobDataHandle() {
BlobDataHandleShared* raw = shared_.get();
raw->AddRef();
- shared_ = 0;
+ shared_ = nullptr;
io_task_runner_->ReleaseSoon(FROM_HERE, raw);
}
-BlobData* BlobDataHandle::data() const {
+scoped_ptr<BlobDataSnapshot> BlobDataHandle::CreateSnapshot() const {
DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
- return shared_->data();
+ return shared_->CreateSnapshot().Pass();
}
-std::string BlobDataHandle::uuid() const {
+const std::string& BlobDataHandle::uuid() const {
return shared_->uuid();
}
diff --git a/storage/browser/blob/blob_data_handle.h b/storage/browser/blob/blob_data_handle.h
index 0b1d151..3041241 100644
--- a/storage/browser/blob/blob_data_handle.h
+++ b/storage/browser/blob/blob_data_handle.h
@@ -18,31 +18,44 @@ class SequencedTaskRunner;
namespace storage {
-class BlobData;
+class BlobDataSnapshot;
class BlobStorageContext;
-// A scoper object for use in chrome's main browser process, ensures
-// the underlying BlobData and its uuid remain in BlobStorageContext's
-// collection for the duration. This object has delete semantics and
-// maybe deleted on any thread.
+// BlobDataHandle ensures that the underlying blob (keyed by the uuid) remains
+// in the BlobStorageContext's collection while this object is alive. Anything
+// that needs to keep a blob alive needs to store this handle.
+// When the blob data itself is needed, clients must call the CreateSnapshot()
+// method on the IO thread to create a snapshot of the blob data. This snapshot
+// is not intended to be persisted, and serves to ensure that the backing
+// resources remain around for the duration of reading the blob. This snapshot
+// can be read on any thread, but it must be destructed on the IO thread.
+// This object has delete semantics and may be deleted on any thread.
class STORAGE_EXPORT BlobDataHandle
: public base::SupportsUserData::Data {
public:
BlobDataHandle(const BlobDataHandle& other); // May be copied on any thread.
- ~BlobDataHandle() override; // Maybe be deleted on any thread.
- BlobData* data() const; // May only be accessed on the IO thread.
+ ~BlobDataHandle() override; // May be deleted on any thread.
- std::string uuid() const; // May be accessed on any thread.
+ // A BlobDataSnapshot is used to read the data from the blob. This object is
+ // intended to be transient and should not be stored for any extended period
+ // of time.
+ // This call and the destruction of the returned snapshot must be called
+ // on the IO thread.
+ scoped_ptr<BlobDataSnapshot> CreateSnapshot() const;
+
+ const std::string& uuid() const; // May be accessed on any thread.
private:
+ // Internal class whose destructor is guarenteed to be called on the IO
+ // thread.
class BlobDataHandleShared
: public base::RefCountedThreadSafe<BlobDataHandleShared> {
public:
- BlobDataHandleShared(BlobData* blob_data,
+ BlobDataHandleShared(const std::string& uuid,
BlobStorageContext* context,
base::SequencedTaskRunner* task_runner);
- BlobData* data() const;
+ scoped_ptr<BlobDataSnapshot> CreateSnapshot() const;
const std::string& uuid() const;
private:
@@ -52,14 +65,15 @@ class STORAGE_EXPORT BlobDataHandle
virtual ~BlobDataHandleShared();
- scoped_refptr<BlobData> blob_data_;
+ const std::string uuid_;
base::WeakPtr<BlobStorageContext> context_;
DISALLOW_COPY_AND_ASSIGN(BlobDataHandleShared);
};
friend class BlobStorageContext;
- BlobDataHandle(BlobData* blob_data, BlobStorageContext* context,
+ BlobDataHandle(const std::string& uuid,
+ BlobStorageContext* context,
base::SequencedTaskRunner* task_runner);
scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
diff --git a/storage/browser/blob/blob_data_item.cc b/storage/browser/blob/blob_data_item.cc
new file mode 100644
index 0000000..504a1c3
--- /dev/null
+++ b/storage/browser/blob/blob_data_item.cc
@@ -0,0 +1,18 @@
+// Copyright (c) 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.
+
+#include "storage/browser/blob/blob_data_item.h"
+
+namespace storage {
+
+BlobDataItem::BlobDataItem(scoped_ptr<DataElement> item,
+ scoped_refptr<ShareableFileReference> file_handle)
+ : item_(item.Pass()), file_handle_(file_handle) {
+}
+BlobDataItem::BlobDataItem(scoped_ptr<DataElement> item) : item_(item.Pass()) {
+}
+BlobDataItem::~BlobDataItem() {
+}
+
+} // namespace storage
diff --git a/storage/browser/blob/blob_data_item.h b/storage/browser/blob/blob_data_item.h
new file mode 100644
index 0000000..099415b
--- /dev/null
+++ b/storage/browser/blob/blob_data_item.h
@@ -0,0 +1,63 @@
+// Copyright (c) 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_DATA_ITEM_H_
+#define STORAGE_BROWSER_BLOB_BLOB_DATA_ITEM_H_
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "storage/browser/blob/shareable_file_reference.h"
+#include "storage/browser/storage_browser_export.h"
+#include "storage/common/data_element.h"
+
+namespace storage {
+class BlobDataBuilder;
+class BlobStorageContext;
+
+// Ref counted blob item. This class owns the backing data of the blob item.
+// The backing data is immutable, and cannot change after creation.
+// The purpose of this class is to allow the resource to stick around in the
+// snapshot even after the resource was swapped in the blob (either to disk or
+// to memory) by the BlobStorageContext.
+class STORAGE_EXPORT BlobDataItem : public base::RefCounted<BlobDataItem> {
+ public:
+ storage::DataElement::Type type() const { return item_->type(); }
+ const char* bytes() const { return item_->bytes(); }
+ const base::FilePath& path() const { return item_->path(); }
+ const GURL& filesystem_url() const { return item_->filesystem_url(); }
+ const std::string& blob_uuid() const { return item_->blob_uuid(); }
+ uint64 offset() const { return item_->offset(); }
+ uint64 length() const { return item_->length(); }
+ const base::Time& expected_modification_time() const {
+ return item_->expected_modification_time();
+ }
+ const DataElement& data_element() const { return *item_; }
+ const DataElement* data_element_ptr() const { return item_.get(); }
+
+ private:
+ friend class BlobDataBuilder;
+ friend class BlobStorageContext;
+ friend class base::RefCounted<BlobDataItem>;
+ BlobDataItem(scoped_ptr<DataElement> item);
+ BlobDataItem(scoped_ptr<DataElement> item,
+ scoped_refptr<ShareableFileReference> file_handle);
+ virtual ~BlobDataItem();
+
+ scoped_ptr<storage::DataElement> item_;
+ scoped_refptr<ShareableFileReference> file_handle_;
+};
+
+#if defined(UNIT_TEST)
+inline bool operator==(const BlobDataItem& a, const BlobDataItem& b) {
+ return a.data_element() == b.data_element();
+}
+
+inline bool operator!=(const BlobDataItem& a, const BlobDataItem& b) {
+ return !(a == b);
+}
+#endif // defined(UNIT_TEST)
+
+} // namespace storage
+
+#endif // STORAGE_BROWSER_BLOB_BLOB_DATA_ITEM_H_
diff --git a/storage/browser/blob/blob_data_snapshot.cc b/storage/browser/blob/blob_data_snapshot.cc
new file mode 100644
index 0000000..6ae74cd
--- /dev/null
+++ b/storage/browser/blob/blob_data_snapshot.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 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.
+
+#include "storage/browser/blob/blob_data_snapshot.h"
+
+namespace storage {
+
+BlobDataSnapshot::BlobDataSnapshot(
+ const std::string& uuid,
+ const std::string& content_type,
+ const std::string& content_disposition,
+ const std::vector<scoped_refptr<BlobDataItem>>& items)
+ : uuid_(uuid),
+ content_type_(content_type),
+ content_disposition_(content_disposition),
+ items_(items) {
+}
+
+BlobDataSnapshot::BlobDataSnapshot(const BlobDataSnapshot& other)
+ : uuid_(other.uuid_),
+ content_type_(other.content_type_),
+ content_disposition_(other.content_disposition_),
+ items_(other.items_) {
+}
+
+BlobDataSnapshot::~BlobDataSnapshot() {
+}
+
+size_t BlobDataSnapshot::GetMemoryUsage() const {
+ int64 memory = 0;
+ for (const auto& data_item : items_) {
+ if (data_item->type() == DataElement::TYPE_BYTES)
+ memory += data_item->length();
+ }
+ return memory;
+}
+
+} // namespace storage
diff --git a/storage/browser/blob/blob_data_snapshot.h b/storage/browser/blob/blob_data_snapshot.h
new file mode 100644
index 0000000..416c386
--- /dev/null
+++ b/storage/browser/blob/blob_data_snapshot.h
@@ -0,0 +1,54 @@
+// 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_DATA_SNAPSHOT_H_
+#define STORAGE_BROWSER_BLOB_BLOB_DATA_SNAPSHOT_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/supports_user_data.h"
+#include "storage/browser/blob/blob_data_item.h"
+#include "storage/browser/storage_browser_export.h"
+
+namespace storage {
+class BlobDataBuilder;
+
+// Snapshot of a Blob. This snapshot holds a refcount of the current
+// blob item resources so the backing storage for these items will stick
+// around for the lifetime of this object. (The data represented by a blob is
+// immutable, but the backing store can change). Keeping this object alive
+// guarantees that the resources stay alive, but it does not guarentee that
+// the blob stays alive. Use the BlobDataHandle to keep a blob alive.
+// This class must be deleted on the IO thread.
+class STORAGE_EXPORT BlobDataSnapshot : public base::SupportsUserData::Data {
+ public:
+ BlobDataSnapshot(const BlobDataSnapshot& other);
+ ~BlobDataSnapshot() override;
+
+ const std::vector<scoped_refptr<BlobDataItem>>& items() const {
+ return items_;
+ }
+ const std::string& content_type() const { return content_type_; }
+ const std::string& content_disposition() const {
+ return content_disposition_;
+ }
+ size_t GetMemoryUsage() const;
+
+ private:
+ friend class BlobDataBuilder;
+ BlobDataSnapshot(const std::string& uuid,
+ const std::string& content_type,
+ const std::string& content_disposition,
+ const std::vector<scoped_refptr<BlobDataItem>>& items);
+
+ const std::string uuid_;
+ const std::string content_type_;
+ const std::string content_disposition_;
+ const std::vector<scoped_refptr<BlobDataItem>> items_;
+};
+
+} // namespace storage
+#endif // STORAGE_BROWSER_BLOB_BLOB_DATA_SNAPSHOT_H_
diff --git a/storage/browser/blob/blob_storage_context.cc b/storage/browser/blob/blob_storage_context.cc
index 9680e4d..1577b6b 100644
--- a/storage/browser/blob/blob_storage_context.cc
+++ b/storage/browser/blob/blob_storage_context.cc
@@ -9,8 +9,8 @@
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/metrics/histogram.h"
-#include "storage/browser/blob/blob_data_handle.h"
-#include "storage/common/blob/blob_data.h"
+#include "base/stl_util.h"
+#include "storage/browser/blob/blob_data_builder.h"
#include "url/gurl.h"
namespace storage {
@@ -43,19 +43,24 @@ BlobStorageContext::BlobMapEntry::BlobMapEntry()
: refcount(0), flags(0) {
}
-BlobStorageContext::BlobMapEntry::BlobMapEntry(
- int refcount, int flags, BlobData* data)
- : refcount(refcount), flags(flags), data(data) {
+BlobStorageContext::BlobMapEntry::BlobMapEntry(int refcount,
+ BlobDataBuilder* data)
+ : refcount(refcount), flags(0), data_builder(data) {
}
BlobStorageContext::BlobMapEntry::~BlobMapEntry() {
}
+bool BlobStorageContext::BlobMapEntry::IsBeingBuilt() {
+ return data_builder;
+}
+
BlobStorageContext::BlobStorageContext()
: memory_usage_(0) {
}
BlobStorageContext::~BlobStorageContext() {
+ STLDeleteContainerPairSecondPointers(blob_map_.begin(), blob_map_.end());
}
scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID(
@@ -64,11 +69,12 @@ scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID(
BlobMap::iterator found = blob_map_.find(uuid);
if (found == blob_map_.end())
return result.Pass();
- if (found->second.flags & EXCEEDED_MEMORY)
+ auto* entry = found->second;
+ if (entry->flags & EXCEEDED_MEMORY)
return result.Pass();
- DCHECK(!(found->second.flags & BEING_BUILT));
- result.reset(new BlobDataHandle(
- found->second.data.get(), this, base::MessageLoopProxy::current().get()));
+ DCHECK(!entry->IsBeingBuilt());
+ result.reset(
+ new BlobDataHandle(uuid, this, base::MessageLoopProxy::current().get()));
return result.Pass();
}
@@ -82,16 +88,13 @@ scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL(
}
scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob(
- const BlobData* data) {
- StartBuildingBlob(data->uuid());
- for (std::vector<BlobData::Item>::const_iterator iter =
- data->items().begin();
- iter != data->items().end(); ++iter) {
- AppendBlobDataItem(data->uuid(), *iter);
- }
- FinishBuildingBlob(data->uuid(), data->content_type());
- scoped_ptr<BlobDataHandle> handle = GetBlobDataFromUUID(data->uuid());
- DecrementBlobRefCount(data->uuid());
+ const BlobDataBuilder& data) {
+ StartBuildingBlob(data.uuid_);
+ for (const auto& blob_item : data.items_)
+ AppendBlobDataItem(data.uuid_, *(blob_item->item_));
+ FinishBuildingBlob(data.uuid_, data.content_type_);
+ scoped_ptr<BlobDataHandle> handle = GetBlobDataFromUUID(data.uuid_);
+ DecrementBlobRefCount(data.uuid_);
return handle.Pass();
}
@@ -115,20 +118,33 @@ void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) {
public_blob_urls_.erase(blob_url);
}
+scoped_ptr<BlobDataSnapshot> BlobStorageContext::CreateSnapshot(
+ const std::string& uuid) {
+ scoped_ptr<BlobDataSnapshot> result;
+ auto found = blob_map_.find(uuid);
+ DCHECK(found != blob_map_.end())
+ << "Blob should be in map, as the handle is still around";
+ BlobMapEntry* entry = found->second;
+ DCHECK(!entry->IsBeingBuilt());
+ result.reset(new BlobDataSnapshot(*entry->data));
+ return result.Pass();
+}
+
void BlobStorageContext::StartBuildingBlob(const std::string& uuid) {
DCHECK(!IsInUse(uuid) && !uuid.empty());
- blob_map_[uuid] = BlobMapEntry(1, BEING_BUILT, new BlobData(uuid));
+ blob_map_[uuid] = new BlobMapEntry(1, new BlobDataBuilder(uuid));
}
-void BlobStorageContext::AppendBlobDataItem(
- const std::string& uuid, const BlobData::Item& item) {
+void BlobStorageContext::AppendBlobDataItem(const std::string& uuid,
+ const DataElement& item) {
DCHECK(IsBeingBuilt(uuid));
BlobMap::iterator found = blob_map_.find(uuid);
if (found == blob_map_.end())
return;
- if (found->second.flags & EXCEEDED_MEMORY)
+ BlobMapEntry* entry = found->second;
+ if (entry->flags & EXCEEDED_MEMORY)
return;
- BlobData* target_blob_data = found->second.data.get();
+ BlobDataBuilder* target_blob_data = entry->data_builder.get();
DCHECK(target_blob_data);
bool exceeded_memory = false;
@@ -149,31 +165,33 @@ void BlobStorageContext::AppendBlobDataItem(
UMA_HISTOGRAM_COUNTS("Storage.Blob.StorageSizeBeforeAppend",
memory_usage_ / 1024);
switch (item.type()) {
- case BlobData::Item::TYPE_BYTES:
+ case DataElement::TYPE_BYTES:
UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Bytes", length / 1024);
DCHECK(!item.offset());
exceeded_memory = !AppendBytesItem(target_blob_data, item.bytes(),
static_cast<int64>(length));
break;
- case BlobData::Item::TYPE_FILE:
+ case DataElement::TYPE_FILE:
UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.File", length / 1024);
- AppendFileItem(target_blob_data, item.path(), item.offset(), length,
- item.expected_modification_time());
+ AppendFileItem(target_blob_data, item.path(), item.offset(),
+ item.length(), item.expected_modification_time());
break;
- case BlobData::Item::TYPE_FILE_FILESYSTEM:
+ case DataElement::TYPE_FILE_FILESYSTEM:
UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.FileSystem", length / 1024);
AppendFileSystemFileItem(target_blob_data, item.filesystem_url(),
- item.offset(), length,
+ item.offset(), item.length(),
item.expected_modification_time());
break;
- case BlobData::Item::TYPE_BLOB: {
+ case DataElement::TYPE_BLOB: {
UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.Blob", length / 1024);
+ // We grab the handle to ensure it stays around while we copy it.
scoped_ptr<BlobDataHandle> src = GetBlobDataFromUUID(item.blob_uuid());
- if (src)
- exceeded_memory = !ExpandStorageItems(target_blob_data,
- src->data(),
- item.offset(),
- item.length());
+ if (src) {
+ BlobMapEntry* entry = blob_map_.find(item.blob_uuid())->second;
+ DCHECK(entry->data);
+ exceeded_memory = !ExpandStorageItems(target_blob_data, *entry->data,
+ item.offset(), item.length());
+ }
break;
}
default:
@@ -188,8 +206,8 @@ void BlobStorageContext::AppendBlobDataItem(
// as a stop gap, we'll prevent memory usage over a max amount.
if (exceeded_memory) {
memory_usage_ -= target_blob_data->GetMemoryUsage();
- found->second.flags |= EXCEEDED_MEMORY;
- found->second.data = new BlobData(uuid);
+ entry->flags |= EXCEEDED_MEMORY;
+ entry->data_builder.reset(new BlobDataBuilder(uuid));
return;
}
}
@@ -200,13 +218,13 @@ void BlobStorageContext::FinishBuildingBlob(
BlobMap::iterator found = blob_map_.find(uuid);
if (found == blob_map_.end())
return;
- found->second.data->set_content_type(content_type);
- found->second.flags &= ~BEING_BUILT;
- UMA_HISTOGRAM_COUNTS("Storage.Blob.ItemCount",
- found->second.data->items().size());
- UMA_HISTOGRAM_BOOLEAN(
- "Storage.Blob.ExceededMemory",
- (found->second.flags & EXCEEDED_MEMORY) == EXCEEDED_MEMORY);
+ BlobMapEntry* entry = found->second;
+ entry->data_builder->set_content_type(content_type);
+ entry->data = entry->data_builder->BuildSnapshot().Pass();
+ entry->data_builder.reset();
+ UMA_HISTOGRAM_COUNTS("Storage.Blob.ItemCount", entry->data->items().size());
+ UMA_HISTOGRAM_BOOLEAN("Storage.Blob.ExceededMemory",
+ (entry->flags & EXCEEDED_MEMORY) == EXCEEDED_MEMORY);
}
void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) {
@@ -220,60 +238,63 @@ void BlobStorageContext::IncrementBlobRefCount(const std::string& uuid) {
DCHECK(false);
return;
}
- ++(found->second.refcount);
+ ++(found->second->refcount);
}
void BlobStorageContext::DecrementBlobRefCount(const std::string& uuid) {
BlobMap::iterator found = blob_map_.find(uuid);
if (found == blob_map_.end())
return;
- DCHECK_EQ(found->second.data->uuid(), uuid);
- if (--(found->second.refcount) == 0) {
- memory_usage_ -= found->second.data->GetMemoryUsage();
+ auto* entry = found->second;
+ if (--(entry->refcount) == 0) {
+ if (entry->IsBeingBuilt()) {
+ memory_usage_ -= entry->data_builder->GetMemoryUsage();
+ } else {
+ memory_usage_ -= entry->data->GetMemoryUsage();
+ }
+ delete entry;
blob_map_.erase(found);
}
}
bool BlobStorageContext::ExpandStorageItems(
- BlobData* target_blob_data, BlobData* src_blob_data,
- uint64 offset, uint64 length) {
- DCHECK(target_blob_data && src_blob_data &&
- length != static_cast<uint64>(-1));
-
- std::vector<BlobData::Item>::const_iterator iter =
- src_blob_data->items().begin();
+ BlobDataBuilder* target_blob_data,
+ const BlobDataSnapshot& src_blob_data,
+ uint64 offset,
+ uint64 length) {
+ DCHECK(target_blob_data && length != static_cast<uint64>(-1));
+
+ const std::vector<scoped_refptr<BlobDataItem>>& items = src_blob_data.items();
+ auto iter = items.begin();
if (offset) {
- for (; iter != src_blob_data->items().end(); ++iter) {
- if (offset >= iter->length())
- offset -= iter->length();
+ for (; iter != items.end(); ++iter) {
+ const BlobDataItem& item = *(iter->get());
+ if (offset >= item.length())
+ offset -= item.length();
else
break;
}
}
- for (; iter != src_blob_data->items().end() && length > 0; ++iter) {
- uint64 current_length = iter->length() - offset;
+ for (; iter != items.end() && length > 0; ++iter) {
+ const BlobDataItem& item = *(iter->get());
+ uint64 current_length = item.length() - offset;
uint64 new_length = current_length > length ? length : current_length;
- if (iter->type() == BlobData::Item::TYPE_BYTES) {
+ if (iter->get()->type() == DataElement::TYPE_BYTES) {
if (!AppendBytesItem(
target_blob_data,
- iter->bytes() + static_cast<size_t>(iter->offset() + offset),
+ item.bytes() + static_cast<size_t>(item.offset() + offset),
static_cast<int64>(new_length))) {
return false; // exceeded memory
}
- } else if (iter->type() == BlobData::Item::TYPE_FILE) {
- AppendFileItem(target_blob_data,
- iter->path(),
- iter->offset() + offset,
- new_length,
- iter->expected_modification_time());
+ } else if (item.type() == DataElement::TYPE_FILE) {
+ AppendFileItem(target_blob_data, item.path(), item.offset() + offset,
+ new_length, item.expected_modification_time());
} else {
- DCHECK(iter->type() == BlobData::Item::TYPE_FILE_FILESYSTEM);
- AppendFileSystemFileItem(target_blob_data,
- iter->filesystem_url(),
- iter->offset() + offset,
- new_length,
- iter->expected_modification_time());
+ DCHECK(item.type() == DataElement::TYPE_FILE_FILESYSTEM);
+ AppendFileSystemFileItem(target_blob_data, item.filesystem_url(),
+ item.offset() + offset, new_length,
+ item.expected_modification_time());
}
length -= new_length;
offset = 0;
@@ -281,36 +302,40 @@ bool BlobStorageContext::ExpandStorageItems(
return true;
}
-bool BlobStorageContext::AppendBytesItem(
- BlobData* target_blob_data, const char* bytes, int64 length) {
+bool BlobStorageContext::AppendBytesItem(BlobDataBuilder* target_blob_data,
+ const char* bytes,
+ int64 length) {
if (length < 0) {
DCHECK(false);
return false;
}
- if (memory_usage_ + length > kMaxMemoryUsage)
+ if (memory_usage_ + length > kMaxMemoryUsage) {
return false;
+ }
target_blob_data->AppendData(bytes, static_cast<size_t>(length));
memory_usage_ += length;
return true;
}
void BlobStorageContext::AppendFileItem(
- BlobData* target_blob_data,
- const base::FilePath& file_path, uint64 offset, uint64 length,
+ BlobDataBuilder* target_blob_data,
+ const base::FilePath& file_path,
+ uint64 offset,
+ uint64 length,
const base::Time& expected_modification_time) {
- target_blob_data->AppendFile(file_path, offset, length,
- expected_modification_time);
-
// It may be a temporary file that should be deleted when no longer needed.
scoped_refptr<ShareableFileReference> shareable_file =
ShareableFileReference::Get(file_path);
- if (shareable_file.get())
- target_blob_data->AttachShareableFileReference(shareable_file.get());
+
+ target_blob_data->AppendFile(file_path, offset, length,
+ expected_modification_time, shareable_file);
}
void BlobStorageContext::AppendFileSystemFileItem(
- BlobData* target_blob_data,
- const GURL& filesystem_url, uint64 offset, uint64 length,
+ BlobDataBuilder* target_blob_data,
+ const GURL& filesystem_url,
+ uint64 offset,
+ uint64 length,
const base::Time& expected_modification_time) {
target_blob_data->AppendFileSystemFile(filesystem_url, offset, length,
expected_modification_time);
@@ -324,7 +349,7 @@ bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) {
BlobMap::iterator found = blob_map_.find(uuid);
if (found == blob_map_.end())
return false;
- return found->second.flags & BEING_BUILT;
+ return found->second->IsBeingBuilt();
}
bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) {
diff --git a/storage/browser/blob/blob_storage_context.h b/storage/browser/blob/blob_storage_context.h
index 7ccc133..322a4c6 100644
--- a/storage/browser/blob/blob_storage_context.h
+++ b/storage/browser/blob/blob_storage_context.h
@@ -12,8 +12,9 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "storage/browser/blob/blob_data_handle.h"
+#include "storage/browser/blob/blob_data_snapshot.h"
#include "storage/browser/storage_browser_export.h"
-#include "storage/common/blob/blob_data.h"
+#include "storage/common/data_element.h"
class GURL;
@@ -29,6 +30,7 @@ class BlobStorageHost;
namespace storage {
class BlobDataHandle;
+class BlobDataBuilder;
// This class handles the logistics of blob Storage within the browser process,
// and maintains a mapping from blob uuid to the data. The class is single
@@ -45,7 +47,7 @@ class STORAGE_EXPORT BlobStorageContext
// Useful for coining blobs from within the browser process. If the
// blob cannot be added due to memory consumption, returns NULL.
- scoped_ptr<BlobDataHandle> AddFinishedBlob(const BlobData* blob_data);
+ scoped_ptr<BlobDataHandle> AddFinishedBlob(const BlobDataBuilder& blob_data);
// Useful for coining blob urls from within the browser process.
bool RegisterPublicBlobURL(const GURL& url, const std::string& uuid);
@@ -57,46 +59,54 @@ class STORAGE_EXPORT BlobStorageContext
friend class ViewBlobInternalsJob;
enum EntryFlags {
- BEING_BUILT = 1 << 0,
EXCEEDED_MEMORY = 1 << 1,
};
struct BlobMapEntry {
int refcount;
int flags;
- scoped_refptr<BlobData> data;
+ // data and data_builder are mutually exclusive.
+ scoped_ptr<BlobDataSnapshot> data;
+ scoped_ptr<BlobDataBuilder> data_builder;
BlobMapEntry();
- BlobMapEntry(int refcount, int flags, BlobData* data);
+ BlobMapEntry(int refcount, BlobDataBuilder* data);
~BlobMapEntry();
+
+ bool IsBeingBuilt();
};
- typedef std::map<std::string, BlobMapEntry>
- BlobMap;
+ typedef std::map<std::string, BlobMapEntry*> BlobMap;
typedef std::map<GURL, std::string> BlobURLMap;
+ // Called by BlobDataHandle.
+ scoped_ptr<BlobDataSnapshot> CreateSnapshot(const std::string& uuid);
+
void StartBuildingBlob(const std::string& uuid);
void AppendBlobDataItem(const std::string& uuid,
- const BlobData::Item& data_item);
+ const DataElement& data_item);
void FinishBuildingBlob(const std::string& uuid, const std::string& type);
void CancelBuildingBlob(const std::string& uuid);
void IncrementBlobRefCount(const std::string& uuid);
void DecrementBlobRefCount(const std::string& uuid);
- bool ExpandStorageItems(BlobData* target_blob_data,
- BlobData* src_blob_data,
+ bool ExpandStorageItems(BlobDataBuilder* target_blob_data,
+ const BlobDataSnapshot& src_blob_data,
uint64 offset,
uint64 length);
- bool AppendBytesItem(BlobData* target_blob_data,
- const char* data, int64 length);
- void AppendFileItem(BlobData* target_blob_data,
+ bool AppendBytesItem(BlobDataBuilder* target_blob_data,
+ const char* data,
+ int64 length);
+ void AppendFileItem(BlobDataBuilder* target_blob_data,
const base::FilePath& file_path,
- uint64 offset, uint64 length,
+ uint64 offset,
+ uint64 length,
const base::Time& expected_modification_time);
- void AppendFileSystemFileItem(
- BlobData* target_blob_data,
- const GURL& url, uint64 offset, uint64 length,
- const base::Time& expected_modification_time);
+ void AppendFileSystemFileItem(BlobDataBuilder* target_blob_data,
+ const GURL& url,
+ uint64 offset,
+ uint64 length,
+ const base::Time& expected_modification_time);
bool IsInUse(const std::string& uuid);
bool IsBeingBuilt(const std::string& uuid);
diff --git a/storage/browser/blob/blob_url_request_job.cc b/storage/browser/blob/blob_url_request_job.cc
index 41e7942..068b5c4 100644
--- a/storage/browser/blob/blob_url_request_job.cc
+++ b/storage/browser/blob/blob_url_request_job.cc
@@ -34,15 +34,16 @@
#include "storage/browser/blob/file_stream_reader.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_url.h"
+#include "storage/common/data_element.h"
namespace storage {
namespace {
-bool IsFileType(BlobData::Item::Type type) {
+bool IsFileType(DataElement::Type type) {
switch (type) {
- case BlobData::Item::TYPE_FILE:
- case BlobData::Item::TYPE_FILE_FILESYSTEM:
+ case DataElement::TYPE_FILE:
+ case DataElement::TYPE_FILE_FILESYSTEM:
return true;
default:
return false;
@@ -54,11 +55,11 @@ bool IsFileType(BlobData::Item::Type type) {
BlobURLRequestJob::BlobURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- const scoped_refptr<BlobData>& blob_data,
+ scoped_ptr<BlobDataSnapshot> blob_data,
storage::FileSystemContext* file_system_context,
base::MessageLoopProxy* file_thread_proxy)
: net::URLRequestJob(request, network_delegate),
- blob_data_(blob_data),
+ blob_data_(blob_data.Pass()),
file_system_context_(file_system_context),
file_thread_proxy_(file_thread_proxy),
total_size_(0),
@@ -174,7 +175,7 @@ void BlobURLRequestJob::DidStart() {
}
// If the blob data is not present, bail out.
- if (!blob_data_.get()) {
+ if (!blob_data_) {
NotifyFailure(net::ERR_FILE_NOT_FOUND);
return;
}
@@ -198,10 +199,11 @@ bool BlobURLRequestJob::AddItemLength(size_t index, int64 item_length) {
void BlobURLRequestJob::CountSize() {
pending_get_file_info_count_ = 0;
total_size_ = 0;
- item_length_list_.resize(blob_data_->items().size());
+ const auto& items = blob_data_->items();
+ item_length_list_.resize(items.size());
- for (size_t i = 0; i < blob_data_->items().size(); ++i) {
- const BlobData::Item& item = blob_data_->items().at(i);
+ for (size_t i = 0; i < items.size(); ++i) {
+ const BlobDataItem& item = *items.at(i);
if (IsFileType(item.type())) {
++pending_get_file_info_count_;
GetFileStreamReader(i)->GetLength(
@@ -257,8 +259,9 @@ void BlobURLRequestJob::DidGetFileItemLength(size_t index, int64 result) {
return;
}
- DCHECK_LT(index, blob_data_->items().size());
- const BlobData::Item& item = blob_data_->items().at(index);
+ const auto& items = blob_data_->items();
+ DCHECK_LT(index, items.size());
+ const BlobDataItem& item = *items.at(index);
DCHECK(IsFileType(item.type()));
uint64 file_length = result;
@@ -290,8 +293,9 @@ void BlobURLRequestJob::DidGetFileItemLength(size_t index, int64 result) {
void BlobURLRequestJob::Seek(int64 offset) {
// Skip the initial items that are not in the range.
+ const auto& items = blob_data_->items();
for (current_item_index_ = 0;
- current_item_index_ < blob_data_->items().size() &&
+ current_item_index_ < items.size() &&
offset >= item_length_list_[current_item_index_];
++current_item_index_) {
offset -= item_length_list_[current_item_index_];
@@ -304,7 +308,7 @@ void BlobURLRequestJob::Seek(int64 offset) {
return;
// Adjust the offset of the first stream if it is of file type.
- const BlobData::Item& item = blob_data_->items().at(current_item_index_);
+ const BlobDataItem& item = *items.at(current_item_index_);
if (IsFileType(item.type())) {
DeleteCurrentFileReader();
CreateFileStreamReader(current_item_index_, offset);
@@ -316,9 +320,10 @@ bool BlobURLRequestJob::ReadItem() {
if (remaining_bytes_ == 0)
return true;
+ const auto& items = blob_data_->items();
// If we get to the last item but still expect something to read, bail out
// since something is wrong.
- if (current_item_index_ >= blob_data_->items().size()) {
+ if (current_item_index_ >= items.size()) {
NotifyFailure(net::ERR_FAILED);
return false;
}
@@ -333,8 +338,8 @@ bool BlobURLRequestJob::ReadItem() {
}
// Do the reading.
- const BlobData::Item& item = blob_data_->items().at(current_item_index_);
- if (item.type() == BlobData::Item::TYPE_BYTES)
+ const BlobDataItem& item = *items.at(current_item_index_);
+ if (item.type() == DataElement::TYPE_BYTES)
return ReadBytesItem(item, bytes_to_read);
if (IsFileType(item.type())) {
return ReadFileItem(GetFileStreamReader(current_item_index_),
@@ -370,7 +375,7 @@ void BlobURLRequestJob::AdvanceBytesRead(int result) {
DCHECK_GE(read_buf_->BytesRemaining(), 0);
}
-bool BlobURLRequestJob::ReadBytesItem(const BlobData::Item& item,
+bool BlobURLRequestJob::ReadBytesItem(const BlobDataItem& item,
int bytes_to_read) {
DCHECK_GE(read_buf_->BytesRemaining(), bytes_to_read);
@@ -555,8 +560,9 @@ void BlobURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) {
}
FileStreamReader* BlobURLRequestJob::GetFileStreamReader(size_t index) {
- DCHECK_LT(index, blob_data_->items().size());
- const BlobData::Item& item = blob_data_->items().at(index);
+ const auto& items = blob_data_->items();
+ DCHECK_LT(index, items.size());
+ const BlobDataItem& item = *items.at(index);
if (!IsFileType(item.type()))
return NULL;
if (index_to_reader_.find(index) == index_to_reader_.end())
@@ -567,21 +573,22 @@ FileStreamReader* BlobURLRequestJob::GetFileStreamReader(size_t index) {
void BlobURLRequestJob::CreateFileStreamReader(size_t index,
int64 additional_offset) {
- DCHECK_LT(index, blob_data_->items().size());
- const BlobData::Item& item = blob_data_->items().at(index);
+ const auto& items = blob_data_->items();
+ DCHECK_LT(index, items.size());
+ const BlobDataItem& item = *items.at(index);
DCHECK(IsFileType(item.type()));
DCHECK_EQ(0U, index_to_reader_.count(index));
FileStreamReader* reader = NULL;
switch (item.type()) {
- case BlobData::Item::TYPE_FILE:
+ case DataElement::TYPE_FILE:
reader = FileStreamReader::CreateForLocalFile(
file_thread_proxy_.get(),
item.path(),
item.offset() + additional_offset,
item.expected_modification_time());
break;
- case BlobData::Item::TYPE_FILE_FILESYSTEM:
+ case DataElement::TYPE_FILE_FILESYSTEM:
reader = file_system_context_
->CreateFileStreamReader(
storage::FileSystemURL(file_system_context_->CrackURL(
diff --git a/storage/browser/blob/blob_url_request_job.h b/storage/browser/blob/blob_url_request_job.h
index dab61dc..cf296b6 100644
--- a/storage/browser/blob/blob_url_request_job.h
+++ b/storage/browser/blob/blob_url_request_job.h
@@ -12,8 +12,8 @@
#include "net/http/http_byte_range.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request_job.h"
+#include "storage/browser/blob/blob_data_snapshot.h"
#include "storage/browser/storage_browser_export.h"
-#include "storage/common/blob/blob_data.h"
namespace base {
class MessageLoopProxy;
@@ -38,7 +38,7 @@ class STORAGE_EXPORT BlobURLRequestJob
public:
BlobURLRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- const scoped_refptr<BlobData>& blob_data,
+ scoped_ptr<BlobDataSnapshot> blob_data,
storage::FileSystemContext* file_system_context,
base::MessageLoopProxy* resolving_message_loop_proxy);
@@ -70,7 +70,7 @@ class STORAGE_EXPORT BlobURLRequestJob
bool ReadItem();
void AdvanceItem();
void AdvanceBytesRead(int result);
- bool ReadBytesItem(const BlobData::Item& item, int bytes_to_read);
+ bool ReadBytesItem(const BlobDataItem& item, int bytes_to_read);
bool ReadFileItem(FileStreamReader* reader, int bytes_to_read);
void DidReadFile(int result);
@@ -92,7 +92,7 @@ class STORAGE_EXPORT BlobURLRequestJob
// Creates a FileStreamReader for the item at |index| with additional_offset.
void CreateFileStreamReader(size_t index, int64 additional_offset);
- scoped_refptr<BlobData> blob_data_;
+ scoped_ptr<BlobDataSnapshot> blob_data_;
// Variables for controlling read from |blob_data_|.
scoped_refptr<storage::FileSystemContext> file_system_context_;
diff --git a/storage/browser/blob/blob_url_request_job_factory.cc b/storage/browser/blob/blob_url_request_job_factory.cc
index 60f9c73..fe193af 100644
--- a/storage/browser/blob/blob_url_request_job_factory.cc
+++ b/storage/browser/blob/blob_url_request_job_factory.cc
@@ -68,11 +68,11 @@ net::URLRequestJob* BlobProtocolHandler::MaybeCreateJob(
file_loop_proxy_.get());
}
-scoped_refptr<storage::BlobData> BlobProtocolHandler::LookupBlobData(
+scoped_ptr<BlobDataSnapshot> BlobProtocolHandler::LookupBlobData(
net::URLRequest* request) const {
BlobDataHandle* blob_data_handle = GetRequestedBlobDataHandle(request);
if (blob_data_handle)
- return blob_data_handle->data();
+ return blob_data_handle->CreateSnapshot().Pass();
if (!context_.get())
return NULL;
@@ -84,7 +84,12 @@ scoped_refptr<storage::BlobData> BlobProtocolHandler::LookupBlobData(
return NULL;
std::string uuid = request->url().spec().substr(kPrefix.length());
scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(uuid);
- return handle.get() ? handle->data() : NULL;
+ scoped_ptr<BlobDataSnapshot> snapshot;
+ if (handle) {
+ snapshot = handle->CreateSnapshot().Pass();
+ SetRequestedBlobDataHandle(request, handle.Pass());
+ }
+ return snapshot.Pass();
}
} // namespace storage
diff --git a/storage/browser/blob/blob_url_request_job_factory.h b/storage/browser/blob/blob_url_request_job_factory.h
index c3e34e3..381a95f 100644
--- a/storage/browser/blob/blob_url_request_job_factory.h
+++ b/storage/browser/blob/blob_url_request_job_factory.h
@@ -26,7 +26,7 @@ class URLRequestContext;
namespace storage {
-class BlobData;
+class BlobDataSnapshot;
class BlobDataHandle;
class BlobStorageContext;
@@ -56,8 +56,7 @@ class STORAGE_EXPORT BlobProtocolHandler
net::NetworkDelegate* network_delegate) const override;
private:
- scoped_refptr<BlobData> LookupBlobData(
- net::URLRequest* request) const;
+ scoped_ptr<BlobDataSnapshot> LookupBlobData(net::URLRequest* request) const;
base::WeakPtr<BlobStorageContext> context_;
const scoped_refptr<storage::FileSystemContext> file_system_context_;
diff --git a/storage/common/blob/scoped_file.cc b/storage/browser/blob/scoped_file.cc
index b544449..cdf4cb8 100644
--- a/storage/common/blob/scoped_file.cc
+++ b/storage/browser/blob/scoped_file.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "storage/common/blob/scoped_file.h"
+#include "storage/browser/blob/scoped_file.h"
#include "base/bind.h"
#include "base/callback.h"
diff --git a/storage/common/blob/scoped_file.h b/storage/browser/blob/scoped_file.h
index 4a51a46..a8fd730 100644
--- a/storage/common/blob/scoped_file.h
+++ b/storage/browser/blob/scoped_file.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef STORAGE_COMMON_BLOB_SCOPED_FILE_H_
-#define STORAGE_COMMON_BLOB_SCOPED_FILE_H_
+#ifndef STORAGE_BROWSER_BLOB_SCOPED_FILE_H_
+#define STORAGE_BROWSER_BLOB_SCOPED_FILE_H_
#include <map>
@@ -11,7 +11,7 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/move.h"
-#include "storage/common/storage_common_export.h"
+#include "storage/browser/storage_browser_export.h"
namespace base {
class TaskRunner;
@@ -26,7 +26,7 @@ namespace storage {
//
// TODO(kinuko): Probably this can be moved under base or somewhere more
// common place.
-class STORAGE_COMMON_EXPORT ScopedFile {
+class STORAGE_EXPORT ScopedFile {
// To support destructive assignment from an l-value assignment.
// This provides Pass() method which creates an r-value for the current
// instance. (See base/move.h for details)
@@ -91,4 +91,4 @@ class STORAGE_COMMON_EXPORT ScopedFile {
} // namespace storage
-#endif // STORAGE_COMMON_BLOB_SCOPED_FILE_H_
+#endif // STORAGE_BROWSER_BLOB_SCOPED_FILE_H_
diff --git a/storage/common/blob/shareable_file_reference.cc b/storage/browser/blob/shareable_file_reference.cc
index c2ec839..02a5be4 100644
--- a/storage/common/blob/shareable_file_reference.cc
+++ b/storage/browser/blob/shareable_file_reference.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "storage/common/blob/shareable_file_reference.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include <map>
diff --git a/storage/common/blob/shareable_file_reference.h b/storage/browser/blob/shareable_file_reference.h
index bd9d050..e2739dc 100644
--- a/storage/common/blob/shareable_file_reference.h
+++ b/storage/browser/blob/shareable_file_reference.h
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef STORAGE_COMMON_BLOB_SHAREABLE_FILE_REFERENCE_H_
-#define STORAGE_COMMON_BLOB_SHAREABLE_FILE_REFERENCE_H_
+#ifndef STORAGE_BROWSER_BLOB_SHAREABLE_FILE_REFERENCE_H_
+#define STORAGE_BROWSER_BLOB_SHAREABLE_FILE_REFERENCE_H_
#include <vector>
-#include "storage/common/blob/scoped_file.h"
+#include "storage/browser/blob/scoped_file.h"
+#include "storage/browser/storage_browser_export.h"
namespace storage {
@@ -15,7 +16,7 @@ namespace storage {
// same path if it already exists in its internal map.
// This class is non-thread-safe and all methods must be called on a single
// thread.
-class STORAGE_COMMON_EXPORT ShareableFileReference
+class STORAGE_EXPORT ShareableFileReference
: public base::RefCounted<ShareableFileReference> {
public:
typedef ScopedFile::ScopeOutCallback FinalReleaseCallback;
@@ -71,4 +72,4 @@ class STORAGE_COMMON_EXPORT ShareableFileReference
} // namespace storage
-#endif // STORAGE_COMMON_BLOB_SHAREABLE_FILE_REFERENCE_H_
+#endif // STORAGE_BROWSER_BLOB_SHAREABLE_FILE_REFERENCE_H_
diff --git a/storage/browser/blob/view_blob_internals_job.cc b/storage/browser/blob/view_blob_internals_job.cc
index 2065a31..3f5cc41 100644
--- a/storage/browser/blob/view_blob_internals_job.cc
+++ b/storage/browser/blob/view_blob_internals_job.cc
@@ -18,8 +18,8 @@
#include "net/base/escape.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"
+#include "storage/browser/blob/blob_data_snapshot.h"
#include "storage/browser/blob/blob_storage_context.h"
-#include "storage/common/blob/blob_data.h"
namespace {
@@ -150,8 +150,7 @@ void ViewBlobInternalsJob::GenerateHTML(std::string* out) const {
iter != blob_storage_context_->blob_map_.end();
++iter) {
AddHTMLBoldText(iter->first, out);
- GenerateHTMLForBlobData(*(iter->second.data.get()),
- iter->second.refcount,
+ GenerateHTMLForBlobData(*(iter->second->data.get()), iter->second->refcount,
out);
}
if (!blob_storage_context_->public_blob_urls_.empty()) {
@@ -168,9 +167,10 @@ void ViewBlobInternalsJob::GenerateHTML(std::string* out) const {
}
}
-void ViewBlobInternalsJob::GenerateHTMLForBlobData(const BlobData& blob_data,
- int refcount,
- std::string* out) {
+void ViewBlobInternalsJob::GenerateHTMLForBlobData(
+ const BlobDataSnapshot& blob_data,
+ int refcount,
+ std::string* out) {
StartHTMLList(out);
AddHTMLListItem(kRefcount, base::IntToString(refcount), out);
@@ -190,13 +190,13 @@ void ViewBlobInternalsJob::GenerateHTMLForBlobData(const BlobData& blob_data,
AddHTMLListItem(kIndex, base::UTF16ToUTF8(base::FormatNumber(i)), out);
StartHTMLList(out);
}
- const BlobData::Item& item = blob_data.items().at(i);
+ const BlobDataItem& item = *(blob_data.items().at(i));
switch (item.type()) {
- case BlobData::Item::TYPE_BYTES:
+ case DataElement::TYPE_BYTES:
AddHTMLListItem(kType, "data", out);
break;
- case BlobData::Item::TYPE_FILE:
+ case DataElement::TYPE_FILE:
AddHTMLListItem(kType, "file", out);
AddHTMLListItem(kPath,
net::EscapeForHTML(item.path().AsUTF8Unsafe()),
@@ -207,10 +207,10 @@ void ViewBlobInternalsJob::GenerateHTMLForBlobData(const BlobData& blob_data,
out);
}
break;
- case BlobData::Item::TYPE_BLOB:
+ case DataElement::TYPE_BLOB:
NOTREACHED(); // Should be flattened in the storage context.
break;
- case BlobData::Item::TYPE_FILE_FILESYSTEM:
+ case DataElement::TYPE_FILE_FILESYSTEM:
AddHTMLListItem(kType, "filesystem", out);
AddHTMLListItem(kURL, item.filesystem_url().spec(), out);
if (!item.expected_modification_time().is_null()) {
@@ -219,7 +219,7 @@ void ViewBlobInternalsJob::GenerateHTMLForBlobData(const BlobData& blob_data,
out);
}
break;
- case BlobData::Item::TYPE_UNKNOWN:
+ case DataElement::TYPE_UNKNOWN:
NOTREACHED();
break;
}
diff --git a/storage/browser/blob/view_blob_internals_job.h b/storage/browser/blob/view_blob_internals_job.h
index 4ab1e30..2abb1d4 100644
--- a/storage/browser/blob/view_blob_internals_job.h
+++ b/storage/browser/blob/view_blob_internals_job.h
@@ -17,7 +17,7 @@ class URLRequest;
namespace storage {
-class BlobData;
+class BlobDataSnapshot;
class BlobStorageContext;
// A job subclass that implements a protocol to inspect the internal
@@ -41,7 +41,7 @@ class STORAGE_EXPORT ViewBlobInternalsJob
~ViewBlobInternalsJob() override;
void GenerateHTML(std::string* out) const;
- static void GenerateHTMLForBlobData(const BlobData& blob_data,
+ static void GenerateHTMLForBlobData(const BlobDataSnapshot& blob_data,
int refcount,
std::string* out);
diff --git a/storage/browser/fileapi/async_file_util_adapter.cc b/storage/browser/fileapi/async_file_util_adapter.cc
index 3bb20f9..7d324c0 100644
--- a/storage/browser/fileapi/async_file_util_adapter.cc
+++ b/storage/browser/fileapi/async_file_util_adapter.cc
@@ -10,11 +10,11 @@
#include "base/sequenced_task_runner.h"
#include "base/task_runner_util.h"
#include "base/thread_task_runner_handle.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_file_util.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_url.h"
-#include "storage/common/blob/shareable_file_reference.h"
#include "storage/common/fileapi/file_system_util.h"
using base::Bind;
diff --git a/storage/browser/fileapi/copy_or_move_operation_delegate.cc b/storage/browser/fileapi/copy_or_move_operation_delegate.cc
index 1b95f79..baa93db 100644
--- a/storage/browser/fileapi/copy_or_move_operation_delegate.cc
+++ b/storage/browser/fileapi/copy_or_move_operation_delegate.cc
@@ -9,6 +9,7 @@
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "storage/browser/blob/file_stream_reader.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/copy_or_move_file_validator.h"
#include "storage/browser/fileapi/file_observers.h"
#include "storage/browser/fileapi/file_stream_writer.h"
@@ -16,7 +17,6 @@
#include "storage/browser/fileapi/file_system_operation_runner.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/recursive_operation_delegate.h"
-#include "storage/common/blob/shareable_file_reference.h"
#include "storage/common/fileapi/file_system_util.h"
namespace storage {
diff --git a/storage/browser/fileapi/dragged_file_util.cc b/storage/browser/fileapi/dragged_file_util.cc
index 9a5b66e..ff581fe 100644
--- a/storage/browser/fileapi/dragged_file_util.cc
+++ b/storage/browser/fileapi/dragged_file_util.cc
@@ -8,12 +8,12 @@
#include <vector>
#include "base/files/file_util.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/isolated_context.h"
#include "storage/browser/fileapi/native_file_util.h"
-#include "storage/common/blob/shareable_file_reference.h"
namespace storage {
diff --git a/storage/browser/fileapi/file_system_file_stream_reader.h b/storage/browser/fileapi/file_system_file_stream_reader.h
index b0a718a..c0cdeb1 100644
--- a/storage/browser/fileapi/file_system_file_stream_reader.h
+++ b/storage/browser/fileapi/file_system_file_stream_reader.h
@@ -10,9 +10,9 @@
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "storage/browser/blob/file_stream_reader.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/storage_browser_export.h"
-#include "storage/common/blob/shareable_file_reference.h"
namespace base {
class FilePath;
diff --git a/storage/browser/fileapi/file_system_file_util.h b/storage/browser/fileapi/file_system_file_util.h
index c649c31..48a127a 100644
--- a/storage/browser/fileapi/file_system_file_util.h
+++ b/storage/browser/fileapi/file_system_file_util.h
@@ -8,9 +8,9 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
+#include "storage/browser/blob/scoped_file.h"
#include "storage/browser/fileapi/file_system_operation.h"
#include "storage/browser/storage_browser_export.h"
-#include "storage/common/blob/scoped_file.h"
namespace base {
class Time;
diff --git a/storage/browser/fileapi/file_system_operation_impl.cc b/storage/browser/fileapi/file_system_operation_impl.cc
index 25613dd..dbca3d6 100644
--- a/storage/browser/fileapi/file_system_operation_impl.cc
+++ b/storage/browser/fileapi/file_system_operation_impl.cc
@@ -10,6 +10,7 @@
#include "base/time/time.h"
#include "net/base/escape.h"
#include "net/url_request/url_request.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/async_file_util.h"
#include "storage/browser/fileapi/copy_or_move_operation_delegate.h"
#include "storage/browser/fileapi/file_observers.h"
@@ -22,7 +23,6 @@
#include "storage/browser/fileapi/remove_operation_delegate.h"
#include "storage/browser/fileapi/sandbox_file_system_backend.h"
#include "storage/browser/quota/quota_manager_proxy.h"
-#include "storage/common/blob/shareable_file_reference.h"
#include "storage/common/fileapi/file_system_types.h"
#include "storage/common/fileapi/file_system_util.h"
#include "storage/common/quota/quota_types.h"
diff --git a/storage/browser/fileapi/file_system_operation_impl.h b/storage/browser/fileapi/file_system_operation_impl.h
index add6b7c..dbf6e3a 100644
--- a/storage/browser/fileapi/file_system_operation_impl.h
+++ b/storage/browser/fileapi/file_system_operation_impl.h
@@ -10,12 +10,12 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "storage/browser/blob/scoped_file.h"
#include "storage/browser/fileapi/file_system_operation.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/file_writer_delegate.h"
#include "storage/browser/storage_browser_export.h"
-#include "storage/common/blob/scoped_file.h"
#include "storage/common/quota/quota_types.h"
namespace storage {
diff --git a/storage/browser/fileapi/file_system_operation_runner.cc b/storage/browser/fileapi/file_system_operation_runner.cc
index 9c1e4a6..848929f 100644
--- a/storage/browser/fileapi/file_system_operation_runner.cc
+++ b/storage/browser/fileapi/file_system_operation_runner.cc
@@ -9,12 +9,12 @@
#include "base/stl_util.h"
#include "net/url_request/url_request_context.h"
#include "storage/browser/blob/blob_url_request_job_factory.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_observers.h"
#include "storage/browser/fileapi/file_stream_writer.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_operation.h"
#include "storage/browser/fileapi/file_writer_delegate.h"
-#include "storage/common/blob/shareable_file_reference.h"
namespace storage {
diff --git a/storage/browser/fileapi/obfuscated_file_util.h b/storage/browser/fileapi/obfuscated_file_util.h
index 090e55e..b8fab48 100644
--- a/storage/browser/fileapi/obfuscated_file_util.h
+++ b/storage/browser/fileapi/obfuscated_file_util.h
@@ -16,12 +16,12 @@
#include "base/files/file_util_proxy.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_system_file_util.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/sandbox_directory_database.h"
#include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
#include "storage/browser/storage_browser_export.h"
-#include "storage/common/blob/shareable_file_reference.h"
#include "storage/common/fileapi/file_system_types.h"
namespace base {
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.h b/storage/browser/fileapi/sandbox_file_stream_writer.h
index 69b3136..61375b1 100644
--- a/storage/browser/fileapi/sandbox_file_stream_writer.h
+++ b/storage/browser/fileapi/sandbox_file_stream_writer.h
@@ -8,11 +8,11 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
+#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_stream_writer.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/task_runner_bound_observer_list.h"
#include "storage/browser/storage_browser_export.h"
-#include "storage/common/blob/shareable_file_reference.h"
#include "storage/common/fileapi/file_system_types.h"
#include "storage/common/quota/quota_types.h"
#include "url/gurl.h"
diff --git a/storage/common/BUILD.gn b/storage/common/BUILD.gn
index 5212a92..0067972 100644
--- a/storage/common/BUILD.gn
+++ b/storage/common/BUILD.gn
@@ -9,12 +9,6 @@ component("common") {
"data_element.cc",
"data_element.h",
"storage_common_export.h",
- "blob/blob_data.cc",
- "blob/blob_data.h",
- "blob/scoped_file.cc",
- "blob/scoped_file.h",
- "blob/shareable_file_reference.cc",
- "blob/shareable_file_reference.h",
"database/database_connections.cc",
"database/database_connections.h",
"database/database_identifier.cc",
diff --git a/storage/common/blob/blob_data.cc b/storage/common/blob/blob_data.cc
deleted file mode 100644
index 23f73e3..0000000
--- a/storage/common/blob/blob_data.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "storage/common/blob/blob_data.h"
-
-#include "base/logging.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-
-namespace storage {
-
-BlobData::BlobData() {}
-BlobData::BlobData(const std::string& uuid)
- : uuid_(uuid) {
-}
-
-BlobData::~BlobData() {}
-
-void BlobData::AppendData(const char* data, size_t length) {
- DCHECK(length > 0);
- items_.push_back(Item());
- items_.back().SetToBytes(data, length);
-}
-
-void BlobData::AppendFile(const base::FilePath& file_path,
- uint64 offset, uint64 length,
- const base::Time& expected_modification_time) {
- DCHECK(length > 0);
- items_.push_back(Item());
- items_.back().SetToFilePathRange(file_path, offset, length,
- expected_modification_time);
-}
-
-void BlobData::AppendBlob(const std::string& uuid,
- uint64 offset, uint64 length) {
- DCHECK_GT(length, 0ul);
- items_.push_back(Item());
- items_.back().SetToBlobRange(uuid, offset, length);
-}
-
-void BlobData::AppendFileSystemFile(
- const GURL& url, uint64 offset,
- uint64 length,
- const base::Time& expected_modification_time) {
- DCHECK(length > 0);
- items_.push_back(Item());
- items_.back().SetToFileSystemUrlRange(url, offset, length,
- expected_modification_time);
-}
-
-int64 BlobData::GetMemoryUsage() const {
- int64 memory = 0;
- for (std::vector<Item>::const_iterator iter = items_.begin();
- iter != items_.end(); ++iter) {
- if (iter->type() == Item::TYPE_BYTES)
- memory += iter->length();
- }
- return memory;
-}
-
-} // namespace storage
diff --git a/storage/common/blob/blob_data.h b/storage/common/blob/blob_data.h
deleted file mode 100644
index 2f48546..0000000
--- a/storage/common/blob/blob_data.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2012 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_COMMON_BLOB_BLOB_DATA_H_
-#define STORAGE_COMMON_BLOB_BLOB_DATA_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/files/file_path.h"
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-#include "storage/common/blob/shareable_file_reference.h"
-#include "storage/common/data_element.h"
-#include "storage/common/storage_common_export.h"
-#include "url/gurl.h"
-
-namespace storage {
-
-class STORAGE_COMMON_EXPORT BlobData
- : public base::RefCounted<BlobData> {
- public:
- typedef storage::DataElement Item;
-
- // TODO(michaeln): remove the empty ctor when we fully transition to uuids.
- BlobData();
- explicit BlobData(const std::string& uuid);
-
- void AppendData(const std::string& data) {
- AppendData(data.c_str(), data.size());
- }
-
- void AppendData(const char* data, size_t length);
-
- void AppendFile(const base::FilePath& file_path, uint64 offset, uint64 length,
- const base::Time& expected_modification_time);
- void AppendBlob(const std::string& uuid, uint64 offset, uint64 length);
- void AppendFileSystemFile(const GURL& url, uint64 offset, uint64 length,
- const base::Time& expected_modification_time);
-
- void AttachShareableFileReference(ShareableFileReference* reference) {
- shareable_files_.push_back(reference);
- }
-
- const std::string& uuid() const { return uuid_; }
- const std::vector<Item>& items() const { return items_; }
- const std::string& content_type() const { return content_type_; }
- void set_content_type(const std::string& content_type) {
- content_type_ = content_type;
- }
-
- const std::string& content_disposition() const {
- return content_disposition_;
- }
- void set_content_disposition(const std::string& content_disposition) {
- content_disposition_ = content_disposition;
- }
-
- int64 GetMemoryUsage() const;
-
- private:
- friend class base::RefCounted<BlobData>;
- virtual ~BlobData();
-
- std::string uuid_;
- std::string content_type_;
- std::string content_disposition_;
- std::vector<Item> items_;
- std::vector<scoped_refptr<ShareableFileReference> > shareable_files_;
-
- DISALLOW_COPY_AND_ASSIGN(BlobData);
-};
-
-#if defined(UNIT_TEST)
-inline bool operator==(const BlobData& a, const BlobData& b) {
- if (a.content_type() != b.content_type())
- return false;
- if (a.content_disposition() != b.content_disposition())
- return false;
- if (a.items().size() != b.items().size())
- return false;
- for (size_t i = 0; i < a.items().size(); ++i) {
- if (a.items()[i] != b.items()[i])
- return false;
- }
- return true;
-}
-
-inline bool operator!=(const BlobData& a, const BlobData& b) {
- return !(a == b);
-}
-#endif // defined(UNIT_TEST)
-
-} // namespace storage
-
-#endif // STORAGE_COMMON_BLOB_BLOB_DATA_H_
diff --git a/storage/storage_browser.gyp b/storage/storage_browser.gyp
index 2ec504f..5f93ecf 100644
--- a/storage/storage_browser.gyp
+++ b/storage/storage_browser.gyp
@@ -25,8 +25,14 @@
],
'defines': ['STORAGE_BROWSER_IMPLEMENTATION'],
'sources': [
+ 'browser/blob/blob_data_builder.cc',
+ 'browser/blob/blob_data_builder.h',
'browser/blob/blob_data_handle.cc',
'browser/blob/blob_data_handle.h',
+ 'browser/blob/blob_data_item.cc',
+ 'browser/blob/blob_data_item.h',
+ 'browser/blob/blob_data_snapshot.cc',
+ 'browser/blob/blob_data_snapshot.h',
'browser/blob/blob_storage_context.cc',
'browser/blob/blob_storage_context.h',
'browser/blob/blob_url_request_job.cc',
@@ -37,6 +43,10 @@
'browser/blob/file_stream_reader.h',
'browser/blob/local_file_stream_reader.cc',
'browser/blob/local_file_stream_reader.h',
+ 'browser/blob/scoped_file.cc',
+ 'browser/blob/scoped_file.h',
+ 'browser/blob/shareable_file_reference.cc',
+ 'browser/blob/shareable_file_reference.h',
'browser/blob/view_blob_internals_job.cc',
'browser/blob/view_blob_internals_job.h',
'browser/database/database_quota_client.cc',
diff --git a/storage/storage_common.gyp b/storage/storage_common.gyp
index 87d34b9..74b9139 100644
--- a/storage/storage_common.gyp
+++ b/storage/storage_common.gyp
@@ -22,12 +22,6 @@
'sources': [
'common/data_element.cc',
'common/data_element.h',
- 'common/blob/blob_data.cc',
- 'common/blob/blob_data.h',
- 'common/blob/scoped_file.cc',
- 'common/blob/scoped_file.h',
- 'common/blob/shareable_file_reference.cc',
- 'common/blob/shareable_file_reference.h',
'common/database/database_connections.cc',
'common/database/database_connections.h',
'common/database/database_identifier.cc',