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 14*6801be33SOleksiy 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 237a9e7621SOleksiy Vyalov bool 24*6801be33SOleksiy Vyalov CalcMD5(const FileSpec &file_spec, uint64_t offset, uint64_t length, llvm::MD5::MD5Result &md5_result) 257a9e7621SOleksiy Vyalov { 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 31*6801be33SOleksiy Vyalov if (offset > 0) 32*6801be33SOleksiy Vyalov file.seekg(offset, file.beg); 33*6801be33SOleksiy Vyalov 347a9e7621SOleksiy Vyalov std::vector<char> read_buf(4096); 35*6801be33SOleksiy Vyalov uint64_t total_read_bytes = 0; 367a9e7621SOleksiy Vyalov while (!file.eof()) 377a9e7621SOleksiy Vyalov { 38*6801be33SOleksiy Vyalov const uint64_t to_read = (length > 0) ? 39*6801be33SOleksiy Vyalov std::min(static_cast<uint64_t>(read_buf.size()), length - total_read_bytes) : 40*6801be33SOleksiy Vyalov read_buf.size(); 41*6801be33SOleksiy Vyalov if (to_read == 0) 42*6801be33SOleksiy Vyalov break; 43*6801be33SOleksiy Vyalov 44*6801be33SOleksiy 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)); 50*6801be33SOleksiy 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 597a9e7621SOleksiy Vyalov bool 607a9e7621SOleksiy Vyalov FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high) 617a9e7621SOleksiy Vyalov { 62*6801be33SOleksiy Vyalov return CalculateMD5(file_spec, 0, 0, low, high); 63*6801be33SOleksiy Vyalov } 64*6801be33SOleksiy Vyalov 65*6801be33SOleksiy Vyalov bool 66*6801be33SOleksiy Vyalov FileSystem::CalculateMD5(const FileSpec &file_spec, 67*6801be33SOleksiy Vyalov uint64_t offset, 68*6801be33SOleksiy Vyalov uint64_t length, 69*6801be33SOleksiy Vyalov uint64_t &low, 70*6801be33SOleksiy Vyalov uint64_t &high) 71*6801be33SOleksiy Vyalov { 727a9e7621SOleksiy Vyalov llvm::MD5::MD5Result md5_result; 73*6801be33SOleksiy Vyalov if (!CalcMD5(file_spec, offset, length, md5_result)) 747a9e7621SOleksiy Vyalov return false; 757a9e7621SOleksiy Vyalov 767a9e7621SOleksiy Vyalov const auto uint64_res = reinterpret_cast<const uint64_t*>(md5_result); 777a9e7621SOleksiy Vyalov high = uint64_res[0]; 787a9e7621SOleksiy Vyalov low = uint64_res[1]; 797a9e7621SOleksiy Vyalov 807a9e7621SOleksiy Vyalov return true; 817a9e7621SOleksiy Vyalov } 827a9e7621SOleksiy Vyalov 837a9e7621SOleksiy Vyalov bool 847a9e7621SOleksiy Vyalov FileSystem::CalculateMD5AsString(const FileSpec &file_spec, std::string& digest_str) 857a9e7621SOleksiy Vyalov { 86*6801be33SOleksiy Vyalov return CalculateMD5AsString(file_spec, 0, 0, digest_str); 87*6801be33SOleksiy Vyalov } 88*6801be33SOleksiy Vyalov 89*6801be33SOleksiy Vyalov bool 90*6801be33SOleksiy Vyalov FileSystem::CalculateMD5AsString(const FileSpec &file_spec, 91*6801be33SOleksiy Vyalov uint64_t offset, 92*6801be33SOleksiy Vyalov uint64_t length, 93*6801be33SOleksiy Vyalov std::string& digest_str) 94*6801be33SOleksiy Vyalov { 957a9e7621SOleksiy Vyalov llvm::MD5::MD5Result md5_result; 96*6801be33SOleksiy Vyalov if (!CalcMD5(file_spec, offset, length, md5_result)) 977a9e7621SOleksiy Vyalov return false; 987a9e7621SOleksiy Vyalov 997a9e7621SOleksiy Vyalov llvm::SmallString<32> result_str; 1007a9e7621SOleksiy Vyalov llvm::MD5::stringifyResult(md5_result, result_str); 1017a9e7621SOleksiy Vyalov digest_str = result_str.c_str(); 1027a9e7621SOleksiy Vyalov return true; 1037a9e7621SOleksiy Vyalov } 104