mirror of https://github.com/qpdf/qpdf.git
Add Pl_Function -- a generic function pipeline
This commit is contained in:
parent
bb0ea2f8e7
commit
eae75dbe44
|
@ -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
|
// provided, this pipeline will also pass the data through to it and
|
||||||
// will forward finish() to it.
|
// will forward finish() to it.
|
||||||
//
|
//
|
||||||
// It is okay to not call finish() on this pipeline. This makes it
|
// It is okay to not call finish() on this pipeline if it has no
|
||||||
// easy to stick this in front of another pipeline to capture data
|
// "next". This makes it easy to stick this in front of another
|
||||||
// that is written to the other pipeline without interfering with when
|
// pipeline to capture data that is written to the other pipeline
|
||||||
// finish is called on the other pipeline and without having to put a
|
// without interfering with when finish is called on the other
|
||||||
// Pl_Concatenate after it.
|
// pipeline and without having to put a Pl_Concatenate after it.
|
||||||
|
|
||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ set(libqpdf_SOURCES
|
||||||
Pl_DCT.cc
|
Pl_DCT.cc
|
||||||
Pl_Discard.cc
|
Pl_Discard.cc
|
||||||
Pl_Flate.cc
|
Pl_Flate.cc
|
||||||
|
Pl_Function.cc
|
||||||
Pl_LZWDecoder.cc
|
Pl_LZWDecoder.cc
|
||||||
Pl_MD5.cc
|
Pl_MD5.cc
|
||||||
Pl_OStream.cc
|
Pl_OStream.cc
|
||||||
|
|
|
@ -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
|
nntree
|
||||||
numrange
|
numrange
|
||||||
pdf_version
|
pdf_version
|
||||||
|
pl_function
|
||||||
pointer_holder
|
pointer_holder
|
||||||
predictors
|
predictors
|
||||||
qintc
|
qintc
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
|
@ -0,0 +1,2 @@
|
||||||
|
p1: 6: potato
|
||||||
|
p2: 5: salad
|
|
@ -16,6 +16,7 @@
|
||||||
#include <qpdf/Pl_DCT.hh>
|
#include <qpdf/Pl_DCT.hh>
|
||||||
#include <qpdf/Pl_Discard.hh>
|
#include <qpdf/Pl_Discard.hh>
|
||||||
#include <qpdf/Pl_Flate.hh>
|
#include <qpdf/Pl_Flate.hh>
|
||||||
|
#include <qpdf/Pl_Function.hh>
|
||||||
#include <qpdf/Pl_OStream.hh>
|
#include <qpdf/Pl_OStream.hh>
|
||||||
#include <qpdf/Pl_QPDFTokenizer.hh>
|
#include <qpdf/Pl_QPDFTokenizer.hh>
|
||||||
#include <qpdf/Pl_RunLength.hh>
|
#include <qpdf/Pl_RunLength.hh>
|
||||||
|
@ -78,6 +79,7 @@ main()
|
||||||
print_size(Pl_DCT);
|
print_size(Pl_DCT);
|
||||||
print_size(Pl_Discard);
|
print_size(Pl_Discard);
|
||||||
print_size(Pl_Flate);
|
print_size(Pl_Flate);
|
||||||
|
print_size(Pl_Function);
|
||||||
print_size(Pl_OStream);
|
print_size(Pl_OStream);
|
||||||
print_size(Pl_QPDFTokenizer);
|
print_size(Pl_QPDFTokenizer);
|
||||||
print_size(Pl_RunLength);
|
print_size(Pl_RunLength);
|
||||||
|
|
Loading…
Reference in New Issue