Commit 44032bfd4c9b3a3e56c90942f924d8a1f4d1f308

Authored by m-holger
1 parent 94a0e76b

Refactor `FormField`: replace `getFullyQualifiedName`, `getPartialName`, `getAlt…

…ernativeName`, and `getMappingName` with streamlined implementations using `fully_qualified_name`, `partial_name`, `alternative_name`, and `mapping_name`. Simplify logic and enhance consistency across methods.
libqpdf/QPDFFormFieldObjectHelper.cc
@@ -140,23 +140,24 @@ QPDFFormFieldObjectHelper::getFieldType() @@ -140,23 +140,24 @@ QPDFFormFieldObjectHelper::getFieldType()
140 std::string 140 std::string
141 QPDFFormFieldObjectHelper::getFullyQualifiedName() 141 QPDFFormFieldObjectHelper::getFullyQualifiedName()
142 { 142 {
143 - return m->getFullyQualifiedName(); 143 + return m->fully_qualified_name();
144 } 144 }
145 145
146 std::string 146 std::string
147 -FormField::getFullyQualifiedName() 147 +FormField::fully_qualified_name() const
148 { 148 {
149 std::string result; 149 std::string result;
150 - QPDFObjectHandle node = oh(); 150 + auto node = *this;
151 QPDFObjGen::set seen; 151 QPDFObjGen::set seen;
152 - while (!node.null() && seen.add(node)) {  
153 - if (node.getKey("/T").isString()) { 152 + size_t depth = 0; // Don't bother with loop detection until depth becomes suspicious
  153 + while (node && (++depth < 10 || seen.add(node))) {
  154 + if (auto T = node.T()) {
154 if (!result.empty()) { 155 if (!result.empty()) {
155 - result = "." + result; 156 + result.insert(0, 1, '.');
156 } 157 }
157 - result = node.getKey("/T").getUTF8Value() + result; 158 + result.insert(0, T.utf8_value());
158 } 159 }
159 - node = node.getKey("/Parent"); 160 + node = node.Parent();
160 } 161 }
161 return result; 162 return result;
162 } 163 }
@@ -164,51 +165,46 @@ FormField::getFullyQualifiedName() @@ -164,51 +165,46 @@ FormField::getFullyQualifiedName()
164 std::string 165 std::string
165 QPDFFormFieldObjectHelper::getPartialName() 166 QPDFFormFieldObjectHelper::getPartialName()
166 { 167 {
167 - return m->getPartialName(); 168 + return m->partial_name();
168 } 169 }
169 170
170 std::string 171 std::string
171 -FormField::getPartialName() 172 +FormField::partial_name() const
172 { 173 {
173 - std::string result;  
174 - if (oh().getKey("/T").isString()) {  
175 - result = oh().getKey("/T").getUTF8Value(); 174 + if (auto pn = T()) {
  175 + return pn.utf8_value();
176 } 176 }
177 - return result; 177 + return {};
178 } 178 }
179 179
180 std::string 180 std::string
181 QPDFFormFieldObjectHelper::getAlternativeName() 181 QPDFFormFieldObjectHelper::getAlternativeName()
182 { 182 {
183 - return m->getAlternativeName(); 183 + return m->alternative_name();
184 } 184 }
185 185
186 std::string 186 std::string
187 -FormField::getAlternativeName() 187 +FormField::alternative_name() const
188 { 188 {
189 - if (oh().getKey("/TU").isString()) {  
190 - QTC::TC("qpdf", "QPDFFormFieldObjectHelper TU present");  
191 - return oh().getKey("/TU").getUTF8Value(); 189 + if (auto an = TU()) {
  190 + return an.utf8_value();
192 } 191 }
193 - QTC::TC("qpdf", "QPDFFormFieldObjectHelper TU absent");  
194 - return getFullyQualifiedName(); 192 + return fully_qualified_name();
195 } 193 }
196 194
197 std::string 195 std::string
198 QPDFFormFieldObjectHelper::getMappingName() 196 QPDFFormFieldObjectHelper::getMappingName()
199 { 197 {
200 - return m->getMappingName(); 198 + return m->mapping_name();
201 } 199 }
202 200
203 std::string 201 std::string
204 -FormField::getMappingName() 202 +FormField::mapping_name() const
205 { 203 {
206 - if (oh().getKey("/TM").isString()) {  
207 - QTC::TC("qpdf", "QPDFFormFieldObjectHelper TM present");  
208 - return oh().getKey("/TM").getUTF8Value(); 204 + if (auto mn = TM()) {
  205 + return mn.utf8_value();
209 } 206 }
210 - QTC::TC("qpdf", "QPDFFormFieldObjectHelper TM absent");  
211 - return getAlternativeName(); 207 + return alternative_name();
212 } 208 }
213 209
214 QPDFObjectHandle 210 QPDFObjectHandle
libqpdf/qpdf/FormField.hh
@@ -105,9 +105,10 @@ namespace qpdf::impl @@ -105,9 +105,10 @@ namespace qpdf::impl
105 std::string inheritable_string(std::string const& name) const; 105 std::string inheritable_string(std::string const& name) const;
106 106
107 /// @brief Retrieves the field type (/FT attribute). 107 /// @brief Retrieves the field type (/FT attribute).
  108 + ///
