Skip to content

Commit

Permalink
[BlobAsync] Patch 2: Common Constants
Browse files Browse the repository at this point in the history
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}
  • Loading branch information
dmurph authored and Commit bot committed Oct 31, 2015
1 parent 3d5527d commit 0140342
Show file tree
Hide file tree
Showing 17 changed files with 533 additions and 4 deletions.
1 change: 1 addition & 0 deletions content/browser/loader/upload_data_stream_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ scoped_ptr<net::UploadDataStream> UploadDataStreamBuilder::Build(
break;
}
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
case ResourceRequestBody::Element::TYPE_UNKNOWN:
NOTREACHED();
break;
Expand Down
11 changes: 11 additions & 0 deletions content/common/resource_messages.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ void ParamTraits<storage::DataElement>::Write(Message* m, const param_type& p) {
m->WriteData(p.bytes(), static_cast<int>(p.length()));
break;
}
case storage::DataElement::TYPE_BYTES_DESCRIPTION: {
WriteParam(m, p.length());
break;
}
case storage::DataElement::TYPE_FILE: {
WriteParam(m, p.path());
WriteParam(m, p.offset());
Expand Down Expand Up @@ -88,6 +92,13 @@ bool ParamTraits<storage::DataElement>::Read(const Message* m,
r->SetToBytes(data, len);
break;
}
case storage::DataElement::TYPE_BYTES_DESCRIPTION: {
uint64 length;
if (!ReadParam(m, iter, &length))
return false;
r->SetToBytesDescription(length);
break;
}
case storage::DataElement::TYPE_FILE: {
base::FilePath file_path;
uint64 offset, length;
Expand Down
91 changes: 90 additions & 1 deletion storage/browser/blob/blob_data_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand All @@ -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
35 changes: 34 additions & 1 deletion storage/browser/blob/blob_data_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define STORAGE_BROWSER_BLOB_BLOB_DATA_BUILDER_H_

#include <stdint.h>
#include <ostream>
#include <string>
#include <vector>

Expand All @@ -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.
Expand Down Expand Up @@ -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_;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion storage/browser/blob/blob_data_item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 6 additions & 1 deletion storage/browser/blob/blob_data_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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_; }
Expand All @@ -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,
Expand Down
1 change: 1 addition & 0 deletions storage/browser/blob/blob_reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions storage/browser/blob/view_blob_internals_job.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions storage/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
81 changes: 81 additions & 0 deletions storage/common/blob_storage/blob_item_bytes_request.cc
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 0140342

Please sign in to comment.