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

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: egors comments 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_disk_format.h"
12 #include "net/disk_cache/simple/simple_index_util.h"
13 #include "third_party/zlib/zlib.h"
14
15 namespace {
16
17 const uint64 kMaxEntiresInIndex = 100000000;
18
19 uint32 CalculatePickleCRC(const Pickle& pickle) {
20 return crc32(crc32(0, Z_NULL, 0),
21 reinterpret_cast<const Bytef*>(pickle.payload()),
22 implicit_cast<uInt>(pickle.payload_size()));
23 }
24
25 } // namespace
26
27 namespace disk_cache {
28
29 SimpleIndexFile::IndexMetadata::IndexMetadata() :
30 initial_magic_number_(kSimpleIndexInitialMagicNumber),
31 version_(kSimpleVersion),
32 number_of_entries_(0),
33 cache_size_(0) {}
34
35 SimpleIndexFile::IndexMetadata::IndexMetadata(
36 uint64 number_of_entries, uint64 cache_size) :
37 initial_magic_number_(kSimpleIndexInitialMagicNumber),
38 version_(kSimpleVersion),
39 number_of_entries_(number_of_entries),
40 cache_size_(cache_size) {}
41
42 void SimpleIndexFile::IndexMetadata::Serialize(Pickle* pickle) const {
43 DCHECK(pickle);
44 pickle->WriteUInt64(initial_magic_number_);
45 pickle->WriteUInt32(version_);
46 pickle->WriteUInt64(number_of_entries_);
47 pickle->WriteUInt64(cache_size_);
48 }
49
50 bool SimpleIndexFile::IndexMetadata::DeSerialize(PickleIterator* it) {
51 DCHECK(it);
52 return it->ReadUInt64(&initial_magic_number_) &&
53 it->ReadUInt32(&version_) &&
54 it->ReadUInt64(&number_of_entries_)&&
55 it->ReadUInt64(&cache_size_);
56 }
57
58 bool SimpleIndexFile::IndexMetadata::CheckIndexMetadata() {
59 return number_of_entries_ <= kMaxEntiresInIndex &&
60 initial_magic_number_ == disk_cache::kSimpleIndexInitialMagicNumber &&
61 version_ == disk_cache::kSimpleVersion;
62 }
63
64 // static
65 scoped_ptr<EntrySet> SimpleIndexFile::LoadFromDisk(
66 const base::FilePath& index_filename) {
67 std::string contents;
68 if(!file_util::ReadFileToString(index_filename, &contents)) {
69 LOG(WARNING) << "Could not read Simple Index file.";
70 return scoped_ptr<EntrySet>(NULL);
71 }
72
73 Pickle pickle(contents.data(), contents.size());
74 PickleIterator pickle_it(pickle);
75
76 SimpleIndexFile::PickleHeader* header_p =
77 pickle.headerT<SimpleIndexFile::PickleHeader>();
78 const uint32 crc_read = header_p->crc;
79 const uint32 crc_calculated = CalculatePickleCRC(pickle);
80
81 if (crc_read != crc_calculated) {
82 LOG(WARNING) << "Invalid CRC in Simple Index file.";
83 return scoped_ptr<EntrySet>(NULL);
84 }
85
86 SimpleIndexFile::IndexMetadata index_metadata;
87 if (!index_metadata.DeSerialize(&pickle_it)) {
88 LOG(ERROR) << "Invalid index_metadata on Simple Cache Index.";
89 return scoped_ptr<EntrySet>(NULL);
90 }
91
92 if (!index_metadata.CheckIndexMetadata()) {
93 LOG(ERROR) << "Invalid index_metadata on Simple Cache Index.";
94 return scoped_ptr<EntrySet>(NULL);
95 }
96
97 scoped_ptr<EntrySet> index_file_entries(new EntrySet());
98 while (index_file_entries->size() < index_metadata.GetNumberOfEntries()) {
99 EntryMetadata entry_metadata;
100 if (!entry_metadata.DeSerialize(&pickle_it)) {
101 LOG(WARNING) << "Invalid EntryMetadata in Simple Index file.";
102 return scoped_ptr<EntrySet>(NULL);
103 }
104 InsertInEntrySet(entry_metadata,
105 index_file_entries.get());
106 }
107
108 return index_file_entries.Pass();
109 }
110
111 // static
112 scoped_ptr<Pickle> SimpleIndexFile::Serialize(
113 const SimpleIndexFile::IndexMetadata& index_metadata,
114 const EntrySet& entries) {
115 scoped_ptr<Pickle> pickle(new Pickle(sizeof(SimpleIndexFile::PickleHeader)));
116
117 index_metadata.Serialize(pickle.get());
118 for (EntrySet::const_iterator it = entries.begin();
119 it != entries.end(); ++it) {
120 it->second.Serialize(pickle.get());
121 }
122 SimpleIndexFile::PickleHeader* header_p =
123 pickle->headerT<SimpleIndexFile::PickleHeader>();
124 header_p->crc = CalculatePickleCRC(*pickle);
125 return pickle.Pass();
126 }
127
128 // static
129 void SimpleIndexFile::WriteToDisk(const base::FilePath& index_filename,
130 const Pickle& pickle) {
131 const base::FilePath temp_filename =
132 index_filename.DirName().AppendASCII("index_temp");
133 int bytes_written = file_util::WriteFile(
134 temp_filename,
135 reinterpret_cast<const char*>(pickle.data()),
136 pickle.size());
137 DCHECK_EQ(bytes_written, implicit_cast<int>(pickle.size()));
138 if (bytes_written != static_cast<int>(pickle.size())) {
139 // TODO(felipeg): Add better error handling.
140 LOG(ERROR) << "Could not write Simple Cache index to temporary file: "
141 << temp_filename.value();
142 file_util::Delete(temp_filename, /* recursive = */ false);
143 return;
144 }
145 // Swap temp and index_file.
146 bool result = file_util::ReplaceFile(temp_filename, index_filename);
147 DCHECK(result);
148 }
149
150 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698