108 /// @param inherit If set to `true`, the function will attempt to retrieve the value by 109 /// @param inherit If set to `true`, the function will attempt to retrieve the value by
109 /// inheritance from the parent hierarchy of the form field. Defaults to `true`. 110 /// inheritance from the parent hierarchy of the form field. Defaults to `true`.
110 - /// @return Returns the field type if found; otherwise, returns a default-constructed 111 + /// @return Returns the field type if found; otherwise, returns a default-constructed
111 /// `Name`. 112 /// `Name`.
112 Name 113 Name
113 FT(bool inherit = true) const 114 FT(bool inherit = true) const
@@ -115,17 +116,78 @@ namespace qpdf::impl @@ -115,17 +116,78 @@ namespace qpdf::impl
115 return inheritable_value<Name>("/FT"); 116 return inheritable_value<Name>("/FT");
116 } 117 }
117 118
118 - std::string getFullyQualifiedName(); 119 + /// @brief Retrieves the partial field name (/T attribute).
  120 + ///
  121 + /// @return Returns the partial field name if found; otherwise, returns a
  122 + /// default-constructed `String`.
  123 + String
  124 + T() const
  125 + {
  126 + return {get("/T")};
  127 + }
  128 +
  129 + /// @brief Retrieves the alternative name (/TU attribute).
  130 + ///
  131 + /// @return Returns the alternative name if found; otherwise, returns a default-constructed
  132 + /// `String`.
  133 + String
  134 + TU() const
  135 + {
  136 + return {get("/TU")};
  137 + }
  138 +
  139 + /// @brief Retrieves the mapping name (/TM attribute).
  140 + ///
  141 + /// @return Returns the mapping name if found; otherwise, returns a default-constructed
  142 + /// `String`.
  143 + String
  144 + TM() const
  145 + {
  146 + return {get("/TM")};
  147 + }
  148 +
  149 + /// @brief Retrieves the fully qualified name of the form field.
  150 + ///
  151 + /// This method constructs the fully qualified name of the form field by traversing through
  152 + /// its parent hierarchy. The fully qualified name is constructed by concatenating the /T
  153 + /// (field name) attribute of each parent node with periods as separators, starting from the
  154 + /// root of the hierarchy.
  155 + ///
  156 + /// If the field has no parent hierarchy, the result will simply be the /T attribute of the
  157 + /// current field. In cases of potential circular references, loop detection is applied.
  158 + ///
  159 + /// @return A string representing the fully qualified name of the field.
  160 + std::string fully_qualified_name() const;
119 161
120 - std::string getPartialName(); 162 + /// @brief Retrieves the partial name (/T attribute) of the form field.
  163 + ///
  164 + /// This method returns the value of the field's /T attribute, which is the partial name
  165 + /// used to identify the field within its parent hierarchy. If the attribute is not set, an
  166 + /// empty string is returned.
  167 + ///
  168 + /// @return A string representing the partial name of the field in UTF-8 encoding, or an
  169 + /// empty string if the /T attribute is not present.
  170 + std::string partial_name() const;
121 171
122 - // Return the alternative field name (/TU), which is the field name intended to be presented  
123 - // to users. If not present, fall back to the fully qualified name.  
124 - std::string getAlternativeName(); 172 + /// @brief Retrieves the alternative name for the form field.
  173 + ///
  174 + /// This method attempts to return the alternative name (/TU) of the form field, which is
  175 + /// the field name intended to be presented, to users as a UTF-8 string, if it exists. If
  176 + /// the alternative name is not present, the method falls back to the fully qualified name
  177 + /// of the form field.
  178 + ///
  179 + /// @return The alternative name of the form field as a string, or the
  180 + /// fully qualified name if the alternative name is unavailable.
  181 + std::string alternative_name() const;
125 182
126 - // Return the mapping field name (/TM). If not present, fall back to the alternative name,  
127 - // then to the partial name.  
128 - std::string getMappingName(); 183 + /// @brief Retrieves the mapping field name (/TM) for the form field.
  184 + ///
  185 + /// If the mapping name (/TM) is present, it is returned as a UTF-8 string. If not, it falls
  186 + /// back to the 'alternative name', which is obtained using the `alternative_name()` method.
  187 + ///
  188 + /// @return The mapping field name (/TM) as a UTF-8 string or the alternative name
  189 + /// if the mapping name is absent.
  190 + std::string mapping_name() const;
129 191
130 QPDFObjectHandle getValue(); 192 QPDFObjectHandle getValue();
131 193
qpdf/qpdf.testcov
@@ -174,10 +174,6 @@ QPDFObjectHandle dictionary empty map for asMap 0 @@ -174,10 +174,6 @@ QPDFObjectHandle dictionary empty map for asMap 0
174 QPDFObjectHandle numeric non-numeric 0 174 QPDFObjectHandle numeric non-numeric 0
175 QPDFObjectHandle erase array bounds 0 175 QPDFObjectHandle erase array bounds 0
176 qpdf-c called qpdf_check_pdf 0 176 qpdf-c called qpdf_check_pdf 0
177 -QPDFFormFieldObjectHelper TU present 0  
178 -QPDFFormFieldObjectHelper TM present 0  
179 -QPDFFormFieldObjectHelper TU absent 0  
180 -QPDFFormFieldObjectHelper TM absent 0  
181 QPDFFormFieldObjectHelper Q present 1 177 QPDFFormFieldObjectHelper Q present 1
182 QPDFFormFieldObjectHelper DA present 1 178 QPDFFormFieldObjectHelper DA present 1
183 QPDFAcroFormDocumentHelper field found 1 179 QPDFAcroFormDocumentHelper field found 1