/
zoe.h
280 lines (238 loc) · 9.98 KB
/
zoe.h
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*******************************************************************************
* Copyright (C) <2019-2023>, winsoft666, <winsoft666@outlook.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#ifndef ZOE_H_
#define ZOE_H_
#pragma once
#include <string>
#include <memory>
#include <future>
#include <map>
#ifdef ZOE_STATIC
#define ZOE_API
#else
#if defined(ZOE_EXPORTS)
#if defined(_MSC_VER)
#define ZOE_API __declspec(dllexport)
#else
#define ZOE_API
#endif
#else
#if defined(_MSC_VER)
#define ZOE_API __declspec(dllimport)
#else
#define ZOE_API
#endif
#endif
#endif
namespace zoe {
enum Result {
SUCCESSED = 0,
UNKNOWN_ERROR = 1,
INVALID_URL = 2,
INVALID_INDEX_FORMAT = 3,
INVALID_TARGET_FILE_PATH = 4,
INVALID_THREAD_NUM = 5,
INVALID_HASH_POLICY = 6,
INVALID_SLICE_POLICY = 7,
INVALID_NETWORK_CONN_TIMEOUT = 8,
INVALID_NETWORK_READ_TIMEOUT = 9,
INVALID_FETCH_FILE_INFO_RETRY_TIMES = 10,
ALREADY_DOWNLOADING = 11,
CANCELED = 12,
RENAME_TMP_FILE_FAILED = 13,
OPEN_INDEX_FILE_FAILED = 14,
TMP_FILE_EXPIRED = 15,
INIT_CURL_FAILED = 16,
INIT_CURL_MULTI_FAILED = 17,
SET_CURL_OPTION_FAILED = 18,
ADD_CURL_HANDLE_FAILED = 19,
CREATE_TARGET_FILE_FAILED = 20,
CREATE_TMP_FILE_FAILED = 21,
OPEN_TMP_FILE_FAILED = 22,
URL_DIFFERENT = 23,
TMP_FILE_SIZE_ERROR = 24,
TMP_FILE_CANNOT_RW = 25,
FLUSH_TMP_FILE_FAILED = 26,
UPDATE_INDEX_FILE_FAILED = 27,
SLICE_DOWNLOAD_FAILED = 28,
HASH_VERIFY_NOT_PASS = 29,
CALCULATE_HASH_FAILED = 30,
FETCH_FILE_INFO_FAILED = 31,
REDIRECT_URL_DIFFERENT = 32,
NOT_CLEARLY_RESULT = 33,
};
enum DownloadState { STOPPED = 0, DOWNLODING = 1, PAUSED = 2 };
ZOE_API const char* GetResultString(int enumVal);
enum SlicePolicy { Auto = 0, FixedSize, FixedNum };
enum HashType { MD5 = 0, CRC32, SHA1, SHA256 };
enum HashVerifyPolicy { ALWAYS = 0, ONLY_NO_FILESIZE };
enum UncompletedSliceSavePolicy { ALWAYS_DISCARD = 0, SAVE_EXCEPT_FAILED };
class ZOE_API Event {
public:
Event(bool setted = false);
~Event();
void set() noexcept;
void unset() noexcept;
bool isSetted() noexcept;
bool wait(int32_t millseconds) noexcept;
protected:
Event(const Event&) = delete;
Event& operator=(const Event&) = delete;
class EventImpl;
EventImpl* impl_;
};
typedef std::string utf8string;
typedef std::function<void(Result ret)> ResultFunctor;
typedef std::function<void(int64_t total, int64_t downloaded)> ProgressFunctor;
typedef std::function<void(int64_t byte_per_sec)> RealtimeSpeedFunctor;
typedef std::function<void(const utf8string& verbose)> VerboseOuputFunctor;
typedef std::multimap<utf8string, utf8string> HttpHeaders;
class ZOE_API Zoe {
public:
Zoe();
~Zoe();
static void GlobalInit();
static void GlobalUnInit();
void setVerboseOutput(VerboseOuputFunctor verbose_functor) noexcept;
// Pass an int specifying the maximum thread number.
// zoe will use these threads as much as possible.
// Set to 0 or negative to switch to the default built-in thread number - 1.
// The number of threads cannot be greater than 100, otherwise zoe will return INVALID_THREAD_NUM.
//
Result setThreadNum(int32_t thread_num) noexcept;
int32_t threadNum() const noexcept;
// Pass an int. It should contain the maximum time in milliseconds that you allow the connection phase to the server to take.
// This only limits the connection phase, it has no impact once it has connected.
// Set to 0 or negative to switch to the default built-in connection timeout - 3000 milliseconds.
//
Result setNetworkConnectionTimeout(
int32_t milliseconds) noexcept; // milliseconds
int32_t networkConnectionTimeout() const noexcept; // milliseconds
// Pass an int specifying the retry times when request file information(such as file size) failed.
// Set to 0 or negative to switch to the default built-in retry times - 1.
//
Result setFetchFileInfoRetryTimes(int32_t retry_times) noexcept;
int32_t fetchFileInfoRetryTimes() const noexcept;
// If bUseHead is true, zoe will use HEAD method to fetch file info. Otherwise, zoe will use GET method.
Result setFetchFileInfoHeadMethod(bool use_head) noexcept;
bool fetchFileInfoHeadMethod() const noexcept;
// Pass an int as parameter.
// If the interval seconds that from the saved time of temporary file to present greater than or equal to this parameter, the temporary file will be discarded.
// Default to -1, never expired.
//
Result setTmpFileExpiredTime(int32_t seconds) noexcept; // seconds
int32_t tmpFileExpiredTime() const noexcept; // seconds
// Pass an int as parameter.
// If a download exceeds this speed (counted in bytes per second) the transfer will pause to keep the speed less than or equal to the parameter value.
// Defaults to -1, unlimited speed.
// Set to 0 or negative to switch to the default built-in limit - -1(unlimited speed).
// This option doesn't affect transfer speeds done with FILE:// URLs.
//
Result setMaxDownloadSpeed(int32_t byte_per_seconds) noexcept;
int32_t maxDownloadSpeed() const noexcept;
// Pass an int as parameter.
// If a download less than this speed (counted in bytes per second) during "low speed time" seconds,
// the transfer will be considered as failed.
// Default to -1, unlimited speed.
// Set to 0 or negative to switch to the default built-in limit - -1(unlimited speed).
//
Result setMinDownloadSpeed(int32_t byte_per_seconds,
int32_t duration) noexcept; // seconds
int32_t minDownloadSpeed() const noexcept;
int32_t minDownloadSpeedDuration() const noexcept; // seconds
// Pass an unsigned int specifying your maximal size for the disk cache total buffer in zoe.
// This buffer size is by default 20971520 byte (20MB).
//
Result setDiskCacheSize(int32_t cache_size) noexcept; // byte
int32_t diskCacheSize() const noexcept; // byte
// Set an event, zoe will stop downloading when this event set.
// If download is stopped for stop_event set or call stop, zoe will return CANCELED.
//
Result setStopEvent(Event* stop_event) noexcept;
Event* stopEvent() noexcept;
// Set false, zoe will not check whether the redirected url is the same as in the index file,
// Default to true, if the redirected url is different from the url in the index file, zoe will return REDIRECT_URL_DIFFERENT error.
//
Result setRedirectedUrlCheckEnabled(bool enabled) noexcept;
bool redirectedUrlCheckEnabled() const noexcept;
// Set true, zoe will parse Content-Md5 header filed and make sure target file's md5 is same as this value,
// and in this case, slice files will be expired if content_md5 value that cached in index file is changed.
// Content-Md5 is pure md5 string, not by base64.
// Default to false.
//
Result setContentMd5Enabled(bool enabled) noexcept;
bool contentMd5Enabled() const noexcept;
// Set slice policy, tell zoe how to calculate each slice size.
// Default: fixed to 10485760 bytes(10MB)
//
Result setSlicePolicy(SlicePolicy policy, int64_t policy_value) noexcept;
void slicePolicy(SlicePolicy& policy, int64_t& policy_value) const noexcept;
// Set hash verify policy, the hash value is the whole file's hash, not for a slice.
// If fetch file size failed, hash verify is the only way to know whether file download completed.
// If hash value is empty, will not calculate hash, nor verify hash value.
//
Result setHashVerifyPolicy(HashVerifyPolicy policy,
HashType hash_type,
const utf8string& hash_value) noexcept;
void hashVerifyPolicy(HashVerifyPolicy& policy,
HashType& hash_type,
utf8string& hash_value) const noexcept;
Result setHttpHeaders(const HttpHeaders& headers) noexcept;
HttpHeaders httpHeaders() const noexcept;
// set proxy string, such as http://127.0.0.1:8888
//
Result setProxy(const utf8string& proxy) noexcept;
utf8string proxy() const noexcept;
// Set uncompleted slice save policy.
// Default is ALWAYS_DISCARD, because zoe doesn't know how to check slice(especially uncompleted) is valid or not.
//
Result setUncompletedSliceSavePolicy(
UncompletedSliceSavePolicy policy) noexcept;
UncompletedSliceSavePolicy uncompletedSliceSavePolicy() const noexcept;
// Start to download and state change to DOWNLOADING.
// Supported url protocol is as same as curl library.
//
std::shared_future<Result> start(
const utf8string& url,
const utf8string& target_file_path,
ResultFunctor result_functor,
ProgressFunctor progress_functor,
RealtimeSpeedFunctor realtime_speed_functor) noexcept;
// Pause downloading and state change to PAUSED.
//
void pause() noexcept;
// Resume downloading and state change to DOWNLOADING.
void resume() noexcept;
// Stop downloading and state change to STOPPED, zoe will return CANCELED in ResultFunctor.
//
void stop() noexcept;
utf8string url() const noexcept;
utf8string targetFilePath() const noexcept;
// The file size of server side that will be downloaded.
// Return -1 when get original file size failed.
//
int64_t originFileSize() const noexcept;
DownloadState state() const noexcept;
std::shared_future<Result> futureResult() noexcept;
protected:
class ZoeImpl;
ZoeImpl* impl_;
Zoe(const Zoe&) = delete;
Zoe& operator=(const Zoe&) = delete;
};
} // namespace zoe
#endif // !ZOE_H_