Disk ARchive  2.7.15
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 
31 extern "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 
48 namespace 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
137  mycurl_param_list() {};
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