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

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: Cleaned up comments/ 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 = 3 * sizeof(uint32);
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.
79 // First uint32: version; second: resource count. 79 // First uint32: version; second: resource count; third: text encoding.
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 text_encoding_type_ = ptr[2];
92 if (text_encoding_type_ != UTF8 && text_encoding_type_ != UTF16 &&
93 text_encoding_type_ != BINARY) {
94 LOG(ERROR) << "Bad data pack text encoding: got " << text_encoding_type_
95 << ", expected between " << BINARY << " and " << UTF16;
96 mmap_.reset();
97 return false;
98 }
91 99
92 // Sanity check the file. 100 // Sanity check the file.
93 // 1) Check we have enough entries. 101 // 1) Check we have enough entries.
94 if (kHeaderLength + resource_count_ * sizeof(DataPackEntry) > 102 if (kHeaderLength + resource_count_ * sizeof(DataPackEntry) >
95 mmap_->length()) { 103 mmap_->length()) {
96 LOG(ERROR) << "Data pack file corruption: too short for number of " 104 LOG(ERROR) << "Data pack file corruption: too short for number of "
97 "entries specified."; 105 "entries specified.";
98 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INDEX_TRUNCATED, 106 UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INDEX_TRUNCATED,
99 LOAD_ERRORS_COUNT); 107 LOAD_ERRORS_COUNT);
100 mmap_.reset(); 108 mmap_.reset();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 base::StringPiece piece; 157 base::StringPiece piece;
150 if (!GetStringPiece(resource_id, &piece)) 158 if (!GetStringPiece(resource_id, &piece))
151 return NULL; 159 return NULL;
152 160
153 return new RefCountedStaticMemory( 161 return new RefCountedStaticMemory(
154 reinterpret_cast<const unsigned char*>(piece.data()), piece.length()); 162 reinterpret_cast<const unsigned char*>(piece.data()), piece.length());
155 } 163 }
156 164
157 // static 165 // static
158 bool DataPack::WritePack(const FilePath& path, 166 bool DataPack::WritePack(const FilePath& path,
159 const std::map<uint16, base::StringPiece>& resources) { 167 const std::map<uint16, base::StringPiece>& resources,
168 const uint32 textEncodingType) {
160 FILE* file = file_util::OpenFile(path, "wb"); 169 FILE* file = file_util::OpenFile(path, "wb");
161 if (!file) 170 if (!file)
162 return false; 171 return false;
163 172
164 if (fwrite(&kFileFormatVersion, sizeof(kFileFormatVersion), 1, file) != 1) { 173 if (fwrite(&kFileFormatVersion, sizeof(kFileFormatVersion), 1, file) != 1) {
165 LOG(ERROR) << "Failed to write file version"; 174 LOG(ERROR) << "Failed to write file version";
166 file_util::CloseFile(file); 175 file_util::CloseFile(file);
167 return false; 176 return false;
168 } 177 }
169 178
170 // Note: the python version of this function explicitly sorted keys, but 179 // 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. 180 // std::map is a sorted associative container, we shouldn't have to do that.
172 uint32 entry_count = resources.size(); 181 uint32 entry_count = resources.size();
173 if (fwrite(&entry_count, sizeof(entry_count), 1, file) != 1) { 182 if (fwrite(&entry_count, sizeof(entry_count), 1, file) != 1) {
174 LOG(ERROR) << "Failed to write entry count"; 183 LOG(ERROR) << "Failed to write entry count";
175 file_util::CloseFile(file); 184 file_util::CloseFile(file);
176 return false; 185 return false;
177 } 186 }
178 187
188 if (textEncodingType != UTF8 && textEncodingType != UTF16 &&
189 textEncodingType != BINARY) {
190 LOG(ERROR) << "Invalid text encoding type, got " << textEncodingType
191 << ", expected betwee " << BINARY << " and " << UTF16;
tony 2011/08/29 21:24:39 typo: between
marcvs 2011/08/30 07:58:55 Done.
192 file_util::CloseFile(file);
193 return false;
194 }
195
196 if (fwrite(&textEncodingType, sizeof(textEncodingType), 1, file) != 1) {
197 LOG(ERROR) << "Failed to write file text resources encoding";
198 file_util::CloseFile(file);
199 return false;
200 }
201
179 // Each entry is a uint16 + a uint32. We have an extra entry after the last 202 // 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. 203 // item so we can compute the size of the list item.
181 uint32 index_length = (entry_count + 1) * sizeof(DataPackEntry); 204 uint32 index_length = (entry_count + 1) * sizeof(DataPackEntry);
182 uint32 data_offset = kHeaderLength + index_length; 205 uint32 data_offset = kHeaderLength + index_length;
183 for (std::map<uint16, base::StringPiece>::const_iterator it = 206 for (std::map<uint16, base::StringPiece>::const_iterator it =
184 resources.begin(); 207 resources.begin();
185 it != resources.end(); ++it) { 208 it != resources.end(); ++it) {
186 uint16 resource_id = it->first; 209 uint16 resource_id = it->first;
187 if (fwrite(&resource_id, sizeof(resource_id), 1, file) != 1) { 210 if (fwrite(&resource_id, sizeof(resource_id), 1, file) != 1) {
188 LOG(ERROR) << "Failed to write id for " << resource_id; 211 LOG(ERROR) << "Failed to write id for " << resource_id;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 return false; 246 return false;
224 } 247 }
225 } 248 }
226 249
227 file_util::CloseFile(file); 250 file_util::CloseFile(file);
228 251
229 return true; 252 return true;
230 } 253 }
231 254
232 } // namespace ui 255 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698