From e9d3085cf8a995339b9f4069cf0ba8551a128bae Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Tue, 18 Sep 2018 13:12:33 -0700 Subject: Implement progress reporting callback --- src/qpdf/qpdf.cpp | 33 +++++++++++++++++++++++++++++---- tests/test_pdf.py | 9 +++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/qpdf/qpdf.cpp b/src/qpdf/qpdf.cpp index 7094053..fa4964e 100644 --- a/src/qpdf/qpdf.cpp +++ b/src/qpdf/qpdf.cpp @@ -82,8 +82,8 @@ open_pdf( py::object read = stream.attr("read"); py::bytes data = read(); - char *buffer; - ssize_t length; + char *buffer = nullptr; + ssize_t length = 0; PYBIND11_BYTES_AS_STRING_AND_SIZE(data.ptr(), &buffer, &length); @@ -123,6 +123,24 @@ open_pdf( } +class PikeProgressReporter : public QPDFWriter::ProgressReporter { +public: + PikeProgressReporter(py::function callback) + { + this->callback = callback; + } + + virtual ~PikeProgressReporter() {} + + virtual void reportProgress(int percent) override + { + this->callback(percent); + } +private: + py::function callback; +}; + + void save_pdf( std::shared_ptr q, py::object filename_or_stream, @@ -134,7 +152,8 @@ void save_pdf( qpdf_object_stream_e object_stream_mode=qpdf_o_preserve, qpdf_stream_data_e stream_data_mode=qpdf_s_preserve, bool normalize_content=false, - bool linearize=false) + bool linearize=false, + py::object progress=py::none()) { QPDFWriter w(*q); @@ -160,6 +179,11 @@ void save_pdf( w.setContentNormalization(normalize_content); w.setLinearization(linearize); + if (!progress.is_none()) { + auto reporter = PointerHolder(new PikeProgressReporter(progress)); + w.registerProgressReporter(reporter); + } + if (py::hasattr(filename_or_stream, "write") && py::hasattr(filename_or_stream, "seek")) { // Python code gave us an object with a stream interface py::object stream = filename_or_stream; @@ -475,7 +499,8 @@ PYBIND11_MODULE(_qpdf, m) { py::arg("object_stream_mode")=qpdf_o_preserve, py::arg("stream_data_mode")=qpdf_s_preserve, py::arg("normalize_content")=false, - py::arg("linearize")=false + py::arg("linearize")=false, + py::arg("progress")=py::none() ) .def("_get_object_id", &QPDF::getObjectByID) .def("get_object", diff --git a/tests/test_pdf.py b/tests/test_pdf.py index 3d175c5..57c2ed6 100644 --- a/tests/test_pdf.py +++ b/tests/test_pdf.py @@ -6,6 +6,8 @@ import pytest from pikepdf import Pdf, PasswordError, Stream from io import StringIO +from unittest.mock import Mock + def test_non_filename(): with pytest.raises(TypeError): @@ -103,3 +105,10 @@ def test_remove_unreferenced(resources, outdir): def test_show_xref(resources): pdf = Pdf.open(resources / 'pal-1bit-trivial.pdf') pdf.show_xref_table() + + +def test_progress(resources, outdir): + pdf = Pdf.open(resources / 'pal-1bit-trivial.pdf') + mock = Mock() + pdf.save(outdir / 'out.pdf', progress=mock) + mock.assert_called() -- cgit v1.2.3