/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 |