Home | History | Annotate | Download | only in simple
      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 
     19 namespace {
     20 
     21 // Size of the uint64 hash_key number in Hex format in a string.
     22 const size_t kEntryHashKeyAsHexStringSize = 2 * sizeof(uint64);
     23 
     24 // TODO(clamy, gavinp): this should go in base
     25 bool 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 
     45 namespace disk_cache {
     46 
     47 namespace simple_util {
     48 
     49 std::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 
     55 std::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 
     62 bool 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 
     70 uint64 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 
     80 std::string GetFilenameFromEntryHashAndFileIndex(uint64 entry_hash,
     81                                                  int file_index) {
     82   return base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, file_index);
     83 }
     84 
     85 std::string GetSparseFilenameFromEntryHash(uint64 entry_hash) {
     86   return base::StringPrintf("%016" PRIx64 "_s", entry_hash);
     87 }
     88 
     89 std::string GetFilenameFromKeyAndFileIndex(const std::string& key,
     90                                            int file_index) {
     91   return GetEntryHashKeyAsHexString(key) +
     92          base::StringPrintf("_%1d", file_index);
     93 }
     94 
     95 int32 GetDataSizeFromKeyAndFileSize(const std::string& key, int64 file_size) {
     96   int64 data_size = file_size - key.size() - sizeof(SimpleFileHeader) -
     97                     sizeof(SimpleFileEOF);
     98   DCHECK_GE(implicit_cast<int64>(std::numeric_limits<int32>::max()), data_size);
     99   return data_size;
    100 }
    101 
    102 int64 GetFileSizeFromKeyAndDataSize(const std::string& key, int32 data_size) {
    103   return data_size + key.size() + sizeof(SimpleFileHeader) +
    104       sizeof(SimpleFileEOF);
    105 }
    106 
    107 int GetFileIndexFromStreamIndex(int stream_index) {
    108   return (stream_index == 2) ? 1 : 0;
    109 }
    110 
    111 // TODO(clamy, gavinp): this should go in base
    112 bool GetMTime(const base::FilePath& path, base::Time* out_mtime) {
    113   DCHECK(out_mtime);
    114 #if defined(OS_POSIX)
    115   base::ThreadRestrictions::AssertIOAllowed();
    116   struct stat file_stat;
    117   if (stat(path.value().c_str(), &file_stat) != 0)
    118     return false;
    119   time_t sec;
    120   long nsec;
    121   if (GetNanoSecsFromStat(file_stat, &sec, &nsec)) {
    122     int64 usec = (nsec / base::Time::kNanosecondsPerMicrosecond);
    123     *out_mtime = base::Time::FromTimeT(sec)
    124         + base::TimeDelta::FromMicroseconds(usec);
    125     return true;
    126   }
    127 #endif
    128   base::PlatformFileInfo file_info;
    129   if (!base::GetFileInfo(path, &file_info))
    130     return false;
    131   *out_mtime = file_info.last_modified;
    132   return true;
    133 }
    134 
    135 }  // namespace simple_backend
    136 
    137 }  // namespace disk_cache
    138