From 16139d97c83ba48ab31b0f7619bab77d6cdb79e6 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Tue, 3 May 2022 18:40:42 -0400 Subject: [PATCH] Add new Pl_OStream Pipeline --- ChangeLog | 3 ++ TODO | 1 - include/qpdf/Pl_OStream.hh | 69 ++++++++++++++++++++++++++++++++++++++ libqpdf/CMakeLists.txt | 1 + libqpdf/Pl_OStream.cc | 35 +++++++++++++++++++ libtests/base64.cc | 4 +-- manual/release-notes.rst | 3 ++ qpdf/sizes.cc | 2 ++ 8 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 include/qpdf/Pl_OStream.hh create mode 100644 libqpdf/Pl_OStream.cc diff --git a/ChangeLog b/ChangeLog index d8f5ad91..38d5aaa1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2022-05-03 Jay Berkenbilt + * Add new Pipeline class Pl_OStream, similar to Pl_StdioFile but + takes a std::ostream instead of a FILE*. + * Add new convenience methods to Pipeline: writeCStr and writeString. Also add a limit << operator that takes C strings and std::strings. Also add an overloaded version of write that takes diff --git a/TODO b/TODO index d4ffa3fc..98f3dbd6 100644 --- a/TODO +++ b/TODO @@ -47,7 +47,6 @@ Output JSON v2 notes from 5/2: Need new pipelines: -* Pl_OStream(std::ostream) with semantics like Pl_StdioFile * Pl_String to std::string with semantics like Pl_Buffer See if I can change all output and error messages issued by the diff --git a/include/qpdf/Pl_OStream.hh b/include/qpdf/Pl_OStream.hh new file mode 100644 index 00000000..01cede8b --- /dev/null +++ b/include/qpdf/Pl_OStream.hh @@ -0,0 +1,69 @@ +// 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. + +// End-of-line pipeline that simply writes its data to a stdio FILE* object. + +#ifndef PL_OSTREAM_HH +#define PL_OSTREAM_HH + +#include + +#include + +// +// This pipeline is reusable. +// + +class QPDF_DLL_CLASS Pl_OStream: public Pipeline +{ + public: + // os is externally maintained; this class just writes to and + // flushes it. It does not close it. + QPDF_DLL + Pl_OStream(char const* identifier, std::ostream& os); + QPDF_DLL + virtual ~Pl_OStream(); + + 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_OStream; + + public: + QPDF_DLL + ~Members() = default; + + private: + Members(std::ostream&); + Members(Members const&) = delete; + + std::ostream& os; + }; + + std::shared_ptr m; +}; + +#endif // PL_OSTREAM_HH diff --git a/libqpdf/CMakeLists.txt b/libqpdf/CMakeLists.txt index 72b87975..2d5685b4 100644 --- a/libqpdf/CMakeLists.txt +++ b/libqpdf/CMakeLists.txt @@ -44,6 +44,7 @@ set(libqpdf_SOURCES Pl_Flate.cc Pl_LZWDecoder.cc Pl_MD5.cc + Pl_OStream.cc Pl_PNGFilter.cc Pl_QPDFTokenizer.cc Pl_RC4.cc diff --git a/libqpdf/Pl_OStream.cc b/libqpdf/Pl_OStream.cc new file mode 100644 index 00000000..db0081df --- /dev/null +++ b/libqpdf/Pl_OStream.cc @@ -0,0 +1,35 @@ +#include + +#include +#include +#include + +Pl_OStream::Members::Members(std::ostream& os) : + os(os) +{ +} + +Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) : + Pipeline(identifier, 0), + m(new Members(os)) +{ +} + +Pl_OStream::~Pl_OStream() +{ + // Must be explicit and not inline -- see QPDF_DLL_CLASS in + // README-maintainer +} + +void +Pl_OStream::write(unsigned char const* buf, size_t len) +{ + this->m->os.write( + reinterpret_cast(buf), static_cast(len)); +} + +void +Pl_OStream::finish() +{ + this->m->os.flush(); +} diff --git a/libtests/base64.cc b/libtests/base64.cc index 0ce6f9a3..41dc676d 100644 --- a/libtests/base64.cc +++ b/libtests/base64.cc @@ -2,7 +2,7 @@ #include -#include +#include #include #include #include @@ -52,7 +52,7 @@ main(int argc, char* argv[]) } try { - Pl_StdioFile out("stdout", stdout); + Pl_OStream out("stdout", std::cout); Pl_Base64 decode("decode", &out, action); // The comments are "n: n%4 n%3", where n is the number of // bytes read at the end of the call, and are there to diff --git a/manual/release-notes.rst b/manual/release-notes.rst index 990a0188..fdbd21b7 100644 --- a/manual/release-notes.rst +++ b/manual/release-notes.rst @@ -117,6 +117,9 @@ For a detailed list of changes, please see the file - ``operator <<``: for null-terminated C strings and std::strings + - Add new ``Pipeline`` type ``Pl_OStream`` to write to a + ``std::ostream``. + - Other changes - A new chapter on contributing to qpdf has been added to the diff --git a/qpdf/sizes.cc b/qpdf/sizes.cc index 10a25fac..dc5715ab 100644 --- a/qpdf/sizes.cc +++ b/qpdf/sizes.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,7 @@ main() print_size(Pl_DCT); print_size(Pl_Discard); print_size(Pl_Flate); + print_size(Pl_OStream); print_size(Pl_QPDFTokenizer); print_size(Pl_RunLength); print_size(Pl_StdioFile);