1 // Copyright 2013 The Chromium Authors
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_util.h"
6
7 #include <string.h>
8
9 #include <limits>
10 #include <string_view>
11
12 #include "base/check_op.h"
13 #include "base/files/file_util.h"
14 #include "base/format_macros.h"
15 #include "base/hash/sha1.h"
16 #include "base/numerics/byte_conversions.h"
17 #include "base/numerics/safe_conversions.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/threading/thread_restrictions.h"
21 #include "base/time/time.h"
22 #include "net/disk_cache/simple/simple_entry_format.h"
23 #include "third_party/zlib/zlib.h"
24
25 namespace {
26
27 // Size of the uint64_t hash_key number in Hex format in a string.
28 const size_t kEntryHashKeyAsHexStringSize = 2 * sizeof(uint64_t);
29
30 } // namespace
31
32 namespace disk_cache::simple_util {
33
ConvertEntryHashKeyToHexString(uint64_t hash_key)34 std::string ConvertEntryHashKeyToHexString(uint64_t hash_key) {
35 std::string hash_key_str = base::StringPrintf("%016" PRIx64, hash_key);
36 DCHECK_EQ(kEntryHashKeyAsHexStringSize, hash_key_str.size());
37 return hash_key_str;
38 }
39
GetEntryHashKeyAsHexString(const std::string & key)40 std::string GetEntryHashKeyAsHexString(const std::string& key) {
41 std::string hash_key_str =
42 ConvertEntryHashKeyToHexString(GetEntryHashKey(key));
43 DCHECK_EQ(kEntryHashKeyAsHexStringSize, hash_key_str.size());
44 return hash_key_str;
45 }
46
GetEntryHashKeyFromHexString(std::string_view hash_key,uint64_t * hash_key_out)47 bool GetEntryHashKeyFromHexString(std::string_view hash_key,
48 uint64_t* hash_key_out) {
49 if (hash_key.size() != kEntryHashKeyAsHexStringSize) {
50 return false;
51 }
52 return base::HexStringToUInt64(hash_key, hash_key_out);
53 }
54
GetEntryHashKey(const std::string & key)55 uint64_t GetEntryHashKey(const std::string& key) {
56 base::SHA1Digest sha_hash = base::SHA1Hash(base::as_byte_span(key));
57 return base::U64FromLittleEndian(base::span(sha_hash).first<8u>());
58 }
59
GetFilenameFromEntryFileKeyAndFileIndex(const SimpleFileTracker::EntryFileKey & key,int file_index)60 std::string GetFilenameFromEntryFileKeyAndFileIndex(
61 const SimpleFileTracker::EntryFileKey& key,
62 int file_index) {
63 if (key.doom_generation == 0)
64 return base::StringPrintf("%016" PRIx64 "_%1d", key.entry_hash, file_index);
65 else
66 return base::StringPrintf("todelete_%016" PRIx64 "_%1d_%" PRIu64,
67 key.entry_hash, file_index, key.doom_generation);
68 }
69
GetSparseFilenameFromEntryFileKey(const SimpleFileTracker::EntryFileKey & key)70 std::string GetSparseFilenameFromEntryFileKey(
71 const SimpleFileTracker::EntryFileKey& key) {
72 if (key.doom_generation == 0)
73 return base::StringPrintf("%016" PRIx64 "_s", key.entry_hash);
74 else
75 return base::StringPrintf("todelete_%016" PRIx64 "_s_%" PRIu64,
76 key.entry_hash, key.doom_generation);
77 }
78
GetFilenameFromKeyAndFileIndex(const std::string & key,int file_index)79 std::string GetFilenameFromKeyAndFileIndex(const std::string& key,
80 int file_index) {
81 return GetEntryHashKeyAsHexString(key) +
82 base::StringPrintf("_%1d", file_index);
83 }
84
GetHeaderSize(size_t key_length)85 size_t GetHeaderSize(size_t key_length) {
86 return sizeof(SimpleFileHeader) + key_length;
87 }
88
GetDataSizeFromFileSize(size_t key_length,int64_t file_size)89 int32_t GetDataSizeFromFileSize(size_t key_length, int64_t file_size) {
90 int64_t data_size =
91 file_size - key_length - sizeof(SimpleFileHeader) - sizeof(SimpleFileEOF);
92 return base::checked_cast<int32_t>(data_size);
93 }
94
GetFileSizeFromDataSize(size_t key_length,int32_t data_size)95 int64_t GetFileSizeFromDataSize(size_t key_length, int32_t data_size) {
96 return data_size + key_length + sizeof(SimpleFileHeader) +
97 sizeof(SimpleFileEOF);
98 }
99
GetFileIndexFromStreamIndex(int stream_index)100 int GetFileIndexFromStreamIndex(int stream_index) {
101 return (stream_index == 2) ? 1 : 0;
102 }
103
Crc32(base::span<const uint8_t> data)104 uint32_t Crc32(base::span<const uint8_t> data) {
105 auto chars = base::as_chars(data);
106 return Crc32(chars.data(), base::checked_cast<int>(data.size()));
107 }
108
Crc32(const char * data,int length)109 uint32_t Crc32(const char* data, int length) {
110 uint32_t empty_crc = crc32(0, Z_NULL, 0);
111 if (length == 0)
112 return empty_crc;
113 return crc32(empty_crc, reinterpret_cast<const Bytef*>(data), length);
114 }
115
IncrementalCrc32(uint32_t previous_crc,const char * data,int length)116 uint32_t IncrementalCrc32(uint32_t previous_crc, const char* data, int length) {
117 return crc32(previous_crc, reinterpret_cast<const Bytef*>(data), length);
118 }
119
120 } // namespace disk_cache::simple_util
121