Orcus
threaded_sax_token_parser.hpp
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6  */
7 
8 #ifndef INCLUDED_ORCUS_THREADED_SAX_TOKEN_PARSER_HPP
9 #define INCLUDED_ORCUS_THREADED_SAX_TOKEN_PARSER_HPP
10 
11 #include "orcus/tokens.hpp"
12 #include "orcus/xml_namespace.hpp"
13 #include "orcus/sax_token_parser_thread.hpp"
14 #include "orcus/sax_parser_base.hpp"
15 #include "orcus/exception.hpp"
16 #include "orcus/detail/thread.hpp"
17 
18 #include <thread>
19 
20 namespace orcus {
21 
22 class xmlns_context;
23 class string_pool;
24 
25 template<typename _Handler>
27 {
28 public:
29 
30  typedef _Handler handler_type;
31 
43  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt,
44  handler_type& hdl, size_t min_token_size);
45 
58  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt,
59  handler_type& hdl, size_t min_token_size, size_t max_token_size);
60 
64  void parse();
65 
66  void swap_string_pool(string_pool& pool);
67 
68 private:
69  void thread_parse();
70 
71  void process_tokens(sax::parse_tokens_t& tokens);
72 
73 private:
74  sax::parser_thread m_parser_thread;
75  handler_type& m_handler;
76 };
77 
78 template<typename _Handler>
80  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt,
81  handler_type& hdl, size_t min_token_size) :
82  m_parser_thread(p, n, tks, ns_cxt, min_token_size), m_handler(hdl) {}
83 
84 template<typename _Handler>
86  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt, handler_type& hdl,
87  size_t min_token_size, size_t max_token_size) :
88  m_parser_thread(p, n, tks, ns_cxt, min_token_size, max_token_size), m_handler(hdl) {}
89 
90 template<typename _Handler>
92 {
93  std::thread t(&threaded_sax_token_parser::thread_parse, this);
94  detail::thread::scoped_guard guard(std::move(t));
95 
96  sax::parse_tokens_t tokens;
97 
98  try
99  {
100  while (m_parser_thread.next_tokens(tokens))
101  process_tokens(tokens);
102 
103  process_tokens(tokens);
104  }
105  catch (const std::exception& e)
106  {
107  m_parser_thread.abort();
108  throw;
109  }
110 }
111 
112 template<typename _Handler>
114 {
115  m_parser_thread.swap_string_pool(pool);
116 }
117 
118 template<typename _Handler>
119 void threaded_sax_token_parser<_Handler>::thread_parse()
120 {
121  // Start parsing.
122  m_parser_thread.start();
123 }
124 
125 template<typename _Handler>
126 void threaded_sax_token_parser<_Handler>::process_tokens(sax::parse_tokens_t& tks)
127 {
128  std::for_each(tks.begin(), tks.end(),
129  [this](const sax::parse_token& t)
130  {
131  switch (t.type)
132  {
133  case sax::parse_token_t::start_element:
134  m_handler.start_element(*t.element);
135  break;
136  case sax::parse_token_t::end_element:
137  m_handler.end_element(*t.element);
138  break;
139  case sax::parse_token_t::characters:
140  m_handler.characters(pstring(t.characters.p, t.characters.n), false);
141  break;
142  case sax::parse_token_t::parse_error:
143  throw sax::malformed_xml_error(std::string(t.error_value.p, t.error_value.len), t.error_value.offset);
144  default:
145  throw general_error("unknown token type encountered.");
146  }
147  }
148  );
149 }
150 
151 }
152 
153 #endif
154 
155 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition: thread.hpp:16
Definition: sax_token_parser_thread.hpp:78
Definition: string_pool.hpp:24
Definition: threaded_sax_token_parser.hpp:27
threaded_sax_token_parser(const char *p, size_t n, const tokens &tks, xmlns_context &ns_cxt, handler_type &hdl, size_t min_token_size)
Definition: threaded_sax_token_parser.hpp:79
void parse()
Definition: threaded_sax_token_parser.hpp:91
Definition: tokens.hpp:22
Definition: xml_namespace.hpp:83