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