Index: base/data_pack.cc |
diff --git a/base/data_pack.cc b/base/data_pack.cc |
index 27054d3ca53e772b074f036f097c4b269ae38bce..1078d0ade5c5de2f63cb7ccad462cfeb6ced409e 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 |