simple_util.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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_util.h" 6 7#include <limits> 8 9#include "base/file_util.h" 10#include "base/format_macros.h" 11#include "base/logging.h" 12#include "base/sha1.h" 13#include "base/strings/string_number_conversions.h" 14#include "base/strings/stringprintf.h" 15#include "base/threading/thread_restrictions.h" 16#include "base/time/time.h" 17#include "net/disk_cache/simple/simple_entry_format.h" 18 19namespace { 20 21// Size of the uint64 hash_key number in Hex format in a string. 22const size_t kEntryHashKeyAsHexStringSize = 2 * sizeof(uint64); 23 24// TODO(clamy, gavinp): this should go in base 25bool GetNanoSecsFromStat(const struct stat& st, 26 time_t* out_sec, 27 long* out_nsec) { 28#if defined(OS_ANDROID) 29 *out_sec = st.st_mtime; 30 *out_nsec = st.st_mtime_nsec; 31#elif defined(OS_LINUX) 32 *out_sec = st.st_mtim.tv_sec; 33 *out_nsec = st.st_mtim.tv_nsec; 34#elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD) 35 *out_sec = st.st_mtimespec.tv_sec; 36 *out_nsec = st.st_mtimespec.tv_nsec; 37#else 38 return false; 39#endif 40 return true; 41} 42 43} // namespace 44 45namespace disk_cache { 46 47namespace simple_util { 48 49std::string ConvertEntryHashKeyToHexString(uint64 hash_key) { 50 const std::string hash_key_str = base::StringPrintf("%016" PRIx64, hash_key); 51 DCHECK_EQ(kEntryHashKeyAsHexStringSize, hash_key_str.size()); 52 return hash_key_str; 53} 54 55std::string GetEntryHashKeyAsHexString(const std::string& key) { 56 std::string hash_key_str = 57 ConvertEntryHashKeyToHexString(GetEntryHashKey(key)); 58 DCHECK_EQ(kEntryHashKeyAsHexStringSize, hash_key_str.size()); 59 return hash_key_str; 60} 61 62bool GetEntryHashKeyFromHexString(const base::StringPiece& hash_key, 63 uint64* hash_key_out) { 64 if (hash_key.size() != kEntryHashKeyAsHexStringSize) { 65 return false; 66 } 67 return base::HexStringToUInt64(hash_key, hash_key_out); 68} 69 70uint64 GetEntryHashKey(const std::string& key) { 71 union { 72 unsigned char sha_hash[base::kSHA1Length]; 73 uint64 key_hash; 74 } u; 75 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(key.data()), 76 key.size(), u.sha_hash); 77 return u.key_hash; 78} 79 80std::string GetFilenameFromEntryHashAndIndex(uint64 entry_hash, 81 int index) { 82 return base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, index); 83} 84 85std::string GetFilenameFromKeyAndIndex(const std::string& key, int index) { 86 return GetEntryHashKeyAsHexString(key) + base::StringPrintf("_%1d", index); 87} 88 89int32 GetDataSizeFromKeyAndFileSize(const std::string& key, int64 file_size) { 90 int64 data_size = file_size - key.size() - sizeof(SimpleFileHeader) - 91 sizeof(SimpleFileEOF); 92 DCHECK_GE(implicit_cast<int64>(std::numeric_limits<int32>::max()), data_size); 93 return data_size; 94} 95 96int64 GetFileSizeFromKeyAndDataSize(const std::string& key, int32 data_size) { 97 return data_size + key.size() + sizeof(SimpleFileHeader) + 98 sizeof(SimpleFileEOF); 99} 100 101int64 GetFileOffsetFromKeyAndDataOffset(const std::string& key, 102 int data_offset) { 103 const int64 headers_size = sizeof(disk_cache::SimpleFileHeader) + key.size(); 104 return headers_size + data_offset; 105} 106 107// TODO(clamy, gavinp): this should go in base 108bool GetMTime(const base::FilePath& path, base::Time* out_mtime) { 109 DCHECK(out_mtime); 110#if defined(OS_POSIX) 111 base::ThreadRestrictions::AssertIOAllowed(); 112 struct stat file_stat; 113 if (stat(path.value().c_str(), &file_stat) != 0) 114 return false; 115 time_t sec; 116 long nsec; 117 if (GetNanoSecsFromStat(file_stat, &sec, &nsec)) { 118 int64 usec = (nsec / base::Time::kNanosecondsPerMicrosecond); 119 *out_mtime = base::Time::FromTimeT(sec) 120 + base::TimeDelta::FromMicroseconds(usec); 121 return true; 122 } 123#endif 124 base::PlatformFileInfo file_info; 125 if (!file_util::GetFileInfo(path, &file_info)) 126 return false; 127 *out_mtime = file_info.last_modified; 128 return true; 129} 130 131} // namespace simple_backend 132 133} // namespace disk_cache 134