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
19namespace orcus {
20
21class xmlns_context;
22class string_pool;
23
24template<typename _Handler>
26{
27public:
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
67private:
68 void thread_parse();
69
70 void process_tokens(sax::parse_tokens_t& tokens);
71
72private:
73 sax::parser_thread m_parser_thread;
74 handler_type& m_handler;
75};
76
77template<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
83template<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
89template<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
103template<typename _Handler>
105{
106 m_parser_thread.swap_string_pool(pool);
107}
108
109template<typename _Handler>
110void threaded_sax_token_parser<_Handler>::thread_parse()
111{
112 // Start parsing.
113 m_parser_thread.start();
114}
115
116template<typename _Handler>
117void 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: */
Definition: thread.hpp:16
Definition: sax_token_parser_thread.hpp:68
Definition: string_pool.hpp:23
Definition: threaded_sax_token_parser.hpp:26
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
void parse()
Definition: threaded_sax_token_parser.hpp:90
Definition: tokens.hpp:22
Definition: xml_namespace.hpp:83