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

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

Issue 7744017: Updated *.pak file format to support both UTF8 and UTF16 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated. Created 9 years, 3 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
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 static const uint32 kFileFormatVersion = 3; 20 static const uint32 kFileFormatVersion = 4;
21 // Length of file header: version and entry count. 21 // Length of file header: version, entry count and text encoding type.
22 static const size_t kHeaderLength = 2 * sizeof(uint32); 22 static const size_t kHeaderLength = 2 * sizeof(uint32) + sizeof(uint8);
23 23
24 #pragma pack(push,2) 24 #pragma pack(push,2)
25 struct DataPackEntry { 25 struct DataPackEntry {
26 uint16 resource_id; 26 uint16 resource_id;
27 uint32 file_offset; 27 uint32 file_offset;
28 28
29 static int CompareById(const void* void_key, const void* void_entry) { 29 static int CompareById(const void* void_key, const void* void_entry) {
30 uint16 key = *reinterpret_cast<const uint16*>(void_key); 30 uint16 key = *reinterpret_cast<const uint16*>(void_key);
31 const DataPackEntry* entry = 31 const DataPackEntry* entry =
32 reinterpret_cast<const DataPackEntry*>(void_entry); 32 reinterpret_cast<const DataPackEntry*>(void_entry);
(...skipping 20 matching lines...) Expand all
53 ENTRY_NOT_FOUND, 53 ENTRY_NOT_FOUND,
54 54
55 LOAD_ERRORS_COUNT, 55 LOAD_ERRORS_COUNT,
56 }; 56 };
57 57
58 } // namespace 58 } // namespace
59 59
60 namespace ui { 60 namespace ui {
61 61
62 // In .cc for MemoryMappedFile dtor. 62 // In .cc for MemoryMappedFile dtor.
63 DataPack::DataPack() : resource_count_(0) { 63 DataPack::DataPack() : resource_count_(0), text_encoding_type_(BINARY) {
64 } 64 }
65 DataPack::~DataPack() { 65 DataPack::~DataPack() {
66 } 66 }
67 67
68 bool DataPack::Load(const FilePath& path) { 68 bool DataPack::Load(const FilePath& path) {
69 mmap_.reset(new file_util::MemoryMappedFile); 69 mmap_.reset(new file_util::MemoryMappedFile);
70 if (!mmap_->Initialize(path)) { 70 if (!mmap_->Initialize(path)) {
71 DLOG(ERROR) << "Failed to mmap datapack"; 71 DLOG(ERROR) << "Failed to mmap datapack";
72 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INIT_FAILED, 72 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INIT_FAILED,
73 LOAD_ERRORS_COUNT); 73 LOAD_ERRORS_COUNT);
74 mmap_.reset(); 74 mmap_.reset();
75 return false; 75 return false;
76 } 76 }
77 77
78 // Parse the header of the file. 78 // Parse the header of the file.
tony 2011/08/30 21:19:58 We should probably make sure that kHeaderLength <=
marcvs 2011/08/30 22:17:22 Done.
79 // First uint32: version; second: resource count. 79 // First uint32: version; second: resource count;
80 const uint32* ptr = reinterpret_cast<const uint32*>(mmap_->data()); 80 const uint32* ptr = reinterpret_cast<const uint32*>(mmap_->data());
81 uint32 version = ptr[0]; 81 uint32 version = ptr[0];
82 if (version != kFileFormatVersion) { 82 if (version != kFileFormatVersion) {
83 LOG(ERROR) << "Bad data pack version: got " << version << ", expected " 83 LOG(ERROR) << "Bad data pack version: got " << version << ", expected "
84 << kFileFormatVersion; 84 << kFileFormatVersion;
85 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", BAD_VERSION, 85 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", BAD_VERSION,
86 LOAD_ERRORS_COUNT); 86 LOAD_ERRORS_COUNT);
87 mmap_.reset(); 87 mmap_.reset();
88 return false; 88 return false;
89 } 89 }
90 resource_count_ = ptr[1]; 90 resource_count_ = ptr[1];
91 91
92 // third: text encoding.
93 const uint8* ptr_encoding = reinterpret_cast<const uint8*>(ptr + 2);
94 text_encoding_type_ = (TextEncodingType)(*ptr_encoding);
tony 2011/08/30 21:19:58 Nit: static_cast<TextEncodingType>
marcvs 2011/08/30 22:17:22 Done.
95 if (text_encoding_type_ != UTF8 && text_encoding_type_ != UTF16 &&
96 text_encoding_type_ != BINARY) {
97 LOG(ERROR) << "Bad data pack text encoding: got " << text_encoding_type_
98 << ", expected between " << BINARY << " and " << UTF16;
99 mmap_.reset();
100 return false;
101 }
102
92 // Sanity check the file. 103 // Sanity check the file.
93 // 1) Check we have enough entries. 104 // 1) Check we have enough entries.
94 if (kHeaderLength + resource_count_ * sizeof(DataPackEntry) > 105 if (kHeaderLength + resource_count_ * sizeof(DataPackEntry) >
95 mmap_->length()) { 106 mmap_->length()) {
96 LOG(ERROR) << "Data pack file corruption: too short for number of " 107 LOG(ERROR) << "Data pack file corruption: too short for number of "
97 "entries specified."; 108 "entries specified.";
98 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INDEX_TRUNCATED, 109 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INDEX_TRUNCATED,
99 LOAD_ERRORS_COUNT); 110 LOAD_ERRORS_COUNT);
100 mmap_.reset(); 111 mmap_.reset();
101 return false; 112 return false;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 base::StringPiece piece; 160 base::StringPiece piece;
150 if (!GetStringPiece(resource_id, &piece)) 161 if (!GetStringPiece(resource_id, &piece))
151 return NULL; 162 return NULL;
152 163
153 return new RefCountedStaticMemory( 164 return new RefCountedStaticMemory(
154 reinterpret_cast<const unsigned char*>(piece.data()), piece.length()); 165 reinterpret_cast<const unsigned char*>(piece.data()), piece.length());
155 } 166 }
156 167
157 // static 168 // static
158 bool DataPack::WritePack(const FilePath& path, 169 bool DataPack::WritePack(const FilePath& path,
159 const std::map<uint16, base::StringPiece>& resources) { 170 const std::map<uint16, base::StringPiece>& resources,
171 TextEncodingType textEncodingType) {
160 FILE* file = file_util::OpenFile(path, "wb"); 172 FILE* file = file_util::OpenFile(path, "wb");
161 if (!file) 173 if (!file)
162 return false; 174 return false;
163 175
164 if (fwrite(&kFileFormatVersion, sizeof(kFileFormatVersion), 1, file) != 1) { 176 if (fwrite(&kFileFormatVersion, sizeof(kFileFormatVersion), 1, file) != 1) {
165 LOG(ERROR) << "Failed to write file version"; 177 LOG(ERROR) << "Failed to write file version";
166 file_util::CloseFile(file); 178 file_util::CloseFile(file);
167 return false; 179 return false;
168 } 180 }
169 181
170 // Note: the python version of this function explicitly sorted keys, but 182 // Note: the python version of this function explicitly sorted keys, but
171 // std::map is a sorted associative container, we shouldn't have to do that. 183 // std::map is a sorted associative container, we shouldn't have to do that.
172 uint32 entry_count = resources.size(); 184 uint32 entry_count = resources.size();
173 if (fwrite(&entry_count, sizeof(entry_count), 1, file) != 1) { 185 if (fwrite(&entry_count, sizeof(entry_count), 1, file) != 1) {
174 LOG(ERROR) << "Failed to write entry count"; 186 LOG(ERROR) << "Failed to write entry count";
175 file_util::CloseFile(file); 187 file_util::CloseFile(file);
176 return false; 188 return false;
177 } 189 }
178 190
191 if (textEncodingType != UTF8 && textEncodingType != UTF16 &&
192 textEncodingType != BINARY) {
193 LOG(ERROR) << "Invalid text encoding type, got " << textEncodingType
194 << ", expected between " << BINARY << " and " << UTF16;
195 file_util::CloseFile(file);
196 return false;
197 }
198
199 uint8 write_buffer = textEncodingType;
200 if (fwrite(&write_buffer, sizeof(uint8), 1, file) != 1) {
201 LOG(ERROR) << "Failed to write file text resources encoding";
202 file_util::CloseFile(file);
203 return false;
204 }
205
179 // Each entry is a uint16 + a uint32. We have an extra entry after the last 206 // Each entry is a uint16 + a uint32. We have an extra entry after the last
180 // item so we can compute the size of the list item. 207 // item so we can compute the size of the list item.
181 uint32 index_length = (entry_count + 1) * sizeof(DataPackEntry); 208 uint32 index_length = (entry_count + 1) * sizeof(DataPackEntry);
182 uint32 data_offset = kHeaderLength + index_length; 209 uint32 data_offset = kHeaderLength + index_length;
183 for (std::map<uint16, base::StringPiece>::const_iterator it = 210 for (std::map<uint16, base::StringPiece>::const_iterator it =
184 resources.begin(); 211 resources.begin();
185 it != resources.end(); ++it) { 212 it != resources.end(); ++it) {
186 uint16 resource_id = it->first; 213 uint16 resource_id = it->first;
187 if (fwrite(&resource_id, sizeof(resource_id), 1, file) != 1) { 214 if (fwrite(&resource_id, sizeof(resource_id), 1, file) != 1) {
188 LOG(ERROR) << "Failed to write id for " << resource_id; 215 LOG(ERROR) << "Failed to write id for " << resource_id;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 return false; 250 return false;
224 } 251 }
225 } 252 }
226 253
227 file_util::CloseFile(file); 254 file_util::CloseFile(file);
228 255
229 return true; 256 return true;
230 } 257 }
231 258
232 } // namespace ui 259 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698