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

Side by Side Diff: net/disk_cache/simple/simple_index_file.cc

Issue 14263005: Refactor our SimpleIndex file format and serialization to use Pickle instead of the previously bugg… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: to commit again, since the last dcommit failed Created 7 years, 8 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
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/disk_cache/simple/simple_index_file.h"
6
7 #include "base/file_util.h"
8 #include "base/hash.h"
9 #include "base/logging.h"
10 #include "base/pickle.h"
11 #include "net/disk_cache/simple/simple_entry_format.h"
12 #include "net/disk_cache/simple/simple_index.h"
13 #include "net/disk_cache/simple/simple_util.h"
14 #include "third_party/zlib/zlib.h"
15
16
17 namespace {
18
19 const uint64 kMaxEntiresInIndex = 100000000;
20
21 uint32 CalculatePickleCRC(const Pickle& pickle) {
22 return crc32(crc32(0, Z_NULL, 0),
23 reinterpret_cast<const Bytef*>(pickle.payload()),
24 pickle.payload_size());
25 }
26
27 } // namespace
28
29 namespace disk_cache {
30
31 SimpleIndexFile::IndexMetadata::IndexMetadata() :
32 magic_number_(kSimpleIndexMagicNumber),
33 version_(kSimpleVersion),
34 number_of_entries_(0),
35 cache_size_(0) {}
36
37 SimpleIndexFile::IndexMetadata::IndexMetadata(
38 uint64 number_of_entries, uint64 cache_size) :
39 magic_number_(kSimpleIndexMagicNumber),
40 version_(kSimpleVersion),
41 number_of_entries_(number_of_entries),
42 cache_size_(cache_size) {}
43
44 void SimpleIndexFile::IndexMetadata::Serialize(Pickle* pickle) const {
45 DCHECK(pickle);
46 pickle->WriteUInt64(magic_number_);
47 pickle->WriteUInt32(version_);
48 pickle->WriteUInt64(number_of_entries_);
49 pickle->WriteUInt64(cache_size_);
50 }
51
52 bool SimpleIndexFile::IndexMetadata::Deserialize(PickleIterator* it) {
53 DCHECK(it);
54 return it->ReadUInt64(&magic_number_) &&
55 it->ReadUInt32(&version_) &&
56 it->ReadUInt64(&number_of_entries_)&&
57 it->ReadUInt64(&cache_size_);
58 }
59
60 bool SimpleIndexFile::IndexMetadata::CheckIndexMetadata() {
61 return number_of_entries_ <= kMaxEntiresInIndex &&
62 magic_number_ == disk_cache::kSimpleIndexMagicNumber &&
63 version_ == disk_cache::kSimpleVersion;
64 }
65
66 // static
67 scoped_ptr<SimpleIndex::EntrySet> SimpleIndexFile::LoadFromDisk(
68 const base::FilePath& index_filename) {
69 std::string contents;
70 if(!file_util::ReadFileToString(index_filename, &contents)) {
71 LOG(WARNING) << "Could not read Simple Index file.";
72 return scoped_ptr<SimpleIndex::EntrySet>(NULL);
73 }
74
75 return SimpleIndexFile::Deserialize(contents.data(), contents.size());
76 }
77
78 // static
79 scoped_ptr<SimpleIndex::EntrySet> SimpleIndexFile::Deserialize(const char* data,
80 int data_len) {
81 DCHECK(data);
82 Pickle pickle(data, data_len);
83 if (!pickle.data()) {
84 LOG(WARNING) << "Corrupt Simple Index File.";
85 return scoped_ptr<SimpleIndex::EntrySet>(NULL);
86 }
87
88 PickleIterator pickle_it(pickle);
89
90 SimpleIndexFile::PickleHeader* header_p =
91 pickle.headerT<SimpleIndexFile::PickleHeader>();
92 const uint32 crc_read = header_p->crc;
93 const uint32 crc_calculated = CalculatePickleCRC(pickle);
94
95 if (crc_read != crc_calculated) {
96 LOG(WARNING) << "Invalid CRC in Simple Index file.";
97 return scoped_ptr<SimpleIndex::EntrySet>(NULL);
98 }
99
100 SimpleIndexFile::IndexMetadata index_metadata;
101 if (!index_metadata.Deserialize(&pickle_it)) {
102 LOG(ERROR) << "Invalid index_metadata on Simple Cache Index.";
103 return scoped_ptr<SimpleIndex::EntrySet>(NULL);
104 }
105
106 if (!index_metadata.CheckIndexMetadata()) {
107 LOG(ERROR) << "Invalid index_metadata on Simple Cache Index.";
108 return scoped_ptr<SimpleIndex::EntrySet>(NULL);
109 }
110
111 scoped_ptr<SimpleIndex::EntrySet> index_file_entries(
112 new SimpleIndex::EntrySet());
113 while (index_file_entries->size() < index_metadata.GetNumberOfEntries()) {
114 EntryMetadata entry_metadata;
115 if (!entry_metadata.Deserialize(&pickle_it)) {
116 LOG(WARNING) << "Invalid EntryMetadata in Simple Index file.";
117 return scoped_ptr<SimpleIndex::EntrySet>(NULL);
118 }
119 SimpleIndex::InsertInEntrySet(entry_metadata, index_file_entries.get());
120 }
121
122 return index_file_entries.Pass();
123 }
124
125 // static
126 scoped_ptr<Pickle> SimpleIndexFile::Serialize(
127 const SimpleIndexFile::IndexMetadata& index_metadata,
128 const SimpleIndex::EntrySet& entries) {
129 scoped_ptr<Pickle> pickle(new Pickle(sizeof(SimpleIndexFile::PickleHeader)));
130
131 index_metadata.Serialize(pickle.get());
132 for (SimpleIndex::EntrySet::const_iterator it = entries.begin();
133 it != entries.end(); ++it) {
134 it->second.Serialize(pickle.get());
135 }
136 SimpleIndexFile::PickleHeader* header_p =
137 pickle->headerT<SimpleIndexFile::PickleHeader>();
138 header_p->crc = CalculatePickleCRC(*pickle);
139 return pickle.Pass();
140 }
141
142 // static
143 void SimpleIndexFile::WriteToDisk(const base::FilePath& index_filename,
144 const Pickle& pickle) {
145 const base::FilePath temp_filename =
146 index_filename.DirName().AppendASCII("index_temp");
147 int bytes_written = file_util::WriteFile(
148 temp_filename,
149 reinterpret_cast<const char*>(pickle.data()),
150 pickle.size());
151 DCHECK_EQ(bytes_written, implicit_cast<int>(pickle.size()));
152 if (bytes_written != static_cast<int>(pickle.size())) {
153 // TODO(felipeg): Add better error handling.
154 LOG(ERROR) << "Could not write Simple Cache index to temporary file: "
155 << temp_filename.value();
156 file_util::Delete(temp_filename, /* recursive = */ false);
157 return;
158 }
159 // Swap temp and index_file.
160 bool result = file_util::ReplaceFile(temp_filename, index_filename);
161 DCHECK(result);
162 }
163
164 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/simple/simple_index_file.h ('k') | net/disk_cache/simple/simple_index_file_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698