1*7a9e7621SOleksiy Vyalov //===-- FileSystem.cpp ------------------------------------------*- C++ -*-===//
2*7a9e7621SOleksiy Vyalov //
3*7a9e7621SOleksiy Vyalov //                     The LLVM Compiler Infrastructure
4*7a9e7621SOleksiy Vyalov //
5*7a9e7621SOleksiy Vyalov // This file is distributed under the University of Illinois Open Source
6*7a9e7621SOleksiy Vyalov // License. See LICENSE.TXT for details.
7*7a9e7621SOleksiy Vyalov //
8*7a9e7621SOleksiy Vyalov //===----------------------------------------------------------------------===//
9*7a9e7621SOleksiy Vyalov 
10*7a9e7621SOleksiy Vyalov #include "lldb/Host/FileSystem.h"
11*7a9e7621SOleksiy Vyalov 
12*7a9e7621SOleksiy Vyalov #include "llvm/Support/MD5.h"
13*7a9e7621SOleksiy Vyalov 
14*7a9e7621SOleksiy Vyalov #include <fstream>
15*7a9e7621SOleksiy Vyalov #include <vector>
16*7a9e7621SOleksiy Vyalov 
17*7a9e7621SOleksiy Vyalov using namespace lldb;
18*7a9e7621SOleksiy Vyalov using namespace lldb_private;
19*7a9e7621SOleksiy Vyalov 
20*7a9e7621SOleksiy Vyalov namespace {
21*7a9e7621SOleksiy Vyalov 
22*7a9e7621SOleksiy Vyalov bool
23*7a9e7621SOleksiy Vyalov CalcMD5(const FileSpec &file_spec, llvm::MD5::MD5Result &md5_result)
24*7a9e7621SOleksiy Vyalov {
25*7a9e7621SOleksiy Vyalov     llvm::MD5 md5_hash;
26*7a9e7621SOleksiy Vyalov     std::ifstream file(file_spec.GetPath(), std::ios::binary);
27*7a9e7621SOleksiy Vyalov     if (!file.is_open())
28*7a9e7621SOleksiy Vyalov         return false;
29*7a9e7621SOleksiy Vyalov 
30*7a9e7621SOleksiy Vyalov     std::vector<char> read_buf(4096);
31*7a9e7621SOleksiy Vyalov     while (!file.eof())
32*7a9e7621SOleksiy Vyalov     {
33*7a9e7621SOleksiy Vyalov         file.read(&read_buf[0], read_buf.size());
34*7a9e7621SOleksiy Vyalov         const auto read_bytes = file.gcount();
35*7a9e7621SOleksiy Vyalov         if (read_bytes == 0)
36*7a9e7621SOleksiy Vyalov             break;
37*7a9e7621SOleksiy Vyalov 
38*7a9e7621SOleksiy Vyalov         md5_hash.update(llvm::StringRef(&read_buf[0], read_bytes));
39*7a9e7621SOleksiy Vyalov     }
40*7a9e7621SOleksiy Vyalov 
41*7a9e7621SOleksiy Vyalov     md5_hash.final(md5_result);
42*7a9e7621SOleksiy Vyalov     return true;
43*7a9e7621SOleksiy Vyalov }
44*7a9e7621SOleksiy Vyalov 
45*7a9e7621SOleksiy Vyalov }  // namespace
46*7a9e7621SOleksiy Vyalov 
47*7a9e7621SOleksiy Vyalov bool
48*7a9e7621SOleksiy Vyalov FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high)
49*7a9e7621SOleksiy Vyalov {
50*7a9e7621SOleksiy Vyalov     llvm::MD5::MD5Result md5_result;
51*7a9e7621SOleksiy Vyalov     if (!CalcMD5(file_spec, md5_result))
52*7a9e7621SOleksiy Vyalov         return false;
53*7a9e7621SOleksiy Vyalov 
54*7a9e7621SOleksiy Vyalov     const auto uint64_res = reinterpret_cast<const uint64_t*>(md5_result);
55*7a9e7621SOleksiy Vyalov     high = uint64_res[0];
56*7a9e7621SOleksiy Vyalov     low = uint64_res[1];
57*7a9e7621SOleksiy Vyalov 
58*7a9e7621SOleksiy Vyalov     return true;
59*7a9e7621SOleksiy Vyalov }
60*7a9e7621SOleksiy Vyalov 
61*7a9e7621SOleksiy Vyalov bool
62*7a9e7621SOleksiy Vyalov FileSystem::CalculateMD5AsString(const FileSpec &file_spec, std::string& digest_str)
63*7a9e7621SOleksiy Vyalov {
64*7a9e7621SOleksiy Vyalov     llvm::MD5::MD5Result md5_result;
65*7a9e7621SOleksiy Vyalov     if (!CalcMD5(file_spec, md5_result))
66*7a9e7621SOleksiy Vyalov         return false;
67*7a9e7621SOleksiy Vyalov 
68*7a9e7621SOleksiy Vyalov     llvm::SmallString<32> result_str;
69*7a9e7621SOleksiy Vyalov     llvm::MD5::stringifyResult(md5_result, result_str);
70*7a9e7621SOleksiy Vyalov     digest_str = result_str.c_str();
71*7a9e7621SOleksiy Vyalov     return true;
72*7a9e7621SOleksiy Vyalov }
73