Chromium Code Reviews| Index: storage/common/blob/blob_data.h |
| diff --git a/storage/common/blob/blob_data.h b/storage/common/blob/blob_data.h |
| index 2f48546585b302b6587cc8d2855681dca017f49c..5850e851e90f75e615959b1e96c6403c562ff0c5 100644 |
| --- a/storage/common/blob/blob_data.h |
| +++ b/storage/common/blob/blob_data.h |
| @@ -18,15 +18,80 @@ |
| #include "url/gurl.h" |
| namespace storage { |
| +class BlobDataBuilder; |
| +class BlobStorageContext; |
| + |
| +// 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 STORAGE_COMMON_EXPORT BlobDataItem |
| + : public base::RefCountedThreadSafe<BlobDataItem> { |
| + public: |
| + storage::DataElement::Type type() const { return item_->type(); } |
| + const char* bytes() const { return item_->bytes(); } |
| + const base::FilePath& path() const { return item_->path(); } |
| + const GURL& filesystem_url() const { return item_->filesystem_url(); } |
| + const std::string& blob_uuid() const { return item_->blob_uuid(); } |
| + uint64 offset() const { return item_->offset(); } |
| + uint64 length() const { return item_->length(); } |
| + const base::Time& expected_modification_time() const { |
| + return item_->expected_modification_time(); |
| + } |
| + const DataElement& data_element() const { return *item_; } |
| + const DataElement* data_element_ptr() const { return item_.get(); } |
| + |
| + private: |
| + friend class BlobDataBuilder; |
| + friend class BlobStorageContext; |
| + friend class base::RefCountedThreadSafe<BlobDataItem>; |
| + BlobDataItem(scoped_ptr<DataElement> item); |
| + BlobDataItem(scoped_ptr<DataElement> item, |
| + scoped_refptr<ShareableFileReference> file_handle); |
| + virtual ~BlobDataItem(); |
| + |
| + scoped_ptr<storage::DataElement> item_; |
| + scoped_refptr<ShareableFileReference> file_handle_; |
| +}; |
| -class STORAGE_COMMON_EXPORT BlobData |
| - : public base::RefCounted<BlobData> { |
| +// Snapshot of a Blob. This snapshot holds a refcount of the current |
| +// blob item resources so the backing storage for these items will stick |
| +// around for the lifetime of this object. (The data represented by a blob is |
| +// immutable, but the backing store can change). This structure thread safe. |
| +class STORAGE_COMMON_EXPORT BlobDataSnapshot { |
| public: |
| - typedef storage::DataElement Item; |
| + BlobDataSnapshot(const BlobDataSnapshot& other); |
| + ~BlobDataSnapshot(); |
| + const std::string& uuid() const { return uuid_; } |
| + const std::vector<scoped_refptr<BlobDataItem>>& items() const { |
| + return items_; |
| + } |
| + const std::string& content_type() const { return content_type_; } |
| + const std::string& content_disposition() const { |
| + return content_disposition_; |
| + } |
| + size_t GetMemoryUsage() const; |
| - // TODO(michaeln): remove the empty ctor when we fully transition to uuids. |
| - BlobData(); |
| - explicit BlobData(const std::string& uuid); |
| + private: |
| + friend class BlobDataBuilder; |
| + BlobDataSnapshot(const std::string& uuid, |
| + const std::string& content_type, |
| + const std::string& content_disposition, |
| + const std::vector<scoped_refptr<BlobDataItem>>& items); |
| + |
| + const std::string uuid_; |
| + const std::string content_type_; |
| + const std::string content_disposition_; |
| + const std::vector<scoped_refptr<BlobDataItem>> items_; |
| +}; |
| + |
| +class STORAGE_COMMON_EXPORT BlobDataBuilder { |
| + public: |
| + explicit BlobDataBuilder(const std::string& uuid); |
| + virtual ~BlobDataBuilder(); |
| + |
| + const std::string& uuid() const { return uuid_; } |
| void AppendData(const std::string& data) { |
| AppendData(data.c_str(), data.size()); |
| @@ -34,61 +99,96 @@ class STORAGE_COMMON_EXPORT BlobData |
| void AppendData(const char* data, size_t length); |
| - void AppendFile(const base::FilePath& file_path, uint64 offset, uint64 length, |
| + void AppendFile(const base::FilePath& file_path, |
| + uint64 offset, |
| + uint64 length, |
| const base::Time& expected_modification_time); |
| + |
| + void AppendFile(const base::FilePath& file_path, |
| + uint64 offset, |
| + uint64 length, |
| + const base::Time& expected_modification_time, |
| + scoped_refptr<ShareableFileReference> shareable_file); |
| + |
| void AppendBlob(const std::string& uuid, uint64 offset, uint64 length); |
| void AppendFileSystemFile(const GURL& url, uint64 offset, uint64 length, |
| const base::Time& expected_modification_time); |
| - void AttachShareableFileReference(ShareableFileReference* reference) { |
| - shareable_files_.push_back(reference); |
| - } |
| - |
| - const std::string& uuid() const { return uuid_; } |
| - const std::vector<Item>& items() const { return items_; } |
| - const std::string& content_type() const { return content_type_; } |
| void set_content_type(const std::string& content_type) { |
| content_type_ = content_type; |
| } |
| - const std::string& content_disposition() const { |
| - return content_disposition_; |
| - } |
| void set_content_disposition(const std::string& content_disposition) { |
| content_disposition_ = content_disposition; |
| } |
| - int64 GetMemoryUsage() const; |
| + size_t GetMemoryUsage() const; |
| + |
| + scoped_ptr<BlobDataSnapshot> Build(); |
| private: |
| - friend class base::RefCounted<BlobData>; |
| - virtual ~BlobData(); |
| + friend class BlobStorageContext; |
| + friend bool operator==(const BlobDataBuilder& a, const BlobDataBuilder& b); |
| + friend bool operator==(const BlobDataSnapshot& a, const BlobDataBuilder& b); |
| std::string uuid_; |
| std::string content_type_; |
| std::string content_disposition_; |
| - std::vector<Item> items_; |
| - std::vector<scoped_refptr<ShareableFileReference> > shareable_files_; |
| + std::vector<scoped_refptr<BlobDataItem>> items_; |
| - DISALLOW_COPY_AND_ASSIGN(BlobData); |
| + DISALLOW_COPY_AND_ASSIGN(BlobDataBuilder); |
| }; |
| #if defined(UNIT_TEST) |
| -inline bool operator==(const BlobData& a, const BlobData& b) { |
| - if (a.content_type() != b.content_type()) |
| +inline bool operator==(const BlobDataItem& a, const BlobDataItem& b) { |
| + return a.data_element() == b.data_element(); |
| +} |
| + |
| +inline bool operator!=(const BlobDataItem& a, const BlobDataItem& b) { |
| + return !(a == b); |
| +} |
| + |
| +inline bool operator==(const BlobDataBuilder& a, const BlobDataBuilder& b) { |
| + if (a.content_type_ != b.content_type_) |
| return false; |
| - if (a.content_disposition() != b.content_disposition()) |
| + if (a.content_disposition_ != b.content_disposition_) |
| return false; |
| - if (a.items().size() != b.items().size()) |
| + if (a.items_.size() != b.items_.size()) |
| return false; |
| + for (size_t i = 0; i < a.items_.size(); ++i) { |
| + if (a.items_[i] != b.items_[i]) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +inline bool operator==(const BlobDataSnapshot& a, const BlobDataBuilder& b) { |
|
michaeln
2015/01/16 00:09:09
an odd operator
dmurph
2015/01/16 23:45:56
It's to make testing easier. We grab a snapshot a
|
| + if (a.content_type() != b.content_type_) { |
| + printf("content type\n"); |
| + return false; |
| + } |
| + if (a.content_disposition() != b.content_disposition_) { |
| + printf("content disposition\n"); |
| + return false; |
| + } |
| + if (a.items().size() != b.items_.size()) { |
| + printf("items size\n"); |
| + return false; |
| + } |
| for (size_t i = 0; i < a.items().size(); ++i) { |
| - if (a.items()[i] != b.items()[i]) |
| + if (*(a.items()[i]) != *(b.items_[i])) { |
| + printf("item\n"); |
| return false; |
| + } |
| } |
| return true; |
| } |
| -inline bool operator!=(const BlobData& a, const BlobData& b) { |
| +inline bool operator!=(const BlobDataSnapshot& a, const BlobDataBuilder& b) { |
| + return !(a == b); |
| +} |
| + |
| +inline bool operator!=(const BlobDataBuilder& a, const BlobDataBuilder& b) { |
| return !(a == b); |
| } |
| #endif // defined(UNIT_TEST) |