/src/qpdf/libqpdf/Pl_QPDFTokenizer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include <qpdf/Pl_QPDFTokenizer.hh> |
2 | | |
3 | | #include <qpdf/BufferInputSource.hh> |
4 | | #include <qpdf/QTC.hh> |
5 | | #include <stdexcept> |
6 | | |
7 | | class Pl_QPDFTokenizer::Members |
8 | | { |
9 | | public: |
10 | 0 | Members() = default; |
11 | | Members(Members const&) = delete; |
12 | 0 | ~Members() = default; |
13 | | |
14 | | QPDFObjectHandle::TokenFilter* filter{nullptr}; |
15 | | QPDFTokenizer tokenizer; |
16 | | Pl_Buffer buf{"tokenizer buffer"}; |
17 | | }; |
18 | | |
19 | | Pl_QPDFTokenizer::Pl_QPDFTokenizer( |
20 | | char const* identifier, QPDFObjectHandle::TokenFilter* filter, Pipeline* next) : |
21 | 0 | Pipeline(identifier, next), |
22 | 0 | m(std::make_unique<Members>()) |
23 | 0 | { |
24 | 0 | m->filter = filter; |
25 | 0 | QPDFObjectHandle::TokenFilter::PipelineAccessor::setPipeline(m->filter, next); |
26 | 0 | m->tokenizer.allowEOF(); |
27 | 0 | m->tokenizer.includeIgnorable(); |
28 | 0 | } |
29 | | |
30 | | // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
31 | 0 | Pl_QPDFTokenizer::~Pl_QPDFTokenizer() = default; |
32 | | |
33 | | void |
34 | | Pl_QPDFTokenizer::write(unsigned char const* data, size_t len) |
35 | 0 | { |
36 | 0 | m->buf.write(data, len); |
37 | 0 | } |
38 | | |
39 | | void |
40 | | Pl_QPDFTokenizer::finish() |
41 | 0 | { |
42 | 0 | m->buf.finish(); |
43 | 0 | auto input = BufferInputSource("tokenizer data", m->buf.getBuffer(), true); |
44 | 0 | std::string empty; |
45 | 0 | while (true) { |
46 | 0 | auto token = m->tokenizer.readToken(input, empty, true); |
47 | 0 | m->filter->handleToken(token); |
48 | 0 | if (token.getType() == QPDFTokenizer::tt_eof) { |
49 | 0 | break; |
50 | 0 | } else if (token.isWord("ID")) { |
51 | | // Read the space after the ID. |
52 | 0 | char ch = ' '; |
53 | 0 | input.read(&ch, 1); |
54 | 0 | m->filter->handleToken( |
55 | | // line-break |
56 | 0 | QPDFTokenizer::Token(QPDFTokenizer::tt_space, std::string(1, ch))); |
57 | 0 | QTC::TC("qpdf", "Pl_QPDFTokenizer found ID"); |
58 | 0 | m->tokenizer.expectInlineImage(input); |
59 | 0 | } |
60 | 0 | } |
61 | 0 | m->filter->handleEOF(); |
62 | 0 | QPDFObjectHandle::TokenFilter::PipelineAccessor::setPipeline(m->filter, nullptr); |
63 | 0 | if (next()) { |
64 | 0 | next()->finish(); |
65 | 0 | } |
66 | 0 | } |