1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include <hash/hash.h>
10 #include <fstream>
11 #include <iostream>
12 #include <sstream>
13 
14 #include "util/options.h"
15 #include "util/common.h"
16 #include "util/logger.h"
17 
18 namespace OHOS {
19 namespace HDI {
GenHashKey()20 bool Hash::GenHashKey()
21 {
22     FileDetailMap fileDetails;
23     if (!Preprocessor::UnitPreprocess(fileDetails)) {
24         return false;
25     }
26 
27     std::string filePath = Options::GetInstance().GetOutPutFile();
28     return filePath.empty() ? FormatStdout(fileDetails) : FormatFile(fileDetails, filePath);
29 }
30 
FormatStdout(const FileDetailMap & fileDetails)31 bool Hash::FormatStdout(const FileDetailMap &fileDetails)
32 {
33     std::vector<std::string> hashInfos = Hash::GetHashInfo(fileDetails);
34     if (hashInfos.empty()) {
35         return false;
36     }
37 
38     for (const auto &info : hashInfos) {
39         std::cout << info << "\n";
40     }
41     return true;
42 }
43 
FormatFile(const FileDetailMap & fileDetails,const std::string & filePath)44 bool Hash::FormatFile(const FileDetailMap &fileDetails, const std::string &filePath)
45 {
46     std::vector<std::string> hashInfos = Hash::GetHashInfo(fileDetails);
47     if (hashInfos.empty()) {
48         return false;
49     }
50 
51     std::ofstream hashFile(filePath, std::ios::out | std::ios ::binary);
52     if (!hashFile.is_open()) {
53         Logger::E(TAG, "failed to open %s", filePath.c_str());
54         return false;
55     }
56 
57     for (const auto &info : hashInfos) {
58         hashFile << info << "\n";
59     }
60 
61     hashFile.close();
62     return true;
63 }
64 
GetHashInfo(const FileDetailMap & fileDetails)65 std::vector<std::string> Hash::GetHashInfo(const FileDetailMap &fileDetails)
66 {
67     std::vector<std::string> hashInfos;
68     for (const auto &detail : fileDetails) {
69         size_t haskKey = 0;
70         std::stringstream hashInfo;
71         if (!Hash::GenFileHashKey(detail.second.filePath_, haskKey)) {
72             return std::vector<std::string>();
73         }
74         hashInfo << detail.first << ":" << haskKey;
75         hashInfos.push_back(hashInfo.str());
76     }
77 
78     return hashInfos;
79 }
80 
GenFileHashKey(const std::string & path,size_t & hashKey)81 bool Hash::GenFileHashKey(const std::string &path, size_t &hashKey)
82 {
83     std::ifstream fs(path);
84     if (!fs.is_open()) {
85         Logger::E(TAG, "invalid file path '%s'", path.c_str());
86         return false;
87     }
88 
89     std::stringstream buffer;
90     buffer << fs.rdbuf();
91 
92     hashKey = std::hash<std::string>()(buffer.str());
93     fs.close();
94     return true;
95 }
96 } // namespace HDI
97 } // namespace OHOS
98