Coverage Report

Created: 2026-02-26 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/include/exiv2/value.hpp
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
#ifndef EXIV2_VALUE_HPP
4
#define EXIV2_VALUE_HPP
5
6
// *****************************************************************************
7
#include "exiv2lib_export.h"
8
9
// included header files
10
#include "types.hpp"
11
12
// + standard includes
13
#include <cmath>
14
#include <cstring>
15
#include <iomanip>
16
#include <map>
17
#include <memory>
18
19
// *****************************************************************************
20
// namespace extensions
21
namespace Exiv2 {
22
// *****************************************************************************
23
// class definitions
24
25
/*!
26
  @brief Common interface for all types of values used with metadata.
27
28
  The interface provides a uniform way to access values independent of
29
  their actual C++ type for simple tasks like reading the values from a
30
  string or data buffer.  For other tasks, like modifying values you may
31
  need to downcast it to a specific subclass to access its interface.
32
 */
33
class EXIV2API Value {
34
 public:
35
  //! Shortcut for a %Value auto pointer.
36
  using UniquePtr = std::unique_ptr<Value>;
37
38
  //! @name Creators
39
  //@{
40
  //! Constructor, taking a type id to initialize the base class with
41
  explicit Value(TypeId typeId);
42
  //! Virtual destructor.
43
40.7M
  virtual ~Value() = default;
44
  //@}
45
46
  //! @name Manipulators
47
  //@{
48
49
  /// @brief Read the value from a character buffer.
50
  /// @param buf Pointer to the data buffer to read from
51
  /// @param len Number of bytes in the data buffer
52
  /// @param byteOrder Applicable byte order (little or big endian).
53
  /// @return 0 if successful.
54
  virtual int read(const byte* buf, size_t len, ByteOrder byteOrder) = 0;
55
56
  /*!
57
    @brief Set the value from a string buffer. The format of the string
58
           corresponds to that of the write() method, i.e., a string
59
           obtained through the write() method can be read by this
60
           function.
61
62
    @param buf The string to read from.
63
64
    @return 0 if successful.
65
   */
66
  virtual int read(const std::string& buf) = 0;
67
  /*!
68
    @brief Set the data area, if the value has one by copying (cloning)
69
           the buffer pointed to by buf.
70
71
    Values may have a data area, which can contain additional
72
    information besides the actual value. This method is used to set such
73
    a data area.
74
75
    @param buf Pointer to the source data area
76
    @param len Size of the data area
77
    @return Return -1 if the value has no data area, else 0.
78
   */
79
  virtual int setDataArea(const byte* buf, size_t len);
80
  //@}
81
82
  //! @name Accessors
83
  //@{
84
  //! Return the type identifier (Exif data format type).
85
34.4M
  TypeId typeId() const {
86
34.4M
    return type_;
87
34.4M
  }
88
  /*!
89
    @brief Return an auto-pointer to a copy of itself (deep copy).
90
           The caller owns this copy and the auto-pointer ensures that
91
           it will be deleted.
92
   */
93
30.3M
  UniquePtr clone() const {
94
30.3M
    return UniquePtr(clone_());
95
30.3M
  }
96
  /*!
97
    @brief Write value to a data buffer.
98
99
    The user must ensure that the buffer has enough memory. Otherwise
100
    the call results in undefined behaviour.
101
102
    @param buf Data buffer to write to.
103
    @param byteOrder Applicable byte order (little or big endian).
104
    @return Number of bytes written.
105
  */
106
  virtual size_t copy(byte* buf, ByteOrder byteOrder) const = 0;
107
  //! Return the number of components of the value
108
  virtual size_t count() const = 0;
109
  //! Return the size of the value in bytes
110
  virtual size_t size() const = 0;
111
  /*!
112
    @brief Write the value to an output stream. You do not usually have
113
           to use this function; it is used for the implementation of
114
           the output operator for %Value,
115
           operator<<(std::ostream &os, const Value &value).
116
  */
117
  virtual std::ostream& write(std::ostream& os) const = 0;
118
  /*!
119
    @brief Return the value as a string. Implemented in terms of
120
           write(std::ostream& os) const of the concrete class.
121
   */
122
  std::string toString() const;
123
  /*!
124
    @brief Return the <EM>n</EM>-th component of the value as a string.
125
           The default implementation returns toString(). The behaviour
126
           of this method may be undefined if there is no <EM>n</EM>-th
127
           component.
128
   */
129
  virtual std::string toString(size_t n) const;
130
  /*!
131
    @brief Convert the <EM>n</EM>-th component of the value to an int64_t.
132
           The behaviour of this method may be undefined if there is no
133
           <EM>n</EM>-th component.
134
135
    @return The converted value.
136
   */
137
  virtual int64_t toInt64(size_t n = 0) const = 0;
138
  /*!
139
    @brief Convert the <EM>n</EM>-th component of the value to a float.
140
           The behaviour of this method may be undefined if there is no
141
           <EM>n</EM>-th component.
142
143
    @return The converted value.
144
   */
145
  virtual uint32_t toUint32(size_t n = 0) const = 0;
146
  /*!
147
    @brief Convert the <EM>n</EM>-th component of the value to a float.
148
           The behaviour of this method may be undefined if there is no
149
           <EM>n</EM>-th component.
150
151
    @return The converted value.
152
   */
153
  virtual float toFloat(size_t n = 0) const = 0;
154
  /*!
155
    @brief Convert the <EM>n</EM>-th component of the value to a Rational.
156
           The behaviour of this method may be undefined if there is no
157
           <EM>n</EM>-th component.
158
159
    @return The converted value.
160
   */
161
  virtual Rational toRational(size_t n = 0) const = 0;
162
  //! Return the size of the data area, 0 if there is none.
163
  virtual size_t sizeDataArea() const;
164
  /*!
165
    @brief Return a copy of the data area if the value has one. The
166
           caller owns this copy and DataBuf ensures that it will be
167
           deleted.
168
169
    Values may have a data area, which can contain additional
170
    information besides the actual value. This method is used to access
171
    such a data area.
172
173
    @return A DataBuf containing a copy of the data area or an empty
174
            DataBuf if the value does not have a data area assigned.
175
   */
176
  virtual DataBuf dataArea() const;
177
  /*!
178
    @brief Check the \em ok status indicator. After a to<Type> conversion,
179
           this indicator shows whether the conversion was successful.
180
   */
181
107k
  bool ok() const {
182
107k
    return ok_;
183
107k
  }
184
  //@}
185
186
  /*!
187
    @brief A (simple) factory to create a Value type.
188
189
    The following Value subclasses are created depending on typeId:<BR><BR>
190
    <TABLE>
191
    <TR><TD><B>typeId</B></TD><TD><B>%Value subclass</B></TD></TR>
192
    <TR><TD><CODE>invalidTypeId</CODE></TD><TD>%DataValue(invalidTypeId)</TD></TR>
193
    <TR><TD><CODE>unsignedByte</CODE></TD><TD>%DataValue(unsignedByte)</TD></TR>
194
    <TR><TD><CODE>asciiString</CODE></TD><TD>%AsciiValue</TD></TR>
195
    <TR><TD><CODE>string</CODE></TD><TD>%StringValue</TD></TR>
196
    <TR><TD><CODE>unsignedShort</CODE></TD><TD>%ValueType &lt; uint16_t &gt;</TD></TR>
197
    <TR><TD><CODE>unsignedLong</CODE></TD><TD>%ValueType &lt; uint32_t &gt;</TD></TR>
198
    <TR><TD><CODE>unsignedRational</CODE></TD><TD>%ValueType &lt; URational &gt;</TD></TR>
199
    <TR><TD><CODE>invalid6</CODE></TD><TD>%DataValue(invalid6)</TD></TR>
200
    <TR><TD><CODE>undefined</CODE></TD><TD>%DataValue</TD></TR>
201
    <TR><TD><CODE>signedShort</CODE></TD><TD>%ValueType &lt; int16_t &gt;</TD></TR>
202
    <TR><TD><CODE>signedLong</CODE></TD><TD>%ValueType &lt; int32_t &gt;</TD></TR>
203
    <TR><TD><CODE>signedRational</CODE></TD><TD>%ValueType &lt; Rational &gt;</TD></TR>
204
    <TR><TD><CODE>tiffFloat</CODE></TD><TD>%ValueType &lt; float &gt;</TD></TR>
205
    <TR><TD><CODE>tiffDouble</CODE></TD><TD>%ValueType &lt; double &gt;</TD></TR>
206
    <TR><TD><CODE>tiffIfd</CODE></TD><TD>%ValueType &lt; uint32_t &gt;</TD></TR>
207
    <TR><TD><CODE>date</CODE></TD><TD>%DateValue</TD></TR>
208
    <TR><TD><CODE>time</CODE></TD><TD>%TimeValue</TD></TR>
209
    <TR><TD><CODE>comment</CODE></TD><TD>%CommentValue</TD></TR>
210
    <TR><TD><CODE>xmpText</CODE></TD><TD>%XmpTextValue</TD></TR>
211
    <TR><TD><CODE>xmpBag</CODE></TD><TD>%XmpArrayValue</TD></TR>
212
    <TR><TD><CODE>xmpSeq</CODE></TD><TD>%XmpArrayValue</TD></TR>
213
    <TR><TD><CODE>xmpAlt</CODE></TD><TD>%XmpArrayValue</TD></TR>
214
    <TR><TD><CODE>langAlt</CODE></TD><TD>%LangAltValue</TD></TR>
215
    <TR><TD><EM>default</EM></TD><TD>%DataValue(typeId)</TD></TR>
216
    </TABLE>
217
218
    @param typeId Type of the value.
219
    @return Auto-pointer to the newly created Value. The caller owns this
220
            copy and the auto-pointer ensures that it will be deleted.
221
   */
222
  static UniquePtr create(TypeId typeId);
223
224
 protected:
225
18.3M
  Value(const Value&) = default;
226
  /*!
227
    @brief Assignment operator. Protected so that it can only be used
228
           by subclasses but not directly.
229
   */
230
  Value& operator=(const Value&) = default;
231
  // DATA
232
  mutable bool ok_{true};  //!< Indicates the status of the previous to<Type> conversion
233
234
 private:
235
  //! Internal virtual copy constructor.
236
  virtual Value* clone_() const = 0;
237
  // DATA
238
  TypeId type_;  //!< Type of the data
239
};
240
241
//! Output operator for Value types
242
246k
inline std::ostream& operator<<(std::ostream& os, const Value& value) {
243
246k
  return value.write(os);
244
246k
}
245
246
//! %Value for an undefined data type.
247
class EXIV2API DataValue : public Value {
248
 public:
249
  //! Shortcut for a %DataValue auto pointer.
250
  using UniquePtr = std::unique_ptr<DataValue>;
251
252
  explicit DataValue(TypeId typeId = undefined);
253
254
  DataValue(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder, TypeId typeId = undefined);
255
256
  //! @name Manipulators
257
  //@{
258
  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
259
  //! Set the data from a string of integer values (e.g., "0 1 2 3")
260
  int read(const std::string& buf) override;
261
  //@}
262
263
  //! @name Accessors
264
  //@{
265
0
  UniquePtr clone() const {
266
0
    return UniquePtr(clone_());
267
0
  }
268
  /*!
269
    @brief Write value to a character data buffer.
270
271
    @note The byte order is required by the interface but not used by this
272
          method, so just use the default.
273
274
    The user must ensure that the buffer has enough memory. Otherwise
275
    the call results in undefined behaviour.
276
277
    @param buf Data buffer to write to.
278
    @param byteOrder Byte order. Not needed.
279
    @return Number of characters written.
280
  */
281
  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
282
  size_t count() const override;
283
  size_t size() const override;
284
  std::ostream& write(std::ostream& os) const override;
285
  /*!
286
    @brief Return the <EM>n</EM>-th component of the value as a string.
287
           The behaviour of this method may be undefined if there is no
288
           <EM>n</EM>-th component.
289
   */
290
  std::string toString(size_t n) const override;
291
  int64_t toInt64(size_t n = 0) const override;
292
  uint32_t toUint32(size_t n = 0) const override;
293
  float toFloat(size_t n = 0) const override;
294
  Rational toRational(size_t n = 0) const override;
295
  //@}
296
297
 private:
298
  //! Internal virtual copy constructor.
299
  DataValue* clone_() const override;
300
301
 public:
302
  //! Type used to store the data.
303
  using ValueType = std::vector<byte>;
304
  // DATA
305
  ValueType value_;  //!< Stores the data value
306
307
};  // class DataValue
308
309
/*!
310
  @brief Abstract base class for a string based %Value type.
311
312
  Uses a std::string to store the value and implements defaults for
313
  most operations.
314
 */
315
class EXIV2API StringValueBase : public Value {
316
  using Value::Value;
317
318
 public:
319
  //! Shortcut for a %StringValueBase auto pointer.
320
  using UniquePtr = std::unique_ptr<StringValueBase>;
321
322
  //! @name Creators
323
  //@{
324
  //! Constructor for subclasses
325
  StringValueBase(TypeId typeId, const std::string& buf);
326
  //@}
327
328
  //! @name Manipulators
329
  //@{
330
  //! Read the value from buf. This default implementation uses buf as it is.
331
  int read(const std::string& buf) override;
332
  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
333
  //@}
334
335
  //! @name Accessors
336
  //@{
337
0
  UniquePtr clone() const {
338
0
    return UniquePtr(clone_());
339
0
  }
340
  /*!
341
    @brief Write value to a character data buffer.
342
343
    The user must ensure that the buffer has enough memory. Otherwise
344
    the call results in undefined behaviour.
345
346
    @note The byte order is required by the interface but not used by this
347
          method, so just use the default.
348
349
    @param buf Data buffer to write to.
350
    @param byteOrder Byte order. Not used.
351
    @return Number of characters written.
352
  */
353
  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
354
  size_t count() const override;
355
  size_t size() const override;
356
  int64_t toInt64(size_t n = 0) const override;
357
  uint32_t toUint32(size_t n = 0) const override;
358
  float toFloat(size_t n = 0) const override;
359
  Rational toRational(size_t n = 0) const override;
360
  std::ostream& write(std::ostream& os) const override;
361
  //@}
362
363
 protected:
364
  //! Internal virtual copy constructor.
365
  StringValueBase* clone_() const override = 0;
366
367
 public:
368
  // DATA
369
  std::string value_;  //!< Stores the string value.
370
371
};  // class StringValueBase
372
373
/*!
374
  @brief %Value for string type.
375
376
  This can be a plain Ascii string or a multiple byte encoded string. It is
377
  left to caller to decode and encode the string to and from readable
378
  text if that is required.
379
*/
380
class EXIV2API StringValue : public StringValueBase {
381
 public:
382
  //! Shortcut for a %StringValue auto pointer.
383
  using UniquePtr = std::unique_ptr<StringValue>;
384
385
  //! @name Creators
386
  //@{
387
  //! Default constructor.
388
  StringValue();
389
  //! Constructor
390
  explicit StringValue(const std::string& buf);
391
  //@}
392
393
  //! @name Accessors
394
  //@{
395
0
  UniquePtr clone() const {
396
0
    return UniquePtr(clone_());
397
0
  }
398
  //@}
399
400
 private:
401
  //! Internal virtual copy constructor.
402
  StringValue* clone_() const override;
403
404
};  // class StringValue
405
406
/*!
407
  @brief %Value for an Ascii string type.
408
409
  This class is for null terminated single byte Ascii strings.
410
  This class also ensures that the string is null terminated.
411
 */
412
class EXIV2API AsciiValue : public StringValueBase {
413
 public:
414
  //! Shortcut for a %AsciiValue auto pointer.
415
  using UniquePtr = std::unique_ptr<AsciiValue>;
416
417
  //! @name Creators
418
  //@{
419
  //! Default constructor.
420
  AsciiValue();
421
  //! Constructor
422
  explicit AsciiValue(const std::string& buf);
423
  //@}
424
425
  //! @name Manipulators
426
  //@{
427
  using StringValueBase::read;
428
  /*!
429
    @brief Set the value to that of the string buf. Overrides base class
430
           to append a terminating '\\0' character if buf doesn't end
431
           with '\\0'.
432
   */
433
  int read(const std::string& buf) override;
434
  //@}
435
436
  //! @name Accessors
437
  //@{
438
0
  UniquePtr clone() const {
439
0
    return UniquePtr(clone_());
440
0
  }
441
  /*!
442
    @brief Write the ASCII value up to the first '\\0' character to an
443
           output stream.  Any further characters are ignored and not
444
           written to the output stream.
445
  */
446
  std::ostream& write(std::ostream& os) const override;
447
  //@}
448
449
 private:
450
  //! Internal virtual copy constructor.
451
  AsciiValue* clone_() const override;
452
453
};  // class AsciiValue
454
455
/*!
456
  @brief %Value for an Exif comment.
457
458
  This can be a plain Ascii string or a multiple byte encoded string. The
459
  comment is expected to be encoded in the character set indicated (default
460
  undefined), but this is not checked. It is left to caller to decode and
461
  encode the string to and from readable text if that is required.
462
*/
463
class EXIV2API CommentValue : public StringValueBase {
464
 public:
465
  //! Character set identifiers for the character sets defined by %Exif
466
  enum CharsetId { ascii, jis, unicode, undefined, invalidCharsetId, lastCharsetId };
467
  //! Information pertaining to the defined character sets
468
  struct CharsetTable {
469
    CharsetId charsetId_;  //!< Charset id
470
    const char* name_;     //!< Name of the charset
471
    const char* code_;     //!< Code of the charset
472
  };
473
474
  //! Charset information lookup functions. Implemented as a static class.
475
  class EXIV2API CharsetInfo {
476
   public:
477
    //! Return the name for a charset id
478
    static const char* name(CharsetId charsetId);
479
    //! Return the code for a charset id
480
    static const char* code(CharsetId charsetId);
481
    //! Return the charset id for a name
482
    static CharsetId charsetIdByName(const std::string& name);
483
    //! Return the charset id for a code
484
    static CharsetId charsetIdByCode(const std::string& code);
485
486
   private:
487
    static const CharsetTable charsetTable_[];
488
  };  // class CharsetInfo
489
490
  //! Shortcut for a %CommentValue auto pointer.
491
  using UniquePtr = std::unique_ptr<CommentValue>;
492
493
  //! @name Creators
494
  //@{
495
  //! Default constructor.
496
  CommentValue();
497
  //! Constructor, uses read(const std::string& comment)
498
  explicit CommentValue(const std::string& comment);
499
  //@}
500
501
  //! @name Manipulators
502
  //@{
503
  /*!
504
    @brief Read the value from a comment
505
506
    The format of \em comment is:
507
    <BR>
508
    <CODE>[charset=["]Ascii|Jis|Unicode|Undefined["] ]comment</CODE>
509
    <BR>
510
    The default charset is Undefined.
511
512
    @return 0 if successful<BR>
513
            1 if an invalid character set is encountered
514
  */
515
  int read(const std::string& comment) override;
516
  int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
517
  //@}
518
519
  //! @name Accessors
520
  //@{
521
0
  UniquePtr clone() const {
522
0
    return UniquePtr(clone_());
523
0
  }
524
  size_t copy(byte* buf, ByteOrder byteOrder) const override;
525
  /*!
526
    @brief Write the comment in a format which can be read by
527
    read(const std::string& comment).
528
   */
529
  std::ostream& write(std::ostream& os) const override;
530
  /*!
531
    @brief Return the comment (without a charset="..." prefix)
532
533
    The comment is decoded to UTF-8. For Exif UNICODE comments, the
534
    function makes an attempt to correctly determine the character
535
    encoding of the value. Alternatively, the optional \em encoding
536
    parameter can be used to specify it.
537
538
    @param encoding Optional argument to specify the character encoding
539
        that the comment is encoded in, as an iconv(3) name. Only used
540
        for Exif UNICODE comments.
541
542
    @return A string containing the comment converted to UTF-8.
543
   */
544
  std::string comment(const char* encoding = nullptr) const;
545
  /*!
546
    @brief Determine the character encoding that was used to encode the
547
        UNICODE comment value as an iconv(3) name.
548
549
    If the comment \em c starts with a BOM, the BOM is interpreted and
550
    removed from the string.
551
552
    Todo: Implement rules to guess if the comment is UTF-8 encoded.
553
   */
554
  const char* detectCharset(std::string& c) const;
555
  //! Return the Exif charset id of the comment
556
  CharsetId charsetId() const;
557
  //@}
558
559
 private:
560
  //! Internal virtual copy constructor.
561
  CommentValue* clone_() const override;
562
563
 public:
564
  // DATA
565
  ByteOrder byteOrder_{littleEndian};  //!< Byte order of the comment string that was read
566
567
};  // class CommentValue
568
569
/*!
570
  @brief Base class for all Exiv2 values used to store XMP property values.
571
 */
572
class EXIV2API XmpValue : public Value {
573
  using Value::Value;
574
575
 public:
576
  //! Shortcut for a %XmpValue auto pointer.
577
  using UniquePtr = std::unique_ptr<XmpValue>;
578
579
  //! XMP array types.
580
  enum XmpArrayType { xaNone, xaAlt, xaBag, xaSeq };
581
  //! XMP structure indicator.
582
  enum XmpStruct { xsNone, xsStruct };
583
584
  //! @name Accessors
585
  //@{
586
  //! Return XMP array type, indicates if an XMP value is an array.
587
  XmpArrayType xmpArrayType() const;
588
  //! Return XMP struct, indicates if an XMP value is a structure.
589
  XmpStruct xmpStruct() const;
590
  size_t size() const override;
591
  /*!
592
    @brief Write value to a character data buffer.
593
594
    The user must ensure that the buffer has enough memory. Otherwise
595
    the call results in undefined behaviour.
596
597
    @note The byte order is required by the interface but not used by this
598
          method, so just use the default.
599
600
    @param buf Data buffer to write to.
601
    @param byteOrder Byte order. Not used.
602
    @return Number of characters written.
603
  */
604
  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
605
  //@}
606
607
  //! @name Manipulators
608
  //@{
609
  //! Set the XMP array type to indicate that an XMP value is an array.
610
  void setXmpArrayType(XmpArrayType xmpArrayType);
611
  //! Set the XMP struct type to indicate that an XMP value is a structure.
612
  void setXmpStruct(XmpStruct xmpStruct = xsStruct);
613
614
  /// @note Uses read(const std::string& buf)
615
  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
616
  int read(const std::string& buf) override = 0;
617
  //@}
618
619
  /*!
620
    @brief Return XMP array type for an array Value TypeId, xaNone if
621
           \em typeId is not an XMP array value type.
622
   */
623
  static XmpArrayType xmpArrayType(TypeId typeId);
624
625
 private:
626
  // DATA
627
  XmpArrayType xmpArrayType_{xaNone};  //!< Type of XMP array
628
  XmpStruct xmpStruct_{xsNone};        //!< XMP structure indicator
629
630
};  // class XmpValue
631
632
/*!
633
  @brief %Value type suitable for simple XMP properties and
634
         XMP nodes of complex types which are not parsed into
635
         specific values.
636
637
  Uses a std::string to store the value.
638
 */
639
class EXIV2API XmpTextValue : public XmpValue {
640
 public:
641
  //! Shortcut for a %XmpTextValue auto pointer.
642
  using UniquePtr = std::unique_ptr<XmpTextValue>;
643
644
  //! @name Creators
645
  //@{
646
  //! Constructor.
647
  XmpTextValue();
648
  //! Constructor, reads the value from a string.
649
  explicit XmpTextValue(const std::string& buf);
650
  //@}
651
652
  //! @name Manipulators
653
  //@{
654
  using XmpValue::read;
655
  /*!
656
    @brief Read a simple property value from \em buf to set the value.
657
658
    Sets the value to the contents of \em buf. A optional keyword,
659
    \em type is supported to set the XMP value type. This is useful for
660
    complex value types for which Exiv2 does not have direct support.
661
662
    The format of \em buf is:
663
    <BR>
664
    <CODE>[type=["]Alt|Bag|Seq|Struct["] ]text</CODE>
665
    <BR>
666
667
    @return 0 if successful.
668
   */
669
670
  int read(const std::string& buf) override;
671
  //@}
672
673
  //! @name Accessors
674
  //@{
675
  UniquePtr clone() const;
676
  size_t size() const override;
677
  size_t count() const override;
678
  /*!
679
    @brief Convert the value to an int64_t.
680
           The optional parameter \em n is not used and is ignored.
681
682
    @return The converted value.
683
   */
684
  int64_t toInt64(size_t n = 0) const override;
685
  /*!
686
    @brief Convert the value to an uint32_t.
687
           The optional parameter \em n is not used and is ignored.
688
689
    @return The converted value.
690
   */
691
  uint32_t toUint32(size_t n = 0) const override;
692
  /*!
693
    @brief Convert the value to a float.
694
           The optional parameter \em n is not used and is ignored.
695
696
    @return The converted value.
697
   */
698
  float toFloat(size_t n = 0) const override;
699
  /*!
700
    @brief Convert the value to a Rational.
701
           The optional parameter \em n is not used and is ignored.
702
703
    @return The converted value.
704
   */
705
  Rational toRational(size_t n = 0) const override;
706
  std::ostream& write(std::ostream& os) const override;
707
  //@}
708
709
 private:
710
  //! Internal virtual copy constructor.
711
  XmpTextValue* clone_() const override;
712
713
 public:
714
  // DATA
715
  std::string value_;  //!< Stores the string values.
716
717
};  // class XmpTextValue
718
719
/*!
720
  @brief %Value type for simple arrays. Each item in the array is a simple
721
         value, without qualifiers. The array may be an ordered (\em seq),
722
         unordered (\em bag) or alternative array (\em alt). The array
723
         items must not contain qualifiers. For language alternatives use
724
         LangAltValue.
725
726
  Uses a vector of std::string to store the value(s).
727
 */
728
class EXIV2API XmpArrayValue : public XmpValue {
729
 public:
730
  //! Shortcut for a %XmpArrayValue auto pointer.
731
  using UniquePtr = std::unique_ptr<XmpArrayValue>;
732
733
  //! @name Creators
734
  //@{
735
  //! Constructor. \em typeId can be one of xmpBag, xmpSeq or xmpAlt.
736
  explicit XmpArrayValue(TypeId typeId = xmpBag);
737
  //@}
738
739
  //! @name Manipulators
740
  //@{
741
  using XmpValue::read;
742
  /*!
743
    @brief Read a simple property value from \em buf and append it
744
           to the value.
745
746
    Appends \em buf to the value after the last existing array element.
747
    Subsequent calls will therefore populate multiple array elements in
748
    the order they are read.
749
750
    @return 0 if successful.
751
   */
752
  int read(const std::string& buf) override;
753
  //@}
754
755
  //! @name Accessors
756
  //@{
757
  UniquePtr clone() const;
758
  size_t count() const override;
759
  /*!
760
    @brief Return the <EM>n</EM>-th component of the value as a string.
761
           The behaviour of this method may be undefined if there is no
762
           <EM>n</EM>-th component.
763
   */
764
  std::string toString(size_t n) const override;
765
  int64_t toInt64(size_t n = 0) const override;
766
  uint32_t toUint32(size_t n = 0) const override;
767
  float toFloat(size_t n = 0) const override;
768
  Rational toRational(size_t n = 0) const override;
769
  /*!
770
    @brief Write all elements of the value to \em os, separated by commas.
771
772
    @note The output of this method cannot directly be used as the parameter
773
          for read().
774
   */
775
  std::ostream& write(std::ostream& os) const override;
776
  //@}
777
778
 private:
779
  //! Internal virtual copy constructor.
780
  XmpArrayValue* clone_() const override;
781
782
  std::vector<std::string> value_;  //!< Stores the string values.
783
784
};  // class XmpArrayValue
785
786
/*!
787
  @brief %LangAltValueComparator
788
789
  #1058
790
  https://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf
791
  XMP spec chapter B.4 (page 42) the xml:lang qualifier is to be compared case insensitive.
792
  */
793
struct LangAltValueComparator {
794
  //! LangAltValueComparator comparison case insensitive function
795
26.5k
  bool operator()(const std::string& str1, const std::string& str2) const {
796
26.5k
    if (str1.size() != str2.size())
797
16.6k
      return str1.size() > str2.size();
798
799
165k
    auto f = [](unsigned char a, unsigned char b) { return std::tolower(a) > std::tolower(b); };
800
9.84k
    return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end(), f);
801
26.5k
  }
802
};
803
804
/*!
805
  @brief %Value type for XMP language alternative properties.
806
807
  A language alternative is an array consisting of simple text values,
808
  each of which has a language qualifier.
809
 */
