OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "storage/browser/blob/blob_flattener.h" | |
6 | |
7 #include <limits> | |
8 #include <set> | |
9 #include <utility> | |
10 | |
11 #include "storage/browser/blob/blob_async_transport_request_builder.h" | |
12 #include "storage/browser/blob/blob_data_builder.h" | |
13 #include "storage/browser/blob/blob_slice.h" | |
14 #include "storage/browser/blob/blob_storage_context.h" | |
15 #include "storage/browser/blob/blob_storage_registry.h" | |
16 #include "storage/browser/blob/shareable_blob_data_item.h" | |
17 | |
18 namespace storage { | |
19 namespace { | |
20 using ItemCopyEntry = BlobStorageRegistry::ItemCopyEntry; | |
21 using BlobEntry = BlobStorageRegistry::Entry; | |
22 | |
23 bool IsBytes(DataElement::Type type) { | |
24 return type == DataElement::TYPE_BYTES || | |
25 type == DataElement::TYPE_BYTES_DESCRIPTION; | |
26 } | |
27 | |
28 } // namespace | |
29 | |
30 // static | |
31 BlobFlattener::BlobFlattener(const BlobDataBuilder& transportation_result, | |
32 InternalBlobData* output_blob, | |
33 BlobStorageRegistry* registry) { | |
34 const std::vector<scoped_refptr<BlobDataItem>>& transport_items = | |
35 transportation_result.items_; | |
36 const std::string& uuid = transportation_result.uuid_; | |
37 | |
38 std::set<std::string> dependent_blob_uuids; | |
39 for (scoped_refptr<BlobDataItem> transport_item : transport_items) { | |
40 DataElement::Type type = transport_item->type(); | |
41 contains_pending_content |= type == DataElement::TYPE_BYTES_DESCRIPTION; | |
42 | |
43 if (IsBytes(type)) { | |
44 memory_needed += transport_item->length(); | |
45 total_size += transport_item->length(); | |
46 output_blob->AppendSharedBlobItem( | |
47 uuid, new ShareableBlobDataItem(std::move(transport_item))); | |
kinuko
2016/07/17 16:15:46
if we continue here and the following 'else if' ca
dmurph
2016/07/19 02:26:27
Done.
| |
48 } else if (type == DataElement::TYPE_BLOB) { | |
49 BlobEntry* ref_entry = registry->GetEntry(transport_item->blob_uuid()); | |
50 | |
51 if (!ref_entry || BlobStatusIsError(ref_entry->status) || | |
52 transport_item->blob_uuid() == uuid) { | |
53 contains_broken_references = true; | |
54 return; | |
55 } | |
56 | |
57 if (dependent_blob_uuids.find(transport_item->blob_uuid()) == | |
58 dependent_blob_uuids.end()) { | |
59 dependent_blobs.push_back( | |
60 std::make_pair(transport_item->blob_uuid(), ref_entry)); | |
61 dependent_blob_uuids.insert(transport_item->blob_uuid()); | |
62 } | |
63 | |
64 uint64_t length = transport_item->length() == DataElement::kUnknownSize | |
65 ? ref_entry->data.total_size() | |
66 : transport_item->length(); | |
67 total_size += length; | |
68 | |
69 // If we're referencing the whole blob, then we don't need to slice. | |
70 if (transport_item->offset() == 0 && | |
71 length == ref_entry->data.total_size()) { | |
72 for (const auto& shareable_item : ref_entry->data.items()) { | |
73 output_blob->AppendSharedBlobItem(uuid, shareable_item); | |
74 } | |
75 continue; | |
76 } | |
77 | |
78 // Validate our reference has good offset & length. | |
79 if (transport_item->offset() + transport_item->length() > | |
80 ref_entry->data.total_size()) { | |
81 contains_invalid_references = true; | |
82 return; | |
83 } | |
84 | |
85 BlobSlice slice(ref_entry->data, transport_item->offset(), | |
86 transport_item->length()); | |
87 | |
88 if (slice.first_source_item) { | |
89 copies.push_back(ItemCopyEntry(slice.first_source_item, | |
90 slice.first_item_slice_offset, | |
91 slice.dest_items.front())); | |
92 } | |
93 if (slice.last_source_item) { | |
94 copies.push_back( | |
95 ItemCopyEntry(slice.last_source_item, 0, slice.dest_items.back())); | |
96 } | |
97 | |
98 memory_needed += slice.copying_memory_size; | |
99 for (auto& shareable_item : slice.dest_items) { | |
100 output_blob->AppendSharedBlobItem(uuid, std::move(shareable_item)); | |
101 } | |
kinuko
2016/07/17 16:15:46
ditto, continue here and move out the following co
dmurph
2016/07/19 02:26:27
Done.
| |
102 } else { | |
103 if (type == DataElement::TYPE_FILE) { | |
104 contains_pending_content |= | |
105 transport_item->path().value() == | |
106 BlobDataBuilder::kAppendFutureFileTemporaryFileName; | |
107 } | |
108 total_size += transport_item->length(); | |
109 output_blob->AppendSharedBlobItem( | |
110 uuid, new ShareableBlobDataItem(std::move(transport_item))); | |
111 } | |
112 } | |
113 } | |
114 | |
115 BlobFlattener::~BlobFlattener() {} | |
116 | |
117 } // namespace storage | |
OLD | NEW |