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/exception.hpp"
15 #include "orcus/detail/thread.hpp"
16 
17 #include <thread>
18 
19 namespace orcus {
20 
21 class xmlns_context;
22 class string_pool;
23 
24 template<typename _Handler>
26 {
27 public:
28 
29  typedef _Handler handler_type;
30 
42  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt,
43  handler_type& hdl, size_t min_token_size);
44 
57  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt,
58  handler_type& hdl, size_t min_token_size, size_t max_token_size);
59 
63  void parse();
64 
65  void swap_string_pool(string_pool& pool);
66 
67 private:
68  void thread_parse();
69 
70  void process_tokens(sax::parse_tokens_t& tokens);
71 
72 private:
73  sax::parser_thread m_parser_thread;
74  handler_type& m_handler;
75 };
76 
77 template<typename _Handler>
79  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt,
80  handler_type& hdl, size_t min_token_size) :
81  m_parser_thread(p, n, tks, ns_cxt, min_token_size), m_handler(hdl) {}
82 
83 template<typename _Handler>
85  const char* p, size_t n, const tokens& tks, xmlns_context& ns_cxt, handler_type& hdl,
86  size_t min_token_size, size_t max_token_size) :
87  m_parser_thread(p, n, tks, ns_cxt, min_token_size, max_token_size), m_handler(hdl) {}
88 
89 template<typename _Handler>
91 {
92  std::thread t(&threaded_sax_token_parser::thread_parse, this);
93  detail::thread::scoped_guard guard(std::move(t));
94 
95  sax::parse_tokens_t tokens;
96 
97  while (m_parser_thread.next_tokens(tokens))
98  process_tokens(tokens);
99 
100  process_tokens(tokens);
101 }
102 
103 template<typename _Handler>
105 {
106  m_parser_thread.swap_string_pool(pool);
107 }
108 
109 template<typename _Handler>
110 void threaded_sax_token_parser<_Handler>::thread_parse()
111 {
112  // Start parsing.
113  m_parser_thread.start();
114 }
115 
116 template<typename _Handler>
117 void threaded_sax_token_parser<_Handler>::process_tokens(sax::parse_tokens_t& tks)
118 {
119  std::for_each(tks.begin(), tks.end(),
120  [this](const sax::parse_token& t)
121  {
122  switch (t.type)
123  {
124  case sax::parse_token_t::start_element:
125  m_handler.start_element(*t.element);
126  break;
127  case sax::parse_token_t::end_element:
128  m_handler.end_element(*t.element);
129  break;
130  case sax::parse_token_t::characters:
131  m_handler.characters(pstring(t.characters.p, t.characters.n), false);
132  break;
133  default:
134  throw general_error("unknown token type encountered.");
135  }
136  }
137  );
138 }
139 
140 }
141 
142 #endif
143 
144 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
orcus::xmlns_context
Definition: xml_namespace.hpp:83
orcus::threaded_sax_token_parser
Definition: threaded_sax_token_parser.hpp:26
orcus::threaded_sax_token_parser::parse
void parse()
Definition: threaded_sax_token_parser.hpp:90
orcus::string_pool
Definition: string_pool.hpp:23
orcus::threaded_sax_token_parser::threaded_sax_token_parser
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:78
orcus::sax::parser_thread
Definition: sax_token_parser_thread.hpp:68
orcus::detail::thread::scoped_guard
Definition: thread.hpp:16
orcus::tokens
Definition: tokens.hpp:22