810
class EXIV2API LangAltValue : public XmpValue {
811
 public:
812
  //! Shortcut for a %LangAltValue auto pointer.
813
  using UniquePtr = std::unique_ptr<LangAltValue>;
814
815
  //! @name Creators
816
  //@{
817
  //! Constructor.
818
  LangAltValue();
819
  //! Constructor, reads the value from a string.
820
  explicit LangAltValue(const std::string& buf);
821
  //@}
822
823
  //! @name Manipulators
824
  //@{
825
  using XmpValue::read;
826
  /*!
827
    @brief Read a simple property value from \em buf and append it
828
           to the value.
829
830
    Appends \em buf to the value after the last existing array element.
831
    Subsequent calls will therefore populate multiple array elements in
832
    the order they are read.
833
834
    The format of \em buf is:
835
    <BR>
836
    <CODE>[lang=["]language code["] ]text</CODE>
837
    <BR>
838
    The XMP default language code <CODE>x-default</CODE> is used if
839
    \em buf doesn't start with the keyword <CODE>lang</CODE>.
840
841
    @return 0 if successful.
842
   */
843
  int read(const std::string& buf) override;
844
  //@}
845
846
  //! @name Accessors
847
  //@{
848
  UniquePtr clone() const;
849
  size_t count() const override;
850
  /*!
851
    @brief Return the text value associated with the default language
852
           qualifier \c x-default. The parameter \em n is not used, but
853
           it is suggested that only 0 is passed in. Returns an empty
854
           string and sets the ok-flag to \c false if there is no
855
           default value.
856
   */
857
  std::string toString(size_t n) const override;
858
  /*!
859
    @brief Return the text value associated with the language qualifier
860
           \em qualifier. Returns an empty string and sets the ok-flag
861
           to \c false if there is no entry for the language qualifier.
862
   */
863
  std::string toString(const std::string& qualifier) const;
864
  int64_t toInt64(size_t n = 0) const override;
865
  uint32_t toUint32(size_t n = 0) const override;
866
  float toFloat(size_t n = 0) const override;
867
  Rational toRational(size_t n = 0) const override;
868
  /*!
869
    @brief Write all elements of the value to \em os, separated by commas.
870
871
    @note The output of this method cannot directly be used as the parameter
872
          for read().
873
   */
874
  std::ostream& write(std::ostream& os) const override;
875
  //@}
876
877
 private:
878
  //! Internal virtual copy constructor.
879
  LangAltValue* clone_() const override;
880
881
 public:
882
  //! Type used to store language alternative arrays.
883
  using ValueType = std::map<std::string, std::string, LangAltValueComparator>;
884
  // DATA
885
  /*!
886
    @brief Map to store the language alternative values. The language
887
           qualifier is used as the key for the map entries.
888
   */
889
  ValueType value_;
890
891
};  // class LangAltValue
892
893
/*!
894
  @brief %Value for simple ISO 8601 dates
895
896
  This class is limited to parsing simple date strings in the ISO 8601
897
  format CCYYMMDD (century, year, month, day).
898
 */
