summaryrefslogtreecommitdiffstats
path: root/base/data_pack.cc
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-14 20:48:07 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-14 20:48:07 +0000
commitf017cc9f926a81638e324b51bd418ac7f7feeee0 (patch)
tree8db77306164b5d4498eac4ae729753095430a2e5 /base/data_pack.cc
parent3396dc0d719aeca9d4593dfe0f1ab62cdac1629f (diff)
downloadchromium_src-f017cc9f926a81638e324b51bd418ac7f7feeee0.zip
chromium_src-f017cc9f926a81638e324b51bd418ac7f7feeee0.tar.gz
chromium_src-f017cc9f926a81638e324b51bd418ac7f7feeee0.tar.bz2
Try 2: Completely redo how themes are stored on disk and processed at install time.
Same as previous patch, except we now have a BrowserThemeProvider::GetDefaultDisplayProperty() so we don't have UMRs in ntp_resource_cache.cc. BUG=24493,21121 TEST=All the new unit tests pass. All the complex theme startup tests go faster. Previous Review URL: http://codereview.chromium.org/460050 Review URL: http://codereview.chromium.org/499004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34486 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/data_pack.cc')
-rw-r--r--base/data_pack.cc97
1 files changed, 84 insertions, 13 deletions
diff --git a/base/data_pack.cc b/base/data_pack.cc
index 27054d3..1078d0a 100644
--- a/base/data_pack.cc
+++ b/base/data_pack.cc
@@ -14,17 +14,22 @@
// http://dev.chromium.org/developers/design-documents/linuxresourcesandlocalizedstrings
namespace {
-static const uint32_t kFileFormatVersion = 1;
+
+// A word is four bytes.
+static const size_t kWord = 4;
+
+static const uint32 kFileFormatVersion = 1;
// Length of file header: version and entry count.
-static const size_t kHeaderLength = 2 * sizeof(uint32_t);
+static const size_t kHeaderLength = 2 * sizeof(uint32);
+#pragma pack(push,1)
struct DataPackEntry {
- uint32_t resource_id;
- uint32_t file_offset;
- uint32_t length;
+ uint32 resource_id;
+ uint32 file_offset;
+ uint32 length;
static int CompareById(const void* void_key, const void* void_entry) {
- uint32_t key = *reinterpret_cast<const uint32_t*>(void_key);
+ uint32 key = *reinterpret_cast<const uint32*>(void_key);
const DataPackEntry* entry =
reinterpret_cast<const DataPackEntry*>(void_entry);
if (key < entry->resource_id) {
@@ -35,7 +40,10 @@ struct DataPackEntry {
return 0;
}
}
-} __attribute((packed));
+};
+#pragma pack(pop)
+
+COMPILE_ASSERT(sizeof(DataPackEntry) == 12, size_of_header_must_be_twelve);
} // anonymous namespace
@@ -50,12 +58,13 @@ DataPack::~DataPack() {
bool DataPack::Load(const FilePath& path) {
mmap_.reset(new file_util::MemoryMappedFile);
if (!mmap_->Initialize(path)) {
- PCHECK(false) << "Failed to mmap " << path.value();
+ DLOG(ERROR) << "Failed to mmap datapack";
+ return false;
}
// Parse the header of the file.
- // First uint32_t: version; second: resource count.
- const uint32* ptr = reinterpret_cast<const uint32_t*>(mmap_->data());
+ // 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 "
@@ -89,7 +98,7 @@ bool DataPack::Load(const FilePath& path) {
return true;
}
-bool DataPack::GetStringPiece(uint32_t resource_id, StringPiece* data) {
+bool DataPack::GetStringPiece(uint32 resource_id, StringPiece* data) {
// It won't be hard to make this endian-agnostic, but it's not worth
// bothering to do right now.
#if defined(__BYTE_ORDER)
@@ -105,7 +114,6 @@ bool DataPack::GetStringPiece(uint32_t resource_id, StringPiece* data) {
bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_,
sizeof(DataPackEntry), DataPackEntry::CompareById));
if (!target) {
- LOG(ERROR) << "No resource found with id: " << resource_id;
return false;
}
@@ -113,7 +121,7 @@ bool DataPack::GetStringPiece(uint32_t resource_id, StringPiece* data) {
return true;
}
-RefCountedStaticMemory* DataPack::GetStaticMemory(uint32_t resource_id) {
+RefCountedStaticMemory* DataPack::GetStaticMemory(uint32 resource_id) {
base::StringPiece piece;
if (!GetStringPiece(resource_id, &piece))
return NULL;
@@ -122,4 +130,67 @@ RefCountedStaticMemory* DataPack::GetStaticMemory(uint32_t resource_id) {
reinterpret_cast<const unsigned char*>(piece.data()), piece.length());
}
+// static
+bool DataPack::WritePack(const FilePath& path,
+ const std::map<uint32, StringPiece>& resources) {
+ FILE* file = file_util::OpenFile(path, "wb");
+ if (!file)
+ return false;
+
+ if (fwrite(&kFileFormatVersion, 1, kWord, file) != kWord) {
+ LOG(ERROR) << "Failed to write file version";
+ file_util::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, 1, kWord, file) != kWord) {
+ LOG(ERROR) << "Failed to write entry count";
+ file_util::CloseFile(file);
+ return false;
+ }
+
+ // Each entry is 3 uint32s.
+ uint32 index_length = entry_count * 3 * kWord;
+ uint32 data_offset = kHeaderLength + index_length;
+ for (std::map<uint32, StringPiece>::const_iterator it = resources.begin();
+ it != resources.end(); ++it) {
+ if (fwrite(&it->first, 1, kWord, file) != kWord) {
+ LOG(ERROR) << "Failed to write id for " << it->first;
+ file_util::CloseFile(file);
+ return false;
+ }
+
+ if (fwrite(&data_offset, 1, kWord, file) != kWord) {
+ LOG(ERROR) << "Failed to write offset for " << it->first;
+ file_util::CloseFile(file);
+ return false;
+ }
+
+ uint32 len = it->second.length();
+ if (fwrite(&len, 1, kWord, file) != kWord) {
+ LOG(ERROR) << "Failed to write length for " << it->first;
+ file_util::CloseFile(file);
+ return false;
+ }
+
+ data_offset += len;
+ }
+
+ for (std::map<uint32, 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;
+ file_util::CloseFile(file);
+ return false;
+ }
+ }
+
+ file_util::CloseFile(file);
+
+ return true;
+}
+
} // namespace base