blob: 3e864fa1cdf9bcdb0caba7096522b16a0c32193d [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 "base/bind.h"
#include "base/location.h"
#include "base/logging.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 {
namespace {
class FileStreamReaderProviderImpl
: public BlobReader::FileStreamReaderProvider {
public:
FileStreamReaderProviderImpl(FileSystemContext* file_system_context)
: file_system_context_(file_system_context) {}
~FileStreamReaderProviderImpl() override {}
scoped_ptr<FileStreamReader> CreateForLocalFile(
base::TaskRunner* task_runner,
const base::FilePath& file_path,
int64_t initial_offset,
const base::Time& expected_modification_time) override {
return make_scoped_ptr(FileStreamReader::CreateForLocalFile(
task_runner, file_path, initial_offset, expected_modification_time));
}
scoped_ptr<FileStreamReader> CreateFileStreamReader(
const GURL& filesystem_url,
int64_t offset,
int64_t max_bytes_to_read,
const base::Time& expected_modification_time) override {
return file_system_context_->CreateFileStreamReader(
storage::FileSystemURL(
file_system_context_->CrackURL(
filesystem_url)),
offset, max_bytes_to_read,
expected_modification_time)
.Pass();
}
private:
scoped_refptr<FileSystemContext> file_system_context_;
DISALLOW_COPY_AND_ASSIGN(FileStreamReaderProviderImpl);
};
} // namespace
BlobDataHandle::BlobDataHandleShared::BlobDataHandleShared(
const std::string& uuid,
const std::string& content_type,
const std::string& content_disposition,
BlobStorageContext* context)
: uuid_(uuid),
content_type_(content_type),
content_disposition_(content_disposition),
context_(context->AsWeakPtr()) {
context_->IncrementBlobRefCount(uuid);
}
scoped_ptr<BlobReader> BlobDataHandle::CreateReader(
FileSystemContext* file_system_context,
base::SequencedTaskRunner* file_task_runner) const {
return scoped_ptr<BlobReader>(new BlobReader(
this, scoped_ptr<BlobReader::FileStreamReaderProvider>(
new FileStreamReaderProviderImpl(file_system_context)),
file_task_runner));
}
scoped_ptr<BlobDataSnapshot>
BlobDataHandle::BlobDataHandleShared::CreateSnapshot() const {
return context_->CreateSnapshot(uuid_).Pass();
}
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,
BlobStorageContext* context,
base::SequencedTaskRunner* io_task_runner)
: io_task_runner_(io_task_runner),
shared_(new BlobDataHandleShared(uuid,
content_type,
content_disposition,
context)) {
DCHECK(io_task_runner_.get());
DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
}
BlobDataHandle::BlobDataHandle(const BlobDataHandle& other) {
io_task_runner_ = other.io_task_runner_;
shared_ = other.shared_;
}
BlobDataHandle::~BlobDataHandle() {
BlobDataHandleShared* raw = shared_.get();
raw->AddRef();
shared_ = nullptr;
io_task_runner_->ReleaseSoon(FROM_HERE, raw);
}
scoped_ptr<BlobDataSnapshot> BlobDataHandle::CreateSnapshot() const {
DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
return shared_->CreateSnapshot().Pass();
}
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_;
}
} // namespace storage