899
class EXIV2API DateValue : public Value {
900
 public:
901
  //! Shortcut for a %DateValue auto pointer.
902
  using UniquePtr = std::unique_ptr<DateValue>;
903
904
  //! @name Creators
905
  //@{
906
  //! Default constructor.
907
  DateValue();
908
  //! Constructor
909
  DateValue(int32_t year, int32_t month, int32_t day);
910
  //@}
911
912
  //! Simple Date helper structure
913
  struct EXIV2API Date {
914
    int32_t year;   //!< Year
915
    int32_t month;  //!< Month
916
    int32_t day;    //!< Day
917
  };
918
919
  //! @name Manipulators
920
  //@{
921
922
  /// @return 0 if successful<BR>
923
  ///         1 in case of an unsupported date format
924
  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
925
  /*!
926
    @brief Set the value to that of the string buf.
927
928
    @param buf String containing the date
929
930
    @return 0 if successful<BR>
931
            1 in case of an unsupported date format
932
   */
933
  int read(const std::string& buf) override;
934
  //! Set the date
935
  void setDate(const Date& src);
936
  //@}
937
938
  //! @name Accessors
939
  //@{
940
0
  UniquePtr clone() const {
941
0
    return UniquePtr(clone_());
942
0
  }
943
  /*!
944
    @brief Write value to a character data buffer.
945
946
    The user must ensure that the buffer has enough memory. Otherwise
947
    the call results in undefined behaviour.
948
949
    @note The byte order is required by the interface but not used by this
950
          method, so just use the default.
951
952
    @param buf Data buffer to write to.
953
    @param byteOrder Byte order. Not used.
954
    @return Number of characters written.
955
  */
956
  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
957
958
  //! Return date struct containing date information
959
  virtual const Date& getDate() const;
960
  size_t count() const override;
961
  size_t size() const override;
962
  std::ostream& write(std::ostream& os) const override;
963
  //! Return the value as a UNIX calendar time converted to int64_t.
964
  int64_t toInt64(size_t n = 0) const override;
965
  //! Return the value as a UNIX calendar time converted to uint32_t.
966
  uint32_t toUint32(size_t n = 0) const override;
967
  //! Return the value as a UNIX calendar time converted to float.
968
  float toFloat(size_t n = 0) const override;
969
  //! Return the value as a UNIX calendar time converted to Rational.
970
  Rational toRational(size_t n = 0) const override;
971
  //@}
972
973
 private:
974
  //! Internal virtual copy constructor.
975
  DateValue* clone_() const override;
976
977
  // DATA
978
  Date date_;
979
980
};  // class DateValue
981
982
/*!
983
 @brief %Value for simple ISO 8601 times.
984
985
 This class is limited to handling simple time strings in the ISO 8601
986
 format HHMMSS±HHMM where HHMMSS refers to local hour, minute and
987
 seconds and ±HHMM refers to hours and minutes ahead or behind
988
 Universal Coordinated Time.
989
 */
990
class EXIV2API TimeValue : public Value {
991
 public:
992
  //! Shortcut for a %TimeValue auto pointer.
993
  using UniquePtr = std::unique_ptr<TimeValue>;
994
995
  //! @name Creators
996
  //@{
997
  //! Default constructor.
998
  TimeValue();
999
  //! Constructor
1000
  TimeValue(int32_t hour, int32_t minute, int32_t second = 0, int32_t tzHour = 0, int32_t tzMinute = 0);
1001
  //@}
1002
1003
  //! Simple Time helper structure
1004
  struct Time {
1005
    int32_t hour;      //!< Hour
1006
    int32_t minute;    //!< Minute
1007
    int32_t second;    //!< Second
1008
    int32_t tzHour;    //!< Hours ahead or behind UTC
1009
    int32_t tzMinute;  //!< Minutes ahead or behind UTC
1010
  };
1011
1012
  //! @name Manipulators
1013
  //@{
1014
1015
  ///  @return 0 if successful<BR>
1016
  ///          1 in case of an unsupported time format
1017
  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
1018
  /*!
1019
    @brief Set the value to that of the string buf.
1020
1021
    @param buf String containing the time.
1022
1023
    @return 0 if successful<BR>
1024
            1 in case of an unsupported time format
1025
   */
1026
  int read(const std::string& buf) override;
1027
  //! Set the time
1028
  void setTime(const Time& src);
1029
  //@}
1030
1031
  //! @name Accessors
1032
  //@{
1033
0
  UniquePtr clone() const {
1034
0
    return UniquePtr(clone_());
1035
0
  }
1036
  /*!
1037
    @brief Write value to a character data buffer.
1038
1039
    The user must ensure that the buffer has enough memory. Otherwise
1040
    the call results in undefined behaviour.
1041
1042
    @note The byte order is required by the interface but not used by this
1043
          method, so just use the default.
1044
1045
    @param buf Data buffer to write to.
1046
    @param byteOrder Byte order. Not used.
1047
    @return Number of characters written.
1048
  */
1049
  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
1050
  //! Return time struct containing time information
1051
  virtual const Time& getTime() const;
1052
  size_t count() const override;
1053
  size_t size() const override;
1054
  std::ostream& write(std::ostream& os) const override;
1055
  //! Returns number of seconds in the day in UTC.
1056
  int64_t toInt64(size_t n = 0) const override;
1057
  //! Returns number of seconds in the day in UTC.
1058
  uint32_t toUint32(size_t n = 0) const override;
1059
  //! Returns number of seconds in the day in UTC converted to float.
1060
  float toFloat(size_t n = 0) const override;
1061
  //! Returns number of seconds in the day in UTC converted to Rational.
1062
  Rational toRational(size_t n = 0) const override;
1063
  //@}
1064
1065
 private:
1066
  //! @name Accessors
1067
  //@{
1068
  //! Internal virtual copy constructor.
1069
  TimeValue* clone_() const override;
1070
  //@}
1071
1072
  // DATA
1073
  Time time_;
1074
1075
};  // class TimeValue
1076
1077
//! Template to determine the TypeId for a type T
1078
template <typename T>
1079
TypeId getType();
1080
1081
//! Specialization for an unsigned short
1082
template <>
1083
5.08M
inline TypeId getType<uint16_t>() {
1084
5.08M
  return unsignedShort;
1085
5.08M
}
1086
//! Specialization for an unsigned long
1087
template <>
1088
26.7k
inline TypeId getType<uint32_t>() {
1089
26.7k
  return unsignedLong;
1090
26.7k
}
1091
//! Specialization for an unsigned rational
1092
template <>
1093
49.3k
inline TypeId getType<URational>() {
1094
49.3k
  return unsignedRational;
1095
49.3k
}
1096
//! Specialization for a signed short
1097
template <>
1098
328k
inline TypeId getType<int16_t>() {
1099
328k
  return signedShort;
1100
328k
}
1101
//! Specialization for a signed long
1102
template <>
1103
68.6k
inline TypeId getType<int32_t>() {
1104
68.6k
  return signedLong;
1105
68.6k
}
1106
//! Specialization for a signed rational
1107
template <>
1108
35.3k
inline TypeId getType<Rational>() {
1109
35.3k
  return signedRational;
1110
35.3k
}
1111
//! Specialization for a float
1112
template <>
1113
14.2k
inline TypeId getType<float>() {
1114
14.2k
  return tiffFloat;
1115
14.2k
}
1116
//! Specialization for a double
1117
template <>
1118
18.5k
inline TypeId getType<double>() {
1119
18.5k
  return tiffDouble;
1120
18.5k
}
1121
1122
// No default implementation: let the compiler/linker complain
1123
// template<typename T> inline TypeId getType() { return invalid; }
1124
1125
/*!
1126
  @brief Template for a %Value of a basic type. This is used for unsigned
1127
         and signed short, long and rationals.
1128
 */
