Unity Scopes API
XmlAsyncReader.h
1 /*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of version 3 of the GNU Lesser General Public License as published
6 * by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 * details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Xavi Garcia <xavi.garcia.mena@canonical.com>
17 */
18 #pragma once
19 
20 #ifndef _ENABLE_QT_EXPERIMENTAL_
21 #error You should define _ENABLE_QT_EXPERIMENTAL_ in order to use this experimental header file.
22 #endif
23 
24 #include <unity/scopes/qt/HttpAsyncReader.h>
25 #include <unity/util/DefinesPtrs.h>
26 #include <unity/util/NonCopyable.h>
27 
28 #include <QtCore/QXmlStreamReader>
29 #include <QtCore/QVector>
30 
31 #include <future>
32 #include <memory>
33 
34 namespace unity
35 {
36 
37 namespace scopes
38 {
39 
40 namespace qt
41 {
42 
44 template <typename TYPE>
45 using ResultsList = std::deque<std::shared_ptr<TYPE>>;
46 
47 template <typename B, typename T>
48 static bool get_results(QXmlStreamReader& xml,
49  const std::string& object_name,
50  ResultsList<B>& results,
51  std::string& error_string);
53 
64 {
65 public:
67  NONCOPYABLE(XmlAsyncReader);
68  UNITY_DEFINES_PTRS(XmlAsyncReader);
69 
70  template <typename T>
71  using ParserFunc =
72  std::function<bool(QXmlStreamReader& root, const std::string&, std::deque<std::shared_ptr<T>>&, std::string&)>;
73 
74  template <typename T>
75  using ResultsFuture = std::future<std::deque<std::shared_ptr<T>>>;
76 
77  template <typename TYPE>
78  using ResultsList = std::deque<std::shared_ptr<TYPE>>;
79 
80  typedef std::future<std::shared_ptr<QXmlStreamReader>> QXmlStreamReaderFuture;
81 
82  typedef std::shared_ptr<QXmlStreamReader> QXmlStreamReaderSptr;
83 
84  typedef std::vector<std::pair<std::string, std::string>> QXmlStreamReaderParams;
85 
87  virtual ~XmlAsyncReader() = default;
89 
112  template <typename BASE, typename TYPE>
113  ResultsFuture<BASE> async_get(std::string const& uri,
114  std::string const& object_name,
115  ParserFunc<BASE> const& parse = get_results<BASE, TYPE>) const;
116 
134  template <typename T>
135  ResultsFuture<T> async_get(std::string const& uri,
136  std::string const& object_name,
137  ParserFunc<T> const& parse = get_results<T, T>) const;
138 
162  template <typename BASE, typename TYPE>
163  ResultsFuture<BASE> async_get(std::string const& host,
164  QXmlStreamReaderParams const& params,
165  std::string const& object_name,
166  ParserFunc<BASE> const& parse = get_results<BASE, TYPE>) const;
167 
189  template <typename T>
190  ResultsFuture<T> async_get(std::string const& host,
191  QXmlStreamReaderParams const& params,
192  std::string const& object_name,
193  ParserFunc<T> const& parse = get_results<T, T>) const;
194 
205  QXmlStreamReaderFuture async_get_parser(std::string const& uri) const;
206 
218  QXmlStreamReaderFuture async_get_parser(std::string const& host, QXmlStreamReaderParams const& params) const;
219 
220 protected:
229  static QXmlStreamReaderSptr create_parser_with_data(std::string const& data, std::string& error);
230 
232  std::shared_ptr<HttpAsyncReader> p_;
234 };
235 
236 template <typename BASE, typename TYPE>
237 XmlAsyncReader::ResultsFuture<BASE> XmlAsyncReader::async_get(std::string const& uri,
238  std::string const& object_name,
239  ParserFunc<BASE> const& parse) const
240 {
241  return p_->async_get<BASE, TYPE, QXmlStreamReader>(
242  uri, object_name, XmlAsyncReader::create_parser_with_data, parse);
243 }
244 
245 template <typename T>
246 XmlAsyncReader::ResultsFuture<T> XmlAsyncReader::async_get(std::string const& uri,
247  std::string const& object_name,
248  ParserFunc<T> const& parse) const
249 {
250  return p_->async_get<T, T, QXmlStreamReader>(uri, object_name, XmlAsyncReader::create_parser_with_data, parse);
251 }
252 
253 template <typename BASE, typename TYPE>
254 XmlAsyncReader::ResultsFuture<BASE> XmlAsyncReader::async_get(std::string const& host,
255  QXmlStreamReaderParams const& params,
256  std::string const& object_name,
257  ParserFunc<BASE> const& parse) const
258 {
259  std::string uri = p_->get_uri(host, params);
260  return p_->async_get<BASE, TYPE, QXmlStreamReader>(
261  uri, object_name, XmlAsyncReader::create_parser_with_data, parse);
262 }
263 
264 template <typename T>
265 XmlAsyncReader::ResultsFuture<T> XmlAsyncReader::async_get(std::string const& host,
266  QXmlStreamReaderParams const& params,
267  std::string const& object_name,
268  ParserFunc<T> const& parse) const
269 {
270  std::string uri = p_->get_uri(host, params);
271  return p_->async_get<T, T, QXmlStreamReader>(uri, object_name, XmlAsyncReader::create_parser_with_data, parse);
272 }
273 
274 template <typename B, typename T>
275 static bool get_results(QXmlStreamReader& xml,
276  std::string const& object_name,
277  ResultsList<B>& results,
278  std::string& error_string)
279 {
280  while (!xml.atEnd() && !xml.hasError())
281  {
282  /* Read next element.*/
283  QXmlStreamReader::TokenType token = xml.readNext();
284  /* If token is just StartDocument, we'll go to next.*/
285  if (token == QXmlStreamReader::StartDocument)
286  {
287  continue;
288  }
289  /* If token is StartElement, we'll see if we can read it.*/
290  if (token == QXmlStreamReader::StartElement)
291  {
292  /* If it's named persons, we'll go to the next.*/
293  if (xml.name() == QString(object_name.c_str()))
294  {
295  results.emplace_back(std::make_shared<T>(xml));
296  }
297  }
298  }
299  if (xml.hasError())
300  {
301  error_string = "get_results: ERROR: " + xml.errorString().toStdString() + " at line: " + std::to_string(10);
302  }
303  /* Error handling. */
304  return !xml.hasError();
305 }
306 
307 } // namespace qt
308 
309 } // namespace scopes
310 
311 } // namespace unity
static QXmlStreamReaderSptr create_parser_with_data(std::string const &data, std::string &error)
Creates a QXmlStreamReader filled with the given data.
Definition: HttpAsyncReader.h:45
QXmlStreamReaderFuture async_get_parser(std::string const &uri) const
Downloads a HTTP remote file asynchronously and returns a future to a valid XML parser containing the...
Top-level namespace for all things Unity-related.
Definition: Version.h:49
Class that downloads http XML files asynchronously.
Definition: XmlAsyncReader.h:63
ResultsFuture< BASE > async_get(std::string const &uri, std::string const &object_name, ParserFunc< BASE > const &parse=get_results< BASE, TYPE >) const
Downloads a HTTP XML remote file asynchronously and returns a future to a list of results This method...
Definition: XmlAsyncReader.h:237