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

Side by Side Diff: ui/base/resource/data_pack.cc

Issue 7555003: Update the .pak file format to version 2: Make resource ids 16bit (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: evan's review feedback Created 9 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « ui/base/resource/data_pack.h ('k') | ui/base/resource/data_pack_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ui/base/resource/data_pack.h" 5 #include "ui/base/resource/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/memory/ref_counted_memory.h" 11 #include "base/memory/ref_counted_memory.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/string_piece.h" 13 #include "base/string_piece.h"
14 14
15 // For details of the file layout, see 15 // For details of the file layout, see
16 // http://dev.chromium.org/developers/design-documents/linuxresourcesandlocalize dstrings 16 // http://dev.chromium.org/developers/design-documents/linuxresourcesandlocalize dstrings
17 17
18 namespace { 18 namespace {
19 19
20 // A word is four bytes. 20 static const uint32 kFileFormatVersion = 2;
21 static const size_t kWord = 4;
22
23 static const uint32 kFileFormatVersion = 1;
24 // Length of file header: version and entry count. 21 // Length of file header: version and entry count.
25 static const size_t kHeaderLength = 2 * sizeof(uint32); 22 static const size_t kHeaderLength = 2 * sizeof(uint32);
26 23
24 #pragma pack(push,2)
27 struct DataPackEntry { 25 struct DataPackEntry {
28 uint32 resource_id; 26 uint16 resource_id;
29 uint32 file_offset; 27 uint32 file_offset;
30 uint32 length; 28 uint32 length;
31 29
32 static int CompareById(const void* void_key, const void* void_entry) { 30 static int CompareById(const void* void_key, const void* void_entry) {
33 uint32 key = *reinterpret_cast<const uint32*>(void_key); 31 uint16 key = *reinterpret_cast<const uint16*>(void_key);
34 const DataPackEntry* entry = 32 const DataPackEntry* entry =
35 reinterpret_cast<const DataPackEntry*>(void_entry); 33 reinterpret_cast<const DataPackEntry*>(void_entry);
36 if (key < entry->resource_id) { 34 if (key < entry->resource_id) {
37 return -1; 35 return -1;
38 } else if (key > entry->resource_id) { 36 } else if (key > entry->resource_id) {
39 return 1; 37 return 1;
40 } else { 38 } else {
41 return 0; 39 return 0;
42 } 40 }
43 } 41 }
44 }; 42 };
43 #pragma pack(pop)
45 44
46 COMPILE_ASSERT(sizeof(DataPackEntry) == 12, size_of_header_must_be_twelve); 45 COMPILE_ASSERT(sizeof(DataPackEntry) == 10, size_of_header_must_be_ten);
47 46
48 // We're crashing when trying to load a pak file on Windows. Add some error 47 // We're crashing when trying to load a pak file on Windows. Add some error
49 // codes for logging. 48 // codes for logging.
50 // http://crbug.com/58056 49 // http://crbug.com/58056
51 enum LoadErrors { 50 enum LoadErrors {
52 INIT_FAILED = 1, 51 INIT_FAILED = 1,
53 BAD_VERSION, 52 BAD_VERSION,
54 INDEX_TRUNCATED, 53 INDEX_TRUNCATED,
55 ENTRY_NOT_FOUND, 54 ENTRY_NOT_FOUND,
56 55
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", ENTRY_NOT_FOUND, 111 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", ENTRY_NOT_FOUND,
113 LOAD_ERRORS_COUNT); 112 LOAD_ERRORS_COUNT);
114 mmap_.reset(); 113 mmap_.reset();
115 return false; 114 return false;
116 } 115 }
117 } 116 }
118 117
119 return true; 118 return true;
120 } 119 }
121 120
122 bool DataPack::GetStringPiece(uint32 resource_id, 121 bool DataPack::GetStringPiece(uint16 resource_id,
123 base::StringPiece* data) const { 122 base::StringPiece* data) const {
124 // It won't be hard to make this endian-agnostic, but it's not worth 123 // It won't be hard to make this endian-agnostic, but it's not worth
125 // bothering to do right now. 124 // bothering to do right now.
126 #if defined(__BYTE_ORDER) 125 #if defined(__BYTE_ORDER)
127 // Linux check 126 // Linux check
128 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, 127 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN,
129 datapack_assumes_little_endian); 128 datapack_assumes_little_endian);
130 #elif defined(__BIG_ENDIAN__) 129 #elif defined(__BIG_ENDIAN__)
131 // Mac check 130 // Mac check
132 #error DataPack assumes little endian 131 #error DataPack assumes little endian
133 #endif 132 #endif
134 133
135 DataPackEntry* target = reinterpret_cast<DataPackEntry*>( 134 DataPackEntry* target = reinterpret_cast<DataPackEntry*>(
136 bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_, 135 bsearch(&resource_id, mmap_->data() + kHeaderLength, resource_count_,
137 sizeof(DataPackEntry), DataPackEntry::CompareById)); 136 sizeof(DataPackEntry), DataPackEntry::CompareById));
138 if (!target) { 137 if (!target) {
139 return false; 138 return false;
140 } 139 }
141 140
142 data->set(mmap_->data() + target->file_offset, target->length); 141 data->set(mmap_->data() + target->file_offset, target->length);
143 return true; 142 return true;
144 } 143 }
145 144
146 RefCountedStaticMemory* DataPack::GetStaticMemory(uint32 resource_id) const { 145 RefCountedStaticMemory* DataPack::GetStaticMemory(uint16 resource_id) const {
147 base::StringPiece piece; 146 base::StringPiece piece;
148 if (!GetStringPiece(resource_id, &piece)) 147 if (!GetStringPiece(resource_id, &piece))
149 return NULL; 148 return NULL;
150 149
151 return new RefCountedStaticMemory( 150 return new RefCountedStaticMemory(
152 reinterpret_cast<const unsigned char*>(piece.data()), piece.length()); 151 reinterpret_cast<const unsigned char*>(piece.data()), piece.length());
153 } 152 }
154 153
155 // static 154 // static
156 bool DataPack::WritePack(const FilePath& path, 155 bool DataPack::WritePack(const FilePath& path,
157 const std::map<uint32, base::StringPiece>& resources) { 156 const std::map<uint16, base::StringPiece>& resources) {
158 FILE* file = file_util::OpenFile(path, "wb"); 157 FILE* file = file_util::OpenFile(path, "wb");
159 if (!file) 158 if (!file)
160 return false; 159 return false;
161 160
162 if (fwrite(&kFileFormatVersion, 1, kWord, file) != kWord) { 161 if (fwrite(&kFileFormatVersion, sizeof(kFileFormatVersion), 1, file) != 1) {
163 LOG(ERROR) << "Failed to write file version"; 162 LOG(ERROR) << "Failed to write file version";
164 file_util::CloseFile(file); 163 file_util::CloseFile(file);
165 return false; 164 return false;
166 } 165 }
167 166
168 // Note: the python version of this function explicitly sorted keys, but 167 // Note: the python version of this function explicitly sorted keys, but
169 // std::map is a sorted associative container, we shouldn't have to do that. 168 // std::map is a sorted associative container, we shouldn't have to do that.
170 uint32 entry_count = resources.size(); 169 uint32 entry_count = resources.size();
171 if (fwrite(&entry_count, 1, kWord, file) != kWord) { 170 if (fwrite(&entry_count, sizeof(entry_count), 1, file) != 1) {
172 LOG(ERROR) << "Failed to write entry count"; 171 LOG(ERROR) << "Failed to write entry count";
173 file_util::CloseFile(file); 172 file_util::CloseFile(file);
174 return false; 173 return false;
175 } 174 }
176 175
177 // Each entry is 3 uint32s. 176 // Each entry is 1 uint16 + 2 uint32s.
178 uint32 index_length = entry_count * 3 * kWord; 177 uint32 index_length = entry_count * sizeof(DataPackEntry);
179 uint32 data_offset = kHeaderLength + index_length; 178 uint32 data_offset = kHeaderLength + index_length;
180 for (std::map<uint32, base::StringPiece>::const_iterator it = 179 for (std::map<uint16, base::StringPiece>::const_iterator it =
181 resources.begin(); 180 resources.begin();
182 it != resources.end(); ++it) { 181 it != resources.end(); ++it) {
183 if (fwrite(&it->first, 1, kWord, file) != kWord) { 182 uint16 resource_id = it->first;
184 LOG(ERROR) << "Failed to write id for " << it->first; 183 if (fwrite(&resource_id, sizeof(resource_id), 1, file) != 1) {
184 LOG(ERROR) << "Failed to write id for " << resource_id;
185 file_util::CloseFile(file); 185 file_util::CloseFile(file);
186 return false; 186 return false;
187 } 187 }
188 188
189 if (fwrite(&data_offset, 1, kWord, file) != kWord) { 189 if (fwrite(&data_offset, sizeof(data_offset), 1, file) != 1) {
190 LOG(ERROR) << "Failed to write offset for " << it->first; 190 LOG(ERROR) << "Failed to write offset for " << resource_id;
191 file_util::CloseFile(file); 191 file_util::CloseFile(file);
192 return false; 192 return false;
193 } 193 }
194 194
195 uint32 len = it->second.length(); 195 uint32 len = it->second.length();
196 if (fwrite(&len, 1, kWord, file) != kWord) { 196 if (fwrite(&len, sizeof(len), 1, file) != 1) {
197 LOG(ERROR) << "Failed to write length for " << it->first; 197 LOG(ERROR) << "Failed to write length for " << resource_id;
198 file_util::CloseFile(file); 198 file_util::CloseFile(file);
199 return false; 199 return false;
200 } 200 }
201 201
202 data_offset += len; 202 data_offset += len;
203 } 203 }
204 204
205 for (std::map<uint32, base::StringPiece>::const_iterator it = 205 for (std::map<uint16, base::StringPiece>::const_iterator it =
206 resources.begin(); 206 resources.begin();
207 it != resources.end(); ++it) { 207 it != resources.end(); ++it) {
208 if (fwrite(it->second.data(), it->second.length(), 1, file) != 1) { 208 if (fwrite(it->second.data(), it->second.length(), 1, file) != 1) {
209 LOG(ERROR) << "Failed to write data for " << it->first; 209 LOG(ERROR) << "Failed to write data for " << it->first;
210 file_util::CloseFile(file); 210 file_util::CloseFile(file);
211 return false; 211 return false;
212 } 212 }
213 } 213 }
214 214
215 file_util::CloseFile(file); 215 file_util::CloseFile(file);
216 216
217 return true; 217 return true;
218 } 218 }
219 219
220 } // namespace ui 220 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/resource/data_pack.h ('k') | ui/base/resource/data_pack_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698