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