1129
template <typename T>
1130
class ValueType : public Value {
1131
  using Value::Value;
1132
1133
 public:
1134
  //! Shortcut for a %ValueType\<T\> auto pointer.
1135
  using UniquePtr = std::unique_ptr<ValueType<T>>;
1136
1137
  //! @name Creators
1138
  //@{
1139
  //! Default Constructor.
1140
  ValueType();
1141
  //! Constructor.
1142
  ValueType(const byte* buf, size_t len, ByteOrder byteOrder, TypeId typeId = getType<T>());
1143
  //! Constructor.
1144
  explicit ValueType(const T& val, TypeId typeId = getType<T>());
1145
  //! Copy constructor
1146
  ValueType(const ValueType<T>& rhs);
1147
  //@}
1148
1149
  //! @name Manipulators
1150
  //@{
1151
  //! Assignment operator.
1152
  ValueType<T>& operator=(const ValueType<T>& rhs);
1153
  int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
1154
  /*!
1155
    @brief Set the data from a string of values of type T (e.g.,
1156
           "0 1 2 3" or "1/2 1/3 1/4" depending on what T is).
1157
           Generally, the accepted input format is the same as that
1158
           produced by the write() method.
1159
   */
1160
  int read(const std::string& buf) override;
1161
  /*!
1162
    @brief Set the data area. This method copies (clones) the buffer
1163
           pointed to by buf.
1164
   */
1165
  int setDataArea(const byte* buf, size_t len) override;
1166
  //@}
1167
1168
  //! @name Accessors
1169
  //@{
1170
  UniquePtr clone() const {
1171
    return UniquePtr(clone_());
1172
  }
1173
  size_t copy(byte* buf, ByteOrder byteOrder) const override;
1174
  size_t count() const override;
1175
  size_t size() const override;
1176
  std::ostream& write(std::ostream& os) const override;
1177
  /*!
1178
    @brief Return the <EM>n</EM>-th component of the value as a string.
1179
           The behaviour of this method may be undefined if there is no
1180
           <EM>n</EM>-th
1181
           component.
1182
   */
1183
  std::string toString(size_t n) const override;
1184
  int64_t toInt64(size_t n = 0) const override;
1185
  uint32_t toUint32(size_t n = 0) const override;
1186
  float toFloat(size_t n = 0) const override;
1187
  Rational toRational(size_t n = 0) const override;
1188
  //! Return the size of the data area.
1189
  size_t sizeDataArea() const override;
1190
  /*!
1191
    @brief Return a copy of the data area in a DataBuf. The caller owns
1192
           this copy and DataBuf ensures that it will be deleted.
1193
   */
1194
  DataBuf dataArea() const override;
1195
  //@}
1196
1197
  //! Container for values
1198
  using ValueList = std::vector<T>;
1199
1200
  // DATA
1201
  /*!
1202
    @brief The container for all values. In your application, if you know
1203
           what subclass of Value you're dealing with (and possibly the T)
1204
           then you can access this STL container through the usual
1205
           standard library functions.
1206
   */
1207
  ValueList value_;
1208
1209
 private:
1210
  //! Utility for toInt64, toUint32, etc.
1211
  template <typename I>
1212
35.7k
  I float_to_integer_helper(size_t n) const {
1213
35.7k
    const auto v = value_.at(n);
1214
35.7k
    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
1215
28.5k
        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
1216
22.9k
      return static_cast<I>(std::lround(v));
1217
22.9k
    }
1218
12.7k
    return 0;
1219
35.7k
  }
long Exiv2::ValueType<double>::float_to_integer_helper<long>(unsigned long) const
Line
Count
Source
1212
4.32k
  I float_to_integer_helper(size_t n) const {
1213
4.32k
    const auto v = value_.at(n);
1214
4.32k
    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
1215
3.61k
        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
1216
2.35k
      return static_cast<I>(std::lround(v));
1217
2.35k
    }
1218
1.96k
    return 0;
1219
4.32k
  }
unsigned int Exiv2::ValueType<double>::float_to_integer_helper<unsigned int>(unsigned long) const
Line
Count
Source
1212
9.96k
  I float_to_integer_helper(size_t n) const {
1213
9.96k
    const auto v = value_.at(n);
1214
9.96k
    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
1215
8.40k
        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
1216
6.20k
      return static_cast<I>(std::lround(v));
1217
6.20k
    }
1218
3.75k
    return 0;
1219
9.96k
  }
long Exiv2::ValueType<float>::float_to_integer_helper<long>(unsigned long) const
Line
Count
Source
1212
7.82k
  I float_to_integer_helper(size_t n) const {
1213
7.82k
    const auto v = value_.at(n);
1214
7.82k
    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
1215
6.60k
        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
1216
5.56k
      return static_cast<I>(std::lround(v));
1217
5.56k
    }
1218
2.25k
    return 0;
1219
7.82k
  }
unsigned int Exiv2::ValueType<float>::float_to_integer_helper<unsigned int>(unsigned long) const
Line
Count
Source
1212
13.6k
  I float_to_integer_helper(size_t n) const {
1213
13.6k
    const auto v = value_.at(n);
1214
13.6k
    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
1215
9.96k
        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
1216
8.86k
      return static_cast<I>(std::lround(v));
1217
8.86k
    }
1218
4.80k
    return 0;
1219
13.6k
  }
1220
1221
  //! Utility for toInt64, toUint32, etc.
1222
  template <typename I>
1223
170k
  I rational_to_integer_helper(size_t n) const {
1224
170k
    auto a = value_.at(n).first;
1225
170k
    auto b = value_.at(n).second;
1226
1227
    // Protect against divide-by-zero.
1228
170k
    if (b <= 0) {
1229
18.7k
      return 0;
1230
18.7k
    }
1231
1232
    // Check for integer overflow.
1233
151k
#ifdef __cpp_if_constexpr
1234
151k
    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
1235
#else
1236
    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
1237
#endif
1238
      // conversion does not change sign
1239
95.8k
      const auto imin = std::numeric_limits<I>::min();
1240
95.8k
      const auto imax = std::numeric_limits<I>::max();
1241
95.8k
      if (imax < b || a < imin || imax < a) {
1242
0
        return 0;
1243
0
      }
1244
95.8k
#ifdef __cpp_if_constexpr
1245
95.8k
    } else if constexpr (std::is_signed_v<I>) {
1246
#else
1247
    } else if (std::is_signed<I>::value) {
1248
#endif
1249
      // conversion is from unsigned to signed
1250
21.8k
      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
1251
21.8k
      if (imax < b || imax < a) {
1252
0
        return 0;
1253
0
      }
1254
33.6k
    } else {
1255
      // conversion is from signed to unsigned
1256
33.6k
      const auto imax = std::numeric_limits<I>::max();
1257
33.6k
      if (a < 0) {
1258
3.01k
        return 0;
1259
3.01k
      }
1260
      // Inputs are not negative so convert them to unsigned.
1261
30.5k
      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
1262
30.5k
      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
1263
30.5k
      if (imax < b_u || imax < a_u) {
1264
0
        return 0;
1265
0
      }
1266
30.5k
    }
1267
1268
148k
    return static_cast<I>(a) / static_cast<I>(b);
1269
170k
  }
long Exiv2::ValueType<std::__1::pair<int, int> >::rational_to_integer_helper<long>(unsigned long) const
Line
Count
Source
1223
51.8k
  I rational_to_integer_helper(size_t n) const {
1224
51.8k
    auto a = value_.at(n).first;
1225
51.8k
    auto b = value_.at(n).second;
1226
1227
    // Protect against divide-by-zero.
1228
51.8k
    if (b <= 0) {
1229
9.27k
      return 0;
1230
9.27k
    }
1231
1232
    // Check for integer overflow.
1233
42.5k
#ifdef __cpp_if_constexpr
1234
42.5k
    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
1235
#else
1236
    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
1237
#endif
1238
      // conversion does not change sign
1239
42.5k
      const auto imin = std::numeric_limits<I>::min();
1240
42.5k
      const auto imax = std::numeric_limits<I>::max();
1241
42.5k
      if (imax < b || a < imin || imax < a) {
1242
0
        return 0;
1243
0
      }
1244
42.5k
#ifdef __cpp_if_constexpr
1245
    } else if constexpr (std::is_signed_v<I>) {
1246
#else
1247
    } else if (std::is_signed<I>::value) {
1248
#endif
1249
      // conversion is from unsigned to signed
1250
      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
1251
      if (imax < b || imax < a) {
1252
        return 0;
1253
      }
1254
    } else {
1255
      // conversion is from signed to unsigned
1256
      const auto imax = std::numeric_limits<I>::max();
1257
      if (a < 0) {
1258
        return 0;
1259
      }
1260
      // Inputs are not negative so convert them to unsigned.
1261
      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
1262
      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
1263
      if (imax < b_u || imax < a_u) {
1264
        return 0;
1265
      }
1266
    }
1267
1268
42.5k
    return static_cast<I>(a) / static_cast<I>(b);
1269
51.8k
  }
unsigned int Exiv2::ValueType<std::__1::pair<int, int> >::rational_to_integer_helper<unsigned int>(unsigned long) const
Line
Count
Source
1223
40.6k
  I rational_to_integer_helper(size_t n) const {
1224
40.6k
    auto a = value_.at(n).first;
1225
40.6k
    auto b = value_.at(n).second;
1226
1227
    // Protect against divide-by-zero.
1228
40.6k
    if (b <= 0) {
1229
7.08k
      return 0;
1230
7.08k
    }
1231
1232
    // Check for integer overflow.
1233
33.6k
#ifdef __cpp_if_constexpr
1234
    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
1235
#else
1236
    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
1237
#endif
1238
      // conversion does not change sign
1239
      const auto imin = std::numeric_limits<I>::min();
1240
      const auto imax = std::numeric_limits<I>::max();
1241
      if (imax < b || a < imin || imax < a) {
1242
        return 0;
1243
      }
1244
#ifdef __cpp_if_constexpr
1245
    } else if constexpr (std::is_signed_v<I>) {
1246
#else
1247
    } else if (std::is_signed<I>::value) {
1248
#endif
1249
      // conversion is from unsigned to signed
1250
      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
1251
      if (imax < b || imax < a) {
1252
        return 0;
1253
      }
1254
33.6k
    } else {
1255
      // conversion is from signed to unsigned
1256
33.6k
      const auto imax = std::numeric_limits<I>::max();
1257
33.6k
      if (a < 0) {
1258
3.01k
        return 0;
1259
3.01k
      }
1260
      // Inputs are not negative so convert them to unsigned.
1261
30.5k
      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
1262
30.5k
      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
1263
30.5k
      if (imax < b_u || imax < a_u) {
1264
0
        return 0;
1265
0
      }
1266
30.5k
    }
1267
1268
30.5k
    return static_cast<I>(a) / static_cast<I>(b);
1269
40.6k
  }
long Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::rational_to_integer_helper<long>(unsigned long) const
Line
Count
Source
1223
22.6k
  I rational_to_integer_helper(size_t n) const {
1224
22.6k
    auto a = value_.at(n).first;
1225
22.6k
    auto b = value_.at(n).second;
1226
1227
    // Protect against divide-by-zero.
1228
22.6k
    if (b <= 0) {
1229
784
      return 0;
1230
784
    }
1231
1232
    // Check for integer overflow.
1233
21.8k
#ifdef __cpp_if_constexpr
1234
    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
1235
#else
1236
    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
1237
#endif
1238
      // conversion does not change sign
1239
      const auto imin = std::numeric_limits<I>::min();
1240
      const auto imax = std::numeric_limits<I>::max();
1241
      if (imax < b || a < imin || imax < a) {
1242
        return 0;
1243
      }
1244
#ifdef __cpp_if_constexpr
1245
21.8k
    } else if constexpr (std::is_signed_v<I>) {
1246
#else
1247
    } else if (std::is_signed<I>::value) {
1248
#endif
1249
      // conversion is from unsigned to signed
1250
21.8k
      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
1251
21.8k
      if (imax < b || imax < a) {
1252
0
        return 0;
1253
0
      }
1254
    } else {
1255
      // conversion is from signed to unsigned
1256
      const auto imax = std::numeric_limits<I>::max();
1257
      if (a < 0) {
1258
        return 0;
1259
      }
1260
      // Inputs are not negative so convert them to unsigned.
1261
      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
1262
      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
1263
      if (imax < b_u || imax < a_u) {
1264
        return 0;
1265
      }
1266
    }
1267
1268
21.8k
    return static_cast<I>(a) / static_cast<I>(b);
1269
22.6k
  }
unsigned int Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::rational_to_integer_helper<unsigned int>(unsigned long) const
Line
Count
Source
1223
54.9k
  I rational_to_integer_helper(size_t n) const {
1224
54.9k
    auto a = value_.at(n).first;
1225
54.9k
    auto b = value_.at(n).second;
1226
1227
    // Protect against divide-by-zero.
1228
54.9k
    if (b <= 0) {
1229
1.61k
      return 0;
1230
1.61k
    }
1231
1232
    // Check for integer overflow.
1233
53.3k
#ifdef __cpp_if_constexpr
1234
53.3k
    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
1235
#else
1236
    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
1237
#endif
1238
      // conversion does not change sign
1239
53.3k
      const auto imin = std::numeric_limits<I>::min();
1240
53.3k
      const auto imax = std::numeric_limits<I>::max();
1241
53.3k
      if (imax < b || a < imin || imax < a) {
1242
0
        return 0;
1243
0
      }
1244
53.3k
#ifdef __cpp_if_constexpr
1245
    } else if constexpr (std::is_signed_v<I>) {
1246
#else
1247
    } else if (std::is_signed<I>::value) {
1248
#endif
1249
      // conversion is from unsigned to signed
1250
      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
1251
      if (imax < b || imax < a) {
1252
        return 0;
1253
      }
1254
    } else {
1255
      // conversion is from signed to unsigned
1256
      const auto imax = std::numeric_limits<I>::max();
1257
      if (a < 0) {
1258
        return 0;
1259
      }
1260
      // Inputs are not negative so convert them to unsigned.
1261
      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
1262
      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
1263
      if (imax < b_u || imax < a_u) {
1264
        return 0;
1265
      }
1266
    }
1267
1268
53.3k
    return static_cast<I>(a) / static_cast<I>(b);
1269
54.9k
  }
1270
1271
  //! Internal virtual copy constructor.
1272
  ValueType<T>* clone_() const override;
1273
1274
  // DATA
1275
  //! Pointer to the buffer, nullptr if none has been allocated
1276
  Blob pDataArea_;
1277
};  // class ValueType
1278
1279
//! Unsigned short value type
1280
using UShortValue = ValueType<uint16_t>;
1281
//! Unsigned long value type
1282
using ULongValue = ValueType<uint32_t>;
1283
//! Unsigned rational value type
1284
using URationalValue = ValueType<URational>;
1285
//! Signed short value type
1286
using ShortValue = ValueType<int16_t>;
1287
//! Signed long value type
1288
using LongValue = ValueType<int32_t>;
1289
//! Signed rational value type
1290
using RationalValue = ValueType<Rational>;
1291
//! Float value type
1292
using FloatValue = ValueType<float>;
1293
//! Double value type
1294
using DoubleValue = ValueType<double>;
1295
1296
// *****************************************************************************
1297
// free functions, template and inline definitions
1298
1299
/*!
1300
  @brief Read a value of type T from the data buffer.
1301
1302
  We need this template function for the ValueType template classes.
1303
  There are only specializations of this function available; no default
1304
  implementation is provided.
1305
1306
  @param buf Pointer to the data buffer to read from.
1307
  @param byteOrder Applicable byte order (little or big endian).
1308
  @return A value of type T.
1309
 */
1310
template <typename T>
1311
T getValue(const byte* buf, ByteOrder byteOrder);
1312
// Specialization for a 2 byte unsigned short value.
1313
template <>
1314
7.49M
inline uint16_t getValue(const byte* buf, ByteOrder byteOrder) {
1315
7.49M
  return getUShort(buf, byteOrder);
1316
7.49M
}
1317
// Specialization for a 4 byte unsigned long value.
1318
template <>
1319
2.29M
inline uint32_t getValue(const byte* buf, ByteOrder byteOrder) {
1320
2.29M
  return getULong(buf, byteOrder);
1321
2.29M
}
1322
// Specialization for an 8 byte unsigned rational value.
1323
template <>
1324
371k
inline URational getValue(const byte* buf, ByteOrder byteOrder) {
1325
371k
  return getURational(buf, byteOrder);
1326
371k
}
1327
// Specialization for a 2 byte signed short value.
1328
template <>
1329
2.63M
inline int16_t getValue(const byte* buf, ByteOrder byteOrder) {
1330
2.63M
  return getShort(buf, byteOrder);
1331
2.63M
}
1332
// Specialization for a 4 byte signed long value.
1333
template <>
1334
766k
inline int32_t getValue(const byte* buf, ByteOrder byteOrder) {
1335
766k
  return getLong(buf, byteOrder);
1336
766k
}
1337
// Specialization for an 8 byte signed rational value.
1338
template <>
1339
372k
inline Rational getValue(const byte* buf, ByteOrder byteOrder) {
1340
372k
  return getRational(buf, byteOrder);
1341
372k
}
1342
// Specialization for a 4 byte float value.
1343
template <>
1344
152k
inline float getValue(const byte* buf, ByteOrder byteOrder) {
1345
152k
  return getFloat(buf, byteOrder);
1346
152k
}
1347
// Specialization for a 8 byte double value.
1348
template <>
1349
365k
inline double getValue(const byte* buf, ByteOrder byteOrder) {
1350
365k
  return getDouble(buf, byteOrder);
1351
365k
}
1352
1353
/*!
1354
  @brief Convert a value of type T to data, write the data to the data buffer.
1355
1356
  We need this template function for the ValueType template classes.
1357
  There are only specializations of this function available; no default
1358
  implementation is provided.
1359
1360
  @param buf Pointer to the data buffer to write to.
1361
  @param t Value to be converted.
1362
  @param byteOrder Applicable byte order (little or big endian).
1363
  @return The number of bytes written to the buffer.
1364
 */
1365
template <typename T>
1366
size_t toData(byte* buf, T t, ByteOrder byteOrder);
1367
/*!
1368
  @brief Specialization to write an unsigned short to the data buffer.
1369
         Return the number of bytes written.
1370
 */
1371
template <>
1372
2.34M
inline size_t toData(byte* buf, uint16_t t, ByteOrder byteOrder) {
1373
2.34M
  return us2Data(buf, t, byteOrder);
1374
2.34M
}
1375
/*!
1376
  @brief Specialization to write an unsigned long to the data buffer.
1377
         Return the number of bytes written.
1378
 */
1379
template <>
1380
570k
inline size_t toData(byte* buf, uint32_t t, ByteOrder byteOrder) {
1381
570k
  return ul2Data(buf, t, byteOrder);
1382
570k
}
1383
/*!
1384
  @brief Specialization to write an unsigned rational to the data buffer.
1385
         Return the number of bytes written.
1386
 */
1387
template <>
1388
369k
inline size_t toData(byte* buf, URational t, ByteOrder byteOrder) {
1389
369k
  return ur2Data(buf, t, byteOrder);
1390
369k
}
1391
/*!
1392
  @brief Specialization to write a signed short to the data buffer.
1393
         Return the number of bytes written.
1394
 */
1395
template <>
1396
251k
inline size_t toData(byte* buf, int16_t t, ByteOrder byteOrder) {
1397
251k
  return s2Data(buf, t, byteOrder);
1398
251k
}
1399
/*!
1400
  @brief Specialization to write a signed long to the data buffer.
1401
         Return the number of bytes written.
1402
 */
1403
template <>
1404
490k
inline size_t toData(byte* buf, int32_t t, ByteOrder byteOrder) {
1405
490k
  return l2Data(buf, t, byteOrder);
1406
490k
}
1407
/*!
1408
  @brief Specialization to write a signed rational to the data buffer.
1409
         Return the number of bytes written.
1410
 */
1411
template <>
1412
149k
inline size_t toData(byte* buf, Rational t, ByteOrder byteOrder) {
1413
149k
  return r2Data(buf, t, byteOrder);
1414
149k
}
1415
/*!
1416
  @brief Specialization to write a float to the data buffer.
1417
         Return the number of bytes written.
1418
 */
1419
template <>
1420
139k
inline size_t toData(byte* buf, float t, ByteOrder byteOrder) {
1421
139k
  return f2Data(buf, t, byteOrder);
1422
139k
}
1423
/*!
1424
  @brief Specialization to write a double to the data buffer.
1425
         Return the number of bytes written.
1426
 */
1427
template <>
1428
374k
inline size_t toData(byte* buf, double t, ByteOrder byteOrder) {
1429
374k
  return d2Data(buf, t, byteOrder);
1430
374k
}
1431
1432
template <typename T>
1433
5.62M
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
5.62M
}
Exiv2::ValueType<unsigned short>::ValueType()
Line
Count
Source
1433
5.08M
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
5.08M
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::ValueType()
Line
Count
Source
1433
49.3k
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
49.3k
}
Exiv2::ValueType<short>::ValueType()
Line
Count
Source
1433
328k
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
328k
}
Exiv2::ValueType<int>::ValueType()
Line
Count
Source
1433
68.6k
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
68.6k
}
Exiv2::ValueType<std::__1::pair<int, int> >::ValueType()
Line
Count
Source
1433
35.3k
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
35.3k
}
Exiv2::ValueType<float>::ValueType()
Line
Count
Source
1433
14.2k
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
14.2k
}
Exiv2::ValueType<double>::ValueType()
Line
Count
Source
1433
18.5k
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
18.5k
}
Exiv2::ValueType<unsigned int>::ValueType()
Line
Count
Source
1433
26.7k
ValueType<T>::ValueType() : Value(getType<T>()) {
1434
26.7k
}
1435
1436
template <typename T>
1437
ValueType<T>::ValueType(const byte* buf, size_t len, ByteOrder byteOrder, TypeId typeId) : Value(typeId) {
1438
  read(buf, len, byteOrder);
1439
}
1440
1441
template <typename T>
1442
ValueType<T>::ValueType(const T& val, TypeId typeId) : Value(typeId) {
1443
  value_.push_back(val);
1444
}
1445
1446
template <typename T>
1447
12.0M
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
12.0M
  if (!rhs.pDataArea_.empty())
1449
12.6k
    pDataArea_ = rhs.pDataArea_;
1450
12.0M
}
Exiv2::ValueType<unsigned short>::ValueType(Exiv2::ValueType<unsigned short> const&)
Line
Count
Source
1447
10.2M
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
10.2M
  if (!rhs.pDataArea_.empty())
1449
2.90k
    pDataArea_ = rhs.pDataArea_;
1450
10.2M
}
Exiv2::ValueType<unsigned int>::ValueType(Exiv2::ValueType<unsigned int> const&)
Line
Count
Source
1447
662k
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
662k
  if (!rhs.pDataArea_.empty())
1449
526
    pDataArea_ = rhs.pDataArea_;
1450
662k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::ValueType(Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> > const&)
Line
Count
Source
1447
133k
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
133k
  if (!rhs.pDataArea_.empty())
1449
1.89k
    pDataArea_ = rhs.pDataArea_;
1450
133k
}
Exiv2::ValueType<short>::ValueType(Exiv2::ValueType<short> const&)
Line
Count
Source
1447
676k
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
676k
  if (!rhs.pDataArea_.empty())
1449
677
    pDataArea_ = rhs.pDataArea_;
1450
676k
}
Exiv2::ValueType<int>::ValueType(Exiv2::ValueType<int> const&)
Line
Count
Source
1447
173k
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
173k
  if (!rhs.pDataArea_.empty())
