Orcus
Loading...
Searching...
No Matches
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 "tokens.hpp"
12#include "xml_namespace.hpp"
13#include "sax_token_parser_thread.hpp"
14#include "sax_parser_base.hpp"
15#include "exception.hpp"
16#include "detail/thread.hpp"
17
18#include <thread>
19
20namespace orcus {
21
22class xmlns_context;
23class string_pool;
24
25template<typename _Handler>
27{
28public:
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
68private:
69 void thread_parse();
70
71 void process_tokens(const sax::parse_tokens_t& tokens);
72
73private:
74 sax::parser_thread m_parser_thread;
75 handler_type& m_handler;
76};
77
78template<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
84template<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
90template<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&)
106 {
107 m_parser_thread.abort();
108 throw;
109 }
110}
111
112template<typename _Handler>
114{
115 m_parser_thread.swap_string_pool(pool);
116}
117
118template<typename _Handler>
119void threaded_sax_token_parser<_Handler>::thread_parse()
120{
121 // Start parsing.
122 m_parser_thread.start();
123}
124
125template<typename _Handler>
126void threaded_sax_token_parser<_Handler>::process_tokens(const sax::parse_tokens_t& tks)
127{
128 for (const sax::parse_token& t : tks)
129 {
130 switch (t.type)
131 {
132 case sax::parse_token_t::start_element:
133 {
134 const auto* elem = std::get<const xml_token_element_t*>(t.value);
135 m_handler.start_element(*elem);
136 break;
137 }
138 case sax::parse_token_t::end_element:
139 {
140 const auto* elem = std::get<const xml_token_element_t*>(t.value);
141 m_handler.end_element(*elem);
142 break;
143 }
144 case sax::parse_token_t::characters:
145 {
146 auto s = std::get<std::string_view>(t.value);
147 m_handler.characters(s, false);
148 break;
149 }
150 case sax::parse_token_t::parse_error:
151 {
152 auto v = std::get<parse_error_value_t>(t.value);
153 throw malformed_xml_error(std::string{v.str}, v.offset);
154 }
155 default:
156 throw general_error("unknown token type encountered.");
157 }
158 }
159}
160
161}
162
163#endif
164
165/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition thread.hpp:16
Definition sax_token_parser_thread.hpp:62
Definition string_pool.hpp:26
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:30
Definition xml_namespace.hpp:100