Disk ARchive 2.7.8
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-2022 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:
135
136#if LIBCURL_AVAILABLE
137
138 mycurl_param_list(const mycurl_param_list & ref) { copy_from(ref); };
139 mycurl_param_list(mycurl_param_list && ref) noexcept = default;
140 mycurl_param_list & operator = (const mycurl_param_list & ref) { element_list.clear(); copy_from(ref); reset_read(); return *this; };
141 mycurl_param_list & operator = (mycurl_param_list && ref) = default;
142 ~mycurl_param_list() = default;
143
144 // operations with the list
145
146 template<class T> void add(CURLoption opt, const T & val) { element_list[opt] = std::make_unique<mycurl_param_element<T> >(val); reset_read(); }
147 void clear(CURLoption opt);
148 void clear() { element_list.clear(); reset_read(); };
149 U_I size() const { return element_list.size(); };
150 void reset_read() const { cursor = element_list.begin(); };
151 bool read_next(CURLoption & opt);
152
153 template<class T> void read_opt(const T* & val) const
154 {
155 if(cursor == element_list.end())
156 throw Erange("mycurl_param_list::read_opt", "Cannot read option when no more option is available");
157
158 if(cursor->second)
159 {
160 const mycurl_param_element<T>* ptr = dynamic_cast<const mycurl_param_element<T>*>(cursor->second.get());
161
162 if(ptr != nullptr)
163 val = ptr->get_value_address();
164 else
165 val = nullptr;
166 }
167 else
168 val = nullptr;
169
170 ++cursor;
171 }
172
173 template<class T>bool get_val(CURLoption opt, const T* & val) const
174 {
175 std::map<CURLoption, std::unique_ptr<mycurl_param_element_generic> >::const_iterator it = element_list.find(opt);
176
177 if(it == element_list.end())
178 return false;
179
180 if(it->second)
181 {
182 const mycurl_param_element<T>* ptr = dynamic_cast<const mycurl_param_element<T>*>(it->second.get());
183
184 if(ptr != nullptr)
185 val = ptr->get_value_address();
186 else
187 val = nullptr;
188 }
189 else
190 val = nullptr;
191
192 return true;
193 }
194
195 // operations between lists
196
197
200
208
209 std::list<CURLoption> update_with(const mycurl_param_list & wanted);
210
211 private:
212 std::map<CURLoption, std::unique_ptr<mycurl_param_element_generic> > element_list;
213 mutable std::map<CURLoption, std::unique_ptr<mycurl_param_element_generic> >::const_iterator cursor;
214
215 void add_clone(CURLoption opt, const mycurl_param_element_generic & val) { element_list[opt] = val.clone(); }
216 void copy_from(const mycurl_param_list & ref);
217
218#endif
219 };
220
221
223
224
225} // end of namespace
226
227#endif
228
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