1449
1.19k
    pDataArea_ = rhs.pDataArea_;
1450
173k
}
Exiv2::ValueType<std::__1::pair<int, int> >::ValueType(Exiv2::ValueType<std::__1::pair<int, int> > const&)
Line
Count
Source
1447
92.6k
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
92.6k
  if (!rhs.pDataArea_.empty())
1449
2.01k
    pDataArea_ = rhs.pDataArea_;
1450
92.6k
}
Exiv2::ValueType<float>::ValueType(Exiv2::ValueType<float> const&)
Line
Count
Source
1447
47.4k
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
47.4k
  if (!rhs.pDataArea_.empty())
1449
1.93k
    pDataArea_ = rhs.pDataArea_;
1450
47.4k
}
Exiv2::ValueType<double>::ValueType(Exiv2::ValueType<double> const&)
Line
Count
Source
1447
58.8k
ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
1448
58.8k
  if (!rhs.pDataArea_.empty())
1449
1.47k
    pDataArea_ = rhs.pDataArea_;
1450
58.8k
}
1451
1452
template <typename T>
1453
ValueType<T>& ValueType<T>::operator=(const ValueType<T>& rhs) {
1454
  if (this == &rhs)
1455
    return *this;
1456
  value_ = rhs.value_;
1457
1458
  if (!rhs.pDataArea_.empty())
1459
    pDataArea_ = rhs.pDataArea_;
1460
  else
1461
    pDataArea_.clear();
1462
1463
  return *this;
1464
}
1465
1466
template <typename T>
1467
5.85M
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
5.85M
  value_.clear();
1469
5.85M
  size_t ts = TypeInfo::typeSize(typeId());
1470
5.85M
  if (ts > 0 && len % ts != 0)
1471
2.87k
    len = (len / ts) * ts;
1472
20.3M
  for (size_t i = 0; i < len; i += ts) {
1473
14.4M
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
14.4M
  }
1475
5.85M
  return 0;
1476
5.85M
}
Exiv2::ValueType<unsigned short>::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
5.08M
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
5.08M
  value_.clear();
1469
5.08M
  size_t ts = TypeInfo::typeSize(typeId());
1470
5.08M
  if (ts > 0 && len % ts != 0)
1471
1.23k
    len = (len / ts) * ts;
1472
12.5M
  for (size_t i = 0; i < len; i += ts) {
1473
7.49M
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
7.49M
  }
1475
5.08M
  return 0;
1476
5.08M
}
Exiv2::ValueType<unsigned int>::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
262k
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
262k
  value_.clear();
1469
262k
  size_t ts = TypeInfo::typeSize(typeId());
1470
262k
  if (ts > 0 && len % ts != 0)
1471
189
    len = (len / ts) * ts;
1472
2.55M
  for (size_t i = 0; i < len; i += ts) {
1473
2.29M
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
2.29M
  }
1475
262k
  return 0;
1476
262k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
48.8k
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
48.8k
  value_.clear();
1469
48.8k
  size_t ts = TypeInfo::typeSize(typeId());
1470
48.8k
  if (ts > 0 && len % ts != 0)
1471
0
    len = (len / ts) * ts;
1472
420k
  for (size_t i = 0; i < len; i += ts) {
1473
371k
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
371k
  }
1475
48.8k
  return 0;
1476
48.8k
}
Exiv2::ValueType<short>::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
323k
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
323k
  value_.clear();
1469
323k
  size_t ts = TypeInfo::typeSize(typeId());
1470
323k
  if (ts > 0 && len % ts != 0)
1471
468
    len = (len / ts) * ts;
1472
2.95M
  for (size_t i = 0; i < len; i += ts) {
1473
2.63M
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
2.63M
  }
1475
323k
  return 0;
1476
323k
}
Exiv2::ValueType<int>::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
68.6k
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
68.6k
  value_.clear();
1469
68.6k
  size_t ts = TypeInfo::typeSize(typeId());
1470
68.6k
  if (ts > 0 && len % ts != 0)
1471
977
    len = (len / ts) * ts;
1472
834k
  for (size_t i = 0; i < len; i += ts) {
1473
766k
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
766k
  }
1475
68.6k
  return 0;
1476
68.6k
}
Exiv2::ValueType<std::__1::pair<int, int> >::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
35.3k
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
35.3k
  value_.clear();
1469
35.3k
  size_t ts = TypeInfo::typeSize(typeId());
1470
35.3k
  if (ts > 0 && len % ts != 0)
1471
0
    len = (len / ts) * ts;
1472
408k
  for (size_t i = 0; i < len; i += ts) {
1473
372k
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
372k
  }
1475
35.3k
  return 0;
1476
35.3k
}
Exiv2::ValueType<float>::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
14.2k
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
14.2k
  value_.clear();
1469
14.2k
  size_t ts = TypeInfo::typeSize(typeId());
1470
14.2k
  if (ts > 0 && len % ts != 0)
1471
0
    len = (len / ts) * ts;
1472
166k
  for (size_t i = 0; i < len; i += ts) {
1473
152k
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
152k
  }
1475
14.2k
  return 0;
1476
14.2k
}
Exiv2::ValueType<double>::read(unsigned char const*, unsigned long, Exiv2::ByteOrder)
Line
Count
Source
1467
18.5k
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1468
18.5k
  value_.clear();
1469
18.5k
  size_t ts = TypeInfo::typeSize(typeId());
1470
18.5k
  if (ts > 0 && len % ts != 0)
1471
0
    len = (len / ts) * ts;
1472
383k
  for (size_t i = 0; i < len; i += ts) {
1473
365k
    value_.push_back(getValue<T>(buf + i, byteOrder));
1474
365k
  }
1475
18.5k
  return 0;
1476
18.5k
}
1477
1478
template <typename T>
1479
6.70k
int ValueType<T>::read(const std::string& buf) {
1480
6.70k
  std::istringstream is(buf);
1481
6.70k
  T tmp;
1482
6.70k
  ValueList val;
1483
16.6k
  while (is >> tmp)
1484
9.93k
    val.push_back(tmp);
1485
6.70k
  if (!is.eof())
1486
12
    return 1;
1487
6.69k
  value_ = std::move(val);
1488
6.69k
  return 0;
1489
6.70k
}
Exiv2::ValueType<unsigned short>::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
1479
1.35k
int ValueType<T>::read(const std::string& buf) {
1480
1.35k
  std::istringstream is(buf);
1481
1.35k
  T tmp;
1482
1.35k
  ValueList val;
1483
2.22k
  while (is >> tmp)
1484
871
    val.push_back(tmp);
1485
1.35k
  if (!is.eof())
1486
12
    return 1;
1487
1.34k
  value_ = std::move(val);
1488
1.34k
  return 0;
1489
1.35k
}
Unexecuted instantiation: Exiv2::ValueType<unsigned int>::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Exiv2::ValueType<short>::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
1479
5.35k
int ValueType<T>::read(const std::string& buf) {
1480
5.35k
  std::istringstream is(buf);
1481
5.35k
  T tmp;
1482
5.35k
  ValueList val;
1483
14.4k
  while (is >> tmp)
1484
9.06k
    val.push_back(tmp);
1485
5.35k
  if (!is.eof())
1486
0
    return 1;
1487
5.35k
  value_ = std::move(val);
1488
5.35k
  return 0;
1489
5.35k
}
Unexecuted instantiation: Exiv2::ValueType<int>::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: Exiv2::ValueType<std::__1::pair<int, int> >::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: Exiv2::ValueType<float>::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: Exiv2::ValueType<double>::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
1490
1491
template <typename T>
1492
240k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
240k
  size_t offset = 0;
1494
4.68M
  for (const auto& val : value_) {
1495
4.68M
    offset += toData(buf + offset, val, byteOrder);
1496
4.68M
  }
1497
240k
  return offset;
1498
240k
}
Exiv2::ValueType<unsigned short>::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
63.8k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
63.8k
  size_t offset = 0;
1494
2.34M
  for (const auto& val : value_) {
1495
2.34M
    offset += toData(buf + offset, val, byteOrder);
1496
2.34M
  }
1497
63.8k
  return offset;
1498
63.8k
}
Exiv2::ValueType<unsigned int>::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
75.2k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
75.2k
  size_t offset = 0;
1494
570k
  for (const auto& val : value_) {
1495
570k
    offset += toData(buf + offset, val, byteOrder);
1496
570k
  }
1497
75.2k
  return offset;
1498
75.2k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
26.7k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
26.7k
  size_t offset = 0;
1494
369k
  for (const auto& val : value_) {
1495
369k
    offset += toData(buf + offset, val, byteOrder);
1496
369k
  }
1497
26.7k
  return offset;
1498
26.7k
}
Exiv2::ValueType<short>::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
14.0k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
14.0k
  size_t offset = 0;
1494
251k
  for (const auto& val : value_) {
1495
251k
    offset += toData(buf + offset, val, byteOrder);
1496
251k
  }
1497
14.0k
  return offset;
1498
14.0k
}
Exiv2::ValueType<int>::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
24.0k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
24.0k
  size_t offset = 0;
1494
490k
  for (const auto& val : value_) {
1495
490k
    offset += toData(buf + offset, val, byteOrder);
1496
490k
  }
1497
24.0k
  return offset;
1498
24.0k
}
Exiv2::ValueType<std::__1::pair<int, int> >::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
15.0k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
15.0k
  size_t offset = 0;
1494
149k
  for (const auto& val : value_) {
1495
149k
    offset += toData(buf + offset, val, byteOrder);
1496
149k
  }
1497
15.0k
  return offset;
1498
15.0k
}
Exiv2::ValueType<float>::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
9.68k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
9.68k
  size_t offset = 0;
1494
139k
  for (const auto& val : value_) {
1495
139k
    offset += toData(buf + offset, val, byteOrder);
1496
139k
  }
1497
9.68k
  return offset;
1498
9.68k
}
Exiv2::ValueType<double>::copy(unsigned char*, Exiv2::ByteOrder) const
Line
Count
Source
1492
12.1k
size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1493
12.1k
  size_t offset = 0;
1494
374k
  for (const auto& val : value_) {
1495
374k
    offset += toData(buf + offset, val, byteOrder);
1496
374k
  }
1497
12.1k
  return offset;
