blob: 2dc1699de718d87024bd236b31219eb8fe6b5f44 [file] [log] [blame]
// 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/file_system/file_stream_reader.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/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()) {
io_task_runner_->ReleaseSoon(FROM_HERE, std::move(shared_));
}
}
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