| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "platform/blob/BlobData.h" | 31 #include "platform/blob/BlobData.h" |
| 32 | 32 |
| 33 #include <memory> | 33 #include <memory> |
| 34 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 35 #include "platform/CrossThreadFunctional.h" |
| 34 #include "platform/UUID.h" | 36 #include "platform/UUID.h" |
| 37 #include "platform/WebTaskRunner.h" |
| 38 #include "platform/blob/BlobBytesProvider.h" |
| 35 #include "platform/blob/BlobRegistry.h" | 39 #include "platform/blob/BlobRegistry.h" |
| 36 #include "platform/text/LineEnding.h" | 40 #include "platform/text/LineEnding.h" |
| 37 #include "platform/wtf/PassRefPtr.h" | 41 #include "platform/wtf/PassRefPtr.h" |
| 38 #include "platform/wtf/PtrUtil.h" | 42 #include "platform/wtf/PtrUtil.h" |
| 39 #include "platform/wtf/RefPtr.h" | 43 #include "platform/wtf/RefPtr.h" |
| 44 #include "platform/wtf/Time.h" |
| 40 #include "platform/wtf/Vector.h" | 45 #include "platform/wtf/Vector.h" |
| 41 #include "platform/wtf/text/CString.h" | 46 #include "platform/wtf/text/CString.h" |
| 42 #include "platform/wtf/text/TextEncoding.h" | 47 #include "platform/wtf/text/TextEncoding.h" |
| 48 #include "public/platform/InterfaceProvider.h" |
| 49 #include "public/platform/Platform.h" |
| 43 | 50 |
| 44 namespace blink { | 51 namespace blink { |
| 45 | 52 |
| 46 namespace { | 53 namespace { |
| 47 | 54 |
| 48 // All consecutive items that are accumulate to < this number will have the | 55 // All consecutive items that are accumulate to < this number will have the |
| 49 // data appended to the same item. | 56 // data appended to the same item. |
| 50 static const size_t kMaxConsolidatedItemSizeInBytes = 15 * 1024; | 57 static const size_t kMaxConsolidatedItemSizeInBytes = 15 * 1024; |
| 51 | 58 |
| 52 // http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob | 59 // http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob |
| 53 bool IsValidBlobType(const String& type) { | 60 bool IsValidBlobType(const String& type) { |
| 54 for (unsigned i = 0; i < type.length(); ++i) { | 61 for (unsigned i = 0; i < type.length(); ++i) { |
| 55 UChar c = type[i]; | 62 UChar c = type[i]; |
| 56 if (c < 0x20 || c > 0x7E) | 63 if (c < 0x20 || c > 0x7E) |
| 57 return false; | 64 return false; |
| 58 } | 65 } |
| 59 return true; | 66 return true; |
| 60 } | 67 } |
| 61 | 68 |
| 69 Time TimeFromDouble(double dt) { |
| 70 if (dt == 0 || std::isnan(dt)) |
| 71 return Time(); |
| 72 return Time::FromSeconds(base::Time::kTimeTToMicrosecondsOffset / 1000000 + |
| 73 dt); |
| 74 } |
| 75 |
| 76 void BindBytesProvider(std::unique_ptr<BlobBytesProvider> provider, |
| 77 storage::mojom::blink::BytesProviderRequest request) { |
| 78 mojo::MakeStrongBinding(std::move(provider), std::move(request)); |
| 79 } |
| 80 |
| 62 } // namespace | 81 } // namespace |
| 63 | 82 |
| 64 const long long BlobDataItem::kToEndOfFile = -1; | 83 const long long BlobDataItem::kToEndOfFile = -1; |
| 65 | 84 |
| 66 RawData::RawData() {} | 85 RawData::RawData() {} |
| 67 | 86 |
| 68 void RawData::DetachFromCurrentThread() {} | 87 void RawData::DetachFromCurrentThread() {} |
| 69 | 88 |
| 70 void BlobDataItem::DetachFromCurrentThread() { | 89 void BlobDataItem::DetachFromCurrentThread() { |
| 71 data->DetachFromCurrentThread(); | 90 data->DetachFromCurrentThread(); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 return false; | 254 return false; |
| 236 if (last_item.data->length() + length > kMaxConsolidatedItemSizeInBytes) | 255 if (last_item.data->length() + length > kMaxConsolidatedItemSizeInBytes) |
| 237 return false; | 256 return false; |
| 238 return true; | 257 return true; |
| 239 } | 258 } |
| 240 | 259 |
| 241 BlobDataHandle::BlobDataHandle() | 260 BlobDataHandle::BlobDataHandle() |
| 242 : uuid_(CreateCanonicalUUIDString()), | 261 : uuid_(CreateCanonicalUUIDString()), |
| 243 size_(0), | 262 size_(0), |
| 244 is_single_unknown_size_file_(false) { | 263 is_single_unknown_size_file_(false) { |
| 245 BlobRegistry::RegisterBlobData(uuid_, BlobData::Create()); | 264 // BlobRegistry::RegisterBlobData(uuid_, BlobData::Create()); |
| 265 |
| 266 storage::mojom::blink::BlobRegistryPtr registry; |
| 267 Platform::Current()->GetInterfaceProvider()->GetInterface( |
| 268 MakeRequest(®istry)); |
| 269 registry->Register(MakeRequest(&blob_), uuid_, "", "", {}); |
| 246 } | 270 } |
| 247 | 271 |
| 248 BlobDataHandle::BlobDataHandle(std::unique_ptr<BlobData> data, long long size) | 272 BlobDataHandle::BlobDataHandle(std::unique_ptr<BlobData> data, long long size) |
| 249 : uuid_(CreateCanonicalUUIDString()), | 273 : uuid_(CreateCanonicalUUIDString()), |
| 250 type_(data->ContentType().IsolatedCopy()), | 274 type_(data->ContentType().IsolatedCopy()), |
| 251 size_(size), | 275 size_(size), |
| 252 is_single_unknown_size_file_(data->IsSingleUnknownSizeFile()) { | 276 is_single_unknown_size_file_(data->IsSingleUnknownSizeFile()) { |
| 253 BlobRegistry::RegisterBlobData(uuid_, std::move(data)); | 277 storage::mojom::blink::BlobRegistryPtr registry; |
| 278 // TODO(mek): Getting interface relies on main thread to make progress, even |
| 279 // in workers. |
| 280 Platform::Current()->GetInterfaceProvider()->GetInterface( |
| 281 MakeRequest(®istry)); |
| 282 |
| 283 base::SingleThreadTaskRunner* io_runner = BlobRegistry::GetIORunner(); |
| 284 // TODO(mek): Get max data population from somewhere. |
| 285 size_t max_data_population = 5; // 250 * 1024; |
| 286 Vector<storage::mojom::blink::DataElementPtr> elements; |
| 287 size_t current_memory_population = 0; |
| 288 BlobBytesProvider* last_bytes_provider = nullptr; |
| 289 storage::mojom::blink::DataElementPtr nullElement = nullptr; |
| 290 for (const auto& item : data->Items()) { |
| 291 switch (item.type) { |
| 292 case BlobDataItem::kData: |
| 293 if (item.data->length() != 0) { |
| 294 const storage::mojom::blink::DataElementPtr& lastElement = |
| 295 elements.IsEmpty() ? nullElement : elements.back(); |
| 296 if (current_memory_population + item.data->length() <= |
| 297 max_data_population) { |
| 298 if (lastElement && lastElement->is_bytes()) { |
| 299 lastElement->get_bytes().Append(item.data->data(), |
| 300 item.data->length()); |
| 301 } else { |
| 302 Vector<uint8_t> bytes; |
| 303 bytes.Append(item.data->data(), item.data->length()); |
| 304 elements.push_back( |
| 305 storage::mojom::blink::DataElement::NewBytes(bytes)); |
| 306 } |
| 307 } else { |
| 308 if (lastElement && lastElement->is_large_bytes() && |
| 309 last_bytes_provider) { |
| 310 lastElement->get_large_bytes()->length += item.data->length(); |
| 311 last_bytes_provider->AppendData(item.data); |
| 312 } else { |
| 313 storage::mojom::blink::BytesProviderPtr ptr; |
| 314 if (io_runner) { |
| 315 auto provider = WTF::MakeUnique<BlobBytesProvider>(item.data); |
| 316 last_bytes_provider = provider.get(); |
| 317 io_runner->PostTask( |
| 318 FROM_HERE, |
| 319 base::Bind(&BindBytesProvider, |
| 320 base::Passed(std::move(provider)), |
| 321 base::Passed(mojo::MakeRequest(&ptr)))); |
| 322 last_bytes_provider->uuid = uuid_.IsolatedCopy(); |
| 323 } else |
| 324 mojo::MakeRequest(&ptr); |
| 325 elements.push_back( |
| 326 storage::mojom::blink::DataElement::NewLargeBytes( |
| 327 storage::mojom::blink::DataElementBytes::New( |
| 328 item.data->length(), std::move(ptr)))); |
| 329 } |
| 330 } |
| 331 } |
| 332 break; |
| 333 case BlobDataItem::kFile: |
| 334 if (item.length != 0) |
| 335 elements.push_back(storage::mojom::blink::DataElement::NewFile( |
| 336 storage::mojom::blink::DataElementFile::New( |
| 337 item.path.IsNull() ? "" : item.path, item.offset, item.length, |
| 338 TimeFromDouble(item.expected_modification_time)))); |
| 339 break; |
| 340 case BlobDataItem::kBlob: |
| 341 if (item.length != 0) { |
| 342 storage::mojom::blink::BlobPtr blob; |
| 343 item.blob_data_handle->blob_->Clone(MakeRequest(&blob)); |
| 344 elements.push_back(storage::mojom::blink::DataElement::NewBlob( |
| 345 storage::mojom::blink::DataElementBlob::New( |
| 346 std::move(blob), item.offset, item.length))); |
| 347 } |
| 348 break; |
| 349 case BlobDataItem::kFileSystemURL: |
| 350 if (item.length != 0) |
| 351 elements.push_back( |
| 352 storage::mojom::blink::DataElement::NewFileFilesystem( |
| 353 storage::mojom::blink::DataElementFilesystemURL::New( |
| 354 item.file_system_url, item.offset, item.length, |
| 355 TimeFromDouble(item.expected_modification_time)))); |
| 356 break; |
| 357 } |
| 358 } |
| 359 registry->Register(MakeRequest(&blob_), uuid_, type_.IsNull() ? "" : type_, |
| 360 "", std::move(elements)); |
| 361 // BlobRegistry::RegisterBlobData(uuid_, std::move(data)); |
| 254 } | 362 } |
| 255 | 363 |
| 256 BlobDataHandle::BlobDataHandle(const String& uuid, | 364 BlobDataHandle::BlobDataHandle(const String& uuid, |
| 257 const String& type, | 365 const String& type, |
| 258 long long size) | 366 long long size) |
| 259 : uuid_(uuid.IsolatedCopy()), | 367 : uuid_(uuid.IsolatedCopy()), |
| 260 type_(IsValidBlobType(type) ? type.IsolatedCopy() : ""), | 368 type_(IsValidBlobType(type) ? type.IsolatedCopy() : ""), |
| 261 size_(size), | 369 size_(size), |
| 262 is_single_unknown_size_file_(false) { | 370 is_single_unknown_size_file_(false) { |
| 263 BlobRegistry::AddBlobDataRef(uuid_); | 371 // BlobRegistry::AddBlobDataRef(uuid_); |
| 372 |
| 373 storage::mojom::blink::BlobRegistryPtr registry; |
| 374 Platform::Current()->GetInterfaceProvider()->GetInterface( |
| 375 MakeRequest(®istry)); |
| 376 registry->DeprecatedGetBlob(uuid_, MakeRequest(&blob_)); |
| 264 } | 377 } |
| 265 | 378 |
| 266 BlobDataHandle::~BlobDataHandle() { | 379 BlobDataHandle::~BlobDataHandle() { |
| 267 BlobRegistry::RemoveBlobDataRef(uuid_); | 380 // BlobRegistry::RemoveBlobDataRef(uuid_); |
| 268 } | 381 } |
| 269 | 382 |
| 270 } // namespace blink | 383 } // namespace blink |
| OLD | NEW |