1498
12.1k
}
1499
1500
template <typename T>
1501
10.5M
size_t ValueType<T>::count() const {
1502
10.5M
  return value_.size();
1503
10.5M
}
Exiv2::ValueType<unsigned short>::count() const
Line
Count
Source
1501
5.48M
size_t ValueType<T>::count() const {
1502
5.48M
  return value_.size();
1503
5.48M
}
Exiv2::ValueType<unsigned int>::count() const
Line
Count
Source
1501
473k
size_t ValueType<T>::count() const {
1502
473k
  return value_.size();
1503
473k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::count() const
Line
Count
Source
1501
150k
size_t ValueType<T>::count() const {
1502
150k
  return value_.size();
1503
150k
}
Exiv2::ValueType<short>::count() const
Line
Count
Source
1501
4.08M
size_t ValueType<T>::count() const {
1502
4.08M
  return value_.size();
1503
4.08M
}
Exiv2::ValueType<int>::count() const
Line
Count
Source
1501
153k
size_t ValueType<T>::count() const {
1502
153k
  return value_.size();
1503
153k
}
Exiv2::ValueType<std::__1::pair<int, int> >::count() const
Line
Count
Source
1501
96.3k
size_t ValueType<T>::count() const {
1502
96.3k
  return value_.size();
1503
96.3k
}
Exiv2::ValueType<float>::count() const
Line
Count
Source
1501
50.4k
size_t ValueType<T>::count() const {
1502
50.4k
  return value_.size();
1503
50.4k
}
Exiv2::ValueType<double>::count() const
Line
Count
Source
1501
49.3k
size_t ValueType<T>::count() const {
1502
49.3k
  return value_.size();
1503
49.3k
}
1504
1505
template <typename T>
1506
1.14M
size_t ValueType<T>::size() const {
1507
1.14M
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
1.14M
}
Exiv2::ValueType<unsigned short>::size() const
Line
Count
Source
1506
340k
size_t ValueType<T>::size() const {
1507
340k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
340k
}
Exiv2::ValueType<unsigned int>::size() const
Line
Count
Source
1506
411k
size_t ValueType<T>::size() const {
1507
411k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
411k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::size() const
Line
Count
Source
1506
75.0k
size_t ValueType<T>::size() const {
1507
75.0k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
75.0k
}
Exiv2::ValueType<short>::size() const
Line
Count
Source
1506
49.0k
size_t ValueType<T>::size() const {
1507
49.0k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
49.0k
}
Exiv2::ValueType<int>::size() const
Line
Count
Source
1506
159k
size_t ValueType<T>::size() const {
1507
159k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
159k
}
Exiv2::ValueType<std::__1::pair<int, int> >::size() const
Line
Count
Source
1506
44.0k
size_t ValueType<T>::size() const {
1507
44.0k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
44.0k
}
Exiv2::ValueType<float>::size() const
Line
Count
Source
1506
29.1k
size_t ValueType<T>::size() const {
1507
29.1k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
29.1k
}
Exiv2::ValueType<double>::size() const
Line
Count
Source
1506
39.7k
size_t ValueType<T>::size() const {
1507
39.7k
  return TypeInfo::typeSize(typeId()) * value_.size();
1508
39.7k
}
1509
1510
template <typename T>
1511
12.0M
ValueType<T>* ValueType<T>::clone_() const {
1512
12.0M
  return new ValueType<T>(*this);
1513
12.0M
}
Exiv2::ValueType<unsigned short>::clone_() const
Line
Count
Source
1511
10.2M
ValueType<T>* ValueType<T>::clone_() const {
1512
10.2M
  return new ValueType<T>(*this);
1513
10.2M
}
Exiv2::ValueType<unsigned int>::clone_() const
Line
Count
Source
1511
662k
ValueType<T>* ValueType<T>::clone_() const {
1512
662k
  return new ValueType<T>(*this);
1513
662k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::clone_() const
Line
Count
Source
1511
133k
ValueType<T>* ValueType<T>::clone_() const {
1512
133k
  return new ValueType<T>(*this);
1513
133k
}
Exiv2::ValueType<short>::clone_() const
Line
Count
Source
1511
676k
ValueType<T>* ValueType<T>::clone_() const {
1512
676k
  return new ValueType<T>(*this);
1513
676k
}
Exiv2::ValueType<int>::clone_() const
Line
Count
Source
1511
173k
ValueType<T>* ValueType<T>::clone_() const {
1512
173k
  return new ValueType<T>(*this);
1513
173k
}
Exiv2::ValueType<std::__1::pair<int, int> >::clone_() const
Line
Count
Source
1511
92.6k
ValueType<T>* ValueType<T>::clone_() const {
1512
92.6k
  return new ValueType<T>(*this);
1513
92.6k
}
Exiv2::ValueType<float>::clone_() const
Line
Count
Source
1511
47.4k
ValueType<T>* ValueType<T>::clone_() const {
1512
47.4k
  return new ValueType<T>(*this);
1513
47.4k
}
Exiv2::ValueType<double>::clone_() const
Line
Count
Source
1511
58.8k
ValueType<T>* ValueType<T>::clone_() const {
1512
58.8k
  return new ValueType<T>(*this);
1513
58.8k
}
1514
1515
template <typename T>
1516
116k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
116k
  auto end = value_.end();
1518
116k
  auto i = value_.begin();
1519
1.41M
  while (i != end) {
1520
1.30M
    os << std::setprecision(15) << *i;
1521
1.30M
    if (++i != end)
1522
1.18M
      os << " ";
1523
1.30M
  }
1524
116k
  return os;
1525
116k
}
Exiv2::ValueType<unsigned short>::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
39.0k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
39.0k
  auto end = value_.end();
1518
39.0k
  auto i = value_.begin();
1519
274k
  while (i != end) {
1520
235k
    os << std::setprecision(15) << *i;
1521
235k
    if (++i != end)
1522
196k
      os << " ";
1523
235k
  }
1524
39.0k
  return os;
1525
39.0k
}
Exiv2::ValueType<unsigned int>::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
51.5k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
51.5k
  auto end = value_.end();
1518
51.5k
  auto i = value_.begin();
1519
428k
  while (i != end) {
1520
377k
    os << std::setprecision(15) << *i;
1521
377k
    if (++i != end)
1522
325k
      os << " ";
1523
377k
  }
1524
51.5k
  return os;
1525
51.5k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
4.25k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
4.25k
  auto end = value_.end();
1518
4.25k
  auto i = value_.begin();
1519
159k
  while (i != end) {
1520
154k
    os << std::setprecision(15) << *i;
1521
154k
    if (++i != end)
1522
151k
      os << " ";
1523
154k
  }
1524
4.25k
  return os;
1525
4.25k
}
Exiv2::ValueType<short>::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
8.68k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
8.68k
  auto end = value_.end();
1518
8.68k
  auto i = value_.begin();
1519
114k
  while (i != end) {
1520
105k
    os << std::setprecision(15) << *i;
1521
105k
    if (++i != end)
1522
97.4k
      os << " ";
1523
105k
  }
1524
8.68k
  return os;
1525
8.68k
}
Exiv2::ValueType<int>::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
3.65k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
3.65k
  auto end = value_.end();
1518
3.65k
  auto i = value_.begin();
1519
256k
  while (i != end) {
1520
252k
    os << std::setprecision(15) << *i;
1521
252k
    if (++i != end)
1522
249k
      os << " ";
1523
252k
  }
1524
3.65k
  return os;
1525
3.65k
}
Exiv2::ValueType<std::__1::pair<int, int> >::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
6.20k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
6.20k
  auto end = value_.end();
1518
6.20k
  auto i = value_.begin();
1519
41.8k
  while (i != end) {
1520
35.6k
    os << std::setprecision(15) << *i;
1521
35.6k
    if (++i != end)
1522
29.6k
      os << " ";
1523
35.6k
  }
1524
6.20k
  return os;
1525
6.20k
}
Exiv2::ValueType<float>::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
2.30k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
2.30k
  auto end = value_.end();
1518
2.30k
  auto i = value_.begin();
1519
134k
  while (i != end) {
1520
132k
    os << std::setprecision(15) << *i;
1521
132k
    if (++i != end)
1522
130k
      os << " ";
1523
132k
  }
1524
2.30k
  return os;
