mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add Pl_Function -- a generic function pipeline
This commit is contained in:
parent
bb0ea2f8e7
commit
eae75dbe44
73
include/qpdf/Pl_Function.hh
Normal file
73
include/qpdf/Pl_Function.hh
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright (c) 2005-2022 Jay Berkenbilt
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
|
||||
#ifndef PL_FUNCTION_HH
|
||||
#define PL_FUNCTION_HH
|
||||
|
||||
// This pipeline calls an arbitrary function with whatever data is
|
||||
// passed to it. This pipeline can be reused.
|
||||
//
|
||||
// For this pipeline, "next" may be null. If a next pointer is
|
||||
// provided, this pipeline will also pass the data through to it and
|
||||
// will forward finish() to it.
|
||||
//
|
||||
// It is okay to not call finish() on this pipeline if it has no
|
||||
// "next".
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
#include <functional>
|
||||
|
||||
class QPDF_DLL_CLASS Pl_Function: public Pipeline
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(unsigned char const*, size_t)> writer_t;
|
||||
|
||||
QPDF_DLL
|
||||
Pl_Function(char const* identifier, Pipeline* next, writer_t fn);
|
||||
QPDF_DLL
|
||||
virtual ~Pl_Function();
|
||||
|
||||
QPDF_DLL
|
||||
virtual void write(unsigned char const* buf, size_t len);
|
||||
QPDF_DLL
|
||||
virtual void finish();
|
||||
|
||||
private:
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_Function;
|
||||
|
||||
public:
|
||||
QPDF_DLL
|
||||
~Members() = default;
|
||||
|
||||
private:
|
||||
Members(writer_t);
|
||||
Members(Members const&) = delete;
|
||||
|
||||
writer_t fn;
|
||||
};
|
||||
|
||||
std::shared_ptr<Members> m;
|
||||
};
|
||||
|
||||
#endif // PL_FUNCTION_HH
|
@ -30,11 +30,11 @@
|
||||
// provided, this pipeline will also pass the data through to it and
|
||||
// will forward finish() to it.
|
||||
//
|
||||
// It is okay to not call finish() on this pipeline. This makes it
|
||||
// easy to stick this in front of another pipeline to capture data
|
||||
// that is written to the other pipeline without interfering with when
|
||||
// finish is called on the other pipeline and without having to put a
|
||||
// Pl_Concatenate after it.
|
||||
// It is okay to not call finish() on this pipeline if it has no
|
||||
// "next". This makes it easy to stick this in front of another
|
||||
// pipeline to capture data that is written to the other pipeline
|
||||
// without interfering with when finish is called on the other
|
||||
// pipeline and without having to put a Pl_Concatenate after it.
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
|
@ -42,6 +42,7 @@ set(libqpdf_SOURCES
|
||||
Pl_DCT.cc
|
||||
Pl_Discard.cc
|
||||
Pl_Flate.cc
|
||||
Pl_Function.cc
|
||||
Pl_LZWDecoder.cc
|
||||
Pl_MD5.cc
|
||||
Pl_OStream.cc
|
||||
|
39
libqpdf/Pl_Function.cc
Normal file
39
libqpdf/Pl_Function.cc
Normal file
@ -0,0 +1,39 @@
|
||||
#include <qpdf/Pl_Function.hh>
|
||||
|
||||
#include <qpdf/QUtil.hh>
|
||||
#include <errno.h>
|
||||
#include <stdexcept>
|
||||
|
||||
Pl_Function::Members::Members(writer_t fn) :
|
||||
fn(fn)
|
||||
{
|
||||
}
|
||||
|
||||
Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_t fn) :
|
||||
Pipeline(identifier, next),
|
||||
m(new Members(fn))
|
||||
{
|
||||
}
|
||||
|
||||
Pl_Function::~Pl_Function()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
Pl_Function::write(unsigned char const* buf, size_t len)
|
||||
{
|
||||
this->m->fn(buf, len);
|
||||
if (getNext(true)) {
|
||||
getNext()->write(buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Pl_Function::finish()
|
||||
{
|
||||
if (getNext(true)) {
|
||||
getNext()->finish();
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ set(TEST_PROGRAMS
|
||||
nntree
|
||||
numrange
|
||||
pdf_version
|
||||
pl_function
|
||||
pointer_holder
|
||||
predictors
|
||||
qintc
|
||||
|
29
libtests/pl_function.cc
Normal file
29
libtests/pl_function.cc
Normal file
@ -0,0 +1,29 @@
|
||||
#include <qpdf/assert_test.h>
|
||||
|
||||
#include <qpdf/Pl_Function.hh>
|
||||
#include <qpdf/Pl_String.hh>
|
||||
#include <qpdf/Pl_Base64.hh>
|
||||
#include <iostream>
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
Pl_Function p1(
|
||||
"p1", nullptr, [](unsigned char const* data, size_t len) {
|
||||
std::cout << "p1: " << len << ": " << data << std::endl;
|
||||
});
|
||||
p1.write(reinterpret_cast<unsigned char const*>("potato"), 6);
|
||||
|
||||
std::string s;
|
||||
Pl_String ps("string", nullptr, s);
|
||||
Pl_Base64 b("base64", &ps, Pl_Base64::a_encode);
|
||||
Pl_Function p2(
|
||||
"p2", &b, [](unsigned char const* data, size_t len) {
|
||||
std::cout << "p2: " << len << ": " << data << std::endl;
|
||||
});
|
||||
p2.write(reinterpret_cast<unsigned char const*>("salad"), 5);
|
||||
p2.finish();
|
||||
assert(s == "c2FsYWQ=");
|
||||
|
||||
return 0;
|
||||
}
|
17
libtests/qtest/pl_function.test
Normal file
17
libtests/qtest/pl_function.test
Normal file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env perl
|
||||
require 5.008;
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
chdir("pl_function") or die "chdir testdir failed: $!\n";
|
||||
|
||||
require TestDriver;
|
||||
|
||||
my $td = new TestDriver('pl_function');
|
||||
|
||||
$td->runtest("pl_function",
|
||||
{$td->COMMAND => "pl_function"},
|
||||
{$td->FILE => "exp", $td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
|
||||
$td->report(1);
|
2
libtests/qtest/pl_function/exp
Normal file
2
libtests/qtest/pl_function/exp
Normal file
@ -0,0 +1,2 @@
|
||||
p1: 6: potato
|
||||
p2: 5: salad
|
@ -16,6 +16,7 @@
|
||||
#include <qpdf/Pl_DCT.hh>
|
||||
#include <qpdf/Pl_Discard.hh>
|
||||
#include <qpdf/Pl_Flate.hh>
|
||||
#include <qpdf/Pl_Function.hh>
|
||||
#include <qpdf/Pl_OStream.hh>
|
||||
#include <qpdf/Pl_QPDFTokenizer.hh>
|
||||
#include <qpdf/Pl_RunLength.hh>
|
||||
@ -78,6 +79,7 @@ main()
|
||||
print_size(Pl_DCT);
|
||||
print_size(Pl_Discard);
|
||||
print_size(Pl_Flate);
|
||||
print_size(Pl_Function);
|
||||
print_size(Pl_OStream);
|
||||
print_size(Pl_QPDFTokenizer);
|
||||
print_size(Pl_RunLength);
|
||||
|
Loading…
Reference in New Issue
Block a user