Commit a78d18f7e7603965a6ff750dd79d8c8e38efb260
1 parent
613c1221
Refactor `PipelinePopper` to add manual `pop` method and update its usage for si…
…mplified pipeline stack management in `QPDFWriter`.
Showing
1 changed file
with
24 additions
and
12 deletions
libqpdf/QPDFWriter.cc
| ... | ... | @@ -95,6 +95,9 @@ class QPDFWriter::PipelinePopper |
| 95 | 95 | |
| 96 | 96 | ~PipelinePopper(); |
| 97 | 97 | |
| 98 | + // Manually pop pipeline from the pipeline stack. | |
| 99 | + void pop(); | |
| 100 | + | |
| 98 | 101 | Pl_stack* stack{nullptr}; |
| 99 | 102 | unsigned long stack_id{0}; |
| 100 | 103 | }; |
| ... | ... | @@ -198,11 +201,10 @@ namespace |
| 198 | 201 | qpdf_assert_debug(stack.size() >= 2); |
| 199 | 202 | top->finish(); |
| 200 | 203 | qpdf_assert_debug(dynamic_cast<pl::Count*>(stack.back()) == top); |
| 201 | - // It might be possible for this assertion to fail if writeLinearized exits by exception | |
| 202 | - // when deterministic ID, but I don't think so. As of this writing, this is the only | |
| 203 | - // case in which two dynamically allocated PipelinePopper objects ever exist at the same | |
| 204 | - // time, so the assertion will fail if they get popped out of order from automatic | |
| 205 | - // destruction. | |
| 204 | + // It used to be possible for this assertion to fail if writeLinearized exits by | |
| 205 | + // exception when deterministic ID. There are no longer any cases in which two | |
| 206 | + // dynamically allocated PipelinePopper objects ever exist at the same time, so the | |
| 207 | + // assertion will fail if they get popped out of order from automatic destruction. | |
| 206 | 208 | qpdf_assert_debug(top->id() == stack_id); |
| 207 | 209 | delete stack.back(); |
| 208 | 210 | stack.pop_back(); |
| ... | ... | @@ -240,6 +242,16 @@ QPDFWriter::PipelinePopper::~PipelinePopper() |
| 240 | 242 | } |
| 241 | 243 | } |
| 242 | 244 | |
| 245 | +void | |
| 246 | +QPDFWriter::PipelinePopper::pop() | |
| 247 | +{ | |
| 248 | + if (stack) { | |
| 249 | + stack->pop(stack_id); | |
| 250 | + } | |
| 251 | + stack_id = 0; | |
| 252 | + stack = nullptr; | |
| 253 | +} | |
| 254 | + | |
| 243 | 255 | class QPDFWriter::Members |
| 244 | 256 | { |
| 245 | 257 | friend class QPDFWriter; |
| ... | ... | @@ -2762,19 +2774,19 @@ QPDFWriter::writeLinearized() |
| 2762 | 2774 | // Write file in two passes. Part numbers refer to PDF spec 1.4. |
| 2763 | 2775 | |
| 2764 | 2776 | FILE* lin_pass1_file = nullptr; |
| 2765 | - auto pp_pass1 = std::make_unique<PipelinePopper>(m->pipeline_stack); | |
| 2766 | - auto pp_md5 = std::make_unique<PipelinePopper>(m->pipeline_stack); | |
| 2777 | + auto pp_pass1 = m->pipeline_stack.popper(); | |
| 2778 | + auto pp_md5 = m->pipeline_stack.popper(); | |
| 2767 | 2779 | for (int pass: {1, 2}) { |
| 2768 | 2780 | if (pass == 1) { |
| 2769 | 2781 | if (!m->lin_pass1_filename.empty()) { |
| 2770 | 2782 | lin_pass1_file = QUtil::safe_fopen(m->lin_pass1_filename.c_str(), "wb"); |
| 2771 | 2783 | m->pipeline_stack.push(new Pl_StdioFile("linearization pass1", lin_pass1_file)); |
| 2772 | - m->pipeline_stack.activate(*pp_pass1); | |
| 2784 | + m->pipeline_stack.activate(pp_pass1); | |
| 2773 | 2785 | } else { |
| 2774 | - m->pipeline_stack.activate(*pp_pass1, true); | |
| 2786 | + m->pipeline_stack.activate(pp_pass1, true); | |
| 2775 | 2787 | } |
| 2776 | 2788 | if (m->deterministic_id) { |
| 2777 | - pushMD5Pipeline(*pp_md5); | |
| 2789 | + pushMD5Pipeline(pp_md5); | |
| 2778 | 2790 | } |
| 2779 | 2791 | } |
| 2780 | 2792 | |
| ... | ... | @@ -2949,13 +2961,13 @@ QPDFWriter::writeLinearized() |
| 2949 | 2961 | if (m->deterministic_id) { |
| 2950 | 2962 | QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1); |
| 2951 | 2963 | computeDeterministicIDData(); |
| 2952 | - pp_md5 = nullptr; | |
| 2964 | + pp_md5.pop(); | |
| 2953 | 2965 | qpdf_assert_debug(m->md5_pipeline == nullptr); |
| 2954 | 2966 | } |
| 2955 | 2967 | |
| 2956 | 2968 | // Close first pass pipeline |
| 2957 | 2969 | file_size = m->pipeline->getCount(); |
| 2958 | - pp_pass1 = nullptr; | |
| 2970 | + pp_pass1.pop(); | |
| 2959 | 2971 | |
| 2960 | 2972 | // Save hint offset since it will be set to zero by calling openObject. |
| 2961 | 2973 | qpdf_offset_t hint_offset1 = m->new_obj[hint_id].xref.getOffset(); | ... | ... |