| Index: ui/base/resource/data_pack.cc
|
| diff --git a/ui/base/resource/data_pack.cc b/ui/base/resource/data_pack.cc
|
| deleted file mode 100644
|
| index 70841b6ba8f32a883f718d5b387800236cab1e39..0000000000000000000000000000000000000000
|
| --- a/ui/base/resource/data_pack.cc
|
| +++ /dev/null
|
| @@ -1,325 +0,0 @@
|
| -// Copyright (c) 2012 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 "ui/base/resource/data_pack.h"
|
| -
|
| -#include <errno.h>
|
| -
|
| -#include "base/files/file_util.h"
|
| -#include "base/files/memory_mapped_file.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/ref_counted_memory.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/strings/string_piece.h"
|
| -
|
| -// For details of the file layout, see
|
| -// http://dev.chromium.org/developers/design-documents/linuxresourcesandlocalizedstrings
|
| -
|
| -namespace {
|
| -
|
| -static const uint32 kFileFormatVersion = 4;
|
| -// Length of file header: version, entry count and text encoding type.
|
| -static const size_t kHeaderLength = 2 * sizeof(uint32) + sizeof(uint8);
|
| -
|
| -#pragma pack(push,2)
|
| -struct DataPackEntry {
|
| - uint16 resource_id;
|
| - uint32 file_offset;
|
| -
|
| - static int CompareById(const void* void_key, const void* void_entry) {
|
| - uint16 key = *reinterpret_cast<const uint16*>(void_key);
|
| - const DataPackEntry* entry =
|
| - reinterpret_cast<const DataPackEntry*>(void_entry);
|
| - if (key < entry->resource_id) {
|
| - return -1;
|
| - } else if (key > entry->resource_id) {
|
| - return 1;
|
| - } else {
|
| - return 0;
|
| - }
|
| - }
|
| -};
|
| -#pragma pack(pop)
|
| -
|
| -COMPILE_ASSERT(sizeof(DataPackEntry) == 6, size_of_entry_must_be_six);
|
| -
|
| -// We're crashing when trying to load a pak file on Windows. Add some error
|
| -// codes for logging.
|
| -// http://crbug.com/58056
|
| -enum LoadErrors {
|
| - INIT_FAILED = 1,
|
| - BAD_VERSION,
|
| - INDEX_TRUNCATED,
|
| - ENTRY_NOT_FOUND,
|
| - HEADER_TRUNCATED,
|
| - WRONG_ENCODING,
|
| - INIT_FAILED_FROM_FILE,
|
| -
|
| - LOAD_ERRORS_COUNT,
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -namespace ui {
|
| -
|
| -DataPack::DataPack(ui::ScaleFactor scale_factor)
|
| - : resource_count_(0),
|
| - text_encoding_type_(BINARY),
|
| - scale_factor_(scale_factor) {
|
| -}
|
| -
|
| -DataPack::~DataPack() {
|
| -}
|
| -
|
| -bool DataPack::LoadFromPath(const base::FilePath& path) {
|
| - mmap_.reset(new base::MemoryMappedFile);
|
| - if (!mmap_->Initialize(path)) {
|
| - DLOG(ERROR) << "Failed to mmap datapack";
|
| - UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INIT_FAILED,
|
| - LOAD_ERRORS_COUNT);
|
| - mmap_.reset();
|
| - return false;
|
| - }
|
| - return LoadImpl();
|
| -}
|
| -
|
| -bool DataPack::LoadFromFile(base::File file) {
|
| - return LoadFromFileRegion(file.Pass(),
|
| - base::MemoryMappedFile::Region::kWholeFile);
|
| -}
|
| -
|
| -bool DataPack::LoadFromFileRegion(
|
| - base::File file,
|
| - const base::MemoryMappedFile::Region& region) {
|
| - mmap_.reset(new base::MemoryMappedFile);
|
| - if (!mmap_->Initialize(file.Pass(), region)) {
|
| - DLOG(ERROR) << "Failed to mmap datapack";
|
| - UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INIT_FAILED_FROM_FILE,
|
| - LOAD_ERRORS_COUNT);
|
| - mmap_.reset();
|
| - return false;
|
| - }
|
| - return LoadImpl();
|
| -}
|
| -
|
| -bool DataPack::LoadImpl() {
|
| - // Sanity check the header of the file.
|
| - if (kHeaderLength > mmap_->length()) {
|
| - DLOG(ERROR) << "Data pack file corruption: incomplete file header.";
|
| - UMA_HISTOGRAM_ENUMERATION("DataPack.Load", HEADER_TRUNCATED,
|
| - LOAD_ERRORS_COUNT);
|
| - mmap_.reset();
|
| - return false;
|
| - }
|
| -
|
| - // Parse the header of the file.
|
| - // First uint32: version; second: resource count;
|
| - const uint32* ptr = reinterpret_cast<const uint32*>(mmap_->data());
|
| - uint32 version = ptr[0];
|
| - if (version != kFileFormatVersion) {
|
| - LOG(ERROR) << "Bad data pack version: got " << version << ", expected "
|
| - << kFileFormatVersion;
|
| - UMA_HISTOGRAM_ENUMERATION("DataPack.Load", BAD_VERSION,
|
| - LOAD_ERRORS_COUNT);
|
| - mmap_.reset();
|
| - return false;
|
| - }
|
| - resource_count_ = ptr[1];
|
| -
|
| - // third: text encoding.
|
| - const uint8* ptr_encoding = reinterpret_cast<const uint8*>(ptr + 2);
|
| - text_encoding_type_ = static_cast<TextEncodingType>(*ptr_encoding);
|
| - if (text_encoding_type_ != UTF8 && text_encoding_type_ != UTF16 &&
|
| - text_encoding_type_ != BINARY) {
|
| - LOG(ERROR) << "Bad data pack text encoding: got " << text_encoding_type_
|
| - << ", expected between " << BINARY << " and " << UTF16;
|
| - UMA_HISTOGRAM_ENUMERATION("DataPack.Load", WRONG_ENCODING,
|
| - LOAD_ERRORS_COUNT);
|
| - mmap_.reset();
|
| - return false;
|
| - }
|
| -
|
| - // Sanity check the file.
|
| - // 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()) {
|
| - LOG(ERROR) << "Data pack file corruption: too short for number of "
|
| - "entries specified.";
|
| - UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INDEX_TRUNCATED,
|
| - LOAD_ERRORS_COUNT);
|
| - mmap_.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()) {
|
| - LOG(ERROR) << "Entry #" << i << " in data pack points off end of file. "
|
| - << "Was the file corrupted?";
|
| - UMA_HISTOGRAM_ENUMERATION("DataPack.Load", ENTRY_NOT_FOUND,
|
| - LOAD_ERRORS_COUNT);
|
| - mmap_.reset();
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool DataPack::HasResource(uint16 resource_id) const {
|
| - return !!bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_,
|
| - sizeof(DataPackEntry), DataPackEntry::CompareById);
|
| -}
|
| -
|
| -bool DataPack::GetStringPiece(uint16 resource_id,
|
| - base::StringPiece* data) const {
|
| - // It won't be hard to make this endian-agnostic, but it's not worth
|
| - // bothering to do right now.
|
| -#if defined(__BYTE_ORDER)
|
| - // Linux check
|
| - COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN,
|
| - datapack_assumes_little_endian);
|
| -#elif defined(__BIG_ENDIAN__)
|
| - // Mac check
|
| - #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));
|
| - if (!target) {
|
| - return false;
|
| - }
|
| -
|
| - const DataPackEntry* next_entry = target + 1;
|
| - // 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);
|
| - LOG(ERROR) << "Entry #" << entry_index << " in data pack points off end "
|
| - << "of file. This should have been caught when loading. Was the "
|
| - << "file modified?";
|
| - return false;
|
| - }
|
| -
|
| - size_t length = next_entry->file_offset - target->file_offset;
|
| - data->set(reinterpret_cast<const char*>(mmap_->data() + target->file_offset),
|
| - length);
|
| - return true;
|
| -}
|
| -
|
| -base::RefCountedStaticMemory* DataPack::GetStaticMemory(
|
| - uint16 resource_id) const {
|
| - base::StringPiece piece;
|
| - if (!GetStringPiece(resource_id, &piece))
|
| - return NULL;
|
| -
|
| - return new base::RefCountedStaticMemory(piece.data(), piece.length());
|
| -}
|
| -
|
| -ResourceHandle::TextEncodingType DataPack::GetTextEncodingType() const {
|
| - return text_encoding_type_;
|
| -}
|
| -
|
| -ui::ScaleFactor DataPack::GetScaleFactor() const {
|
| - return scale_factor_;
|
| -}
|
| -
|
| -// static
|
| -bool DataPack::WritePack(const base::FilePath& path,
|
| - const std::map<uint16, base::StringPiece>& resources,
|
| - TextEncodingType textEncodingType) {
|
| - FILE* file = base::OpenFile(path, "wb");
|
| - if (!file)
|
| - return false;
|
| -
|
| - if (fwrite(&kFileFormatVersion, sizeof(kFileFormatVersion), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write file version";
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - // Note: the python version of this function explicitly sorted keys, but
|
| - // std::map is a sorted associative container, we shouldn't have to do that.
|
| - uint32 entry_count = resources.size();
|
| - if (fwrite(&entry_count, sizeof(entry_count), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write entry count";
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - if (textEncodingType != UTF8 && textEncodingType != UTF16 &&
|
| - textEncodingType != BINARY) {
|
| - LOG(ERROR) << "Invalid text encoding type, got " << textEncodingType
|
| - << ", expected between " << BINARY << " and " << UTF16;
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - uint8 write_buffer = static_cast<uint8>(textEncodingType);
|
| - if (fwrite(&write_buffer, sizeof(uint8), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write file text resources encoding";
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - // Each entry is a uint16 + a uint32. We have an extra entry after the last
|
| - // item so we can compute the size of the list item.
|
| - uint32 index_length = (entry_count + 1) * sizeof(DataPackEntry);
|
| - uint32 data_offset = kHeaderLength + index_length;
|
| - for (std::map<uint16, base::StringPiece>::const_iterator it =
|
| - resources.begin();
|
| - it != resources.end(); ++it) {
|
| - uint16 resource_id = it->first;
|
| - if (fwrite(&resource_id, sizeof(resource_id), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write id for " << resource_id;
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - if (fwrite(&data_offset, sizeof(data_offset), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write offset for " << resource_id;
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - data_offset += it->second.length();
|
| - }
|
| -
|
| - // We place an extra entry after the last item that allows us to read the
|
| - // size of the last item.
|
| - uint16 resource_id = 0;
|
| - if (fwrite(&resource_id, sizeof(resource_id), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write extra resource id.";
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - if (fwrite(&data_offset, sizeof(data_offset), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write extra offset.";
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| -
|
| - for (std::map<uint16, base::StringPiece>::const_iterator it =
|
| - resources.begin();
|
| - it != resources.end(); ++it) {
|
| - if (fwrite(it->second.data(), it->second.length(), 1, file) != 1) {
|
| - LOG(ERROR) << "Failed to write data for " << it->first;
|
| - base::CloseFile(file);
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - base::CloseFile(file);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -} // namespace ui
|
|
|