Index: ui/base/resource/data_pack.cc |
diff --git a/ui/base/resource/data_pack.cc b/ui/base/resource/data_pack.cc |
index 544baf6c6e952cdda23f9fcb8812e63ef5164104..c460703af6d863fbf516048467366788b6453239 100644 |
--- a/ui/base/resource/data_pack.cc |
+++ b/ui/base/resource/data_pack.cc |
@@ -68,6 +68,53 @@ void LogDataPackError(LoadErrors error) { |
namespace ui { |
+class DataPack::DataSource { |
sky
2017/02/08 22:22:58
Add description.
altimin
2017/02/09 00:13:51
Done.
|
+ public: |
+ virtual ~DataSource() {} |
+ |
+ virtual size_t Length() const = 0; |
sky
2017/02/08 22:22:58
Please use GetLength and GetData.
altimin
2017/02/09 00:13:51
Done.
|
+ virtual const uint8_t* Data() const = 0; |
+}; |
+ |
+namespace { |
+ |
+class MemoryMappedDataSource : public DataPack::DataSource { |
+ public: |
+ explicit MemoryMappedDataSource(std::unique_ptr<base::MemoryMappedFile> mmap) |
+ : mmap_(std::move(mmap)) {} |
+ |
+ ~MemoryMappedDataSource() override {} |
+ |
+ size_t Length() const override { return mmap_->length(); } |
sky
2017/02/08 22:22:58
Generally we prefix overrides with the class the o
altimin
2017/02/09 00:13:51
Done.
|
+ |
+ const uint8_t* Data() const override { return mmap_->data(); } |
+ |
+ private: |
+ std::unique_ptr<base::MemoryMappedFile> mmap_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MemoryMappedDataSource); |
+}; |
+ |
+class BufferDataSource : public DataPack::DataSource { |
+ public: |
+ explicit BufferDataSource(base::StringPiece buffer) : buffer_(buffer) {} |
+ |
+ ~BufferDataSource() override {} |
+ |
+ size_t Length() const override { return buffer_.length(); } |
sky
2017/02/08 22:22:58
Same comment about adding where overrides come fro
altimin
2017/02/09 00:13:52
Done.
|
+ |
+ const uint8_t* Data() const override { |
+ return reinterpret_cast<const uint8_t*>(buffer_.data()); |
sky
2017/02/08 22:22:58
Can't this be a static_cast?
altimin
2017/02/09 00:13:52
It's impossible to cast from const int8_t* to cons
|
+ } |
+ |
+ private: |
+ base::StringPiece buffer_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BufferDataSource); |
+}; |
+ |
+} // namespace |
+ |
DataPack::DataPack(ui::ScaleFactor scale_factor) |
: resource_count_(0), |
text_encoding_type_(BINARY), |
@@ -78,13 +125,14 @@ DataPack::~DataPack() { |
} |
bool DataPack::LoadFromPath(const base::FilePath& path) { |
- mmap_.reset(new base::MemoryMappedFile); |
- if (!mmap_->Initialize(path)) { |
+ std::unique_ptr<base::MemoryMappedFile> mmap(new base::MemoryMappedFile); |
sky
2017/02/08 22:22:58
MakeUnique where using unique_ptr.
altimin
2017/02/09 00:13:52
Done.
|
+ if (!mmap->Initialize(path)) { |
DLOG(ERROR) << "Failed to mmap datapack"; |
LogDataPackError(INIT_FAILED); |
- mmap_.reset(); |
+ mmap.reset(); |
return false; |
} |
+ data_source_.reset(new MemoryMappedDataSource(std::move(mmap))); |
return LoadImpl(); |
} |
@@ -96,34 +144,40 @@ bool DataPack::LoadFromFile(base::File file) { |
bool DataPack::LoadFromFileRegion( |
base::File file, |
const base::MemoryMappedFile::Region& region) { |
- mmap_.reset(new base::MemoryMappedFile); |
- if (!mmap_->Initialize(std::move(file), region)) { |
+ std::unique_ptr<base::MemoryMappedFile> mmap(new base::MemoryMappedFile); |
+ if (!mmap->Initialize(std::move(file), region)) { |
DLOG(ERROR) << "Failed to mmap datapack"; |
LogDataPackError(INIT_FAILED_FROM_FILE); |
- mmap_.reset(); |
+ mmap.reset(); |
return false; |
} |
+ data_source_.reset(new MemoryMappedDataSource(std::move(mmap))); |
+ return LoadImpl(); |
+} |
+ |
+bool DataPack::LoadFromBuffer(base::StringPiece buffer) { |
+ data_source_.reset(new BufferDataSource(buffer)); |
return LoadImpl(); |
} |
bool DataPack::LoadImpl() { |
// Sanity check the header of the file. |
- if (kHeaderLength > mmap_->length()) { |
+ if (kHeaderLength > data_source_->Length()) { |
DLOG(ERROR) << "Data pack file corruption: incomplete file header."; |
LogDataPackError(HEADER_TRUNCATED); |
- mmap_.reset(); |
+ data_source_.reset(); |
sky
2017/02/08 22:22:58
I think this code would be less fragile if you pas
altimin
2017/02/09 00:13:52
Great suggestion, thanks!
Done.
|
return false; |
} |
// Parse the header of the file. |
// First uint32_t: version; second: resource count; |
- const uint32_t* ptr = reinterpret_cast<const uint32_t*>(mmap_->data()); |
+ const uint32_t* ptr = reinterpret_cast<const uint32_t*>(data_source_->Data()); |
uint32_t version = ptr[0]; |
if (version != kFileFormatVersion) { |
LOG(ERROR) << "Bad data pack version: got " << version << ", expected " |
<< kFileFormatVersion; |
LogDataPackError(BAD_VERSION); |
- mmap_.reset(); |
+ data_source_.reset(); |
return false; |
} |
resource_count_ = ptr[1]; |
@@ -136,7 +190,7 @@ bool DataPack::LoadImpl() { |
LOG(ERROR) << "Bad data pack text encoding: got " << text_encoding_type_ |
<< ", expected between " << BINARY << " and " << UTF16; |
LogDataPackError(WRONG_ENCODING); |
- mmap_.reset(); |
+ data_source_.reset(); |
return false; |
} |
@@ -144,23 +198,23 @@ bool DataPack::LoadImpl() { |
// 1) Check we have enough entries. There's an extra entry after the last item |
// which gives the length of the last item. |
if (kHeaderLength + (resource_count_ + 1) * sizeof(DataPackEntry) > |
- mmap_->length()) { |
+ data_source_->Length()) { |
LOG(ERROR) << "Data pack file corruption: too short for number of " |
"entries specified."; |
LogDataPackError(INDEX_TRUNCATED); |
- mmap_.reset(); |
+ data_source_.reset(); |
return false; |
} |
// 2) Verify the entries are within the appropriate bounds. There's an extra |
// entry after the last item which gives us the length of the last item. |
for (size_t i = 0; i < resource_count_ + 1; ++i) { |
const DataPackEntry* entry = reinterpret_cast<const DataPackEntry*>( |
- mmap_->data() + kHeaderLength + (i * sizeof(DataPackEntry))); |
- if (entry->file_offset > mmap_->length()) { |
+ data_source_->Data() + kHeaderLength + (i * sizeof(DataPackEntry))); |
+ if (entry->file_offset > data_source_->Length()) { |
LOG(ERROR) << "Entry #" << i << " in data pack points off end of file. " |
<< "Was the file corrupted?"; |
LogDataPackError(ENTRY_NOT_FOUND); |
- mmap_.reset(); |
+ data_source_.reset(); |
return false; |
} |
} |
@@ -169,8 +223,9 @@ bool DataPack::LoadImpl() { |
} |
bool DataPack::HasResource(uint16_t resource_id) const { |
- return !!bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_, |
- sizeof(DataPackEntry), DataPackEntry::CompareById); |
+ return !!bsearch(&resource_id, data_source_->Data() + kHeaderLength, |
+ resource_count_, sizeof(DataPackEntry), |
+ DataPackEntry::CompareById); |
} |
bool DataPack::GetStringPiece(uint16_t resource_id, |
@@ -186,9 +241,9 @@ bool DataPack::GetStringPiece(uint16_t resource_id, |
#error DataPack assumes little endian |
#endif |
- const DataPackEntry* target = reinterpret_cast<const DataPackEntry*>( |
- bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_, |
- sizeof(DataPackEntry), DataPackEntry::CompareById)); |
+ const DataPackEntry* target = reinterpret_cast<const DataPackEntry*>(bsearch( |
+ &resource_id, data_source_->Data() + kHeaderLength, resource_count_, |
+ sizeof(DataPackEntry), DataPackEntry::CompareById)); |
if (!target) { |
return false; |
} |
@@ -197,9 +252,9 @@ bool DataPack::GetStringPiece(uint16_t resource_id, |
// If the next entry points beyond the end of the file this data pack's entry |
// table is corrupt. Log an error and return false. See |
// http://crbug.com/371301. |
- if (next_entry->file_offset > mmap_->length()) { |
- size_t entry_index = target - |
- reinterpret_cast<const DataPackEntry*>(mmap_->data() + kHeaderLength); |
+ if (next_entry->file_offset > data_source_->Length()) { |
+ size_t entry_index = target - reinterpret_cast<const DataPackEntry*>( |
+ data_source_->Data() + kHeaderLength); |
LOG(ERROR) << "Entry #" << entry_index << " in data pack points off end " |
<< "of file. This should have been caught when loading. Was the " |
<< "file modified?"; |
@@ -207,8 +262,9 @@ bool DataPack::GetStringPiece(uint16_t resource_id, |
} |
size_t length = next_entry->file_offset - target->file_offset; |
- data->set(reinterpret_cast<const char*>(mmap_->data() + target->file_offset), |
- length); |
+ data->set( |
+ reinterpret_cast<const char*>(data_source_->Data() + target->file_offset), |
sky
2017/02/08 22:22:58
Can this be a static_cast?
altimin
2017/02/09 00:13:51
See above.
|
+ length); |
return true; |
} |
@@ -234,7 +290,7 @@ void DataPack::CheckForDuplicateResources( |
const ScopedVector<ResourceHandle>& packs) { |
for (size_t i = 0; i < resource_count_ + 1; ++i) { |
const DataPackEntry* entry = reinterpret_cast<const DataPackEntry*>( |
- mmap_->data() + kHeaderLength + (i * sizeof(DataPackEntry))); |
+ data_source_->Data() + kHeaderLength + (i * sizeof(DataPackEntry))); |
const uint16_t resource_id = entry->resource_id; |
const float resource_scale = GetScaleForScaleFactor(scale_factor_); |
for (const ResourceHandle* handle : packs) { |