Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: base/data_pack.cc

Issue 499004: Try 2: Completely redo how themes are stored on disk and processed at install time. (Closed)
Patch Set: Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/data_pack.h" 5 #include "base/data_pack.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/string_piece.h" 11 #include "base/string_piece.h"
12 12
13 // For details of the file layout, see 13 // For details of the file layout, see
14 // http://dev.chromium.org/developers/design-documents/linuxresourcesandlocalize dstrings 14 // http://dev.chromium.org/developers/design-documents/linuxresourcesandlocalize dstrings
15 15
16 namespace { 16 namespace {
17 static const uint32_t kFileFormatVersion = 1; 17
18 // A word is four bytes.
19 static const size_t kWord = 4;
20
21 static const uint32 kFileFormatVersion = 1;
18 // Length of file header: version and entry count. 22 // Length of file header: version and entry count.
19 static const size_t kHeaderLength = 2 * sizeof(uint32_t); 23 static const size_t kHeaderLength = 2 * sizeof(uint32);
20 24
25 #pragma pack(push,1)
21 struct DataPackEntry { 26 struct DataPackEntry {
22 uint32_t resource_id; 27 uint32 resource_id;
23 uint32_t file_offset; 28 uint32 file_offset;
24 uint32_t length; 29 uint32 length;
25 30
26 static int CompareById(const void* void_key, const void* void_entry) { 31 static int CompareById(const void* void_key, const void* void_entry) {
27 uint32_t key = *reinterpret_cast<const uint32_t*>(void_key); 32 uint32 key = *reinterpret_cast<const uint32*>(void_key);
28 const DataPackEntry* entry = 33 const DataPackEntry* entry =
29 reinterpret_cast<const DataPackEntry*>(void_entry); 34 reinterpret_cast<const DataPackEntry*>(void_entry);
30 if (key < entry->resource_id) { 35 if (key < entry->resource_id) {
31 return -1; 36 return -1;
32 } else if (key > entry->resource_id) { 37 } else if (key > entry->resource_id) {
33 return 1; 38 return 1;
34 } else { 39 } else {
35 return 0; 40 return 0;
36 } 41 }
37 } 42 }
38 } __attribute((packed)); 43 };
44 #pragma pack(pop)
45
46 COMPILE_ASSERT(sizeof(DataPackEntry) == 12, size_of_header_must_be_twelve);
39 47
40 } // anonymous namespace 48 } // anonymous namespace
41 49
42 namespace base { 50 namespace base {
43 51
44 // In .cc for MemoryMappedFile dtor. 52 // In .cc for MemoryMappedFile dtor.
45 DataPack::DataPack() : resource_count_(0) { 53 DataPack::DataPack() : resource_count_(0) {
46 } 54 }
47 DataPack::~DataPack() { 55 DataPack::~DataPack() {
48 } 56 }
49 57
50 bool DataPack::Load(const FilePath& path) { 58 bool DataPack::Load(const FilePath& path) {
51 mmap_.reset(new file_util::MemoryMappedFile); 59 mmap_.reset(new file_util::MemoryMappedFile);
52 if (!mmap_->Initialize(path)) { 60 if (!mmap_->Initialize(path)) {
53 PCHECK(false) << "Failed to mmap " << path.value(); 61 DLOG(ERROR) << "Failed to mmap datapack";
62 return false;
54 } 63 }
55 64
56 // Parse the header of the file. 65 // Parse the header of the file.
57 // First uint32_t: version; second: resource count. 66 // First uint32: version; second: resource count.
58 const uint32* ptr = reinterpret_cast<const uint32_t*>(mmap_->data()); 67 const uint32* ptr = reinterpret_cast<const uint32*>(mmap_->data());
59 uint32 version = ptr[0]; 68 uint32 version = ptr[0];
60 if (version != kFileFormatVersion) { 69 if (version != kFileFormatVersion) {
61 LOG(ERROR) << "Bad data pack version: got " << version << ", expected " 70 LOG(ERROR) << "Bad data pack version: got " << version << ", expected "
62 << kFileFormatVersion; 71 << kFileFormatVersion;
63 mmap_.reset(); 72 mmap_.reset();
64 return false; 73 return false;
65 } 74 }
66 resource_count_ = ptr[1]; 75 resource_count_ = ptr[1];
67 76
68 // Sanity check the file. 77 // Sanity check the file.
(...skipping 13 matching lines...) Expand all
82 LOG(ERROR) << "Entry #" << i << " in data pack points off end of file. " 91 LOG(ERROR) << "Entry #" << i << " in data pack points off end of file. "
83 << "Was the file corrupted?"; 92 << "Was the file corrupted?";
84 mmap_.reset(); 93 mmap_.reset();
85 return false; 94 return false;
86 } 95 }
87 } 96 }
88 97
89 return true; 98 return true;
90 } 99 }
91 100
92 bool DataPack::GetStringPiece(uint32_t resource_id, StringPiece* data) { 101 bool DataPack::GetStringPiece(uint32 resource_id, StringPiece* data) {
93 // It won't be hard to make this endian-agnostic, but it's not worth 102 // It won't be hard to make this endian-agnostic, but it's not worth
94 // bothering to do right now. 103 // bothering to do right now.
95 #if defined(__BYTE_ORDER) 104 #if defined(__BYTE_ORDER)
96 // Linux check 105 // Linux check
97 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, 106 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN,
98 datapack_assumes_little_endian); 107 datapack_assumes_little_endian);
99 #elif defined(__BIG_ENDIAN__) 108 #elif defined(__BIG_ENDIAN__)
100 // Mac check 109 // Mac check
101 #error DataPack assumes little endian 110 #error DataPack assumes little endian
102 #endif 111 #endif
103 112
104 DataPackEntry* target = reinterpret_cast<DataPackEntry*>( 113 DataPackEntry* target = reinterpret_cast<DataPackEntry*>(
105 bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_, 114 bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_,
106 sizeof(DataPackEntry), DataPackEntry::CompareById)); 115 sizeof(DataPackEntry), DataPackEntry::CompareById));
107 if (!target) { 116 if (!target) {
108 LOG(ERROR) << "No resource found with id: " << resource_id;
109 return false; 117 return false;
110 } 118 }
111 119
112 data->set(mmap_->data() + target->file_offset, target->length); 120 data->set(mmap_->data() + target->file_offset, target->length);
113 return true; 121 return true;
114 } 122 }
115 123
116 RefCountedStaticMemory* DataPack::GetStaticMemory(uint32_t resource_id) { 124 RefCountedStaticMemory* DataPack::GetStaticMemory(uint32 resource_id) {
117 base::StringPiece piece; 125 base::StringPiece piece;
118 if (!GetStringPiece(resource_id, &piece)) 126 if (!GetStringPiece(resource_id, &piece))
119 return NULL; 127 return NULL;
120 128
121 return new RefCountedStaticMemory( 129 return new RefCountedStaticMemory(
122 reinterpret_cast<const unsigned char*>(piece.data()), piece.length()); 130 reinterpret_cast<const unsigned char*>(piece.data()), piece.length());
123 } 131 }
124 132
133 // static
134 bool DataPack::WritePack(const FilePath& path,
135 const std::map<uint32, StringPiece>& resources) {
136 FILE* file = file_util::OpenFile(path, "wb");
137 if (!file)
138 return false;
139
140 if (fwrite(&kFileFormatVersion, 1, kWord, file) != kWord) {
141 LOG(ERROR) << "Failed to write file version";
142 file_util::CloseFile(file);
143 return false;
144 }
145
146 // Note: the python version of this function explicitly sorted keys, but
147 // std::map is a sorted associative container, we shouldn't have to do that.
148 uint32 entry_count = resources.size();
149 if (fwrite(&entry_count, 1, kWord, file) != kWord) {
150 LOG(ERROR) << "Failed to write entry count";
151 file_util::CloseFile(file);
152 return false;
153 }
154
155 // Each entry is 3 uint32s.
156 uint32 index_length = entry_count * 3 * kWord;
157 uint32 data_offset = kHeaderLength + index_length;
158 for (std::map<uint32, StringPiece>::const_iterator it = resources.begin();
159 it != resources.end(); ++it) {
160 if (fwrite(&it->first, 1, kWord, file) != kWord) {
161 LOG(ERROR) << "Failed to write id for " << it->first;
162 file_util::CloseFile(file);
163 return false;
164 }
165
166 if (fwrite(&data_offset, 1, kWord, file) != kWord) {
167 LOG(ERROR) << "Failed to write offset for " << it->first;
168 file_util::CloseFile(file);
169 return false;
170 }
171
172 uint32 len = it->second.length();
173 if (fwrite(&len, 1, kWord, file) != kWord) {
174 LOG(ERROR) << "Failed to write length for " << it->first;
175 file_util::CloseFile(file);
176 return false;
177 }
178
179 data_offset += len;
180 }
181
182 for (std::map<uint32, StringPiece>::const_iterator it = resources.begin();
183 it != resources.end(); ++it) {
184 if (fwrite(it->second.data(), it->second.length(), 1, file) != 1) {
185 LOG(ERROR) << "Failed to write data for " << it->first;
186 file_util::CloseFile(file);
187 return false;
188 }
189 }
190
191 file_util::CloseFile(file);
192
193 return true;
194 }
195
125 } // namespace base 196 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698