Commit 6379f3f13af112b524305de2b3b44475b047eacb

Authored by m-holger
1 parent bd67a468

Refactor `AcroForm`: rename member variables to follow consistent naming convent…

…ion and improve code clarity.
libqpdf/QPDFAcroFormDocumentHelper.cc
... ... @@ -49,10 +49,11 @@ QPDFAcroFormDocumentHelper::validate(bool repair)
49 49 void
50 50 QPDFAcroFormDocumentHelper::invalidateCache()
51 51 {
52   - m->cache_valid = false;
53   - m->field_to.clear();
54   - m->annotation_to_field.clear();
55   - m->bad_fields.clear();
  52 + m->cache_valid_ = false;
  53 + m->fields_.clear();
  54 + m->annotation_to_field_.clear();
  55 + m->bad_fields_.clear();
  56 + m->name_to_fields_.clear();
56 57 }
57 58  
58 59 bool
... ... @@ -148,19 +149,19 @@ QPDFAcroFormDocumentHelper::removeFormFields(std::set<QPDFObjGen> const& to_remo
148 149 }
149 150  
150 151 for (auto const& og: to_remove) {
151   - auto it = m->field_to.find(og);
152   - if (it != m->field_to.end()) {
  152 + auto it = m->fields_.find(og);
  153 + if (it != m->fields_.end()) {
153 154 for (auto aoh: it->second.annotations) {
154   - m->annotation_to_field.erase(aoh.getObjectHandle().getObjGen());
  155 + m->annotation_to_field_.erase(aoh.getObjectHandle().getObjGen());
155 156 }
156 157 auto const& name = it->second.name;
157 158 if (!name.empty()) {
158   - m->name_to_fields[name].erase(og);
159   - if (m->name_to_fields[name].empty()) {
160   - m->name_to_fields.erase(name);
  159 + m->name_to_fields_[name].erase(og);
  160 + if (m->name_to_fields_[name].empty()) {
  161 + m->name_to_fields_.erase(name);
161 162 }
162 163 }
163   - m->field_to.erase(og);
  164 + m->fields_.erase(og);
164 165 }
165 166 }
166 167  
... ... @@ -187,7 +188,7 @@ QPDFAcroFormDocumentHelper::getFormFields()
187 188 {
188 189 m->analyze();
189 190 std::vector<QPDFFormFieldObjectHelper> result;
190   - for (auto const& [og, data]: m->field_to) {
  191 + for (auto const& [og, data]: m->fields_) {
191 192 if (!data.annotations.empty()) {
192 193 result.emplace_back(qpdf.getObject(og));
193 194 }
... ... @@ -200,8 +201,8 @@ QPDFAcroFormDocumentHelper::getFieldsWithQualifiedName(std::string const&amp; name)
200 201 {
201 202 m->analyze();
202 203 // Keep from creating an empty entry
203   - auto iter = m->name_to_fields.find(name);
204   - if (iter != m->name_to_fields.end()) {
  204 + auto iter = m->name_to_fields_.find(name);
  205 + if (iter != m->name_to_fields_.end()) {
205 206 return iter->second;
206 207 }
207 208 return {};
... ... @@ -213,8 +214,8 @@ QPDFAcroFormDocumentHelper::getAnnotationsForField(QPDFFormFieldObjectHelper h)
213 214 m->analyze();
214 215 std::vector<QPDFAnnotationObjectHelper> result;
215 216 QPDFObjGen og(h.getObjectHandle().getObjGen());
216   - if (m->field_to.contains(og)) {
217   - result = m->field_to[og].annotations;
  217 + if (m->fields_.contains(og)) {
  218 + result = m->fields_[og].annotations;
218 219 }
219 220 return result;
220 221 }
... ... @@ -255,8 +256,8 @@ QPDFAcroFormDocumentHelper::getFieldForAnnotation(QPDFAnnotationObjectHelper h)
255 256 }
256 257 m->analyze();
257 258 QPDFObjGen og(oh.getObjGen());
258   - if (m->annotation_to_field.contains(og)) {
259   - return m->annotation_to_field[og];
  259 + if (m->annotation_to_field_.contains(og)) {
  260 + return m->annotation_to_field_[og];
260 261 }
261 262 return Null::temp();
262 263 }
... ... @@ -264,10 +265,10 @@ QPDFAcroFormDocumentHelper::getFieldForAnnotation(QPDFAnnotationObjectHelper h)
264 265 void
265 266 AcroForm::analyze()
266 267 {
267   - if (cache_valid) {
  268 + if (cache_valid_) {
268 269 return;
269 270 }
270   - cache_valid = true;
  271 + cache_valid_ = true;
271 272 QPDFObjectHandle acroform = qpdf.getRoot().getKey("/AcroForm");
272 273 if (!(acroform.isDictionary() && acroform.hasKey("/Fields"))) {
273 274 return;
... ... @@ -294,7 +295,7 @@ AcroForm::analyze()
294 295 for (auto const& iter: getWidgetAnnotationsForPage(ph)) {
295 296 QPDFObjectHandle annot(iter.getObjectHandle());
296 297 QPDFObjGen og(annot.getObjGen());
297   - if (!annotation_to_field.contains(og)) {
  298 + if (!annotation_to_field_.contains(og)) {
298 299 // This is not supposed to happen, but it's easy enough for us to handle this case.
299 300 // Treat the annotation as its own field. This could allow qpdf to sensibly handle a
300 301 // case such as a PDF creator adding a self-contained annotation (merged with the
... ... @@ -303,8 +304,8 @@ AcroForm::analyze()
303 304 annot.warn(
304 305 "this widget annotation is not reachable from /AcroForm in the document "
305 306 "catalog");
306   - annotation_to_field[og] = QPDFFormFieldObjectHelper(annot);
307   - field_to[og].annotations.emplace_back(annot);
  307 + annotation_to_field_[og] = QPDFFormFieldObjectHelper(annot);
  308 + fields_[og].annotations.emplace_back(annot);
308 309 }
309 310 }
310 311 }
... ... @@ -335,7 +336,7 @@ AcroForm::traverseField(QPDFObjectHandle field, QPDFObjectHandle const&amp; parent,
335 336 return false;
336 337 }
337 338 QPDFObjGen og(field.getObjGen());
338   - if (field_to.contains(og) || annotation_to_field.contains(og) || bad_fields.contains(og)) {
  339 + if (fields_.contains(og) || annotation_to_field_.contains(og) || bad_fields_.contains(og)) {
339 340 field.warn("loop detected while traversing /AcroForm");
340 341 return false;
341 342 }
... ... @@ -363,8 +364,8 @@ AcroForm::traverseField(QPDFObjectHandle field, QPDFObjectHandle const&amp; parent,
363 364  
364 365 if (is_annotation) {
365 366 QPDFObjectHandle our_field = (is_field ? field : parent);
366   - field_to[our_field.getObjGen()].annotations.emplace_back(field);
367   - annotation_to_field[og] = QPDFFormFieldObjectHelper(our_field);
  367 + fields_[our_field.getObjGen()].annotations.emplace_back(field);
  368 + annotation_to_field_[og] = QPDFFormFieldObjectHelper(our_field);
368 369 }
369 370  
370 371 if (is_field && depth != 0 && field["/Parent"] != parent) {
... ... @@ -387,22 +388,22 @@ AcroForm::traverseField(QPDFObjectHandle field, QPDFObjectHandle const&amp; parent,
387 388 if (is_field && field.hasKey("/T")) {
388 389 QPDFFormFieldObjectHelper foh(field);
389 390 std::string name = foh.getFullyQualifiedName();
390   - auto old = field_to.find(og);
391   - if (old != field_to.end() && !old->second.name.empty()) {
  391 + auto old = fields_.find(og);
  392 + if (old != fields_.end() && !old->second.name.empty()) {
392 393 // We might be updating after a name change, so remove any old information
393   - name_to_fields[old->second.name].erase(og);
  394 + name_to_fields_[old->second.name].erase(og);
394 395 }
395   - field_to[og].name = name;
396   - name_to_fields[name].insert(og);
  396 + fields_[og].name = name;
  397 + name_to_fields_[name].insert(og);
397 398 }
398 399  
399 400 for (auto const& kid: Kids) {
400   - if (bad_fields.contains(kid)) {
  401 + if (bad_fields_.contains(kid)) {
401 402 continue;
402 403 }
403 404  
404 405 if (!traverseField(kid, field, 1 + depth)) {
405   - bad_fields.insert(kid);
  406 + bad_fields_.insert(kid);
406 407 }
407 408 }
408 409 return true;
... ...
libqpdf/qpdf/AcroForm.hh
... ... @@ -47,7 +47,8 @@ namespace qpdf::impl
47 47 ///
48 48 /// @return A vector of `QPDFAnnotationObjectHelper` objects corresponding to
49 49 /// the widget annotations found on the specified page.
50   - std::vector<QPDFAnnotationObjectHelper> getWidgetAnnotationsForPage(QPDFPageObjectHelper page);
  50 + std::vector<QPDFAnnotationObjectHelper>
  51 + getWidgetAnnotationsForPage(QPDFPageObjectHelper page);
51 52  
52 53 /// Analyzes the AcroForm structure in the PDF document and updates the internal
53 54 /// cache with the form fields and their corresponding widget annotations.
... ... @@ -179,12 +180,13 @@ namespace qpdf::impl
179 180 QPDFObjectHandle stream,
180 181 std::map<std::string, std::map<std::string, std::string>> dr_map);
181 182  
182   - bool cache_valid{false};
183   - std::map<QPDFObjGen, FieldData> field_to;
184   - std::map<QPDFObjGen, QPDFFormFieldObjectHelper> annotation_to_field;
185   - std::map<std::string, std::set<QPDFObjGen>> name_to_fields;
186   - std::set<QPDFObjGen> bad_fields;
187   - }; // class AcroForm
  183 + std::map<QPDFObjGen, FieldData> fields_;
  184 + std::map<QPDFObjGen, QPDFFormFieldObjectHelper> annotation_to_field_;
  185 + std::map<std::string, std::set<QPDFObjGen>> name_to_fields_;
  186 + std::set<QPDFObjGen> bad_fields_;
  187 + bool cache_valid_{false};
  188 +
  189 + }; // class Acroform
188 190  
189 191 /// @class FormNode
190 192 /// @brief Represents a node in the interactive forms tree of a PDF document.
... ...