forked from blastrock/pkgj
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfiledownload.cpp
More file actions
106 lines (80 loc) · 2.27 KB
/
Copy pathfiledownload.cpp
File metadata and controls
106 lines (80 loc) · 2.27 KB
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
#include "filedownload.hpp"
#include "download.hpp"
#include "file.hpp"
#include "pkgi.hpp"
#include "utils.hpp"
#include <fmt/format.h>
#include <boost/scope_exit.hpp>
#include <cereal/archives/binary.hpp>
#include <fstream>
#include <cstddef>
FileDownload::FileDownload(std::unique_ptr<Http> http) : _http(std::move(http))
{
}
void FileDownload::update_progress()
{
update_progress_cb(download_offset, download_size);
}
void FileDownload::start_download()
{
LOGF("HTTP GET: {}", download_url);
_http->start(download_url, 0);
const auto http_length = _http->get_length();
if (http_length < 0)
throw DownloadError("HTTP response has unknown length");
download_size = http_length;
LOGF("Download size: {} bytes", download_size);
}
void FileDownload::download_data(uint32_t size)
{
if (is_canceled())
throw std::runtime_error("download was canceled");
if (size == 0)
return;
update_progress();
std::vector<uint8_t> buffer(size);
{
size_t pos = 0;
while (pos < size)
{
const int read = _http->read(buffer.data() + pos, size - pos);
if (read == 0)
throw DownloadError("HTTP connection closed");
pos += read;
}
}
download_offset += size;
pkgi_write(item_file, buffer.data(), buffer.size());
}
void FileDownload::download_file()
{
LOG("Downloading encrypted content files");
LOGF("creating {} file", root);
item_file = pkgi_create(root.c_str());
if (!item_file)
throw formatEx<DownloadError>("cannot create file {}", root);
BOOST_SCOPE_EXIT_ALL(&)
{
pkgi_close(item_file);
};
start_download();
static constexpr auto SAVE_PERIOD = 64 * 1024;
while (download_offset < download_size)
{
const uint32_t read =
(uint32_t)min64(SAVE_PERIOD, download_size - download_offset);
download_data(read);
}
}
void FileDownload::download(
const std::string& partition,
const std::string& titleid,
const std::string& url)
{
root = fmt::format("{}pkgj/{}-comp.ppk", partition, titleid);
LOGF("temp installation folder: {}", root);
download_size = 0;
download_offset = 0;
download_url = url;
download_file();
}