6 void CURL_File::error_check(CURLcode code)
10 throw Exception(curl_easy_strerror(code));
14 void CURL_File::perform_range(int64_t start, int64_t size)
const
17 const std::string range =
18 std::to_string(start) +
'-' + std::to_string(start + size - 1);
20 error_check(curl_easy_setopt(curl, CURLOPT_RANGE, range.c_str()));
21 error_check(curl_easy_perform(curl));
24 error_check(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code));
26 if (code != 0 && code != 206)
27 throw Exception(
"unexpected response code: " + std::to_string(code));
31 size_t CURL_File::pread_Callback_Data::copy
38 const size_t copy_size = std::min(size - offset, real_size);
39 std::memcpy(buffer + offset, contents, copy_size);
45 size_t CURL_File::pread_callback
54 const size_t real_size = size * nmemb;
55 pread_Callback_Data &callback_data = *(pread_Callback_Data *)p;
56 return callback_data.copy(
reinterpret_cast<char *
>(contents), real_size);
60 size_t CURL_File::pread(
char *buffer,
size_t size, int64_t offset)
const
63 pread_Callback_Data callback_data{buffer, size, 0};
65 error_check(curl_easy_setopt(curl, CURLOPT_WRITEDATA, &callback_data));
66 error_check(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, pread_callback));
68 perform_range(offset, int64_t(size));
70 return callback_data.offset;
74 size_t CURL_File::copy_callback
77 void *
const contents,
83 const size_t real_size = size * nmemb;
84 Buffered_File &destination = *((Buffered_File *)p);
85 destination.sequential_write((
const char *)contents, real_size);
90 void CURL_File::copy_to
93 Buffered_File &destination,
98 const int64_t old_position = destination.get_position();
99 destination.set_position(start);
101 error_check(curl_easy_setopt(curl, CURLOPT_WRITEDATA, &destination));
102 error_check(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, copy_callback));
104 perform_range(start, size);
105 destination.set_position(old_position);
113 throw Exception(
"Could not initialize CURL");
120 curl_easy_cleanup(
curl);
128 error_check(curl_easy_setopt(
curl, CURLOPT_VERBOSE, verbose));
129 error_check(curl_easy_setopt(
curl, CURLOPT_URL, url));
130 error_check(curl_easy_setopt(
curl, CURLOPT_USERAGENT,
"joedb"));
131 error_check(curl_easy_setopt(
curl, CURLOPT_FOLLOWLOCATION, 1L));
CURL_File(const char *url, bool verbose)
@ read_existing
fails if does not exist