OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/blob/blob_storage_controller.h" | 5 #include "webkit/blob/blob_storage_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "googleurl/src/gurl.h" | 8 #include "googleurl/src/gurl.h" |
| 9 #include "net/base/upload_data.h" |
9 #include "webkit/blob/blob_data.h" | 10 #include "webkit/blob/blob_data.h" |
10 | 11 |
11 namespace webkit_blob { | 12 namespace webkit_blob { |
12 | 13 |
13 BlobStorageController::BlobStorageController() { | 14 BlobStorageController::BlobStorageController() { |
14 } | 15 } |
15 | 16 |
16 BlobStorageController::~BlobStorageController() { | 17 BlobStorageController::~BlobStorageController() { |
17 } | 18 } |
18 | 19 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 // 1) The Data item is denoted by the raw data and the range. | 64 // 1) The Data item is denoted by the raw data and the range. |
64 // 2) The File item is denoted by the file path, the range and the expected | 65 // 2) The File item is denoted by the file path, the range and the expected |
65 // modification time. | 66 // modification time. |
66 // All the Blob items in the passing blob data are resolved and expanded into | 67 // All the Blob items in the passing blob data are resolved and expanded into |
67 // a set of Data and File items. | 68 // a set of Data and File items. |
68 | 69 |
69 for (std::vector<BlobData::Item>::const_iterator iter = | 70 for (std::vector<BlobData::Item>::const_iterator iter = |
70 blob_data->items().begin(); | 71 blob_data->items().begin(); |
71 iter != blob_data->items().end(); ++iter) { | 72 iter != blob_data->items().end(); ++iter) { |
72 switch (iter->type()) { | 73 switch (iter->type()) { |
73 case BlobData::TYPE_DATA: | 74 case BlobData::TYPE_DATA: { |
| 75 // WebBlobData does not allow partial data. |
| 76 DCHECK(!(iter->offset()) && iter->length() == iter->data().size()); |
74 target_blob_data->AppendData(iter->data()); | 77 target_blob_data->AppendData(iter->data()); |
75 break; | 78 break; |
| 79 } |
76 case BlobData::TYPE_FILE: | 80 case BlobData::TYPE_FILE: |
77 target_blob_data->AppendFile(iter->file_path(), | 81 target_blob_data->AppendFile(iter->file_path(), |
78 iter->offset(), | 82 iter->offset(), |
79 iter->length(), | 83 iter->length(), |
80 iter->expected_modification_time()); | 84 iter->expected_modification_time()); |
81 break; | 85 break; |
82 case BlobData::TYPE_BLOB: { | 86 case BlobData::TYPE_BLOB: { |
83 scoped_refptr<BlobData> src_blob_data = | 87 BlobData* src_blob_data = GetBlobDataFromUrl(iter->blob_url()); |
84 blob_map_[iter->blob_url().spec()]; | 88 DCHECK(src_blob_data); |
85 DCHECK(src_blob_data.get()); | 89 if (src_blob_data) |
86 if (src_blob_data.get()) | |
87 AppendStorageItems(target_blob_data.get(), | 90 AppendStorageItems(target_blob_data.get(), |
88 src_blob_data.get(), | 91 src_blob_data, |
89 iter->offset(), | 92 iter->offset(), |
90 iter->length()); | 93 iter->length()); |
91 break; | 94 break; |
92 } | 95 } |
93 } | 96 } |
94 } | 97 } |
95 | 98 |
96 blob_map_[url.spec()] = target_blob_data; | 99 blob_map_[url.spec()] = target_blob_data; |
97 } | 100 } |
98 | 101 |
99 void BlobStorageController::RegisterBlobUrlFrom( | 102 void BlobStorageController::RegisterBlobUrlFrom( |
100 const GURL& url, const GURL& src_url) { | 103 const GURL& url, const GURL& src_url) { |
101 BlobData* blob_data = GetBlobDataFromUrl(src_url); | 104 BlobData* blob_data = GetBlobDataFromUrl(src_url); |
| 105 DCHECK(blob_data); |
102 if (!blob_data) | 106 if (!blob_data) |
103 return; | 107 return; |
104 | 108 |
105 blob_map_[url.spec()] = blob_data; | 109 blob_map_[url.spec()] = blob_data; |
106 } | 110 } |
107 | 111 |
108 void BlobStorageController::UnregisterBlobUrl(const GURL& url) { | 112 void BlobStorageController::UnregisterBlobUrl(const GURL& url) { |
109 blob_map_.erase(url.spec()); | 113 blob_map_.erase(url.spec()); |
110 } | 114 } |
111 | 115 |
112 BlobData* BlobStorageController::GetBlobDataFromUrl(const GURL& url) { | 116 BlobData* BlobStorageController::GetBlobDataFromUrl(const GURL& url) { |
113 return (blob_map_.find(url.spec()) == blob_map_.end()) ? | 117 BlobMap::iterator found = blob_map_.find(url.spec()); |
114 NULL : blob_map_[url.spec()].get(); | 118 return (found != blob_map_.end()) ? found->second : NULL; |
| 119 } |
| 120 |
| 121 void BlobStorageController::ResolveBlobReferencesInUploadData( |
| 122 net::UploadData* upload_data) { |
| 123 DCHECK(upload_data); |
| 124 |
| 125 std::vector<net::UploadData::Element>* uploads = upload_data->elements(); |
| 126 std::vector<net::UploadData::Element>::iterator iter; |
| 127 for (iter = uploads->begin(); iter != uploads->end();) { |
| 128 if (iter->type() != net::UploadData::TYPE_BLOB) { |
| 129 iter++; |
| 130 continue; |
| 131 } |
| 132 |
| 133 // Find the referred blob data. |
| 134 webkit_blob::BlobData* blob_data = GetBlobDataFromUrl(iter->blob_url()); |
| 135 DCHECK(blob_data); |
| 136 if (!blob_data) { |
| 137 // TODO(jianli): We should probably fail uploading the data |
| 138 iter++; |
| 139 continue; |
| 140 } |
| 141 |
| 142 // Remove this element. |
| 143 iter = uploads->erase(iter); |
| 144 |
| 145 // If there is no element in the referred blob data, continue the loop. |
| 146 // Note that we should not increase iter since it already points to the one |
| 147 // after the removed element. |
| 148 if (blob_data->items().empty()) |
| 149 continue; |
| 150 |
| 151 // Insert the elements in the referred blob data. |
| 152 // Note that we traverse from the bottom so that the elements can be |
| 153 // inserted in the original order. |
| 154 for (size_t i = blob_data->items().size(); i > 0; --i) { |
| 155 iter = uploads->insert(iter, net::UploadData::Element()); |
| 156 |
| 157 const webkit_blob::BlobData::Item& item = blob_data->items().at(i - 1); |
| 158 switch (item.type()) { |
| 159 case webkit_blob::BlobData::TYPE_DATA: |
| 160 // TODO(jianli): Figure out how to avoid copying the data. |
| 161 iter->SetToBytes( |
| 162 &item.data().at(0) + static_cast<int>(item.offset()), |
| 163 static_cast<int>(item.length())); |
| 164 break; |
| 165 case webkit_blob::BlobData::TYPE_FILE: |
| 166 // TODO(michaeln): Ensure that any temp files survive till the |
| 167 // URLRequest is done with the upload. |
| 168 iter->SetToFilePathRange( |
| 169 item.file_path(), |
| 170 item.offset(), |
| 171 item.length(), |
| 172 item.expected_modification_time()); |
| 173 break; |
| 174 default: |
| 175 NOTREACHED(); |
| 176 break; |
| 177 } |
| 178 } |
| 179 } |
115 } | 180 } |
116 | 181 |
117 } // namespace webkit_blob | 182 } // namespace webkit_blob |
OLD | NEW |