Coverage Report

Created: 2026-03-21 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/include/exiv2/metadatum.hpp
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
#ifndef EXIV2_METADATUM_HPP
4
#define EXIV2_METADATUM_HPP
5
6
// *****************************************************************************
7
#include "exiv2lib_export.h"
8
9
// included header files
10
#include "types.hpp"
11
12
#include <cstdint>
13
#include <memory>
14
15
// *****************************************************************************
16
// namespace extensions
17
namespace Exiv2 {
18
// *****************************************************************************
19
// class declarations
20
class ExifData;
21
class Value;
22
23
// *****************************************************************************
24
// class definitions
25
26
/*!
27
  @brief Abstract base class defining the %Key of a metadatum.
28
         Keys are used to identify and group metadata.
29
*/
30
class EXIV2API Key {
31
 public:
32
  //! Shortcut for a %Key auto pointer.
33
  using UniquePtr = std::unique_ptr<Key>;
34
35
  //! @name Creators
36
  //@{
37
  //! Destructor
38
  virtual ~Key();
39
  //@}
40
  //! @name Accessors
41
  //@{
42
  /*!
43
    @brief Return the key of the metadatum as a string. The key is of the
44
           form 'familyName.groupName.tagName'. Note however that the
45
           key is not necessarily unique, e.g., an ExifData may contain
46
           multiple metadata with the same key.
47
   */
48
  [[nodiscard]] virtual std::string key() const = 0;
49
  //! Return an identifier for the type of metadata (the first part of the key)
50
  [[nodiscard]] virtual const char* familyName() const = 0;
51
  //! Return the name of the group (the second part of the key)
52
  [[nodiscard]] virtual std::string groupName() const = 0;
53
  //! Return the name of the tag (which is also the third part of the key)
54
  [[nodiscard]] virtual std::string tagName() const = 0;
55
  //! Return a label for the tag
56
  [[nodiscard]] virtual std::string tagLabel() const = 0;
57
  //! Return a description for the tag
58
  [[nodiscard]] virtual std::string tagDesc() const = 0;
59
  //! Return the tag number
60
  [[nodiscard]] virtual uint16_t tag() const = 0;
61
  /*!
62
    @brief Return an auto-pointer to a copy of itself (deep copy).
63
           The caller owns this copy and the auto-pointer ensures that it
64
           will be deleted.
65
   */
66
  [[nodiscard]] UniquePtr clone() const;
67
  /*!
68
    @brief Write the key to an output stream. You do not usually have
69
           to use this function; it is used for the implementation of
70
           the output operator for %Key,
71
           operator<<(std::ostream &os, const Key &key).
72
  */
73
0
  std::ostream& write(std::ostream& os) const {
74
0
    return os << key();
75
0
  }
76
  //@}
77
78
 protected:
79
95.7M
  Key() = default;
80
1.01M
  Key(const Key&) = default;
81
  //! @name Manipulators
82
  //@{
83
  /*!
84
    @brief Assignment operator. Protected so that it can only be used
85
           by subclasses but not directly.
86
   */
87
  Key& operator=(const Key&) = default;
88
  //@}
89
90
 private:
91
  //! Internal virtual copy constructor.
92
  [[nodiscard]] virtual Key* clone_() const = 0;
93
94
};  // class Key
95
96
//! Output operator for Key types
97
0
inline std::ostream& operator<<(std::ostream& os, const Key& key) {
98
0
  return key.write(os);
99
0
}
100
101
/*!
102
  @brief Abstract base class defining the interface to access information
103
         related to one metadata tag.
104
 */
105
class EXIV2API Metadatum {
106
 public:
107
  //! @name Creators
108
  //@{
109
  //! Destructor
110
  virtual ~Metadatum();
111
  //@}
112
113
  //! @name Manipulators
114
  //@{
115
  /*!
116
    @brief Set the value. This method copies (clones) the value pointed
117
           to by pValue.
118
   */
119
  virtual void setValue(const Value* pValue) = 0;
120
  /*!
121
    @brief Set the value to the string buf.
122
           Uses Value::read(const std::string& buf). If the metadatum does
123
           not have a value yet, then one is created. See subclasses for
124
           more details. Return 0 if the value was read successfully.
125
   */
126
  virtual int setValue(const std::string& buf) = 0;
127
  //@}
128
129
  //! @name Accessors
130
  //@{
131
  /*!
132
    @brief Write the interpreted value to a string.
133
134
    Implemented in terms of write(), see there.
135
   */
136
  std::string print(const ExifData* pMetadata = nullptr) const;
137
  /*!
138
    @brief Write value to a data buffer and return the number
139
           of bytes written.
140
141
    The user must ensure that the buffer has enough memory. Otherwise
142
    the call results in undefined behaviour.
143
144
    @param buf Data buffer to write to.
145
    @param byteOrder Applicable byte order (little or big endian).
146
    @return Number of characters written.
147
  */
148
  virtual size_t copy(byte* buf, ByteOrder byteOrder) const = 0;
149
  /*!
150
    @brief Write the interpreted value to an output stream, return
151
           the stream.
152
153
    The method takes an optional pointer to a metadata container.
154
    Pretty-print functions may use that to refer to other metadata as it
155
    is sometimes not sufficient to know only the value of the metadatum
156
    that should be interpreted. Thus, it is advisable to always call this
157
    method with a pointer to the metadata container if possible.
158
159
    This functionality is currently only implemented for Exif tags.
160
    The pointer is ignored when used to write IPTC datasets or XMP
161
    properties.
162
163
    Without the optional metadata pointer, you do not usually have to use
164
    this function; it is used for the implementation of the output
165
    operator for %Metadatum,
166
    operator<<(std::ostream &os, const Metadatum &md).
167
168
    See also print(), which prints the interpreted value to a string.
169
   */
170
  virtual std::ostream& write(std::ostream& os, const ExifData* pMetadata = nullptr) const = 0;
171
  /*!
172
    @brief Return the key of the metadatum. The key is of the form
173
           'familyName.groupName.tagName'. Note however that the key
174
           is not necessarily unique, e.g., an ExifData object may
175
           contain multiple metadata with the same key.
176
   */
177
  [[nodiscard]] virtual std::string key() const = 0;
178
  //! Return the name of the metadata family (which is also the first part of the key)
179
  [[nodiscard]] virtual const char* familyName() const = 0;
180
  //! Return the name of the metadata group (which is also the second part of the key)
181
  [[nodiscard]] virtual std::string groupName() const = 0;
182
  //! Return the name of the tag (which is also the third part of the key)
183
  [[nodiscard]] virtual std::string tagName() const = 0;
184
  //! Return a label for the tag
185
  [[nodiscard]] virtual std::string tagLabel() const = 0;
186
  //! Return a description for the tag
187
  [[nodiscard]] virtual std::string tagDesc() const = 0;
188
  //! Return the tag
189
  [[nodiscard]] virtual uint16_t tag() const = 0;
190
  //! Return the type id of the value
191
  [[nodiscard]] virtual TypeId typeId() const = 0;
192
  //! Return the name of the type
193
  [[nodiscard]] virtual const char* typeName() const = 0;
194
  //! Return the size in bytes of one component of this type
195
  [[nodiscard]] virtual size_t typeSize() const = 0;
196
  //! Return the number of components in the value
197
  [[nodiscard]] virtual size_t count() const = 0;
198
  //! Return the size of the value in bytes
199
  [[nodiscard]] virtual size_t size() const = 0;
200
  //! Return the value as a string.
201
  [[nodiscard]] virtual std::string toString() const = 0;
202
  /*!
203
    @brief Return the <EM>n</EM>-th component of the value converted to
204
           a string. The behaviour of the method is undefined if there
205
           is no <EM>n</EM>-th component.
206
   */
207
  [[nodiscard]] virtual std::string toString(size_t n) const = 0;
208
  /*!
209
    @brief Return the <EM>n</EM>-th component of the value converted to int64_t.
210
           The return value is -1 if the value is not set and the behaviour
211
           of the method is undefined if there is no <EM>n</EM>-th component.
212
   */
213
  [[nodiscard]] virtual int64_t toInt64(size_t n = 0) const = 0;
214
  /*!
215
    @brief Return the <EM>n</EM>-th component of the value converted to uint32_t.
216
   */
217
  [[nodiscard]] uint32_t toUint32(size_t n = 0) const;
218
  /*!
219
    @brief Return the <EM>n</EM>-th component of the value converted to float.
220
           The return value is -1 if the value is not set and the behaviour
221
           of the method is undefined if there is no <EM>n</EM>-th component.
222
   */
223
  [[nodiscard]] virtual float toFloat(size_t n = 0) const = 0;
224
  /*!
225
    @brief Return the <EM>n</EM>-th component of the value converted to Rational.
226
           The return value is -1/1 if the value is not set and the behaviour
227
           of the method is undefined if there is no <EM>n</EM>-th component.
228
   */
229
  [[nodiscard]] virtual Rational toRational(size_t n = 0) const = 0;
230
  /*!
231
    @brief Return an auto-pointer to a copy (clone) of the value. The
232
           caller owns this copy and the auto-poiner ensures that it will
233
           be deleted.
234
235
    This method is provided for users who need full control over the
236
    value. A caller may, e.g., downcast the pointer to the appropriate
237
    subclass of Value to make use of the interface of the subclass to set
238
    or modify its contents.
239
240
    @return An auto-pointer containing a pointer to a copy (clone) of the
241
            value, 0 if the value is not set.
242
   */
243
  [[nodiscard]] virtual std::unique_ptr<Value> getValue() const = 0;
244
  /*!
245
    @brief Return a constant reference to the value.
246
247
    This method is provided mostly for convenient and versatile output of
248
    the value which can (to some extent) be formatted through standard
249
    stream manipulators.  Do not attempt to write to the value through
250
    this reference. An Error is thrown if the value is not set; as an
251
    alternative to catching it, one can use count() to check if there
252
    is any data before calling this method.
253
254
    @return A constant reference to the value.
255
    @throw Error if the value is not set.
256
   */
257
  [[nodiscard]] virtual const Value& value() const = 0;
258
  //@}
259
260
 protected:
261
63.6M
  Metadatum() = default;
262
  Metadatum(const Metadatum&) = default;
263
  //! @name Manipulators
264
  //@{
265
  /*!
266
    @brief Assignment operator. Protected so that it can only be used
267
           by subclasses but not directly.
268
   */
269
  Metadatum& operator=(const Metadatum&) = default;
270
  //@}
271
272
};  // class Metadatum
273
274
/*!
275
  @brief Output operator for Metadatum types, writing the interpreted
276
         tag value.
277
 */
278
0
inline std::ostream& operator<<(std::ostream& os, const Metadatum& md) {
279
0
  return md.write(os);
280
0
}
281
282
/*!
283
  @brief Compare two metadata by tag. Return true if the tag of metadatum
284
         lhs is less than that of rhs.
285
 */
286
EXIV2API bool cmpMetadataByTag(const Metadatum& lhs, const Metadatum& rhs);
287
/*!
288
  @brief Compare two metadata by key. Return true if the key of metadatum
289
         lhs is less than that of rhs.
290
 */
291
EXIV2API bool cmpMetadataByKey(const Metadatum& lhs, const Metadatum& rhs);
292
293
}  // namespace Exiv2
294
295
#endif  // EXIV2_METADATUM_HPP