Commit 5e791513c0ad2d0ff68a253f223f753e4523638a

Authored by m-holger
1 parent ac4b5e65

Refactor `PipelinePopper` to improve encapsulation by moving it into `Pl_stack` as a nested class.

include/qpdf/QPDFWriter.hh
... ... @@ -447,7 +447,6 @@ class QPDFWriter
447 447 struct NewObject;
448 448 class ObjTable;
449 449 class NewObjTable;
450   - class PipelinePopper;
451 450  
452 451 private:
453 452 // flags used by unparseObject
... ...
libqpdf/QPDFWriter.cc
... ... @@ -52,61 +52,59 @@ QPDFWriter::FunctionProgressReporter::reportProgress(int progress)
52 52  
53 53 namespace
54 54 {
55   - class Pl_stack;
56   -}
57   -
58   -// A PipelinePopper is normally returned by Pl_stack::activate, or, if necessary, a reference to a
59   -// PipelinePopper instance can be passed into activate. When the PipelinePopper goes out of scope,
60   -// the pipeline stack is popped. This causes finish to be called on the current pipeline and the
61   -// pipeline stack to be popped until the top of stack is a previous active top of stack, and
62   -// restores the pipeline to that point. It deletes any pipelines that it pops.
63   -class QPDFWriter::PipelinePopper
64   -{
65   - public:
66   - PipelinePopper(Pl_stack& stack) :
67   - stack(&stack)
68   - {
69   - }
70   - PipelinePopper() = default;
71   - PipelinePopper(PipelinePopper const&) = delete;
72   - PipelinePopper(PipelinePopper&& other) noexcept
73   - {
74   - // For MSVC, default pops the stack
75   - if (this != &other) {
76   - stack = other.stack;
77   - stack_id = other.stack_id;
78   - other.stack = nullptr;
79   - other.stack_id = 0;
80   - };
81   - }
82   - PipelinePopper& operator=(PipelinePopper const&) = delete;
83   - PipelinePopper&
84   - operator=(PipelinePopper&& other) noexcept
  55 + class Pl_stack
85 56 {
86   - // For MSVC, default pops the stack
87   - if (this != &other) {
88   - stack = other.stack;
89   - stack_id = other.stack_id;
90   - other.stack = nullptr;
91   - other.stack_id = 0;
92   - };
93   - return *this;
94   - }
  57 + // A pipeline Popper is normally returned by Pl_stack::activate, or, if necessary, a
  58 + // reference to a Popper instance can be passed into activate. When the Popper goes out of
  59 + // scope, the pipeline stack is popped. This causes finish to be called on the current
  60 + // pipeline and the pipeline stack to be popped until the top of stack is a previous active
  61 + // top of stack and restores the pipeline to that point. It deletes any pipelines that it
  62 + // pops.
  63 + class Popper
  64 + {
  65 + friend class Pl_stack;
95 66  
96   - ~PipelinePopper();
  67 + public:
  68 + Popper() = default;
  69 + Popper(Popper const&) = delete;
  70 + Popper(Popper&& other) noexcept
  71 + {
  72 + // For MSVC, default pops the stack
  73 + if (this != &other) {
  74 + stack = other.stack;
  75 + stack_id = other.stack_id;
  76 + other.stack = nullptr;
  77 + other.stack_id = 0;
  78 + };
  79 + }
  80 + Popper& operator=(Popper const&) = delete;
  81 + Popper&
  82 + operator=(Popper&& other) noexcept
  83 + {
  84 + // For MSVC, default pops the stack
  85 + if (this != &other) {
  86 + stack = other.stack;
  87 + stack_id = other.stack_id;
  88 + other.stack = nullptr;
  89 + other.stack_id = 0;
  90 + };
  91 + return *this;
  92 + }
97 93  
98   - // Manually pop pipeline from the pipeline stack.
99   - void pop();
  94 + ~Popper();
100 95  
101   - Pl_stack* stack{nullptr};
102   - unsigned long stack_id{0};
103   -};
  96 + // Manually pop pipeline from the pipeline stack.
  97 + void pop();
104 98  
105   -namespace
106   -{
107   - class Pl_stack
108   - {
109   - using PP = QPDFWriter::PipelinePopper;
  99 + private:
  100 + Popper(Pl_stack& stack) :
  101 + stack(&stack)
  102 + {
  103 + }
  104 +
  105 + Pl_stack* stack{nullptr};
  106 + unsigned long stack_id{0};
  107 + };
110 108  
111 109 public:
112 110 Pl_stack(pl::Count*& top, std::unique_ptr<Pl_MD5>& md5_pipeline) :
... ... @@ -115,7 +113,7 @@ namespace
115 113 {
116 114 }
117 115  
118   - PP
  116 + Popper
119 117 popper()
120 118 {
121 119 return {*this};
... ... @@ -129,41 +127,41 @@ namespace
129 127 stack.emplace_back(std::move(c));
130 128 }
131 129  
132   - PP
  130 + Popper
133 131 activate(std::string& str)
134 132 {
135   - PP pp{*this};
  133 + Popper pp{*this};
136 134 activate(pp, str);
137 135 return pp;
138 136 }
139 137  
140 138 void
141   - activate(PP& pp, std::string& str)
  139 + activate(Popper& pp, std::string& str)
142 140 {
143 141 activate(pp, false, &str, nullptr);
144 142 }
145 143  
146 144 void
147   - activate(PP& pp, std::unique_ptr<pl::Link> link)
  145 + activate(Popper& pp, std::unique_ptr<pl::Link> link)
148 146 {
149 147 count_buffer.clear();
150 148 activate(pp, false, &count_buffer, std::move(link));
151 149 }
152 150  
153   - PP
  151 + Popper
154 152 activate(
155 153 bool discard = false,
156 154 std::string* str = nullptr,
157 155 std::unique_ptr<pl::Link> link = nullptr)
158 156 {
159   - PP pp{*this};
  157 + Popper pp{*this};
160 158 activate(pp, discard, str, std::move(link));
161 159 return pp;
162 160 }
163 161  
164 162 void
165 163 activate(
166   - PP& pp,
  164 + Popper& pp,
167 165 bool discard = false,
168 166 std::string* str = nullptr,
169 167 std::unique_ptr<pl::Link> link = nullptr)
... ... @@ -184,7 +182,7 @@ namespace
184 182 ++next_stack_id;
185 183 }
186 184 void
187   - activate_md5(PP& pp)
  185 + activate_md5(Popper& pp)
188 186 {
189 187 qpdf_assert_debug(!md5_pipeline);
190 188 qpdf_assert_debug(md5_id == 0);
... ... @@ -201,8 +199,14 @@ namespace
201 199 }
202 200  
203 201 void
204   - pop(unsigned long stack_id)
  202 + clear_buffer()
  203 + {
  204 + count_buffer.clear();
  205 + }
205 206  
  207 + private:
  208 + void
  209 + pop(unsigned long stack_id)
206 210 {
207 211 if (!stack_id) {
208 212 return;
... ... @@ -212,7 +216,7 @@ namespace
212 216 qpdf_assert_debug(stack.back().get() == top);
213 217 // It used to be possible for this assertion to fail if writeLinearized exits by
214 218 // exception when deterministic ID. There are no longer any cases in which two
215   - // dynamically allocated PipelinePopper objects ever exist at the same time, so the
  219 + // dynamically allocated pipeline Popper objects ever exist at the same time, so the
216 220 // assertion will fail if they get popped out of order from automatic destruction.
217 221 qpdf_assert_debug(top->id() == stack_id);
218 222 if (stack_id == md5_id) {
... ... @@ -223,13 +227,6 @@ namespace
223 227 top = stack.back().get();
224 228 }
225 229  
226   - void
227   - clear_buffer()
228   - {
229   - count_buffer.clear();
230   - }
231   -
232   - private:
233 230 std::vector<std::unique_ptr<pl::Count>> stack;
234 231 pl::Count*& top;
235 232 std::unique_ptr<Pl_MD5>& md5_pipeline;
... ... @@ -237,9 +234,10 @@ namespace
237 234 unsigned long md5_id{0};
238 235 std::string count_buffer;
239 236 };
  237 +
240 238 } // namespace
241 239  
242   -QPDFWriter::PipelinePopper::~PipelinePopper()
  240 +Pl_stack::Popper::~Popper()
243 241 {
244 242 if (stack) {
245 243 stack->pop(stack_id);
... ... @@ -247,7 +245,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper()
247 245 }
248 246  
249 247 void
250   -QPDFWriter::PipelinePopper::pop()
  248 +Pl_stack::Popper::pop()
251 249 {
252 250 if (stack) {
253 251 stack->pop(stack_id);
... ...