Joedb 9.5.0
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
CURL_File.cpp
Go to the documentation of this file.
2
3namespace joedb
4{
5 ////////////////////////////////////////////////////////////////////////////
6 void CURL_File::error_check(CURLcode code)
7 ////////////////////////////////////////////////////////////////////////////
8 {
9 if (code != CURLE_OK)
10 throw Exception(curl_easy_strerror(code));
11 }
12
13 ////////////////////////////////////////////////////////////////////////////
14 void CURL_File::perform_range(int64_t start, int64_t size) const
15 ////////////////////////////////////////////////////////////////////////////
16 {
17 const std::string range =
18 std::to_string(start) + '-' + std::to_string(start + size - 1);
19
20 error_check(curl_easy_setopt(curl, CURLOPT_RANGE, range.c_str()));
21 error_check(curl_easy_perform(curl));
22
23 long code = 0;
24 error_check(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code));
25
26 if (code != 0 && code != 206)
27 throw Exception("unexpected response code: " + std::to_string(code));
28 }
29
30 ////////////////////////////////////////////////////////////////////////////
31 size_t CURL_File::pread_Callback_Data::copy
32 ////////////////////////////////////////////////////////////////////////////
33 (
34 char *contents,
35 size_t real_size
36 )
37 {
38 const size_t copy_size = std::min(size - offset, real_size);
39 std::memcpy(buffer + offset, contents, copy_size);
40 offset += copy_size;
41 return copy_size;
42 }
43
44 ////////////////////////////////////////////////////////////////////////////
45 size_t CURL_File::pread_callback
46 ////////////////////////////////////////////////////////////////////////////
47 (
48 void *contents,
49 size_t size,
50 size_t nmemb,
51 void *p
52 )
53 {
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);
57 }
58
59 ////////////////////////////////////////////////////////////////////////////
60 size_t CURL_File::pread(char *buffer, size_t size, int64_t offset) const
61 ////////////////////////////////////////////////////////////////////////////
62 {
63 pread_Callback_Data callback_data{buffer, size, 0};
64
65 error_check(curl_easy_setopt(curl, CURLOPT_WRITEDATA, &callback_data));
66 error_check(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, pread_callback));
67
68 perform_range(offset, int64_t(size));
69
70 return callback_data.offset;
71 }
72
73 ////////////////////////////////////////////////////////////////////////////
74 size_t CURL_File::copy_callback
75 ////////////////////////////////////////////////////////////////////////////
76 (
77 void * const contents,
78 const size_t size,
79 const size_t nmemb,
80 void * const p
81 )
82 {
83 const size_t real_size = size * nmemb;
84 Buffered_File &destination = *((Buffered_File *)p);
85 destination.sequential_write((const char *)contents, real_size);
86 return real_size;
87 }
88
89 ////////////////////////////////////////////////////////////////////////////
90 void CURL_File::copy_to
91 ////////////////////////////////////////////////////////////////////////////
92 (
93 Buffered_File &destination,
94 const int64_t start,
95 const int64_t size
96 ) const
97 {
98 const int64_t old_position = destination.get_position();
99 destination.set_position(start);
100
101 error_check(curl_easy_setopt(curl, CURLOPT_WRITEDATA, &destination));
102 error_check(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, copy_callback));
103
104 perform_range(start, size);
105 destination.set_position(old_position);
106 }
107
108 ////////////////////////////////////////////////////////////////////////////
109 CURL_Easy::CURL_Easy(): curl(curl_easy_init())
110 ////////////////////////////////////////////////////////////////////////////
111 {
112 if (curl == nullptr)
113 throw Exception("Could not initialize CURL");
114 }
115
116 ////////////////////////////////////////////////////////////////////////////
118 ////////////////////////////////////////////////////////////////////////////
119 {
120 curl_easy_cleanup(curl);
121 }
122
123 ////////////////////////////////////////////////////////////////////////////
124 CURL_File::CURL_File(const char *url, bool verbose):
125 ////////////////////////////////////////////////////////////////////////////
127 {
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));
132 }
133}
CURL *const curl
Definition CURL_File.h:14
CURL_File(const char *url, bool verbose)
Open_Mode
Definition Open_Mode.h:8
@ read_existing
fails if does not exist
Definition Blob.h:7