17a9e7621SOleksiy Vyalov //===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// 27a9e7621SOleksiy Vyalov // 37a9e7621SOleksiy Vyalov // The LLVM Compiler Infrastructure 47a9e7621SOleksiy Vyalov // 57a9e7621SOleksiy Vyalov // This file is distributed under the University of Illinois Open Source 67a9e7621SOleksiy Vyalov // License. See LICENSE.TXT for details. 77a9e7621SOleksiy Vyalov // 87a9e7621SOleksiy Vyalov //===----------------------------------------------------------------------===// 97a9e7621SOleksiy Vyalov 107a9e7621SOleksiy Vyalov #include "lldb/Host/FileSystem.h" 117a9e7621SOleksiy Vyalov 12*1408bf72SPavel Labath #include "llvm/Support/FileSystem.h" 137a9e7621SOleksiy Vyalov #include "llvm/Support/MD5.h" 147a9e7621SOleksiy Vyalov 156801be33SOleksiy Vyalov #include <algorithm> 167a9e7621SOleksiy Vyalov #include <fstream> 177a9e7621SOleksiy Vyalov #include <vector> 187a9e7621SOleksiy Vyalov 197a9e7621SOleksiy Vyalov using namespace lldb; 207a9e7621SOleksiy Vyalov using namespace lldb_private; 217a9e7621SOleksiy Vyalov 227a9e7621SOleksiy Vyalov namespace { 237a9e7621SOleksiy Vyalov 24b9c1b51eSKate Stone bool CalcMD5(const FileSpec &file_spec, uint64_t offset, uint64_t length, 25b9c1b51eSKate Stone llvm::MD5::MD5Result &md5_result) { 267a9e7621SOleksiy Vyalov llvm::MD5 md5_hash; 277a9e7621SOleksiy Vyalov std::ifstream file(file_spec.GetPath(), std::ios::binary); 287a9e7621SOleksiy Vyalov if (!file.is_open()) 297a9e7621SOleksiy Vyalov return false; 307a9e7621SOleksiy Vyalov 316801be33SOleksiy Vyalov if (offset > 0) 326801be33SOleksiy Vyalov file.seekg(offset, file.beg); 336801be33SOleksiy Vyalov 347a9e7621SOleksiy Vyalov std::vector<char> read_buf(4096); 356801be33SOleksiy Vyalov uint64_t total_read_bytes = 0; 36b9c1b51eSKate Stone while (!file.eof()) { 37b9c1b51eSKate Stone const uint64_t to_read = 38b9c1b51eSKate Stone (length > 0) ? std::min(static_cast<uint64_t>(read_buf.size()), 39b9c1b51eSKate Stone length - total_read_bytes) 40b9c1b51eSKate Stone : read_buf.size(); 416801be33SOleksiy Vyalov if (to_read == 0) 426801be33SOleksiy Vyalov break; 436801be33SOleksiy Vyalov 446801be33SOleksiy Vyalov file.read(&read_buf[0], to_read); 457a9e7621SOleksiy Vyalov const auto read_bytes = file.gcount(); 467a9e7621SOleksiy Vyalov if (read_bytes == 0) 477a9e7621SOleksiy Vyalov break; 487a9e7621SOleksiy Vyalov 497a9e7621SOleksiy Vyalov md5_hash.update(llvm::StringRef(&read_buf[0], read_bytes)); 506801be33SOleksiy Vyalov total_read_bytes += read_bytes; 517a9e7621SOleksiy Vyalov } 527a9e7621SOleksiy Vyalov 537a9e7621SOleksiy Vyalov md5_hash.final(md5_result); 547a9e7621SOleksiy Vyalov return true; 557a9e7621SOleksiy Vyalov } 567a9e7621SOleksiy Vyalov 577a9e7621SOleksiy Vyalov } // namespace 587a9e7621SOleksiy Vyalov 59b9c1b51eSKate Stone bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, 60b9c1b51eSKate Stone uint64_t &high) { 616801be33SOleksiy Vyalov return CalculateMD5(file_spec, 0, 0, low, high); 626801be33SOleksiy Vyalov } 636801be33SOleksiy Vyalov 64b9c1b51eSKate Stone bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t offset, 65b9c1b51eSKate Stone uint64_t length, uint64_t &low, uint64_t &high) { 667a9e7621SOleksiy Vyalov llvm::MD5::MD5Result md5_result; 676801be33SOleksiy Vyalov if (!CalcMD5(file_spec, offset, length, md5_result)) 687a9e7621SOleksiy Vyalov return false; 697a9e7621SOleksiy Vyalov 707a9e7621SOleksiy Vyalov const auto uint64_res = reinterpret_cast<const uint64_t *>(md5_result); 717a9e7621SOleksiy Vyalov high = uint64_res[0]; 727a9e7621SOleksiy Vyalov low = uint64_res[1]; 737a9e7621SOleksiy Vyalov 747a9e7621SOleksiy Vyalov return true; 757a9e7621SOleksiy Vyalov } 767a9e7621SOleksiy Vyalov 77b9c1b51eSKate Stone bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec, 78b9c1b51eSKate Stone std::string &digest_str) { 796801be33SOleksiy Vyalov return CalculateMD5AsString(file_spec, 0, 0, digest_str); 806801be33SOleksiy Vyalov } 816801be33SOleksiy Vyalov 82b9c1b51eSKate Stone bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec, 83b9c1b51eSKate Stone uint64_t offset, uint64_t length, 84b9c1b51eSKate Stone std::string &digest_str) { 857a9e7621SOleksiy Vyalov llvm::MD5::MD5Result md5_result; 866801be33SOleksiy Vyalov if (!CalcMD5(file_spec, offset, length, md5_result)) 877a9e7621SOleksiy Vyalov return false; 887a9e7621SOleksiy Vyalov 897a9e7621SOleksiy Vyalov llvm::SmallString<32> result_str; 907a9e7621SOleksiy Vyalov llvm::MD5::stringifyResult(md5_result, result_str); 917a9e7621SOleksiy Vyalov digest_str = result_str.c_str(); 927a9e7621SOleksiy Vyalov return true; 937a9e7621SOleksiy Vyalov } 94*1408bf72SPavel Labath 95*1408bf72SPavel Labath llvm::sys::TimePoint<> 96*1408bf72SPavel Labath FileSystem::GetModificationTime(const FileSpec &file_spec) { 97*1408bf72SPavel Labath llvm::sys::fs::file_status status; 98*1408bf72SPavel Labath std::error_code ec = llvm::sys::fs::status(file_spec.GetPath(), status); 99*1408bf72SPavel Labath if (ec) 100*1408bf72SPavel Labath return llvm::sys::TimePoint<>(); 101*1408bf72SPavel Labath return status.getLastModificationTime(); 102*1408bf72SPavel Labath } 103