summaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
authordmurph <dmurph@chromium.org>2015-10-30 18:04:52 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-31 01:05:34 +0000
commit0140342861a6aa998ffbf44ecfdc360305f560bc (patch)
tree3827bd31bf9c0ff46a68c8bd225a2db93c7dd3cc /storage
parent3d5527dd3085f75ae34245c516fc0bf63ae9d829 (diff)
downloadchromium_src-0140342861a6aa998ffbf44ecfdc360305f560bc.zip
chromium_src-0140342861a6aa998ffbf44ecfdc360305f560bc.tar.gz
chromium_src-0140342861a6aa998ffbf44ecfdc360305f560bc.tar.bz2
[BlobAsync] Patch 2: Common Constants
This CL contains constants for the Blob Async Transport refactor. Note: This CL is currently a no-op, hookup is in the 'Hookup' patch. Patches: 1: https://codereview.chromium.org/1287303002 (Committed!) 2: https://codereview.chromium.org/1288373002 3: https://codereview.chromium.org/1292523002 4: https://codereview.chromium.org/1098853003 Hookup: https://codereview.chromium.org/1234813004 BUG=375297 Review URL: https://codereview.chromium.org/1288373002 Cr-Commit-Position: refs/heads/master@{#357248}
Diffstat (limited to 'storage')
-rw-r--r--storage/browser/blob/blob_data_builder.cc91
-rw-r--r--storage/browser/blob/blob_data_builder.h35
-rw-r--r--storage/browser/blob/blob_data_item.cc10
-rw-r--r--storage/browser/blob/blob_data_item.h7
-rw-r--r--storage/browser/blob/blob_reader.cc1
-rw-r--r--storage/browser/blob/view_blob_internals_job.cc1
-rw-r--r--storage/common/BUILD.gn5
-rw-r--r--storage/common/blob_storage/blob_item_bytes_request.cc81
-rw-r--r--storage/common/blob_storage/blob_item_bytes_request.h86
-rw-r--r--storage/common/blob_storage/blob_item_bytes_response.cc39
-rw-r--r--storage/common/blob_storage/blob_item_bytes_response.h58
-rw-r--r--storage/common/blob_storage/blob_storage_constants.h37
-rw-r--r--storage/common/data_element.cc41
-rw-r--r--storage/common/data_element.h28
-rw-r--r--storage/storage_common.gyp5
15 files changed, 521 insertions, 4 deletions
diff --git a/storage/browser/blob/blob_data_builder.cc b/storage/browser/blob/blob_data_builder.cc
index 94fb9e5..2ebfe89 100644
--- a/storage/browser/blob/blob_data_builder.cc
+++ b/storage/browser/blob/blob_data_builder.cc
@@ -4,6 +4,8 @@
#include "storage/browser/blob/blob_data_builder.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/numerics/safe_math.h"
#include "base/time/time.h"
#include "net/disk_cache/disk_cache.h"
#include "storage/browser/blob/shareable_file_reference.h"
@@ -15,6 +17,34 @@ BlobDataBuilder::BlobDataBuilder(const std::string& uuid) : uuid_(uuid) {
BlobDataBuilder::~BlobDataBuilder() {
}
+void BlobDataBuilder::AppendIPCDataElement(const DataElement& ipc_data) {
+ uint64 length = ipc_data.length();
+ switch (ipc_data.type()) {
+ case DataElement::TYPE_BYTES:
+ DCHECK(!ipc_data.offset());
+ AppendData(ipc_data.bytes(), base::checked_cast<size_t, uint64>(length));
+ break;
+ case DataElement::TYPE_FILE:
+ AppendFile(ipc_data.path(), ipc_data.offset(), length,
+ ipc_data.expected_modification_time());
+ break;
+ case DataElement::TYPE_FILE_FILESYSTEM:
+ AppendFileSystemFile(ipc_data.filesystem_url(), ipc_data.offset(), length,
+ ipc_data.expected_modification_time());
+ break;
+ case DataElement::TYPE_BLOB:
+ // This is a temporary item that will be deconstructed later in
+ // BlobStorageContext.
+ AppendBlob(ipc_data.blob_uuid(), ipc_data.offset(), ipc_data.length());
+ break;
+ case DataElement::TYPE_BYTES_DESCRIPTION:
+ case DataElement::TYPE_UNKNOWN:
+ case DataElement::TYPE_DISK_CACHE_ENTRY: // This type can't be sent by IPC.
+ NOTREACHED();
+ break;
+ }
+}
+
void BlobDataBuilder::AppendData(const char* data, size_t length) {
if (!length)
return;
@@ -23,6 +53,46 @@ void BlobDataBuilder::AppendData(const char* data, size_t length) {
items_.push_back(new BlobDataItem(element.Pass()));
}
+size_t BlobDataBuilder::AppendFutureData(size_t length) {
+ CHECK_NE(length, 0u);
+ scoped_ptr<DataElement> element(new DataElement());
+ element->SetToBytesDescription(length);
+ items_.push_back(new BlobDataItem(element.Pass()));
+ return items_.size() - 1;
+}
+
+bool BlobDataBuilder::PopulateFutureData(size_t index,
+ const char* data,
+ size_t offset,
+ size_t length) {
+ DCHECK(data);
+ DataElement* element = items_.at(index)->data_element_ptr();
+
+ // We lazily allocate our data buffer by waiting until the first
+ // PopulateFutureData call.
+ // Why? The reason we have the AppendFutureData method is to create our Blob
+ // record when the Renderer tells us about the blob without actually
+ // allocating the memory yet, as we might not have the quota yet. So we don't
+ // want to allocate the memory until we're actually receiving the data (which
+ // the browser process only does when it has quota).
+ if (element->type() == DataElement::TYPE_BYTES_DESCRIPTION) {
+ element->SetToAllocatedBytes(element->length());
+ // The type of the element is now TYPE_BYTES.
+ }
+ if (element->type() != DataElement::TYPE_BYTES) {
+ DVLOG(1) << "Invalid item type.";
+ return false;
+ }
+ base::CheckedNumeric<size_t> checked_end = offset;
+ checked_end += length;
+ if (!checked_end.IsValid() || checked_end.ValueOrDie() > element->length()) {
+ DVLOG(1) << "Invalid offset or length.";
+ return false;
+ }
+ std::memcpy(element->mutable_bytes() + offset, data, length);
+ return true;
+}
+
void BlobDataBuilder::AppendFile(const base::FilePath& file_path,
uint64_t offset,
uint64_t length,
@@ -54,7 +124,7 @@ void BlobDataBuilder::AppendFileSystemFile(
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time) {
- DCHECK(length > 0);
+ DCHECK_GT(length, 0ul);
scoped_ptr<DataElement> element(new DataElement());
element->SetToFileSystemUrlRange(url, offset, length,
expected_modification_time);
@@ -73,4 +143,23 @@ void BlobDataBuilder::AppendDiskCacheEntry(
disk_cache_stream_index));
}
+void BlobDataBuilder::Clear() {
+ items_.clear();
+ content_disposition_.clear();
+ content_type_.clear();
+ uuid_.clear();
+}
+
+void PrintTo(const BlobDataBuilder& x, std::ostream* os) {
+ DCHECK(os);
+ *os << "<BlobDataBuilder>{uuid: " << x.uuid()
+ << ", content_type: " << x.content_type_
+ << ", content_disposition: " << x.content_disposition_ << ", items: [";
+ for (const auto& item : x.items_) {
+ PrintTo(*item, os);
+ *os << ", ";
+ }
+ *os << "]}";
+}
+
} // namespace storage
diff --git a/storage/browser/blob/blob_data_builder.h b/storage/browser/blob/blob_data_builder.h
index 115d1f4..8627eba 100644
--- a/storage/browser/blob/blob_data_builder.h
+++ b/storage/browser/blob/blob_data_builder.h
@@ -6,6 +6,7 @@
#define STORAGE_BROWSER_BLOB_BLOB_DATA_BUILDER_H_
#include <stdint.h>
+#include <ostream>
#include <string>
#include <vector>
@@ -32,12 +33,38 @@ class STORAGE_EXPORT BlobDataBuilder {
const std::string& uuid() const { return uuid_; }
+ // Validates the data element that was sent over IPC, and copies the data if
+ // it's a 'bytes' element. Data elements of BYTES_DESCRIPTION or
+ // DISK_CACHE_ENTRY types are not valid IPC data element types, and cannot be
+ // given to this method.
+ void AppendIPCDataElement(const DataElement& ipc_data);
+
+ // Copies the given data into the blob.
void AppendData(const std::string& data) {
AppendData(data.c_str(), data.size());
}
+ // Copies the given data into the blob.
void AppendData(const char* data, size_t length);
+ // Adds an item that is flagged for future data population. The memory is not
+ // allocated until the first call to PopulateFutureData. Returns the index of
+ // the item (to be used in PopulateFutureData).
+ // Length cannot be 0.
+ size_t AppendFutureData(size_t length);
+
+ // Populates a part of an item previously allocated with AppendFutureData.
+ // The first call to PopulateFutureData lazily allocates the memory for the
+ // data element.
+ // Returns true if:
+ // * The item was created by using AppendFutureData,
+ // * The offset and length are valid, and
+ // * data is a valid pointer.
+ bool PopulateFutureData(size_t index,
+ const char* data,
+ size_t offset,
+ size_t length);
+
// You must know the length of the file, you cannot use kuint64max to specify
// the whole file. This method creates a ShareableFileReference to the given
// file, which is stored in this builder.
@@ -67,10 +94,15 @@ class STORAGE_EXPORT BlobDataBuilder {
content_disposition_ = content_disposition;
}
+ void Clear();
+
private:
friend class BlobStorageContext;
+ friend class BlobAsyncBuilderHostTest;
friend bool operator==(const BlobDataBuilder& a, const BlobDataBuilder& b);
friend bool operator==(const BlobDataSnapshot& a, const BlobDataBuilder& b);
+ friend STORAGE_EXPORT void PrintTo(const BlobDataBuilder& x,
+ ::std::ostream* os);
std::string uuid_;
std::string content_type_;
@@ -89,7 +121,7 @@ inline bool operator==(const BlobDataBuilder& a, const BlobDataBuilder& b) {
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])
+ if (*(a.items_[i]) != *(b.items_[i]))
return false;
}
return true;
@@ -119,6 +151,7 @@ inline bool operator!=(const BlobDataSnapshot& a, const BlobDataBuilder& b) {
inline bool operator!=(const BlobDataBuilder& a, const BlobDataBuilder& b) {
return !(a == b);
}
+
#endif // defined(UNIT_TEST)
} // namespace storage
diff --git a/storage/browser/blob/blob_data_item.cc b/storage/browser/blob/blob_data_item.cc
index c1ec3b3..b9ac29b 100644
--- a/storage/browser/blob/blob_data_item.cc
+++ b/storage/browser/blob/blob_data_item.cc
@@ -33,7 +33,15 @@ BlobDataItem::BlobDataItem(scoped_ptr<DataElement> item,
disk_cache_stream_index_(disk_cache_stream_index) {
}
-BlobDataItem::~BlobDataItem() {
+BlobDataItem::~BlobDataItem() {}
+
+void PrintTo(const BlobDataItem& x, ::std::ostream* os) {
+ DCHECK(os);
+ *os << "<BlobDataItem>{item: ";
+ PrintTo(*x.item_, os);
+ *os << ", has_data_handle: " << (x.data_handle_.get() ? "true" : "false")
+ << ", disk_cache_entry_ptr: " << x.disk_cache_entry_
+ << ", disk_cache_stream_index_: " << x.disk_cache_stream_index_ << "}";
}
} // namespace storage
diff --git a/storage/browser/blob/blob_data_item.h b/storage/browser/blob/blob_data_item.h
index 5b25db4..d04a02c85 100644
--- a/storage/browser/blob/blob_data_item.h
+++ b/storage/browser/blob/blob_data_item.h
@@ -5,6 +5,9 @@
#ifndef STORAGE_BROWSER_BLOB_BLOB_DATA_ITEM_H_
#define STORAGE_BROWSER_BLOB_BLOB_DATA_ITEM_H_
+#include <ostream>
+#include <string>
+
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "storage/browser/storage_browser_export.h"
@@ -50,6 +53,7 @@ class STORAGE_EXPORT BlobDataItem : public base::RefCounted<BlobDataItem> {
}
const DataElement& data_element() const { return *item_; }
const DataElement* data_element_ptr() const { return item_.get(); }
+ DataElement* data_element_ptr() { return item_.get(); }
disk_cache::Entry* disk_cache_entry() const { return disk_cache_entry_; }
int disk_cache_stream_index() const { return disk_cache_stream_index_; }
@@ -58,8 +62,9 @@ class STORAGE_EXPORT BlobDataItem : public base::RefCounted<BlobDataItem> {
friend class BlobDataBuilder;
friend class BlobStorageContext;
friend class base::RefCounted<BlobDataItem>;
+ friend STORAGE_EXPORT void PrintTo(const BlobDataItem& x, ::std::ostream* os);
- BlobDataItem(scoped_ptr<DataElement> item);
+ explicit BlobDataItem(scoped_ptr<DataElement> item);
BlobDataItem(scoped_ptr<DataElement> item,
const scoped_refptr<DataHandle>& data_handle);
BlobDataItem(scoped_ptr<DataElement> item,
diff --git a/storage/browser/blob/blob_reader.cc b/storage/browser/blob/blob_reader.cc
index ccb4e55..9c6375d 100644
--- a/storage/browser/blob/blob_reader.cc
+++ b/storage/browser/blob/blob_reader.cc
@@ -539,6 +539,7 @@ scoped_ptr<FileStreamReader> BlobReader::CreateFileStreamReader(
.Pass();
case DataElement::TYPE_BLOB:
case DataElement::TYPE_BYTES:
+ case DataElement::TYPE_BYTES_DESCRIPTION:
case DataElement::TYPE_DISK_CACHE_ENTRY:
case DataElement::TYPE_UNKNOWN:
break;
diff --git a/storage/browser/blob/view_blob_internals_job.cc b/storage/browser/blob/view_blob_internals_job.cc
index 1b5e91e..185338b 100644
--- a/storage/browser/blob/view_blob_internals_job.cc
+++ b/storage/browser/blob/view_blob_internals_job.cc
@@ -223,6 +223,7 @@ void ViewBlobInternalsJob::GenerateHTMLForBlobData(
AddHTMLListItem(kType, "disk cache entry", out);
AddHTMLListItem(kURL, item.disk_cache_entry()->GetKey(), out);
break;
+ case DataElement::TYPE_BYTES_DESCRIPTION:
case DataElement::TYPE_UNKNOWN:
NOTREACHED();
break;
diff --git a/storage/common/BUILD.gn b/storage/common/BUILD.gn
index c6bfd6a..605fd41 100644
--- a/storage/common/BUILD.gn
+++ b/storage/common/BUILD.gn
@@ -6,6 +6,11 @@
component("common") {
output_name = "storage_common"
sources = [
+ "blob_storage/blob_item_bytes_request.cc",
+ "blob_storage/blob_item_bytes_request.h",
+ "blob_storage/blob_item_bytes_response.cc",
+ "blob_storage/blob_item_bytes_response.h",
+ "blob_storage/blob_storage_constants.h",
"data_element.cc",
"data_element.h",
"database/database_connections.cc",
diff --git a/storage/common/blob_storage/blob_item_bytes_request.cc b/storage/common/blob_storage/blob_item_bytes_request.cc
new file mode 100644
index 0000000..13ef484
--- /dev/null
+++ b/storage/common/blob_storage/blob_item_bytes_request.cc
@@ -0,0 +1,81 @@
+// 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.
+
+#include "storage/common/blob_storage/blob_item_bytes_request.h"
+
+namespace storage {
+
+BlobItemBytesRequest BlobItemBytesRequest::CreateIPCRequest(
+ size_t request_number,
+ size_t renderer_item_index,
+ size_t renderer_item_offset,
+ size_t size) {
+ return BlobItemBytesRequest(request_number, IPCBlobItemRequestStrategy::IPC,
+ renderer_item_index, renderer_item_offset, size,
+ kInvalidIndex, kInvalidSize);
+}
+BlobItemBytesRequest BlobItemBytesRequest::CreateSharedMemoryRequest(
+ size_t request_number,
+ size_t renderer_item_index,
+ size_t renderer_item_offset,
+ size_t size,
+ size_t handle_index,
+ uint64_t handle_offset) {
+ return BlobItemBytesRequest(request_number,
+ IPCBlobItemRequestStrategy::SHARED_MEMORY,
+ renderer_item_index, renderer_item_offset, size,
+ handle_index, handle_offset);
+}
+
+BlobItemBytesRequest BlobItemBytesRequest::CreateFileRequest(
+ size_t request_number,
+ size_t renderer_item_index,
+ uint64_t renderer_item_offset,
+ uint64_t size,
+ size_t handle_index,
+ uint64_t handle_offset) {
+ return BlobItemBytesRequest(request_number, IPCBlobItemRequestStrategy::FILE,
+ renderer_item_index, renderer_item_offset, size,
+ handle_index, handle_offset);
+}
+
+BlobItemBytesRequest::BlobItemBytesRequest()
+ : request_number(kInvalidIndex),
+ transport_strategy(IPCBlobItemRequestStrategy::UNKNOWN),
+ renderer_item_index(kInvalidIndex),
+ renderer_item_offset(kInvalidSize),
+ size(kInvalidSize),
+ handle_index(kInvalidIndex),
+ handle_offset(kInvalidSize) {}
+
+BlobItemBytesRequest::BlobItemBytesRequest(
+ size_t request_number,
+ IPCBlobItemRequestStrategy transport_strategy,
+ size_t renderer_item_index,
+ uint64_t renderer_item_offset,
+ uint64_t size,
+ size_t handle_index,
+ uint64_t handle_offset)
+ : request_number(request_number),
+ transport_strategy(transport_strategy),
+ renderer_item_index(renderer_item_index),
+ renderer_item_offset(renderer_item_offset),
+ size(size),
+ handle_index(handle_index),
+ handle_offset(handle_offset) {}
+
+BlobItemBytesRequest::~BlobItemBytesRequest() {}
+
+void PrintTo(const BlobItemBytesRequest& request, std::ostream* os) {
+ *os << "{request_number: " << request.request_number
+ << ", transport_strategy: "
+ << static_cast<int>(request.transport_strategy)
+ << ", renderer_item_index: " << request.renderer_item_index
+ << ", renderer_item_offset: " << request.renderer_item_offset
+ << ", size: " << request.size
+ << ", handle_index: " << request.handle_index
+ << ", handle_offset: " << request.handle_offset << "}";
+}
+
+} // namespace storage
diff --git a/storage/common/blob_storage/blob_item_bytes_request.h b/storage/common/blob_storage/blob_item_bytes_request.h
new file mode 100644
index 0000000..4031309
--- /dev/null
+++ b/storage/common/blob_storage/blob_item_bytes_request.h
@@ -0,0 +1,86 @@
+// 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_COMMON_BLOB_STORAGE_BLOB_ITEM_BYTES_REQUEST_H_
+#define STORAGE_COMMON_BLOB_STORAGE_BLOB_ITEM_BYTES_REQUEST_H_
+
+#include <stdint.h>
+#include <ostream>
+
+#include "base/basictypes.h"
+#include "storage/common/blob_storage/blob_storage_constants.h"
+#include "storage/common/storage_common_export.h"
+
+namespace storage {
+
+// This class is serialized over IPC to request bytes from a blob item.
+struct STORAGE_COMMON_EXPORT BlobItemBytesRequest {
+ // Not using std::numeric_limits<T>::max() because of non-C++11 builds.
+ static const size_t kInvalidIndex = SIZE_MAX;
+ static const uint64_t kInvalidSize = kuint64max;
+
+ static BlobItemBytesRequest CreateIPCRequest(size_t request_number,
+ size_t renderer_item_index,
+ size_t renderer_item_offset,
+ size_t size);
+
+ static BlobItemBytesRequest CreateSharedMemoryRequest(
+ size_t request_number,
+ size_t renderer_item_index,
+ size_t renderer_item_offset,
+ size_t size,
+ size_t handle_index,
+ uint64_t handle_offset);
+
+ static BlobItemBytesRequest CreateFileRequest(size_t request_number,
+ size_t renderer_item_index,
+ uint64_t renderer_item_offset,
+ uint64_t size,
+ size_t handle_index,
+ uint64_t handle_offset);
+
+ BlobItemBytesRequest();
+ BlobItemBytesRequest(size_t request_number,
+ IPCBlobItemRequestStrategy transport_strategy,
+ size_t renderer_item_index,
+ uint64_t renderer_item_offset,
+ uint64_t size,
+ size_t handle_index,
+ uint64_t handle_offset);
+ ~BlobItemBytesRequest();
+
+ // The request number uniquely identifies the memory request. We can't use
+ // the renderer item index or browser item index as there can be multiple
+ // requests for both (as segmentation boundaries can exist in both).
+ size_t request_number;
+ IPCBlobItemRequestStrategy transport_strategy;
+ size_t renderer_item_index;
+ uint64_t renderer_item_offset;
+ uint64_t size;
+ size_t handle_index;
+ uint64_t handle_offset;
+};
+
+STORAGE_COMMON_EXPORT void PrintTo(const BlobItemBytesRequest& request,
+ std::ostream* os);
+
+#if defined(UNIT_TEST)
+STORAGE_COMMON_EXPORT inline bool operator==(const BlobItemBytesRequest& a,
+ const BlobItemBytesRequest& b) {
+ return a.request_number == b.request_number &&
+ a.transport_strategy == b.transport_strategy &&
+ a.renderer_item_index == b.renderer_item_index &&
+ a.renderer_item_offset == b.renderer_item_offset && a.size == b.size &&
+ a.handle_index == b.handle_index && a.handle_offset == b.handle_offset;
+}
+
+STORAGE_COMMON_EXPORT inline bool operator!=(const BlobItemBytesRequest& a,
+ const BlobItemBytesRequest& b) {
+ return !(a == b);
+}
+#endif // defined(UNIT_TEST)
+
+} // namespace storage
+
+#endif // STORAGE_COMMON_BLOB_STORAGE_BLOB_ITEM_BYTES_REQUEST_H_
diff --git a/storage/common/blob_storage/blob_item_bytes_response.cc b/storage/common/blob_storage/blob_item_bytes_response.cc
new file mode 100644
index 0000000..ccb2598
--- /dev/null
+++ b/storage/common/blob_storage/blob_item_bytes_response.cc
@@ -0,0 +1,39 @@
+// 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.
+
+#include "storage/common/blob_storage/blob_item_bytes_response.h"
+
+#include <algorithm>
+#include <string>
+
+#include "base/strings/string_number_conversions.h"
+
+namespace storage {
+
+BlobItemBytesResponse::BlobItemBytesResponse()
+ : request_number(kInvalidIndex) {}
+
+BlobItemBytesResponse::BlobItemBytesResponse(size_t request_number)
+ : request_number(request_number) {}
+
+BlobItemBytesResponse::~BlobItemBytesResponse() {}
+
+void PrintTo(const BlobItemBytesResponse& response, ::std::ostream* os) {
+ const size_t kMaxDataPrintLength = 40;
+ size_t length = std::min(response.inline_data.size(), kMaxDataPrintLength);
+ *os << "{request_number: " << response.request_number
+ << ", inline_data size: " << response.inline_data.size()
+ << ", inline_data: [";
+ if (length == 0) {
+ *os << "<empty>";
+ } else {
+ *os << base::HexEncode(&response.inline_data[0], length);
+ if (length < response.inline_data.size()) {
+ *os << "<...truncated due to length...>";
+ }
+ }
+ *os << "]}";
+}
+
+} // namespace storage
diff --git a/storage/common/blob_storage/blob_item_bytes_response.h b/storage/common/blob_storage/blob_item_bytes_response.h
new file mode 100644
index 0000000..f2aa9c7
--- /dev/null
+++ b/storage/common/blob_storage/blob_item_bytes_response.h
@@ -0,0 +1,58 @@
+// 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_COMMON_BLOB_STORAGE_BLOB_ITEM_BYTES_RESPONSE_H_
+#define STORAGE_COMMON_BLOB_STORAGE_BLOB_ITEM_BYTES_RESPONSE_H_
+
+#include <stdint.h>
+#include <algorithm>
+#include <ostream>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "storage/common/storage_common_export.h"
+
+namespace storage {
+
+// This class is serialized over IPC to send blob item data, or to signal that
+// the memory has been populated.
+struct STORAGE_COMMON_EXPORT BlobItemBytesResponse {
+ // not using std::numeric_limits<T>::max() because of non-C++11 builds.
+ static const size_t kInvalidIndex = SIZE_MAX;
+
+ BlobItemBytesResponse();
+ explicit BlobItemBytesResponse(size_t request_number);
+ ~BlobItemBytesResponse();
+
+ char* allocate_mutable_data(size_t size) {
+ inline_data.resize(size);
+ return &inline_data[0];
+ }
+
+ size_t request_number;
+ std::vector<char> inline_data;
+};
+
+STORAGE_COMMON_EXPORT void PrintTo(const BlobItemBytesResponse& response,
+ std::ostream* os);
+
+#if defined(UNIT_TEST)
+STORAGE_COMMON_EXPORT inline bool operator==(const BlobItemBytesResponse& a,
+ const BlobItemBytesResponse& b) {
+ return a.request_number == b.request_number &&
+ a.inline_data.size() == b.inline_data.size() &&
+ std::equal(a.inline_data.begin(),
+ a.inline_data.begin() + a.inline_data.size(),
+ b.inline_data.begin());
+}
+
+STORAGE_COMMON_EXPORT inline bool operator!=(const BlobItemBytesResponse& a,
+ const BlobItemBytesResponse& b) {
+ return !(a == b);
+}
+#endif // defined(UNIT_TEST)
+
+} // namespace storage
+
+#endif // STORAGE_COMMON_BLOB_STORAGE_BLOB_ITEM_BYTES_RESPONSE_H_
diff --git a/storage/common/blob_storage/blob_storage_constants.h b/storage/common/blob_storage/blob_storage_constants.h
new file mode 100644
index 0000000..ddf97ec
--- /dev/null
+++ b/storage/common/blob_storage/blob_storage_constants.h
@@ -0,0 +1,37 @@
+// 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_COMMON_BLOB_STORAGE_BLOB_STORAGE_CONSTANTS_H_
+#define STORAGE_COMMON_BLOB_STORAGE_BLOB_STORAGE_CONSTANTS_H_
+
+namespace storage {
+
+// TODO(michaeln): use base::SysInfo::AmountOfPhysicalMemoryMB() in some
+// way to come up with a better limit.
+const int64 kBlobStorageMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig.
+const size_t kBlobStorageIPCThresholdBytes = 250 * 1024;
+const size_t kBlobStorageMaxSharedMemoryBytes = 10 * 1024 * 1024;
+const uint64_t kBlobStorageMaxFileSizeBytes = 100 * 1024 * 1024;
+const uint64_t kBlobStorageMinFileSizeBytes = 1 * 1024 * 1024;
+const size_t kBlobStorageMaxBlobMemorySize =
+ kBlobStorageMaxMemoryUsage - kBlobStorageMinFileSizeBytes;
+
+enum class IPCBlobItemRequestStrategy {
+ UNKNOWN = 0,
+ IPC,
+ SHARED_MEMORY,
+ FILE,
+ LAST = FILE
+};
+
+enum class IPCBlobCreationCancelCode {
+ UNKNOWN = 0,
+ OUT_OF_MEMORY,
+ FILE_WRITE_FAILED,
+ LAST = FILE_WRITE_FAILED
+};
+
+} // namespace storage
+
+#endif // STORAGE_COMMON_BLOB_STORAGE_BLOB_STORAGE_CONSTANTS_H_
diff --git a/storage/common/data_element.cc b/storage/common/data_element.cc
index f26058b..c9bbf0e 100644
--- a/storage/common/data_element.cc
+++ b/storage/common/data_element.cc
@@ -4,6 +4,10 @@
#include "storage/common/data_element.h"
+#include <algorithm>
+
+#include "base/strings/string_number_conversions.h"
+
namespace storage {
DataElement::DataElement()
@@ -52,4 +56,41 @@ void DataElement::SetToDiskCacheEntryRange(uint64 offset, uint64 length) {
length_ = length;
}
+void PrintTo(const DataElement& x, std::ostream* os) {
+ const uint64 kMaxDataPrintLength = 40;
+ *os << "<DataElement>{type: ";
+ switch (x.type()) {
+ case DataElement::TYPE_BYTES: {
+ uint64 length = std::min(x.length(), kMaxDataPrintLength);
+ *os << "TYPE_BYTES, data: ["
+ << base::HexEncode(x.bytes(), static_cast<size_t>(length));
+ if (length < x.length()) {
+ *os << "<...truncated due to length...>";
+ }
+ *os << "]";
+ break;
+ }
+ case DataElement::TYPE_FILE:
+ *os << "TYPE_FILE, path: " << x.path().AsUTF8Unsafe()
+ << ", expected_modification_time: " << x.expected_modification_time();
+ break;
+ case DataElement::TYPE_BLOB:
+ *os << "TYPE_BLOB, uuid: " << x.blob_uuid();
+ break;
+ case DataElement::TYPE_FILE_FILESYSTEM:
+ *os << "TYPE_FILE_FILESYSTEM, filesystem_url: " << x.filesystem_url();
+ break;
+ case DataElement::TYPE_DISK_CACHE_ENTRY:
+ *os << "TYPE_DISK_CACHE_ENTRY";
+ break;
+ case DataElement::TYPE_BYTES_DESCRIPTION:
+ *os << "TYPE_BYTES_DESCRIPTION";
+ break;
+ case DataElement::TYPE_UNKNOWN:
+ *os << "TYPE_UNKNOWN";
+ break;
+ }
+ *os << ", length: " << x.length() << ", offset: " << x.offset() << "}";
+}
+
} // namespace storage
diff --git a/storage/common/data_element.h b/storage/common/data_element.h
index 2eeca8e..4cd6863 100644
--- a/storage/common/data_element.h
+++ b/storage/common/data_element.h
@@ -5,6 +5,7 @@
#ifndef STORAGE_COMMON_DATA_ELEMENT_H_
#define STORAGE_COMMON_DATA_ELEMENT_H_
+#include <ostream>
#include <string>
#include <vector>
@@ -24,6 +25,8 @@ class STORAGE_COMMON_EXPORT DataElement {
enum Type {
TYPE_UNKNOWN = -1,
TYPE_BYTES,
+ // Only used with BlobStorageMsg_StartBuildingBlob
+ TYPE_BYTES_DESCRIPTION,
TYPE_FILE,
TYPE_BLOB,
TYPE_FILE_FILESYSTEM,
@@ -44,9 +47,14 @@ class STORAGE_COMMON_EXPORT DataElement {
return expected_modification_time_;
}
+ // For use with SetToAllocatedBytes. Should only be used after calling
+ // SetToAllocatedBytes.
+ char* mutable_bytes() { return &buf_[0]; }
+
// Sets TYPE_BYTES data. This copies the given data into the element.
void SetToBytes(const char* bytes, int bytes_len) {
type_ = TYPE_BYTES;
+ bytes_ = nullptr;
buf_.assign(bytes, bytes + bytes_len);
length_ = buf_.size();
}
@@ -70,6 +78,12 @@ class STORAGE_COMMON_EXPORT DataElement {
length_ = buf_.size();
}
+ void SetToBytesDescription(size_t bytes_len) {
+ type_ = TYPE_BYTES_DESCRIPTION;
+ bytes_ = nullptr;
+ length_ = bytes_len;
+ }
+
// Sets TYPE_BYTES data. This does NOT copy the given data and the caller
// should make sure the data is alive when this element is accessed.
// You cannot use AppendBytes with this method.
@@ -79,6 +93,16 @@ class STORAGE_COMMON_EXPORT DataElement {
length_ = bytes_len;
}
+ // Sets TYPE_BYTES data. This allocates the space for the bytes in the
+ // internal vector but does not populate it with anything. The caller can
+ // then use the bytes() method to access this buffer and populate it.
+ void SetToAllocatedBytes(size_t bytes_len) {
+ type_ = TYPE_BYTES;
+ bytes_ = nullptr;
+ buf_.resize(bytes_len);
+ length_ = bytes_len;
+ }
+
// Sets TYPE_FILE data.
void SetToFilePath(const base::FilePath& path) {
SetToFilePathRange(path, 0, kuint64max, base::Time());
@@ -107,6 +131,8 @@ class STORAGE_COMMON_EXPORT DataElement {
void SetToDiskCacheEntryRange(uint64 offset, uint64 length);
private:
+ friend STORAGE_COMMON_EXPORT void PrintTo(const DataElement& x,
+ ::std::ostream* os);
Type type_;
std::vector<char> buf_; // For TYPE_BYTES.
const char* bytes_; // For TYPE_BYTES.
@@ -138,6 +164,8 @@ inline bool operator==(const DataElement& a, const DataElement& b) {
// We compare only length and offset; we trust the entry itself was
// compared at some higher level such as in BlobDataItem.
return true;
+ case DataElement::TYPE_BYTES_DESCRIPTION:
+ return true;
case DataElement::TYPE_UNKNOWN:
NOTREACHED();
return false;
diff --git a/storage/storage_common.gyp b/storage/storage_common.gyp
index 74b9139..305a612 100644
--- a/storage/storage_common.gyp
+++ b/storage/storage_common.gyp
@@ -20,6 +20,11 @@
],
'defines': ['STORAGE_COMMON_IMPLEMENTATION'],
'sources': [
+ 'common/blob_storage/blob_item_bytes_request.cc',
+ 'common/blob_storage/blob_item_bytes_request.h',
+ 'common/blob_storage/blob_item_bytes_response.cc',
+ 'common/blob_storage/blob_item_bytes_response.h',
+ 'common/blob_storage/blob_storage_constants.h',
'common/data_element.cc',
'common/data_element.h',
'common/database/database_connections.cc',