1525
2.30k
}
Exiv2::ValueType<double>::write(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const
Line
Count
Source
1516
1.17k
std::ostream& ValueType<T>::write(std::ostream& os) const {
1517
1.17k
  auto end = value_.end();
1518
1.17k
  auto i = value_.begin();
1519
7.39k
  while (i != end) {
1520
6.22k
    os << std::setprecision(15) << *i;
1521
6.22k
    if (++i != end)
1522
5.14k
      os << " ";
1523
6.22k
  }
1524
1.17k
  return os;
1525
1.17k
}
1526
1527
template <typename T>
1528
1.84k
std::string ValueType<T>::toString(size_t n) const {
1529
1.84k
  ok_ = true;
1530
1.84k
  return Exiv2::toString<T>(value_.at(n));
1531
1.84k
}
Exiv2::ValueType<unsigned short>::toString(unsigned long) const
Line
Count
Source
1528
918
std::string ValueType<T>::toString(size_t n) const {
1529
918
  ok_ = true;
1530
918
  return Exiv2::toString<T>(value_.at(n));
1531
918
}
Exiv2::ValueType<unsigned int>::toString(unsigned long) const
Line
Count
Source
1528
210
std::string ValueType<T>::toString(size_t n) const {
1529
210
  ok_ = true;
1530
210
  return Exiv2::toString<T>(value_.at(n));
1531
210
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::toString(unsigned long) const
Line
Count
Source
1528
218
std::string ValueType<T>::toString(size_t n) const {
1529
218
  ok_ = true;
1530
218
  return Exiv2::toString<T>(value_.at(n));
1531
218
}
Exiv2::ValueType<short>::toString(unsigned long) const
Line
Count
Source
1528
18
std::string ValueType<T>::toString(size_t n) const {
1529
18
  ok_ = true;
1530
18
  return Exiv2::toString<T>(value_.at(n));
1531
18
}
Exiv2::ValueType<int>::toString(unsigned long) const
Line
Count
Source
1528
50
std::string ValueType<T>::toString(size_t n) const {
1529
50
  ok_ = true;
1530
50
  return Exiv2::toString<T>(value_.at(n));
1531
50
}
Exiv2::ValueType<std::__1::pair<int, int> >::toString(unsigned long) const
Line
Count
Source
1528
180
std::string ValueType<T>::toString(size_t n) const {
1529
180
  ok_ = true;
1530
180
  return Exiv2::toString<T>(value_.at(n));
1531
180
}
Exiv2::ValueType<float>::toString(unsigned long) const
Line
Count
Source
1528
154
std::string ValueType<T>::toString(size_t n) const {
1529
154
  ok_ = true;
1530
154
  return Exiv2::toString<T>(value_.at(n));
1531
154
}
Exiv2::ValueType<double>::toString(unsigned long) const
Line
Count
Source
1528
98
std::string ValueType<T>::toString(size_t n) const {
1529
98
  ok_ = true;
1530
98
  return Exiv2::toString<T>(value_.at(n));
1531
98
}
1532
1533
// Default implementation
1534
template <typename T>
1535
4.02M
int64_t ValueType<T>::toInt64(size_t n) const {
1536
4.02M
  ok_ = true;
1537
4.02M
  return static_cast<int64_t>(value_.at(n));
1538
4.02M
}
Exiv2::ValueType<unsigned short>::toInt64(unsigned long) const
Line
Count
Source
1535
265k
int64_t ValueType<T>::toInt64(size_t n) const {
1536
265k
  ok_ = true;
1537
265k
  return static_cast<int64_t>(value_.at(n));
1538
265k
}
Exiv2::ValueType<unsigned int>::toInt64(unsigned long) const
Line
Count
Source
1535
32.1k
int64_t ValueType<T>::toInt64(size_t n) const {
1536
32.1k
  ok_ = true;
1537
32.1k
  return static_cast<int64_t>(value_.at(n));
1538
32.1k
}
Exiv2::ValueType<short>::toInt64(unsigned long) const
Line
Count
Source
1535
3.70M
int64_t ValueType<T>::toInt64(size_t n) const {
1536
3.70M
  ok_ = true;
1537
3.70M
  return static_cast<int64_t>(value_.at(n));
1538
3.70M
}
Exiv2::ValueType<int>::toInt64(unsigned long) const
Line
Count
Source
1535
25.0k
int64_t ValueType<T>::toInt64(size_t n) const {
1536
25.0k
  ok_ = true;
1537
25.0k
  return static_cast<int64_t>(value_.at(n));
1538
25.0k
}
1539
template <typename T>
1540
282k
uint32_t ValueType<T>::toUint32(size_t n) const {
1541
282k
  ok_ = true;
1542
282k
  return static_cast<uint32_t>(value_.at(n));
1543
282k
}
Exiv2::ValueType<unsigned short>::toUint32(unsigned long) const
Line
Count
Source
1540
128k
uint32_t ValueType<T>::toUint32(size_t n) const {
1541
128k
  ok_ = true;
1542
128k
  return static_cast<uint32_t>(value_.at(n));
1543
128k
}
Exiv2::ValueType<unsigned int>::toUint32(unsigned long) const
Line
Count
Source
1540
64.2k
uint32_t ValueType<T>::toUint32(size_t n) const {
1541
64.2k
  ok_ = true;
1542
64.2k
  return static_cast<uint32_t>(value_.at(n));
1543
64.2k
}
Exiv2::ValueType<short>::toUint32(unsigned long) const
Line
Count
Source
1540
75.7k
uint32_t ValueType<T>::toUint32(size_t n) const {
1541
75.7k
  ok_ = true;
1542
75.7k
  return static_cast<uint32_t>(value_.at(n));
1543
75.7k
}
Exiv2::ValueType<int>::toUint32(unsigned long) const
Line
Count
Source
1540
13.7k
uint32_t ValueType<T>::toUint32(size_t n) const {
1541
13.7k
  ok_ = true;
1542
13.7k
  return static_cast<uint32_t>(value_.at(n));
1543
13.7k
}
1544
// #55 crash when value_.at(n).first == LONG_MIN
1545
#define LARGE_INT 1000000
1546
// Specialization for double
1547
template <>
1548
4.32k
inline int64_t ValueType<double>::toInt64(size_t n) const {
1549
4.32k
  return float_to_integer_helper<int64_t>(n);
1550
4.32k
}
1551
1552
template <>
1553
9.96k
inline uint32_t ValueType<double>::toUint32(size_t n) const {
1554
9.96k
  return float_to_integer_helper<uint32_t>(n);
1555
9.96k
}
1556
// Specialization for float
1557
template <>
1558
7.82k
inline int64_t ValueType<float>::toInt64(size_t n) const {
1559
7.82k
  return float_to_integer_helper<int64_t>(n);
1560
7.82k
}
1561
template <>
1562
13.6k
inline uint32_t ValueType<float>::toUint32(size_t n) const {
1563
13.6k
  return float_to_integer_helper<uint32_t>(n);
1564
13.6k
}
1565
// Specialization for rational
1566
template <>
1567
51.8k
inline int64_t ValueType<Rational>::toInt64(size_t n) const {
1568
51.8k
  return rational_to_integer_helper<int64_t>(n);
1569
51.8k
}
1570
template <>
1571
40.6k
inline uint32_t ValueType<Rational>::toUint32(size_t n) const {
1572
40.6k
  return rational_to_integer_helper<uint32_t>(n);
1573
40.6k
}
1574
// Specialization for unsigned rational
1575
template <>
1576
22.6k
inline int64_t ValueType<URational>::toInt64(size_t n) const {
1577
22.6k
  return rational_to_integer_helper<int64_t>(n);
1578
22.6k
}
1579
template <>
1580
54.9k
inline uint32_t ValueType<URational>::toUint32(size_t n) const {
1581
54.9k
  return rational_to_integer_helper<uint32_t>(n);
1582
54.9k
}
1583
// Default implementation
1584
template <typename T>
1585
8.23k
float ValueType<T>::toFloat(size_t n) const {
1586
8.23k
  ok_ = true;
1587
8.23k
  return static_cast<float>(value_.at(n));
1588
8.23k
}
Exiv2::ValueType<unsigned short>::toFloat(unsigned long) const
Line
Count
Source
1585
7.69k
float ValueType<T>::toFloat(size_t n) const {
1586
7.69k
  ok_ = true;
1587
7.69k
  return static_cast<float>(value_.at(n));
1588
7.69k
}
Exiv2::ValueType<unsigned int>::toFloat(unsigned long) const
Line
Count
Source
1585
90
float ValueType<T>::toFloat(size_t n) const {
1586
90
  ok_ = true;
1587
90
  return static_cast<float>(value_.at(n));
1588
90
}
Exiv2::ValueType<short>::toFloat(unsigned long) const
Line
Count
Source
1585
235
float ValueType<T>::toFloat(size_t n) const {
1586
235
  ok_ = true;
1587
235
  return static_cast<float>(value_.at(n));
1588
235
}
Exiv2::ValueType<int>::toFloat(unsigned long) const
Line
Count
Source
1585
68
float ValueType<T>::toFloat(size_t n) const {
1586
68
  ok_ = true;
1587
68
  return static_cast<float>(value_.at(n));
1588
68
}
Exiv2::ValueType<float>::toFloat(unsigned long) const
Line
Count
Source
1585
57
float ValueType<T>::toFloat(size_t n) const {
1586
57
  ok_ = true;
1587
57
  return static_cast<float>(value_.at(n));
1588
57
}
Exiv2::ValueType<double>::toFloat(unsigned long) const
Line
Count
Source
1585
91
float ValueType<T>::toFloat(size_t n) const {
1586
91
  ok_ = true;
1587
91
  return static_cast<float>(value_.at(n));
1588
91
}
1589
// Specialization for rational
1590
template <>
1591
388
inline float ValueType<Rational>::toFloat(size_t n) const {
1592
388
  ok_ = (value_.at(n).second != 0);
1593
388
  if (!ok_)
1594
6
    return 0.0f;
1595
382
  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1596
388
}
1597
// Specialization for unsigned rational
1598
template <>
1599
2.62k
inline float ValueType<URational>::toFloat(size_t n) const {
1600
2.62k
  ok_ = (value_.at(n).second != 0);
1601
2.62k
  if (!ok_)
1602
31
    return 0.0f;
1603
2.59k
  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1604
2.62k
}
1605
// Default implementation
1606
template <typename T>
1607
582
Rational ValueType<T>::toRational(size_t n) const {
1608
582
  ok_ = true;
1609
582
  return {value_.at(n), 1};
1610
582
}
Exiv2::ValueType<unsigned short>::toRational(unsigned long) const
Line
Count
Source
1607
118
Rational ValueType<T>::toRational(size_t n) const {
1608
118
  ok_ = true;
1609
118
  return {value_.at(n), 1};
1610
118
}
Exiv2::ValueType<unsigned int>::toRational(unsigned long) const
Line
Count
Source
1607
180
Rational ValueType<T>::toRational(size_t n) const {
1608
180
  ok_ = true;
1609
180
  return {value_.at(n), 1};
1610
180
}
Exiv2::ValueType<short>::toRational(unsigned long) const
Line
Count
Source
1607
158
Rational ValueType<T>::toRational(size_t n) const {
1608
158
  ok_ = true;
1609
158
  return {value_.at(n), 1};
1610
158
}
Exiv2::ValueType<int>::toRational(unsigned long) const
Line
Count
Source
1607
126
Rational ValueType<T>::toRational(size_t n) const {
1608
126
  ok_ = true;
1609
126
  return {value_.at(n), 1};
1610
126
}
1611
// Specialization for rational
1612
template <>
1613
1.98k
inline Rational ValueType<Rational>::toRational(size_t n) const {
1614
1.98k
  ok_ = true;
1615
1.98k
  return {value_.at(n).first, value_.at(n).second};
1616
1.98k
}
1617
// Specialization for unsigned rational
1618
template <>
1619
11.4k
inline Rational ValueType<URational>::toRational(size_t n) const {
1620
11.4k
  ok_ = true;
1621
11.4k
  return {value_.at(n).first, value_.at(n).second};
1622
11.4k
}
1623
// Specialization for float.
1624
template <>
1625
2.75k
inline Rational ValueType<float>::toRational(size_t n) const {
1626
2.75k
  ok_ = true;
1627
  // Warning: This is a very simple conversion, see floatToRationalCast()
1628
2.75k
  return floatToRationalCast(value_.at(n));
1629
2.75k
}
1630
// Specialization for double.
1631
template <>
1632
852
inline Rational ValueType<double>::toRational(size_t n) const {
1633
852
  ok_ = true;
1634
  // Warning: This is a very simple conversion, see floatToRationalCast()
1635
852
  return floatToRationalCast(static_cast<float>(value_.at(n)));
1636
852
}
1637
1638
template <typename T>
1639
40.6k
size_t ValueType<T>::sizeDataArea() const {
1640
40.6k
  return pDataArea_.size();
1641
40.6k
}
Exiv2::ValueType<unsigned short>::sizeDataArea() const
Line
Count
Source
1639
4.46k
size_t ValueType<T>::sizeDataArea() const {
1640
4.46k
  return pDataArea_.size();
1641
4.46k
}
Exiv2::ValueType<unsigned int>::sizeDataArea() const
Line
Count
Source
1639
5.90k
size_t ValueType<T>::sizeDataArea() const {
1640
5.90k
  return pDataArea_.size();
1641
5.90k
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::sizeDataArea() const
Line
Count
Source
1639
2.63k
size_t ValueType<T>::sizeDataArea() const {
1640
2.63k
  return pDataArea_.size();
1641
2.63k
}
Exiv2::ValueType<short>::sizeDataArea() const
Line
Count
Source
1639
3.47k
size_t ValueType<T>::sizeDataArea() const {
1640
3.47k
  return pDataArea_.size();
1641
3.47k
}
Exiv2::ValueType<int>::sizeDataArea() const
Line
Count
Source
1639
5.32k
size_t ValueType<T>::sizeDataArea() const {
1640
5.32k
  return pDataArea_.size();
1641
5.32k
}
Exiv2::ValueType<std::__1::pair<int, int> >::sizeDataArea() const
Line
Count
Source
1639
3.33k
size_t ValueType<T>::sizeDataArea() const {
1640
3.33k
  return pDataArea_.size();
1641
3.33k
}
Exiv2::ValueType<float>::sizeDataArea() const
Line
Count
Source
1639
5.61k
size_t ValueType<T>::sizeDataArea() const {
1640
5.61k
  return pDataArea_.size();
1641
5.61k
}
Exiv2::ValueType<double>::sizeDataArea() const
Line
Count
Source
1639
9.88k
size_t ValueType<T>::sizeDataArea() const {
1640
9.88k
  return pDataArea_.size();
1641
9.88k
}
1642
1643
template <typename T>
1644
4.91k
DataBuf ValueType<T>::dataArea() const {
1645
4.91k
  return {pDataArea_.data(), pDataArea_.size()};
1646
4.91k
}
Exiv2::ValueType<unsigned short>::dataArea() const
Line
Count
Source
1644
850
DataBuf ValueType<T>::dataArea() const {
1645
850
  return {pDataArea_.data(), pDataArea_.size()};
1646
850
}
Exiv2::ValueType<unsigned int>::dataArea() const
Line
Count
Source
1644
849
DataBuf ValueType<T>::dataArea() const {
1645
849
  return {pDataArea_.data(), pDataArea_.size()};
1646
849
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::dataArea() const
Line
Count
Source
1644
373
DataBuf ValueType<T>::dataArea() const {
1645
373
  return {pDataArea_.data(), pDataArea_.size()};
1646
373
}
Exiv2::ValueType<short>::dataArea() const
Line
Count
Source
1644
409
DataBuf ValueType<T>::dataArea() const {
1645
409
  return {pDataArea_.data(), pDataArea_.size()};
1646
409
}
Exiv2::ValueType<int>::dataArea() const
Line
Count
Source
1644
659
DataBuf ValueType<T>::dataArea() const {
1645
659
  return {pDataArea_.data(), pDataArea_.size()};
1646
659
}
Exiv2::ValueType<std::__1::pair<int, int> >::dataArea() const
Line
Count
Source
1644
133
DataBuf ValueType<T>::dataArea() const {
1645
133
  return {pDataArea_.data(), pDataArea_.size()};
1646
133
}
Exiv2::ValueType<float>::dataArea() const
Line
Count
Source
1644
306
DataBuf ValueType<T>::dataArea() const {
1645
306
  return {pDataArea_.data(), pDataArea_.size()};
1646
306
}
Exiv2::ValueType<double>::dataArea() const
Line
Count
Source
1644
1.33k
DataBuf ValueType<T>::dataArea() const {
1645
1.33k
  return {pDataArea_.data(), pDataArea_.size()};
1646
1.33k
}
1647
1648
template <typename T>
1649
10.5k
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
10.5k
  if (len > 0)
1651
7.14k
    pDataArea_ = Blob(buf, buf + len);
1652
3.41k
  else
1653
3.41k
    pDataArea_.clear();
1654
10.5k
  return 0;
1655
10.5k
}
Exiv2::ValueType<unsigned short>::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
2.02k
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
2.02k
  if (len > 0)
1651
1.37k
    pDataArea_ = Blob(buf, buf + len);
1652
652
  else
1653
652
    pDataArea_.clear();
1654
2.02k
  return 0;
1655
2.02k
}
Exiv2::ValueType<unsigned int>::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
891
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
891
  if (len > 0)
1651
525
    pDataArea_ = Blob(buf, buf + len);
1652
366
  else
1653
366
    pDataArea_.clear();
1654
891
  return 0;
1655
891
}
Exiv2::ValueType<std::__1::pair<unsigned int, unsigned int> >::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
1.23k
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
1.23k
  if (len > 0)
1651
904
    pDataArea_ = Blob(buf, buf + len);
1652
329
  else
1653
329
    pDataArea_.clear();
1654
1.23k
  return 0;
1655
1.23k
}
Exiv2::ValueType<short>::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
839
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
839
  if (len > 0)
1651
420
    pDataArea_ = Blob(buf, buf + len);
1652
419
  else
1653
419
    pDataArea_.clear();
1654
839
  return 0;
1655
839
}
Exiv2::ValueType<int>::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
1.00k
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
1.00k
  if (len > 0)
1651
581
    pDataArea_ = Blob(buf, buf + len);
1652
424
  else
1653
424
    pDataArea_.clear();
1654
1.00k
  return 0;
1655
1.00k
}
Exiv2::ValueType<std::__1::pair<int, int> >::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
1.82k
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
1.82k
  if (len > 0)
1651
1.24k
    pDataArea_ = Blob(buf, buf + len);
1652
584
  else
1653
584
    pDataArea_.clear();
1654
1.82k
  return 0;
1655
1.82k
}
Exiv2::ValueType<float>::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
1.81k
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
1.81k
  if (len > 0)
1651
1.43k
    pDataArea_ = Blob(buf, buf + len);
1652
372
  else
1653
372
    pDataArea_.clear();
1654
1.81k
  return 0;
1655
1.81k
}
Exiv2::ValueType<double>::setDataArea(unsigned char const*, unsigned long)
Line
Count
Source
1649
928
int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1650
928
  if (len > 0)
1651
661
    pDataArea_ = Blob(buf, buf + len);
1652
267
  else
1653
267
    pDataArea_.clear();
1654
928
  return 0;
1655
928
}
1656
}  // namespace Exiv2
1657
1658
#endif  // EXIV2_VALUE_HPP