Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 pickle.payload_size()); | |
| 23 } | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 27 namespace disk_cache { | |
| 28 | |
| 29 SimpleIndexFile::IndexMetadata::IndexMetadata() : | |
| 30 magic_number_(kSimpleIndexMagicNumber), | |
| 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 magic_number_(kSimpleIndexMagicNumber), | |
| 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(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(&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 magic_number_ == disk_cache::kSimpleIndexMagicNumber && | |
| 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 return SimpleIndexFile::Deserialize(contents.data(), contents.size()); | |
| 74 } | |
| 75 | |
| 76 // static | |
| 77 scoped_ptr<EntrySet> SimpleIndexFile::Deserialize(const char* data, | |
|
gavinp
2013/04/15 19:27:46
Method ordering: methods in .cc should be in the s
| |
| 78 int data_len) { | |
| 79 Pickle pickle(data, data_len); | |
| 80 PickleIterator pickle_it(pickle); | |
| 81 | |
| 82 SimpleIndexFile::PickleHeader* header_p = | |
| 83 pickle.headerT<SimpleIndexFile::PickleHeader>(); | |
| 84 const uint32 crc_read = header_p->crc; | |
| 85 const uint32 crc_calculated = CalculatePickleCRC(pickle); | |
| 86 | |
| 87 if (crc_read != crc_calculated) { | |
| 88 LOG(WARNING) << "Invalid CRC in Simple Index file."; | |
| 89 return scoped_ptr<EntrySet>(NULL); | |
| 90 } | |
| 91 | |
| 92 SimpleIndexFile::IndexMetadata index_metadata; | |
| 93 if (!index_metadata.Deserialize(&pickle_it)) { | |
| 94 LOG(ERROR) << "Invalid index_metadata on Simple Cache Index."; | |
| 95 return scoped_ptr<EntrySet>(NULL); | |
| 96 } | |
| 97 | |
| 98 if (!index_metadata.CheckIndexMetadata()) { | |
| 99 LOG(ERROR) << "Invalid index_metadata on Simple Cache Index."; | |
| 100 return scoped_ptr<EntrySet>(NULL); | |
| 101 } | |
| 102 | |
| 103 scoped_ptr<EntrySet> index_file_entries(new EntrySet()); | |
| 104 while (index_file_entries->size() < index_metadata.GetNumberOfEntries()) { | |
| 105 EntryMetadata entry_metadata; | |
| 106 if (!entry_metadata.Deserialize(&pickle_it)) { | |
| 107 LOG(WARNING) << "Invalid EntryMetadata in Simple Index file."; | |
| 108 return scoped_ptr<EntrySet>(NULL); | |
| 109 } | |
| 110 InsertInEntrySet(entry_metadata, | |
| 111 index_file_entries.get()); | |
| 112 } | |
| 113 | |
| 114 return index_file_entries.Pass(); | |
| 115 } | |
| 116 | |
| 117 // static | |
| 118 scoped_ptr<Pickle> SimpleIndexFile::Serialize( | |
| 119 const SimpleIndexFile::IndexMetadata& index_metadata, | |
| 120 const EntrySet& entries) { | |
| 121 scoped_ptr<Pickle> pickle(new Pickle(sizeof(SimpleIndexFile::PickleHeader))); | |
| 122 | |
| 123 index_metadata.Serialize(pickle.get()); | |
| 124 for (EntrySet::const_iterator it = entries.begin(); | |
| 125 it != entries.end(); ++it) { | |
| 126 it->second.Serialize(pickle.get()); | |
| 127 } | |
| 128 SimpleIndexFile::PickleHeader* header_p = | |
| 129 pickle->headerT<SimpleIndexFile::PickleHeader>(); | |
| 130 header_p->crc = CalculatePickleCRC(*pickle); | |
| 131 return pickle.Pass(); | |
| 132 } | |
| 133 | |
| 134 // static | |
| 135 void SimpleIndexFile::WriteToDisk(const base::FilePath& index_filename, | |
| 136 const Pickle& pickle) { | |
| 137 const base::FilePath temp_filename = | |
| 138 index_filename.DirName().AppendASCII("index_temp"); | |
| 139 int bytes_written = file_util::WriteFile( | |
| 140 temp_filename, | |
| 141 reinterpret_cast<const char*>(pickle.data()), | |
| 142 pickle.size()); | |
| 143 DCHECK_EQ(bytes_written, implicit_cast<int>(pickle.size())); | |
| 144 if (bytes_written != static_cast<int>(pickle.size())) { | |
| 145 // TODO(felipeg): Add better error handling. | |
| 146 LOG(ERROR) << "Could not write Simple Cache index to temporary file: " | |
| 147 << temp_filename.value(); | |
| 148 file_util::Delete(temp_filename, /* recursive = */ false); | |
| 149 return; | |
| 150 } | |
| 151 // Swap temp and index_file. | |
| 152 bool result = file_util::ReplaceFile(temp_filename, index_filename); | |
| 153 DCHECK(result); | |
| 154 } | |
| 155 | |
| 156 } // namespace disk_cache | |
| OLD | NEW |