| // Copyright (c) 2013 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/browser/blob/blob_data_handle.h" |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/task_runner.h" |
| #include "base/time/time.h" |
| #include "storage/browser/blob/blob_data_snapshot.h" |
| #include "storage/browser/blob/blob_reader.h" |
| #include "storage/browser/blob/blob_storage_context.h" |
| #include "storage/browser/fileapi/file_stream_reader.h" |
| #include "storage/browser/fileapi/file_system_context.h" |
| #include "storage/browser/fileapi/file_system_url.h" |
| #include "url/gurl.h" |
| |
| namespace storage { |
| |
| BlobDataHandle::BlobDataHandleShared::BlobDataHandleShared( |
| const std::string& uuid, |
| const std::string& content_type, |
| const std::string& content_disposition, |
| uint64_t size, |
| BlobStorageContext* context) |
| : uuid_(uuid), |
| content_type_(content_type), |
| content_disposition_(content_disposition), |
| size_(size), |
| context_(context->AsWeakPtr()) { |
| context_->IncrementBlobRefCount(uuid); |
| } |
| |
| std::unique_ptr<BlobReader> BlobDataHandle::CreateReader() const { |
| return base::WrapUnique(new BlobReader(this)); |
| } |
| |
| BlobDataHandle::BlobDataHandleShared::~BlobDataHandleShared() { |
| if (context_.get()) |
| context_->DecrementBlobRefCount(uuid_); |
| } |
| |
| BlobDataHandle::BlobDataHandle(const std::string& uuid, |
| const std::string& content_type, |
| const std::string& content_disposition, |
| uint64_t size, |
| BlobStorageContext* context, |
| base::SequencedTaskRunner* io_task_runner) |
| : io_task_runner_(io_task_runner), |
| shared_(new BlobDataHandleShared(uuid, |
| content_type, |
| content_disposition, |
| size, |
| context)) { |
| DCHECK(io_task_runner_.get()); |
| DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| } |
| |
| BlobDataHandle::BlobDataHandle(const BlobDataHandle& other) = default; |
| |
| BlobDataHandle::~BlobDataHandle() { |
| if (!io_task_runner_->RunsTasksInCurrentSequence()) { |
| BlobDataHandleShared* raw = shared_.get(); |
| raw->AddRef(); |
| shared_ = nullptr; |
| io_task_runner_->ReleaseSoon(FROM_HERE, raw); |
| } |
| } |
| |
| BlobDataHandle& BlobDataHandle::operator=( |
| const BlobDataHandle& other) = default; |
| |
| bool BlobDataHandle::IsBeingBuilt() const { |
| DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| if (!shared_->context_) |
| return false; |
| return BlobStatusIsPending(GetBlobStatus()); |
| } |
| |
| bool BlobDataHandle::IsBroken() const { |
| DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| if (!shared_->context_) |
| return true; |
| return BlobStatusIsError(GetBlobStatus()); |
| } |
| |
| BlobStatus BlobDataHandle::GetBlobStatus() const { |
| DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| if (!shared_->context_) |
| return BlobStatus::ERR_REFERENCED_BLOB_BROKEN; |
| return shared_->context_->GetBlobStatus(shared_->uuid_); |
| } |
| |
| void BlobDataHandle::RunOnConstructionComplete(BlobStatusCallback done) { |
| DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| if (!shared_->context_.get()) { |
| std::move(done).Run(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| return; |
| } |
| shared_->context_->RunOnConstructionComplete(shared_->uuid_, std::move(done)); |
| } |
| |
| void BlobDataHandle::RunOnConstructionBegin(BlobStatusCallback done) { |
| DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| if (!shared_->context_.get()) { |
| std::move(done).Run(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| return; |
| } |
| shared_->context_->RunOnConstructionBegin(shared_->uuid_, std::move(done)); |
| } |
| |
| std::unique_ptr<BlobDataSnapshot> BlobDataHandle::CreateSnapshot() const { |
| DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| if (!shared_->context_.get()) |
| return nullptr; |
| return shared_->context_->CreateSnapshot(shared_->uuid_); |
| } |
| |
| const std::string& BlobDataHandle::uuid() const { |
| return shared_->uuid_; |
| } |
| |
| const std::string& BlobDataHandle::content_type() const { |
| return shared_->content_type_; |
| } |
| |
| const std::string& BlobDataHandle::content_disposition() const { |
| return shared_->content_disposition_; |
| } |
| |
| uint64_t BlobDataHandle::size() const { |
| return shared_->size_; |
| } |
| |
| } // namespace storage |