Disk ARchive 2.7.16
Full featured and portable backup and archiving tool
mycurl_param_list.hpp
Go to the documentation of this file.
1/*********************************************************************/
2// dar - disk archive - a backup/restoration program
3// Copyright (C) 2002-2024 Denis Corbin
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18//
19// to contact the author, see the AUTHOR file
20/*********************************************************************/
21
25
26#ifndef MYCURL_PARAM_LIST_HPP
27#define MYCURL_PARAM_LIST_HPP
28
29#include "../my_config.h"
30
31extern "C"
32{
33#if LIBCURL_AVAILABLE
34#if HAVE_CURL_CURL_H
35#include <curl/curl.h>
36#endif
37#endif
38} // end extern "C"
39
40
41#include <string>
42#include <memory>
43#include <map>
44#include <list>
45#include "integers.hpp"
46#include "erreurs.hpp"
47
48namespace libdar
49{
50
53
54
55 // libcurl uses a list of options to a CURL handle, which argument is of variable type
56 // we want to record this list to be able to reset, copy, and do other fancy operations
57 // on CURL handle and have all these managed within a single class (mycurl_easyhandle_node)
58 // for that we need here a list of association of CURLoption type with variable typed value
59 //
60 // This is implemented by a ancestor type (mycurl_param_element_generic) which is an pure abstracted
61 // class, from which derives many template based classes: mycurl_param_element<T>.
62
63
64
66
68 {
69 public:
70 virtual ~mycurl_param_element_generic() = default;
71
72 virtual bool operator == (const mycurl_param_element_generic & val) const = 0;
73 virtual bool operator != (const mycurl_param_element_generic & val) const { return ! (*this == val); };
74
75 virtual std::unique_ptr<mycurl_param_element_generic> clone() const = 0;
76 };
77
78
79
80
82
83 template <class T> class mycurl_param_element: public mycurl_param_element_generic
84 {
85 public:
86 mycurl_param_element(const T & arg): val(arg) {};
87 mycurl_param_element(const mycurl_param_element<T> & e): val(e.val) {};
88 mycurl_param_element(mycurl_param_element<T> && e) noexcept: val(std::move(e.val)) {};
89 mycurl_param_element<T> & operator = (const mycurl_param_element<T> & e) { val = e.val; return this; };
90 mycurl_param_element<T> & operator = (mycurl_param_element<T> && e) { val = std::move(e.val); return this; };
91 ~mycurl_param_element() = default;
92
93 virtual bool operator == (const mycurl_param_element_generic & arg) const override
94 {
95 const mycurl_param_element<T>* arg_ptr = dynamic_cast<const mycurl_param_element<T>*>(&arg);
96 if(arg_ptr == nullptr)
97 return false;
98 return arg_ptr->val == val;
99 }
100
101 T get_value() const { return val; };
102 const T* get_value_address() const { return &val; };
103 void set_value(const T & arg) { val = arg; };
104
105 virtual std::unique_ptr<mycurl_param_element_generic> clone() const override
106 {
107 std::unique_ptr<mycurl_param_element_generic> ret;
108
109 try
110 {
111 ret = std::make_unique<mycurl_param_element<T> >(val);
112 if(!ret)
113 throw Ememory("mycurl_param_list::clone");
114 }
115 catch(...)
116 {
117 throw Ememory("mycurl_param_list::clone");
118 }
119
120 return ret;
121 };
122
123 private:
124 T val;
125 };
126
127
130
132 {
133 public:
134#ifndef LIBCURL_AVAILABLE
135
136 // libcurl not available, no field to initialize
138
139#else
140
141 mycurl_param_list() { reset_read(); }; // fields "element_list" and "cursor" are objects and get initialized by their default constructor
142
143 mycurl_param_list(const mycurl_param_list & ref) { copy_from(ref); };
144 mycurl_param_list(mycurl_param_list && ref) noexcept = default;
145 mycurl_param_list & operator = (const mycurl_param_list & ref) { element_list.clear(); copy_from(ref); reset_read(); return *this; };
146 mycurl_param_list & operator = (mycurl_param_list && ref) = default;
147 ~mycurl_param_list() = default;
148
149 // operations with the list
150
151 template<class T> void add(CURLoption opt, const T & val) { element_list[opt] = std::make_unique<mycurl_param_element<T> >(val); reset_read(); }
152 void clear(CURLoption opt);
153 void clear() { element_list.clear(); reset_read(); };
154 U_I size() const { return element_list.size(); };
155 void reset_read() const { cursor = element_list.begin(); };
156 bool read_next(CURLoption & opt);
157
158 template<class T> void read_opt(const T* & val) const
159 {
160 if(cursor == element_list.end())
161 throw Erange("mycurl_param_list::read_opt", "Cannot read option when no more option is available");
162
163 if(cursor->second)
164 {
165 const mycurl_param_element<T>* ptr = dynamic_cast<const mycurl_param_element<T>*>(cursor->second.get());
166
167 if(ptr != nullptr)
168 val = ptr->get_value_address();
169 else
170 val = nullptr;
171 }
172 else
173 val = nullptr;
174
175 ++cursor;
176 }
177
178 template<class T>bool get_val(CURLoption opt, const T* & val) const
179 {
180 std::map<CURLoption, std::unique_ptr<mycurl_param_element_generic> >::const_iterator it = element_list.find(opt);
181
182 if(it == element_list.end())
183 return false;
184
185 if(it->second)
186 {
187 const mycurl_param_element<T>* ptr = dynamic_cast<const mycurl_param_element<T>*>(it->second.get());
188
189 if(ptr != nullptr)
190 val = ptr->get_value_address();
191 else
192 val = nullptr;
193 }
194 else
195 val = nullptr;
196
197 return true;
198 }
199
200 // operations between lists
201
202
205
213
214 std::list<CURLoption> update_with(const mycurl_param_list & wanted);
215
216 private:
217 std::map<CURLoption, std::unique_ptr<mycurl_param_element_generic> > element_list;
218 mutable std::map<CURLoption, std::unique_ptr<mycurl_param_element_generic> >::const_iterator cursor;
219
220 void add_clone(CURLoption opt, const mycurl_param_element_generic & val) { element_list[opt] = val.clone(); }
221 void copy_from(const mycurl_param_list & ref);
222
223#endif
224 };
225
226
228
229
230} // end of namespace
231
232#endif
233
exception used when memory has been exhausted
Definition: erreurs.hpp:127
exception used to signal range error
Definition: erreurs.hpp:220
the ancestor class of etherogeneous list/map
the implemented inherited classes of the abstracted class for etherogeneous list/map
contains all the excetion class thrown by libdar
are defined here basic integer types that tend to be portable
libdar namespace encapsulate all libdar symbols
Definition: archive.hpp:47