Commit eae75dbe448b0395aee7e49c2a9cca9f82680782
1 parent
bb0ea2f8
Add Pl_Function -- a generic function pipeline
Showing
9 changed files
with
169 additions
and
5 deletions
include/qpdf/Pl_Function.hh
0 → 100644
| 1 | +// Copyright (c) 2005-2022 Jay Berkenbilt | |
| 2 | +// | |
| 3 | +// This file is part of qpdf. | |
| 4 | +// | |
| 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 | +// you may not use this file except in compliance with the License. | |
| 7 | +// You may obtain a copy of the License at | |
| 8 | +// | |
| 9 | +// http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 | +// | |
| 11 | +// Unless required by applicable law or agreed to in writing, software | |
| 12 | +// distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 | +// See the License for the specific language governing permissions and | |
| 15 | +// limitations under the License. | |
| 16 | +// | |
| 17 | +// Versions of qpdf prior to version 7 were released under the terms | |
| 18 | +// of version 2.0 of the Artistic License. At your option, you may | |
| 19 | +// continue to consider qpdf to be licensed under those terms. Please | |
| 20 | +// see the manual for additional information. | |
| 21 | + | |
| 22 | +#ifndef PL_FUNCTION_HH | |
| 23 | +#define PL_FUNCTION_HH | |
| 24 | + | |
| 25 | +// This pipeline calls an arbitrary function with whatever data is | |
| 26 | +// passed to it. This pipeline can be reused. | |
| 27 | +// | |
| 28 | +// For this pipeline, "next" may be null. If a next pointer is | |
| 29 | +// provided, this pipeline will also pass the data through to it and | |
| 30 | +// will forward finish() to it. | |
| 31 | +// | |
| 32 | +// It is okay to not call finish() on this pipeline if it has no | |
| 33 | +// "next". | |
| 34 | + | |
| 35 | +#include <qpdf/Pipeline.hh> | |
| 36 | + | |
| 37 | +#include <functional> | |
| 38 | + | |
| 39 | +class QPDF_DLL_CLASS Pl_Function: public Pipeline | |
| 40 | +{ | |
| 41 | + public: | |
| 42 | + typedef std::function<void(unsigned char const*, size_t)> writer_t; | |
| 43 | + | |
| 44 | + QPDF_DLL | |
| 45 | + Pl_Function(char const* identifier, Pipeline* next, writer_t fn); | |
| 46 | + QPDF_DLL | |
| 47 | + virtual ~Pl_Function(); | |
| 48 | + | |
| 49 | + QPDF_DLL | |
| 50 | + virtual void write(unsigned char const* buf, size_t len); | |
| 51 | + QPDF_DLL | |
| 52 | + virtual void finish(); | |
| 53 | + | |
| 54 | + private: | |
| 55 | + class QPDF_DLL_PRIVATE Members | |
| 56 | + { | |
| 57 | + friend class Pl_Function; | |
| 58 | + | |
| 59 | + public: | |
| 60 | + QPDF_DLL | |
| 61 | + ~Members() = default; | |
| 62 | + | |
| 63 | + private: | |
| 64 | + Members(writer_t); | |
| 65 | + Members(Members const&) = delete; | |
| 66 | + | |
| 67 | + writer_t fn; | |
| 68 | + }; | |
| 69 | + | |
| 70 | + std::shared_ptr<Members> m; | |
| 71 | +}; | |
| 72 | + | |
| 73 | +#endif // PL_FUNCTION_HH | ... | ... |
include/qpdf/Pl_String.hh
| ... | ... | @@ -30,11 +30,11 @@ |
| 30 | 30 | // provided, this pipeline will also pass the data through to it and |
| 31 | 31 | // will forward finish() to it. |
| 32 | 32 | // |
| 33 | -// It is okay to not call finish() on this pipeline. This makes it | |
| 34 | -// easy to stick this in front of another pipeline to capture data | |
| 35 | -// that is written to the other pipeline without interfering with when | |
| 36 | -// finish is called on the other pipeline and without having to put a | |
| 37 | -// Pl_Concatenate after it. | |
| 33 | +// It is okay to not call finish() on this pipeline if it has no | |
| 34 | +// "next". This makes it easy to stick this in front of another | |
| 35 | +// pipeline to capture data that is written to the other pipeline | |
| 36 | +// without interfering with when finish is called on the other | |
| 37 | +// pipeline and without having to put a Pl_Concatenate after it. | |
| 38 | 38 | |
| 39 | 39 | #include <qpdf/Pipeline.hh> |
| 40 | 40 | ... | ... |
libqpdf/CMakeLists.txt
libqpdf/Pl_Function.cc
0 → 100644
| 1 | +#include <qpdf/Pl_Function.hh> | |
| 2 | + | |
| 3 | +#include <qpdf/QUtil.hh> | |
| 4 | +#include <errno.h> | |
| 5 | +#include <stdexcept> | |
| 6 | + | |
| 7 | +Pl_Function::Members::Members(writer_t fn) : | |
| 8 | + fn(fn) | |
| 9 | +{ | |
| 10 | +} | |
| 11 | + | |
| 12 | +Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_t fn) : | |
| 13 | + Pipeline(identifier, next), | |
| 14 | + m(new Members(fn)) | |
| 15 | +{ | |
| 16 | +} | |
| 17 | + | |
| 18 | +Pl_Function::~Pl_Function() | |
| 19 | +{ | |
| 20 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in | |
| 21 | + // README-maintainer | |
| 22 | +} | |
| 23 | + | |
| 24 | +void | |
| 25 | +Pl_Function::write(unsigned char const* buf, size_t len) | |
| 26 | +{ | |
| 27 | + this->m->fn(buf, len); | |
| 28 | + if (getNext(true)) { | |
| 29 | + getNext()->write(buf, len); | |
| 30 | + } | |
| 31 | +} | |
| 32 | + | |
| 33 | +void | |
| 34 | +Pl_Function::finish() | |
| 35 | +{ | |
| 36 | + if (getNext(true)) { | |
| 37 | + getNext()->finish(); | |
| 38 | + } | |
| 39 | +} | ... | ... |
libtests/CMakeLists.txt
libtests/pl_function.cc
0 → 100644
| 1 | +#include <qpdf/assert_test.h> | |
| 2 | + | |
| 3 | +#include <qpdf/Pl_Function.hh> | |
| 4 | +#include <qpdf/Pl_String.hh> | |
| 5 | +#include <qpdf/Pl_Base64.hh> | |
| 6 | +#include <iostream> | |
| 7 | + | |
| 8 | +int | |
| 9 | +main(int argc, char* argv[]) | |
| 10 | +{ | |
| 11 | + Pl_Function p1( | |
| 12 | + "p1", nullptr, [](unsigned char const* data, size_t len) { | |
| 13 | + std::cout << "p1: " << len << ": " << data << std::endl; | |
| 14 | + }); | |
| 15 | + p1.write(reinterpret_cast<unsigned char const*>("potato"), 6); | |
| 16 | + | |
| 17 | + std::string s; | |
| 18 | + Pl_String ps("string", nullptr, s); | |
| 19 | + Pl_Base64 b("base64", &ps, Pl_Base64::a_encode); | |
| 20 | + Pl_Function p2( | |
| 21 | + "p2", &b, [](unsigned char const* data, size_t len) { | |
| 22 | + std::cout << "p2: " << len << ": " << data << std::endl; | |
| 23 | + }); | |
| 24 | + p2.write(reinterpret_cast<unsigned char const*>("salad"), 5); | |
| 25 | + p2.finish(); | |
| 26 | + assert(s == "c2FsYWQ="); | |
| 27 | + | |
| 28 | + return 0; | |
| 29 | +} | ... | ... |
libtests/qtest/pl_function.test
0 → 100644
| 1 | +#!/usr/bin/env perl | |
| 2 | +require 5.008; | |
| 3 | +use warnings; | |
| 4 | +use strict; | |
| 5 | + | |
| 6 | +chdir("pl_function") or die "chdir testdir failed: $!\n"; | |
| 7 | + | |
| 8 | +require TestDriver; | |
| 9 | + | |
| 10 | +my $td = new TestDriver('pl_function'); | |
| 11 | + | |
| 12 | +$td->runtest("pl_function", | |
| 13 | + {$td->COMMAND => "pl_function"}, | |
| 14 | + {$td->FILE => "exp", $td->EXIT_STATUS => 0}, | |
| 15 | + $td->NORMALIZE_NEWLINES); | |
| 16 | + | |
| 17 | +$td->report(1); | ... | ... |
libtests/qtest/pl_function/exp
0 → 100644
qpdf/sizes.cc
| ... | ... | @@ -16,6 +16,7 @@ |
| 16 | 16 | #include <qpdf/Pl_DCT.hh> |
| 17 | 17 | #include <qpdf/Pl_Discard.hh> |
| 18 | 18 | #include <qpdf/Pl_Flate.hh> |
| 19 | +#include <qpdf/Pl_Function.hh> | |
| 19 | 20 | #include <qpdf/Pl_OStream.hh> |
| 20 | 21 | #include <qpdf/Pl_QPDFTokenizer.hh> |
| 21 | 22 | #include <qpdf/Pl_RunLength.hh> |
| ... | ... | @@ -78,6 +79,7 @@ main() |
| 78 | 79 | print_size(Pl_DCT); |
| 79 | 80 | print_size(Pl_Discard); |
| 80 | 81 | print_size(Pl_Flate); |
| 82 | + print_size(Pl_Function); | |
| 81 | 83 | print_size(Pl_OStream); |
| 82 | 84 | print_size(Pl_QPDFTokenizer); |
| 83 | 85 | print_size(Pl_RunLength); | ... | ... |