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 127a9e7621SOleksiy Vyalov #include "llvm/Support/MD5.h" 137a9e7621SOleksiy Vyalov 146801be33SOleksiy Vyalov #include <algorithm> 157a9e7621SOleksiy Vyalov #include <fstream> 167a9e7621SOleksiy Vyalov #include <vector> 177a9e7621SOleksiy Vyalov 187a9e7621SOleksiy Vyalov using namespace lldb; 197a9e7621SOleksiy Vyalov using namespace lldb_private; 207a9e7621SOleksiy Vyalov 217a9e7621SOleksiy Vyalov namespace { 227a9e7621SOleksiy Vyalov 23*b9c1b51eSKate Stone bool CalcMD5(const FileSpec &file_spec, uint64_t offset, uint64_t length, 24*b9c1b51eSKate Stone llvm::MD5::MD5Result &md5_result) { 257a9e7621SOleksiy Vyalov llvm::MD5 md5_hash; 267a9e7621SOleksiy Vyalov std::ifstream file(file_spec.GetPath(), std::ios::binary); 277a9e7621SOleksiy Vyalov if (!file.is_open()) 287a9e7621SOleksiy Vyalov return false; 297a9e7621SOleksiy Vyalov 306801be33SOleksiy Vyalov if (offset > 0) 316801be33SOleksiy Vyalov file.seekg(offset, file.beg); 326801be33SOleksiy Vyalov 337a9e7621SOleksiy Vyalov std::vector<char> read_buf(4096); 346801be33SOleksiy Vyalov uint64_t total_read_bytes = 0; 35*b9c1b51eSKate Stone while (!file.eof()) { 36*b9c1b51eSKate Stone const uint64_t to_read = 37*b9c1b51eSKate Stone (length > 0) ? std::min(static_cast<uint64_t>(read_buf.size()), 38*b9c1b51eSKate Stone length - total_read_bytes) 39*b9c1b51eSKate Stone : read_buf.size(); 406801be33SOleksiy Vyalov if (to_read == 0) 416801be33SOleksiy Vyalov break; 426801be33SOleksiy Vyalov 436801be33SOleksiy Vyalov file.read(&read_buf[0], to_read); 447a9e7621SOleksiy Vyalov const auto read_bytes = file.gcount(); 457a9e7621SOleksiy Vyalov if (read_bytes == 0) 467a9e7621SOleksiy Vyalov break; 477a9e7621SOleksiy Vyalov 487a9e7621SOleksiy Vyalov md5_hash.update(llvm::StringRef(&read_buf[0], read_bytes)); 496801be33SOleksiy Vyalov total_read_bytes += read_bytes; 507a9e7621SOleksiy Vyalov } 517a9e7621SOleksiy Vyalov 527a9e7621SOleksiy Vyalov md5_hash.final(md5_result); 537a9e7621SOleksiy Vyalov return true; 547a9e7621SOleksiy Vyalov } 557a9e7621SOleksiy Vyalov 567a9e7621SOleksiy Vyalov } // namespace 577a9e7621SOleksiy Vyalov 58*b9c1b51eSKate Stone bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, 59*b9c1b51eSKate Stone uint64_t &high) { 606801be33SOleksiy Vyalov return CalculateMD5(file_spec, 0, 0, low, high); 616801be33SOleksiy Vyalov } 626801be33SOleksiy Vyalov 63*b9c1b51eSKate Stone bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t offset, 64*b9c1b51eSKate Stone uint64_t length, uint64_t &low, uint64_t &high) { 657a9e7621SOleksiy Vyalov llvm::MD5::MD5Result md5_result; 666801be33SOleksiy Vyalov if (!CalcMD5(file_spec, offset, length, md5_result)) 677a9e7621SOleksiy Vyalov return false; 687a9e7621SOleksiy Vyalov 697a9e7621SOleksiy Vyalov const auto uint64_res = reinterpret_cast<const uint64_t *>(md5_result); 707a9e7621SOleksiy Vyalov high = uint64_res[0]; 717a9e7621SOleksiy Vyalov low = uint64_res[1]; 727a9e7621SOleksiy Vyalov 737a9e7621SOleksiy Vyalov return true; 747a9e7621SOleksiy Vyalov } 757a9e7621SOleksiy Vyalov 76*b9c1b51eSKate Stone bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec, 77*b9c1b51eSKate Stone std::string &digest_str) { 786801be33SOleksiy Vyalov return CalculateMD5AsString(file_spec, 0, 0, digest_str); 796801be33SOleksiy Vyalov } 806801be33SOleksiy Vyalov 81*b9c1b51eSKate Stone bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec, 82*b9c1b51eSKate Stone uint64_t offset, uint64_t length, 83*b9c1b51eSKate Stone std::string &digest_str) { 847a9e7621SOleksiy Vyalov llvm::MD5::MD5Result md5_result; 856801be33SOleksiy Vyalov if (!CalcMD5(file_spec, offset, length, md5_result)) 867a9e7621SOleksiy Vyalov return false; 877a9e7621SOleksiy Vyalov 887a9e7621SOleksiy Vyalov llvm::SmallString<32> result_str; 897a9e7621SOleksiy Vyalov llvm::MD5::stringifyResult(md5_result, result_str); 907a9e7621SOleksiy Vyalov digest_str = result_str.c_str(); 917a9e7621SOleksiy Vyalov return true; 927a9e7621SOleksiy Vyalov } 93