1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef STORAGE_BROWSER_BLOB_BLOB_DATA_ITEM_H_
#define STORAGE_BROWSER_BLOB_BLOB_DATA_ITEM_H_
#include <stdint.h>
#include <memory>
#include <ostream>
#include <string>
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "components/file_access/scoped_file_access.h"
#include "components/file_access/scoped_file_access_delegate.h"
#include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
#include "net/base/io_buffer.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/file_system/file_system_url.h"
namespace storage {
class BlobDataBuilder;
class BlobStorageContext;
class FileSystemContext;
// Ref counted blob item. This class owns the backing data of the blob item. The
// backing data is immutable, and cannot change after creation. The purpose of
// this class is to allow the resource to stick around in the snapshot even
// after the resource was swapped in the blob (either to disk or to memory) by
// the BlobStorageContext.
class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataItem
: public base::RefCounted<BlobDataItem> {
public:
enum class Type {
kBytes,
kBytesDescription,
kFile,
kFileFilesystem,
kReadableDataHandle,
};
// The DataHandle class is used to persist an interface and resources for
// reading this BlobDataItem. This object will stay around while any reads are
// pending. If all blobs with this item are deleted or the item is swapped for
// a different backend version (mem-to-disk or the reverse), then the item
// will be destructed after all pending reads are complete.
class COMPONENT_EXPORT(STORAGE_BROWSER) DataHandle
: public base::RefCounted<DataHandle> {
public:
// Returns the size of the main blob data.
virtual uint64_t GetSize() const = 0;
// Reads the given data range into the given |producer|.
// Returns the net::Error from the read operation to the callback.
virtual void Read(mojo::ScopedDataPipeProducerHandle producer,
uint64_t src_offset,
uint64_t bytes_to_read,
base::OnceCallback<void(int)> callback) = 0;
// Returns the side data size. If there is no side data, then 0 should
// be returned.
virtual uint64_t GetSideDataSize() const = 0;
// Returns the entire side data as a BigBuffer and the net::Error from
// reading. The number of bytes read is the size of the BigBuffer.
virtual void ReadSideData(
base::OnceCallback<void(int, mojo_base::BigBuffer)> callback) = 0;
// Print a description of the readable DataHandle for debugging.
virtual void PrintTo(::std::ostream* os) const = 0;
protected:
virtual ~DataHandle();
private:
friend class base::RefCounted<DataHandle>;
};
static scoped_refptr<BlobDataItem> CreateBytes(
base::span<const uint8_t> bytes);
static scoped_refptr<BlobDataItem> CreateBytesDescription(size_t length);
static scoped_refptr<BlobDataItem> CreateFile(
base::FilePath path,
uint64_t offset,
uint64_t length,
base::Time expected_modification_time = base::Time(),
scoped_refptr<ShareableFileReference> file_ref = nullptr,
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
file_access = base::NullCallback());
static scoped_refptr<BlobDataItem> CreateFutureFile(uint64_t offset,
uint64_t length,
uint64_t file_id);
static scoped_refptr<BlobDataItem> CreateFileFilesystem(
const FileSystemURL& url,
uint64_t offset,
uint64_t length,
base::Time expected_modification_time,
scoped_refptr<FileSystemContext> file_system_context,
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
file_access = base::NullCallback());
static scoped_refptr<BlobDataItem> CreateReadableDataHandle(
scoped_refptr<DataHandle> data_handle,
uint64_t offset,
uint64_t length);
static scoped_refptr<BlobDataItem> CreateMojoDataItem(
mojom::BlobDataItemPtr item);
Type type() const { return type_; }
uint64_t offset() const { return offset_; }
uint64_t length() const { return length_; }
base::span<const uint8_t> bytes() const {
DCHECK_EQ(type_, Type::kBytes);
return base::span(bytes_);
}
const base::FilePath& path() const {
DCHECK_EQ(type_, Type::kFile);
return path_;
}
const FileSystemURL& filesystem_url() const {
DCHECK_EQ(type_, Type::kFileFilesystem);
return filesystem_url_;
}
FileSystemContext* file_system_context() const {
DCHECK_EQ(type_, Type::kFileFilesystem);
return file_system_context_.get();
}
const base::Time& expected_modification_time() const {
DCHECK(type_ == Type::kFile || type_ == Type::kFileFilesystem)
<< static_cast<int>(type_);
return expected_modification_time_;
}
DataHandle* data_handle() const {
DCHECK_EQ(type_, Type::kReadableDataHandle) << static_cast<int>(type_);
return data_handle_.get();
}
// Returns true if this item was created by CreateFutureFile.
bool IsFutureFileItem() const;
// Returns |file_id| given to CreateFutureFile.
uint64_t GetFutureFileID() const;
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
file_access() const {
DCHECK(type_ == Type::kFile || type_ == Type::kFileFilesystem);
return file_access_;
}
private:
friend class BlobBuilderFromStream;
friend class BlobDataBuilder;
friend class BlobStorageContext;
friend class base::RefCounted<BlobDataItem>;
friend COMPONENT_EXPORT(STORAGE_BROWSER) void PrintTo(const BlobDataItem& x,
::std::ostream* os);
BlobDataItem(Type type, uint64_t offset, uint64_t length);
virtual ~BlobDataItem();
base::span<uint8_t> mutable_bytes() {
DCHECK_EQ(type_, Type::kBytes);
return base::span(bytes_);
}
void AllocateBytes();
void PopulateBytes(base::span<const uint8_t> data);
void ShrinkBytes(size_t new_length);
void PopulateFile(base::FilePath path,
base::Time expected_modification_time,
scoped_refptr<ShareableFileReference> file_ref);
void ShrinkFile(uint64_t new_length);
void GrowFile(uint64_t new_length);
void SetFileModificationTime(base::Time time) {
DCHECK_EQ(type_, Type::kFile);
expected_modification_time_ = time;
}
static void SetFileModificationTimes(
std::vector<scoped_refptr<BlobDataItem>> items,
std::vector<base::Time> times);
Type type_;
uint64_t offset_;
uint64_t length_;
std::vector<uint8_t> bytes_; // For Type::kBytes.
base::FilePath path_; // For Type::kFile.
FileSystemURL filesystem_url_; // For Type::kFileFilesystem.
base::Time
expected_modification_time_; // For Type::kFile and kFileFilesystem.
scoped_refptr<DataHandle> data_handle_; // For kReadableDataHandle.
scoped_refptr<ShareableFileReference> file_ref_; // For Type::kFile
scoped_refptr<FileSystemContext>
file_system_context_; // For Type::kFileFilesystem.
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
file_access_; // For Type::kFile and kFileFilesystem.
};
COMPONENT_EXPORT(STORAGE_BROWSER)
bool operator==(const BlobDataItem& a, const BlobDataItem& b);
COMPONENT_EXPORT(STORAGE_BROWSER)
bool operator!=(const BlobDataItem& a, const BlobDataItem& b);
} // namespace storage
#endif // STORAGE_BROWSER_BLOB_BLOB_DATA_ITEM_H_
|