11c3bbb01SEd Maste //===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// 21c3bbb01SEd Maste // 31c3bbb01SEd Maste // The LLVM Compiler Infrastructure 41c3bbb01SEd Maste // 51c3bbb01SEd Maste // This file is distributed under the University of Illinois Open Source 61c3bbb01SEd Maste // License. See LICENSE.TXT for details. 71c3bbb01SEd Maste // 81c3bbb01SEd Maste //===----------------------------------------------------------------------===// 91c3bbb01SEd Maste 101c3bbb01SEd Maste #include "lldb/Host/FileSystem.h" 111c3bbb01SEd Maste 12435933ddSDimitry Andric #include "llvm/Support/FileSystem.h" 131c3bbb01SEd Maste #include "llvm/Support/MD5.h" 141c3bbb01SEd Maste 151c3bbb01SEd Maste #include <algorithm> 161c3bbb01SEd Maste #include <fstream> 171c3bbb01SEd Maste #include <vector> 181c3bbb01SEd Maste 191c3bbb01SEd Maste using namespace lldb; 201c3bbb01SEd Maste using namespace lldb_private; 211c3bbb01SEd Maste 221c3bbb01SEd Maste namespace { 231c3bbb01SEd Maste 24435933ddSDimitry Andric bool CalcMD5(const FileSpec &file_spec, uint64_t offset, uint64_t length, 25435933ddSDimitry Andric llvm::MD5::MD5Result &md5_result) { 261c3bbb01SEd Maste llvm::MD5 md5_hash; 271c3bbb01SEd Maste std::ifstream file(file_spec.GetPath(), std::ios::binary); 281c3bbb01SEd Maste if (!file.is_open()) 291c3bbb01SEd Maste return false; 301c3bbb01SEd Maste 311c3bbb01SEd Maste if (offset > 0) 321c3bbb01SEd Maste file.seekg(offset, file.beg); 331c3bbb01SEd Maste 341c3bbb01SEd Maste std::vector<char> read_buf(4096); 351c3bbb01SEd Maste uint64_t total_read_bytes = 0; 36435933ddSDimitry Andric while (!file.eof()) { 37435933ddSDimitry Andric const uint64_t to_read = 38435933ddSDimitry Andric (length > 0) ? std::min(static_cast<uint64_t>(read_buf.size()), 39435933ddSDimitry Andric length - total_read_bytes) 40435933ddSDimitry Andric : read_buf.size(); 411c3bbb01SEd Maste if (to_read == 0) 421c3bbb01SEd Maste break; 431c3bbb01SEd Maste 441c3bbb01SEd Maste file.read(&read_buf[0], to_read); 451c3bbb01SEd Maste const auto read_bytes = file.gcount(); 461c3bbb01SEd Maste if (read_bytes == 0) 471c3bbb01SEd Maste break; 481c3bbb01SEd Maste 491c3bbb01SEd Maste md5_hash.update(llvm::StringRef(&read_buf[0], read_bytes)); 501c3bbb01SEd Maste total_read_bytes += read_bytes; 511c3bbb01SEd Maste } 521c3bbb01SEd Maste 531c3bbb01SEd Maste md5_hash.final(md5_result); 541c3bbb01SEd Maste return true; 551c3bbb01SEd Maste } 561c3bbb01SEd Maste 571c3bbb01SEd Maste } // namespace 581c3bbb01SEd Maste 59435933ddSDimitry Andric bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, 60435933ddSDimitry Andric uint64_t &high) { 611c3bbb01SEd Maste return CalculateMD5(file_spec, 0, 0, low, high); 621c3bbb01SEd Maste } 631c3bbb01SEd Maste 64435933ddSDimitry Andric bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t offset, 65435933ddSDimitry Andric uint64_t length, uint64_t &low, uint64_t &high) { 661c3bbb01SEd Maste llvm::MD5::MD5Result md5_result; 671c3bbb01SEd Maste if (!CalcMD5(file_spec, offset, length, md5_result)) 681c3bbb01SEd Maste return false; 691c3bbb01SEd Maste 701c3bbb01SEd Maste const auto uint64_res = reinterpret_cast<const uint64_t *>(md5_result); 711c3bbb01SEd Maste high = uint64_res[0]; 721c3bbb01SEd Maste low = uint64_res[1]; 731c3bbb01SEd Maste 741c3bbb01SEd Maste return true; 751c3bbb01SEd Maste } 761c3bbb01SEd Maste 77435933ddSDimitry Andric bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec, 78435933ddSDimitry Andric std::string &digest_str) { 791c3bbb01SEd Maste return CalculateMD5AsString(file_spec, 0, 0, digest_str); 801c3bbb01SEd Maste } 811c3bbb01SEd Maste 82435933ddSDimitry Andric bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec, 83435933ddSDimitry Andric uint64_t offset, uint64_t length, 84435933ddSDimitry Andric std::string &digest_str) { 851c3bbb01SEd Maste llvm::MD5::MD5Result md5_result; 861c3bbb01SEd Maste if (!CalcMD5(file_spec, offset, length, md5_result)) 871c3bbb01SEd Maste return false; 881c3bbb01SEd Maste 891c3bbb01SEd Maste llvm::SmallString<32> result_str; 901c3bbb01SEd Maste llvm::MD5::stringifyResult(md5_result, result_str); 911c3bbb01SEd Maste digest_str = result_str.c_str(); 921c3bbb01SEd Maste return true; 931c3bbb01SEd Maste } 94435933ddSDimitry Andric 95435933ddSDimitry Andric llvm::sys::TimePoint<> 96435933ddSDimitry Andric FileSystem::GetModificationTime(const FileSpec &file_spec) { 97435933ddSDimitry Andric llvm::sys::fs::file_status status; 98435933ddSDimitry Andric std::error_code ec = llvm::sys::fs::status(file_spec.GetPath(), status); 99435933ddSDimitry Andric if (ec) 100435933ddSDimitry Andric return llvm::sys::TimePoint<>(); 101435933ddSDimitry Andric return status.getLastModificationTime(); 102435933ddSDimitry Andric } 103