-
Notifications
You must be signed in to change notification settings - Fork 12
/
Common.cpp
152 lines (152 loc) · 4.44 KB
/
Common.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "Common.hpp"
#include "Network.hpp"
#include "Platforms/Platform.hpp"
#include <algorithm>
#include <chrono>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <iostream>
#include <iterator>
#include <random>
#include <vector>
std::string file2Str(const fs::path& path) {
std::ifstream in(path);
in.seekg(0, std::ios::end);
auto siz = in.tellg();
in.seekg(0, std::ios::beg);
if(siz <= 0) {
in.clear();
std::string res;
while(in) {
int ch = in.get();
if(ch != EOF)
res.push_back(ch);
else
break;
}
return res;
} else {
std::vector<char> data(siz);
in.read(data.data(), siz);
return std::string(data.data(),
data.data() + siz);
}
}
void showLine(const std::string& col,
const std::string& str) {
std::cout << '\r' << col << str << "\033[0m"
<< std::string(getConsoleWidth() -
str.size(),
' ')
<< std::flush;
}
void line(const std::string& str, char full) {
std::cout << "\033[36m";
int mid = std::max(
3, (46 - static_cast<int>(str.size())) / 2);
for(int i = 0; i < mid; ++i)
std::cout.put(full);
std::cout << str;
for(int i = 0; i < mid; ++i)
std::cout.put(full);
std::cout << "\033[0m" << std::endl;
}
Data::Data(const fs::path& in, const fs::path& out)
: input(in), output(out) {}
bool Data::operator<(const Data& rhs) const {
return input < rhs.input;
}
static fs::path uniqueTempFileName() {
static std::mt19937_64 dev(
std::chrono::high_resolution_clock::now()
.time_since_epoch()
.count());
return fs::temp_directory_path() /
std::to_string(dev());
}
TempFile::TempFile() : mFile(uniqueTempFileName()) {}
fs::path TempFile::path() const {
return mFile;
}
TempFile::~TempFile() {
try {
fs::remove(mFile);
} catch(...) {
}
}
static void clearCache() {
if(fs::exists("CheckerDir/Cache")) {
using DirIter = fs::directory_iterator;
std::vector<fs::path> deferred;
using Clock = fs::file_time_type::clock;
using namespace std::chrono;
auto ct = Clock::now();
for(auto it : DirIter("CheckerDir/Cache")) {
it.refresh();
if(!it.is_regular_file())
continue;
auto wt = it.last_write_time();
if(floor<hours>(ct - wt).count() >= 48) {
std::cout
<< "Cache " << it.path().stem()
<< " is up-to-date." << std::endl;
deferred.push_back(it.path());
}
}
for(auto p : deferred)
fs::remove(p);
} else
fs::create_directory("CheckerDir/Cache");
}
static bool verifyZip(const fs::path& file) {
std::string cmd = "unzip -t -q " + file.string();
int res = system(cmd.c_str());
return res == 0;
}
fs::path downloadFile(const std::string& url,
const std::string& pid,
bool verify) {
clearCache();
if(fs::exists(url))
return url;
else {
fs::path cacheFile = "CheckerDir/Cache/" + pid;
if(verify && fs::exists(cacheFile) &&
!verifyZip(cacheFile))
fs::remove(cacheFile);
if(!fs::exists(cacheFile)) {
bool res = download(url, cacheFile);
if(!res ||
(verify && !verifyZip(cacheFile))) {
if(fs::exists(cacheFile))
fs::remove(cacheFile);
return fs::path();
}
} else
std::cout << "Using cached file "
<< cacheFile << std::endl;
return cacheFile;
}
}
bool unzip(const fs::path& path) {
fs::path dst = fs::temp_directory_path() / "data";
fs::remove_all(dst);
if(!fs::create_directory(dst))
return false;
std::string cmd = "unzip -q -j -d " +
dst.string() + " " + path.string();
int res = system(cmd.c_str());
return res == 0;
}
std::string readConfig(const std::string& optName) {
std::ifstream in("CheckerDir/checker.config");
std::string line;
while(std::getline(in, line)) {
std::size_t pos = line.find('#');
std::string key = line.substr(0, pos);
if(key == optName)
return line.substr(pos + 1);
}
return {};
}