Commit dbfdbd974d54cfd0fbd2b49eff0275c5eebf7862

Authored by m-holger
1 parent 778a9721

Refactor: consolidate `field_to_annotations` and `field_to_name` maps in `QPDFAc…

…roFormDocumentHelper`, replace redundant maps with `FieldData` encapsulation.
libqpdf/QPDFAcroFormDocumentHelper.cc
@@ -20,10 +20,15 @@ class QPDFAcroFormDocumentHelper::Members @@ -20,10 +20,15 @@ class QPDFAcroFormDocumentHelper::Members
20 Members(Members const&) = delete; 20 Members(Members const&) = delete;
21 ~Members() = default; 21 ~Members() = default;
22 22
  23 + struct FieldData
  24 + {
  25 + std::vector<QPDFAnnotationObjectHelper> annotations;
  26 + std::string name;
  27 + };
  28 +
23 bool cache_valid{false}; 29 bool cache_valid{false};
24 - std::map<QPDFObjGen, std::vector<QPDFAnnotationObjectHelper>> field_to_annotations; 30 + std::map<QPDFObjGen, FieldData> field_to;
25 std::map<QPDFObjGen, QPDFFormFieldObjectHelper> annotation_to_field; 31 std::map<QPDFObjGen, QPDFFormFieldObjectHelper> annotation_to_field;
26 - std::map<QPDFObjGen, std::string> field_to_name;  
27 std::map<std::string, std::set<QPDFObjGen>> name_to_fields; 32 std::map<std::string, std::set<QPDFObjGen>> name_to_fields;
28 }; 33 };
29 34
@@ -53,7 +58,7 @@ void @@ -53,7 +58,7 @@ void
53 QPDFAcroFormDocumentHelper::invalidateCache() 58 QPDFAcroFormDocumentHelper::invalidateCache()
54 { 59 {
55 m->cache_valid = false; 60 m->cache_valid = false;
56 - m->field_to_annotations.clear(); 61 + m->field_to.clear();
57 m->annotation_to_field.clear(); 62 m->annotation_to_field.clear();
58 } 63 }
59 64
@@ -151,20 +156,19 @@ QPDFAcroFormDocumentHelper::removeFormFields(std::set&lt;QPDFObjGen&gt; const&amp; to_remo @@ -151,20 +156,19 @@ QPDFAcroFormDocumentHelper::removeFormFields(std::set&lt;QPDFObjGen&gt; const&amp; to_remo
151 } 156 }
152 157
153 for (auto const& og: to_remove) { 158 for (auto const& og: to_remove) {
154 - auto annotations = m->field_to_annotations.find(og);  
155 - if (annotations != m->field_to_annotations.end()) {  
156 - for (auto aoh: annotations->second) { 159 + auto it = m->field_to.find(og);
  160 + if (it != m->field_to.end()) {
  161 + for (auto aoh: it->second.annotations) {
157 m->annotation_to_field.erase(aoh.getObjectHandle().getObjGen()); 162 m->annotation_to_field.erase(aoh.getObjectHandle().getObjGen());
158 } 163 }
159 - m->field_to_annotations.erase(og);  
160 - }  
161 - auto name = m->field_to_name.find(og);  
162 - if (name != m->field_to_name.end()) {  
163 - m->name_to_fields[name->second].erase(og);  
164 - if (m->name_to_fields[name->second].empty()) {  
165 - m->name_to_fields.erase(name->second); 164 + auto const& name = it->second.name;
  165 + if (!name.empty()) {
  166 + m->name_to_fields[name].erase(og);
  167 + if (m->name_to_fields[name].empty()) {
  168 + m->name_to_fields.erase(name);
  169 + }
166 } 170 }
167 - m->field_to_name.erase(og); 171 + m->field_to.erase(og);
168 } 172 }
169 } 173 }
170 174
@@ -193,8 +197,10 @@ QPDFAcroFormDocumentHelper::getFormFields() @@ -193,8 +197,10 @@ QPDFAcroFormDocumentHelper::getFormFields()
193 { 197 {
194 analyze(); 198 analyze();
195 std::vector<QPDFFormFieldObjectHelper> result; 199 std::vector<QPDFFormFieldObjectHelper> result;
196 - for (auto const& iter: m->field_to_annotations) {  
197 - result.emplace_back(qpdf.getObject(iter.first)); 200 + for (auto const& [og, data]: m->field_to) {
  201 + if (!(data.annotations.empty())) {
  202 + result.emplace_back(qpdf.getObject(og));
  203 + }
198 } 204 }
199 return result; 205 return result;
200 } 206 }
@@ -217,8 +223,8 @@ QPDFAcroFormDocumentHelper::getAnnotationsForField(QPDFFormFieldObjectHelper h) @@ -217,8 +223,8 @@ QPDFAcroFormDocumentHelper::getAnnotationsForField(QPDFFormFieldObjectHelper h)
217 analyze(); 223 analyze();
218 std::vector<QPDFAnnotationObjectHelper> result; 224 std::vector<QPDFAnnotationObjectHelper> result;
219 QPDFObjGen og(h.getObjectHandle().getObjGen()); 225 QPDFObjGen og(h.getObjectHandle().getObjGen());
220 - if (m->field_to_annotations.contains(og)) {  
221 - result = m->field_to_annotations[og]; 226 + if (m->field_to.contains(og)) {
  227 + result = m->field_to[og].annotations;
222 } 228 }
223 return result; 229 return result;
224 } 230 }
@@ -308,7 +314,7 @@ QPDFAcroFormDocumentHelper::analyze() @@ -308,7 +314,7 @@ QPDFAcroFormDocumentHelper::analyze()
308 "this widget annotation is not reachable from /AcroForm in the document " 314 "this widget annotation is not reachable from /AcroForm in the document "
309 "catalog"); 315 "catalog");
310 m->annotation_to_field[og] = QPDFFormFieldObjectHelper(annot); 316 m->annotation_to_field[og] = QPDFFormFieldObjectHelper(annot);
311 - m->field_to_annotations[og].emplace_back(annot); 317 + m->field_to[og].annotations.emplace_back(annot);
312 } 318 }
313 } 319 }
314 } 320 }
@@ -371,7 +377,7 @@ QPDFAcroFormDocumentHelper::traverseField( @@ -371,7 +377,7 @@ QPDFAcroFormDocumentHelper::traverseField(
371 377
372 if (is_annotation) { 378 if (is_annotation) {
373 QPDFObjectHandle our_field = (is_field ? field : parent); 379 QPDFObjectHandle our_field = (is_field ? field : parent);
374 - m->field_to_annotations[our_field.getObjGen()].emplace_back(field); 380 + m->field_to[our_field.getObjGen()].annotations.emplace_back(field);
375 m->annotation_to_field[og] = QPDFFormFieldObjectHelper(our_field); 381 m->annotation_to_field[og] = QPDFFormFieldObjectHelper(our_field);
376 } 382 }
377 383
@@ -379,13 +385,12 @@ QPDFAcroFormDocumentHelper::traverseField( @@ -379,13 +385,12 @@ QPDFAcroFormDocumentHelper::traverseField(
379 QPDFFormFieldObjectHelper foh(field); 385 QPDFFormFieldObjectHelper foh(field);
380 auto f_og = field.getObjGen(); 386 auto f_og = field.getObjGen();
381 std::string name = foh.getFullyQualifiedName(); 387 std::string name = foh.getFullyQualifiedName();
382 - auto old = m->field_to_name.find(f_og);  
383 - if (old != m->field_to_name.end()) { 388 + auto old = m->field_to.find(f_og);
  389 + if (old != m->field_to.end() && !old->second.name.empty()) {
384 // We might be updating after a name change, so remove any old information 390 // We might be updating after a name change, so remove any old information
385 - std::string old_name = old->second;  
386 - m->name_to_fields[old_name].erase(f_og); 391 + m->name_to_fields[old->second.name].erase(f_og);
387 } 392 }
388 - m->field_to_name[f_og] = name; 393 + m->field_to[f_og].name = name;
389 m->name_to_fields[name].insert(f_og); 394 m->name_to_fields[name].insert(f_og);
390 } 395 }
391 } 396 }