Exiv2
value.hpp
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #ifndef VALUE_HPP_
4 #define 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 
33 class EXIV2API Value {
34  public:
36  using UniquePtr = std::unique_ptr<Value>;
37 
39 
40  explicit Value(TypeId typeId);
43  virtual ~Value() = default;
45 
47 
48 
54  virtual int read(const byte* buf, size_t len, ByteOrder byteOrder) = 0;
55 
66  virtual int read(const std::string& buf) = 0;
79  virtual int setDataArea(const byte* buf, size_t len);
81 
83 
84  TypeId typeId() const {
86  return type_;
87  }
93  UniquePtr clone() const {
94  return UniquePtr(clone_());
95  }
106  virtual size_t copy(byte* buf, ByteOrder byteOrder) const = 0;
108  virtual size_t count() const = 0;
110  virtual size_t size() const = 0;
117  virtual std::ostream& write(std::ostream& os) const = 0;
122  std::string toString() const;
129  virtual std::string toString(size_t n) const;
137  virtual int64_t toInt64(size_t n = 0) const = 0;
145  virtual uint32_t toUint32(size_t n = 0) const = 0;
153  virtual float toFloat(size_t n = 0) const = 0;
161  virtual Rational toRational(size_t n = 0) const = 0;
163  virtual size_t sizeDataArea() const;
176  virtual DataBuf dataArea() const;
181  bool ok() const {
182  return ok_;
183  }
185 
222  static UniquePtr create(TypeId typeId);
223 
224  protected:
225  Value(const Value&) = default;
230  Value& operator=(const Value&) = default;
231  // DATA
232  mutable bool ok_{true};
233 
234  private:
236  virtual Value* clone_() const = 0;
237  // DATA
238  TypeId type_;
239 };
240 
242 inline std::ostream& operator<<(std::ostream& os, const Value& value) {
243  return value.write(os);
244 }
245 
247 class EXIV2API DataValue : public Value {
248  public:
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 
257 
258  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
260  int read(const std::string& buf) override;
262 
264 
265  UniquePtr clone() const {
266  return UniquePtr(clone_());
267  }
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;
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;
296 
297  private:
299  DataValue* clone_() const override;
300 
302  using ValueType = std::vector<byte>;
303  // DATA
304  ValueType value_;
305 
306 }; // class DataValue
307 
314 class EXIV2API StringValueBase : public Value {
315  using Value::Value;
316 
317  public:
319  using UniquePtr = std::unique_ptr<StringValueBase>;
320 
322 
323  StringValueBase(TypeId typeId, const std::string& buf);
326 
328 
329  int read(const std::string& buf) override;
331  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
333 
335 
336  UniquePtr clone() const {
337  return UniquePtr(clone_());
338  }
352  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
353  size_t count() const override;
354  size_t size() const override;
355  int64_t toInt64(size_t n = 0) const override;
356  uint32_t toUint32(size_t n = 0) const override;
357  float toFloat(size_t n = 0) const override;
358  Rational toRational(size_t n = 0) const override;
359  std::ostream& write(std::ostream& os) const override;
361 
362  protected:
364  StringValueBase* clone_() const override = 0;
365 
366  public:
367  // DATA
368  std::string value_;
369 
370 }; // class StringValueBase
371 
379 class EXIV2API StringValue : public StringValueBase {
380  public:
382  using UniquePtr = std::unique_ptr<StringValue>;
383 
385 
386  StringValue();
389  explicit StringValue(const std::string& buf);
391 
393 
394  UniquePtr clone() const {
395  return UniquePtr(clone_());
396  }
398 
399  private:
401  StringValue* clone_() const override;
402 
403 }; // class StringValue
404 
411 class EXIV2API AsciiValue : public StringValueBase {
412  public:
414  using UniquePtr = std::unique_ptr<AsciiValue>;
415 
417 
418  AsciiValue();
421  explicit AsciiValue(const std::string& buf);
423 
425 
426  using StringValueBase::read;
432  int read(const std::string& buf) override;
434 
436 
437  UniquePtr clone() const {
438  return UniquePtr(clone_());
439  }
445  std::ostream& write(std::ostream& os) const override;
447 
448  private:
450  AsciiValue* clone_() const override;
451 
452 }; // class AsciiValue
453 
462 class EXIV2API CommentValue : public StringValueBase {
463  public:
465  enum CharsetId { ascii, jis, unicode, undefined, invalidCharsetId, lastCharsetId };
467  struct CharsetTable {
469  const char* name_;
470  const char* code_;
471  }; // struct CharsetTable
472 
474  class EXIV2API CharsetInfo {
475  public:
477  static const char* name(CharsetId charsetId);
479  static const char* code(CharsetId charsetId);
481  static CharsetId charsetIdByName(const std::string& name);
483  static CharsetId charsetIdByCode(const std::string& code);
484 
485  private:
486  static const CharsetTable charsetTable_[];
487  }; // class CharsetInfo
488 
490  using UniquePtr = std::unique_ptr<CommentValue>;
491 
493 
494  CommentValue();
497  explicit CommentValue(const std::string& comment);
499 
501 
502 
514  int read(const std::string& comment) override;
515  int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
517 
519 
520  UniquePtr clone() const {
521  return UniquePtr(clone_());
522  }
523  size_t copy(byte* buf, ByteOrder byteOrder) const override;
528  std::ostream& write(std::ostream& os) const override;
543  std::string comment(const char* encoding = nullptr) const;
553  const char* detectCharset(std::string& c) const;
555  CharsetId charsetId() const;
557 
558  private:
560  CommentValue* clone_() const override;
561 
562  public:
563  // DATA
564  ByteOrder byteOrder_{littleEndian};
565 
566 }; // class CommentValue
567 
571 class EXIV2API XmpValue : public Value {
572  using Value::Value;
573 
574  public:
576  using UniquePtr = std::unique_ptr<XmpValue>;
577 
579  enum XmpArrayType { xaNone, xaAlt, xaBag, xaSeq };
581  enum XmpStruct { xsNone, xsStruct };
582 
584 
585  XmpArrayType xmpArrayType() const;
588  XmpStruct xmpStruct() const;
589  size_t size() const override;
603  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
605 
607 
608  void setXmpArrayType(XmpArrayType xmpArrayType);
611  void setXmpStruct(XmpStruct xmpStruct = xsStruct);
612 
614  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
615  int read(const std::string& buf) override = 0;
617 
622  static XmpArrayType xmpArrayType(TypeId typeId);
623 
624  private:
625  // DATA
626  XmpArrayType xmpArrayType_{xaNone};
627  XmpStruct xmpStruct_{xsNone};
628 
629 }; // class XmpValue
630 
638 class EXIV2API XmpTextValue : public XmpValue {
639  public:
641  using UniquePtr = std::unique_ptr<XmpTextValue>;
642 
644 
645  XmpTextValue();
648  explicit XmpTextValue(const std::string& buf);
650 
652 
653  using XmpValue::read;
669  int read(const std::string& buf) override;
671 
673 
674  UniquePtr clone() const;
675  size_t size() const override;
676  size_t count() const override;
683  int64_t toInt64(size_t n = 0) const override;
690  uint32_t toUint32(size_t n = 0) const override;
697  float toFloat(size_t n = 0) const override;
704  Rational toRational(size_t n = 0) const override;
705  std::ostream& write(std::ostream& os) const override;
707 
708  private:
710  XmpTextValue* clone_() const override;
711 
712  public:
713  // DATA
714  std::string value_;
715 
716 }; // class XmpTextValue
717 
727 class EXIV2API XmpArrayValue : public XmpValue {
728  public:
730  using UniquePtr = std::unique_ptr<XmpArrayValue>;
731 
733 
734  explicit XmpArrayValue(TypeId typeId = xmpBag);
737 
739 
740  using XmpValue::read;
751  int read(const std::string& buf) override;
753 
755 
756  UniquePtr clone() const;
757  size_t count() const override;
763  std::string toString(size_t n) const override;
764  int64_t toInt64(size_t n = 0) const override;
765  uint32_t toUint32(size_t n = 0) const override;
766  float toFloat(size_t n = 0) const override;
767  Rational toRational(size_t n = 0) const override;
774  std::ostream& write(std::ostream& os) const override;
776 
777  private:
779  XmpArrayValue* clone_() const override;
780 
781  std::vector<std::string> value_;
782 
783 }; // class XmpArrayValue
784 
794  bool operator()(const std::string& str1, const std::string& str2) const {
795  int result = str1.size() < str2.size() ? 1 : str1.size() > str2.size() ? -1 : 0;
796  if (result == 0) {
797  for (auto c1 = str1.begin(), c2 = str2.begin(); result == 0 && c1 != str1.end(); ++c1, ++c2) {
798  result = tolower(*c1) < tolower(*c2) ? 1 : tolower(*c1) > tolower(*c2) ? -1 : 0;
799  }
800  }
801  return result < 0;
802  }
803 };
804 
811 class EXIV2API LangAltValue : public XmpValue {
812  public:
814  using UniquePtr = std::unique_ptr<LangAltValue>;
815 
817 
818  LangAltValue();
821  explicit LangAltValue(const std::string& buf);
823 
825 
826  using XmpValue::read;
844  int read(const std::string& buf) override;
846 
848 
849  UniquePtr clone() const;
850  size_t count() const override;
858  std::string toString(size_t n) const override;
864  std::string toString(const std::string& qualifier) const;
865  int64_t toInt64(size_t n = 0) const override;
866  uint32_t toUint32(size_t n = 0) const override;
867  float toFloat(size_t n = 0) const override;
868  Rational toRational(size_t n = 0) const override;
875  std::ostream& write(std::ostream& os) const override;
877 
878  private:
880  LangAltValue* clone_() const override;
881 
882  public:
884  using ValueType = std::map<std::string, std::string, LangAltValueComparator>;
885  // DATA
891 
892 }; // class LangAltValue
893 
900 class EXIV2API DateValue : public Value {
901  public:
903  using UniquePtr = std::unique_ptr<DateValue>;
904 
906 
907  DateValue();
910  DateValue(int32_t year, int32_t month, int32_t day);
912 
914  struct EXIV2API Date {
915  int32_t year;
916  int32_t month;
917  int32_t day;
918  };
919 
921 
922 
925  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
934  int read(const std::string& buf) override;
936  void setDate(const Date& src);
938 
940 
941  UniquePtr clone() const {
942  return UniquePtr(clone_());
943  }
957  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
958 
960  virtual const Date& getDate() const;
961  size_t count() const override;
962  size_t size() const override;
963  std::ostream& write(std::ostream& os) const override;
965  int64_t toInt64(size_t n = 0) const override;
967  uint32_t toUint32(size_t n = 0) const override;
969  float toFloat(size_t n = 0) const override;
971  Rational toRational(size_t n = 0) const override;
973 
974  private:
976  DateValue* clone_() const override;
977 
978  // DATA
979  Date date_;
980 
981 }; // class DateValue
982 
991 class EXIV2API TimeValue : public Value {
992  public:
994  using UniquePtr = std::unique_ptr<TimeValue>;
995 
997 
998  TimeValue();
1001  TimeValue(int32_t hour, int32_t minute, int32_t second = 0, int32_t tzHour = 0, int32_t tzMinute = 0);
1003 
1005  struct Time {
1006  int32_t hour;
1007  int32_t minute;
1008  int32_t second;
1009  int32_t tzHour;
1010  int32_t tzMinute;
1011  };
1012 
1014 
1015 
1018  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
1027  int read(const std::string& buf) override;
1029  void setTime(const Time& src);
1031 
1033 
1034  UniquePtr clone() const {
1035  return UniquePtr(clone_());
1036  }
1050  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
1052  virtual const Time& getTime() const;
1053  size_t count() const override;
1054  size_t size() const override;
1055  std::ostream& write(std::ostream& os) const override;
1057  int64_t toInt64(size_t n = 0) const override;
1059  uint32_t toUint32(size_t n = 0) const override;
1061  float toFloat(size_t n = 0) const override;
1063  Rational toRational(size_t n = 0) const override;
1065 
1066  private:
1068 
1069  TimeValue* clone_() const override;
1072 
1073  // DATA
1074  Time time_;
1075 
1076 }; // class TimeValue
1077 
1079 template <typename T>
1080 TypeId getType();
1081 
1083 template <>
1085  return unsignedShort;
1086 }
1088 template <>
1090  return unsignedLong;
1091 }
1093 template <>
1095  return unsignedRational;
1096 }
1098 template <>
1100  return signedShort;
1101 }
1103 template <>
1105  return signedLong;
1106 }
1108 template <>
1110  return signedRational;
1111 }
1113 template <>
1115  return tiffFloat;
1116 }
1118 template <>
1120  return tiffDouble;
1121 }
1122 
1123 // No default implementation: let the compiler/linker complain
1124 // template<typename T> inline TypeId getType() { return invalid; }
1125 
1130 template <typename T>
1131 class ValueType : public Value {
1132  using Value::Value;
1133 
1134  public:
1136  using UniquePtr = std::unique_ptr<ValueType<T>>;
1137 
1139 
1140  ValueType();
1143  ValueType(const byte* buf, size_t len, ByteOrder byteOrder, TypeId typeId = getType<T>());
1145  explicit ValueType(const T& val, TypeId typeId = getType<T>());
1147  ValueType(const ValueType<T>& rhs);
1149  ~ValueType() override;
1151 
1153 
1154  ValueType<T>& operator=(const ValueType<T>& rhs);
1156  int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
1163  int read(const std::string& buf) override;
1168  int setDataArea(const byte* buf, size_t len) override;
1170 
1172 
1173  UniquePtr clone() const {
1174  return UniquePtr(clone_());
1175  }
1176  size_t copy(byte* buf, ByteOrder byteOrder) const override;
1177  size_t count() const override;
1178  size_t size() const override;
1179  std::ostream& write(std::ostream& os) const override;
1186  std::string toString(size_t n) const override;
1187  int64_t toInt64(size_t n = 0) const override;
1188  uint32_t toUint32(size_t n = 0) const override;
1189  float toFloat(size_t n = 0) const override;
1190  Rational toRational(size_t n = 0) const override;
1192  size_t sizeDataArea() const override;
1197  DataBuf dataArea() const override;
1199 
1201  using ValueList = std::vector<T>;
1203  using iterator = typename std::vector<T>::iterator;
1205  using const_iterator = typename std::vector<T>::const_iterator;
1206 
1207  // DATA
1215 
1216  private:
1218  template <typename I>
1219  inline I float_to_integer_helper(size_t n) const {
1220  const auto v = value_.at(n);
1221  if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
1222  v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
1223  return static_cast<I>(std::round(v));
1224  }
1225  return 0;
1226  }
1227 
1229  template <typename I>
1230  inline I rational_to_integer_helper(size_t n) const {
1231  auto a = value_.at(n).first;
1232  auto b = value_.at(n).second;
1233 
1234  // Protect against divide-by-zero.
1235  if (b <= 0) {
1236  return 0;
1237  }
1238 
1239  // Check for integer overflow.
1240 #ifdef __cpp_if_constexpr
1241  if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
1242 #else
1243  if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
1244 #endif
1245  // conversion does not change sign
1246  const auto imin = std::numeric_limits<I>::min();
1247  const auto imax = std::numeric_limits<I>::max();
1248  if (imax < b || a < imin || imax < a) {
1249  return 0;
1250  }
1251 #ifdef __cpp_if_constexpr
1252  } else if constexpr (std::is_signed_v<I>) {
1253 #else
1254  } else if (std::is_signed<I>::value) {
1255 #endif
1256  // conversion is from unsigned to signed
1257 #if __cplusplus >= 201402L || _MSVC_LANG >= 201402L
1258  const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
1259 #else
1260  const auto imax = static_cast<typename std::make_unsigned<I>::type>(std::numeric_limits<I>::max());
1261 #endif
1262  if (imax < b || imax < a) {
1263  return 0;
1264  }
1265  } else {
1266  // conversion is from signed to unsigned
1267  const auto imax = std::numeric_limits<I>::max();
1268  if (a < 0) {
1269  return 0;
1270  }
1271  // Inputs are not negative so convert them to unsigned.
1272 #if __cplusplus >= 201402L || _MSVC_LANG >= 201402L
1273  const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
1274  const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
1275 #else
1276  const auto a_u = static_cast<typename std::make_unsigned<decltype(a)>::type>(a);
1277  const auto b_u = static_cast<typename std::make_unsigned<decltype(b)>::type>(b);
1278 #endif
1279  if (imax < b_u || imax < a_u) {
1280  return 0;
1281  }
1282  }
1283 
1284  return static_cast<I>(a) / static_cast<I>(b);
1285  }
1286 
1288  ValueType<T>* clone_() const override;
1289 
1290  // DATA
1292  byte* pDataArea_{nullptr};
1294  size_t sizeDataArea_{0};
1295 }; // class ValueType
1296 
1313 
1314 // *****************************************************************************
1315 // free functions, template and inline definitions
1316 
1328 template <typename T>
1329 T getValue(const byte* buf, ByteOrder byteOrder);
1330 // Specialization for a 2 byte unsigned short value.
1331 template <>
1332 inline uint16_t getValue(const byte* buf, ByteOrder byteOrder) {
1333  return getUShort(buf, byteOrder);
1334 }
1335 // Specialization for a 4 byte unsigned long value.
1336 template <>
1337 inline uint32_t getValue(const byte* buf, ByteOrder byteOrder) {
1338  return getULong(buf, byteOrder);
1339 }
1340 // Specialization for an 8 byte unsigned rational value.
1341 template <>
1342 inline URational getValue(const byte* buf, ByteOrder byteOrder) {
1343  return getURational(buf, byteOrder);
1344 }
1345 // Specialization for a 2 byte signed short value.
1346 template <>
1347 inline int16_t getValue(const byte* buf, ByteOrder byteOrder) {
1348  return getShort(buf, byteOrder);
1349 }
1350 // Specialization for a 4 byte signed long value.
1351 template <>
1352 inline int32_t getValue(const byte* buf, ByteOrder byteOrder) {
1353  return getLong(buf, byteOrder);
1354 }
1355 // Specialization for an 8 byte signed rational value.
1356 template <>
1357 inline Rational getValue(const byte* buf, ByteOrder byteOrder) {
1358  return getRational(buf, byteOrder);
1359 }
1360 // Specialization for a 4 byte float value.
1361 template <>
1362 inline float getValue(const byte* buf, ByteOrder byteOrder) {
1363  return getFloat(buf, byteOrder);
1364 }
1365 // Specialization for a 8 byte double value.
1366 template <>
1367 inline double getValue(const byte* buf, ByteOrder byteOrder) {
1368  return getDouble(buf, byteOrder);
1369 }
1370 
1383 template <typename T>
1384 size_t toData(byte* buf, T t, ByteOrder byteOrder);
1389 template <>
1390 inline size_t toData(byte* buf, uint16_t t, ByteOrder byteOrder) {
1391  return us2Data(buf, t, byteOrder);
1392 }
1397 template <>
1398 inline size_t toData(byte* buf, uint32_t t, ByteOrder byteOrder) {
1399  return ul2Data(buf, t, byteOrder);
1400 }
1405 template <>
1406 inline size_t toData(byte* buf, URational t, ByteOrder byteOrder) {
1407  return ur2Data(buf, t, byteOrder);
1408 }
1413 template <>
1414 inline size_t toData(byte* buf, int16_t t, ByteOrder byteOrder) {
1415  return s2Data(buf, t, byteOrder);
1416 }
1421 template <>
1422 inline size_t toData(byte* buf, int32_t t, ByteOrder byteOrder) {
1423  return l2Data(buf, t, byteOrder);
1424 }
1429 template <>
1430 inline size_t toData(byte* buf, Rational t, ByteOrder byteOrder) {
1431  return r2Data(buf, t, byteOrder);
1432 }
1437 template <>
1438 inline size_t toData(byte* buf, float t, ByteOrder byteOrder) {
1439  return f2Data(buf, t, byteOrder);
1440 }
1445 template <>
1446 inline size_t toData(byte* buf, double t, ByteOrder byteOrder) {
1447  return d2Data(buf, t, byteOrder);
1448 }
1449 
1450 template <typename T>
1452 }
1453 
1454 template <typename T>
1455 ValueType<T>::ValueType(const byte* buf, size_t len, ByteOrder byteOrder, TypeId typeId) : Value(typeId) {
1456  read(buf, len, byteOrder);
1457 }
1458 
1459 template <typename T>
1460 ValueType<T>::ValueType(const T& val, TypeId typeId) : Value(typeId) {
1461  value_.push_back(val);
1462 }
1463 
1464 template <typename T>
1466  Value(rhs.typeId()),
1467  value_(rhs.value_)
1468 
1469 {
1470  if (rhs.sizeDataArea_ > 0) {
1471  pDataArea_ = new byte[rhs.sizeDataArea_];
1472  std::memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea_);
1473  sizeDataArea_ = rhs.sizeDataArea_;
1474  }
1475 }
1476 
1477 template <typename T>
1479  delete[] pDataArea_;
1480 }
1481 
1482 template <typename T>
1484  if (this == &rhs)
1485  return *this;
1486  Value::operator=(rhs);
1487  value_ = rhs.value_;
1488 
1489  byte* tmp = nullptr;
1490  if (rhs.sizeDataArea_ > 0) {
1491  tmp = new byte[rhs.sizeDataArea_];
1492  std::memcpy(tmp, rhs.pDataArea_, rhs.sizeDataArea_);
1493  }
1494  delete[] pDataArea_;
1495  pDataArea_ = tmp;
1496  sizeDataArea_ = rhs.sizeDataArea_;
1497 
1498  return *this;
1499 }
1500 
1501 template <typename T>
1502 int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1503  value_.clear();
1504  size_t ts = TypeInfo::typeSize(typeId());
1505  if (ts > 0 && len % ts != 0)
1506  len = (len / ts) * ts;
1507  for (size_t i = 0; i < len; i += ts) {
1508  value_.push_back(getValue<T>(buf + i, byteOrder));
1509  }
1510  return 0;
1511 }
1512 
1513 template <typename T>
1514 int ValueType<T>::read(const std::string& buf) {
1515  std::istringstream is(buf);
1516  T tmp = T();
1517  ValueList val;
1518  while (!(is.eof())) {
1519  is >> tmp;
1520  if (is.fail())
1521  return 1;
1522  val.push_back(tmp);
1523  }
1524  value_.swap(val);
1525  return 0;
1526 }
1527 
1528 template <typename T>
1529 size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1530  size_t offset = 0;
1531  for (auto i = value_.begin(); i != value_.end(); ++i) {
1532  offset += toData(buf + offset, *i, byteOrder);
1533  }
1534  return offset;
1535 }
1536 
1537 template <typename T>
1538 size_t ValueType<T>::count() const {
1539  return value_.size();
1540 }
1541 
1542 template <typename T>
1543 size_t ValueType<T>::size() const {
1544  return TypeInfo::typeSize(typeId()) * value_.size();
1545 }
1546 
1547 template <typename T>
1549  return new ValueType<T>(*this);
1550 }
1551 
1552 template <typename T>
1553 std::ostream& ValueType<T>::write(std::ostream& os) const {
1554  auto end = value_.end();
1555  auto i = value_.begin();
1556  while (i != end) {
1557  os << std::setprecision(15) << *i;
1558  if (++i != end)
1559  os << " ";
1560  }
1561  return os;
1562 }
1563 
1564 template <typename T>
1565 std::string ValueType<T>::toString(size_t n) const {
1566  ok_ = true;
1567  return Exiv2::toString<T>(value_.at(n));
1568 }
1569 
1570 // Default implementation
1571 template <typename T>
1572 int64_t ValueType<T>::toInt64(size_t n) const {
1573  ok_ = true;
1574  return static_cast<int64_t>(value_.at(n));
1575 }
1576 template <typename T>
1577 uint32_t ValueType<T>::toUint32(size_t n) const {
1578  ok_ = true;
1579  return static_cast<uint32_t>(value_.at(n));
1580 }
1581 // #55 crash when value_.at(n).first == LONG_MIN
1582 #define LARGE_INT 1000000
1583 // Specialization for double
1584 template <>
1585 inline int64_t ValueType<double>::toInt64(size_t n) const {
1586  return float_to_integer_helper<int64_t>(n);
1587 }
1588 
1589 template <>
1590 inline uint32_t ValueType<double>::toUint32(size_t n) const {
1591  return float_to_integer_helper<uint32_t>(n);
1592 }
1593 // Specialization for float
1594 template <>
1595 inline int64_t ValueType<float>::toInt64(size_t n) const {
1596  return float_to_integer_helper<int64_t>(n);
1597 }
1598 template <>
1599 inline uint32_t ValueType<float>::toUint32(size_t n) const {
1600  return float_to_integer_helper<uint32_t>(n);
1601 }
1602 // Specialization for rational
1603 template <>
1604 inline int64_t ValueType<Rational>::toInt64(size_t n) const {
1605  return rational_to_integer_helper<int64_t>(n);
1606 }
1607 template <>
1608 inline uint32_t ValueType<Rational>::toUint32(size_t n) const {
1609  return rational_to_integer_helper<uint32_t>(n);
1610 }
1611 // Specialization for unsigned rational
1612 template <>
1613 inline int64_t ValueType<URational>::toInt64(size_t n) const {
1614  return rational_to_integer_helper<int64_t>(n);
1615 }
1616 template <>
1617 inline uint32_t ValueType<URational>::toUint32(size_t n) const {
1618  return rational_to_integer_helper<uint32_t>(n);
1619 }
1620 // Default implementation
1621 template <typename T>
1622 float ValueType<T>::toFloat(size_t n) const {
1623  ok_ = true;
1624  return static_cast<float>(value_.at(n));
1625 }
1626 // Specialization for rational
1627 template <>
1628 inline float ValueType<Rational>::toFloat(size_t n) const {
1629  ok_ = (value_.at(n).second != 0);
1630  if (!ok_)
1631  return 0.0f;
1632  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1633 }
1634 // Specialization for unsigned rational
1635 template <>
1636 inline float ValueType<URational>::toFloat(size_t n) const {
1637  ok_ = (value_.at(n).second != 0);
1638  if (!ok_)
1639  return 0.0f;
1640  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1641 }
1642 // Default implementation
1643 template <typename T>
1645  ok_ = true;
1646  return {value_.at(n), 1};
1647 }
1648 // Specialization for rational
1649 template <>
1651  ok_ = true;
1652  return {value_.at(n).first, value_.at(n).second};
1653 }
1654 // Specialization for unsigned rational
1655 template <>
1657  ok_ = true;
1658  return {value_.at(n).first, value_.at(n).second};
1659 }
1660 // Specialization for float.
1661 template <>
1662 inline Rational ValueType<float>::toRational(size_t n) const {
1663  ok_ = true;
1664  // Warning: This is a very simple conversion, see floatToRationalCast()
1665  return floatToRationalCast(value_.at(n));
1666 }
1667 // Specialization for double.
1668 template <>
1669 inline Rational ValueType<double>::toRational(size_t n) const {
1670  ok_ = true;
1671  // Warning: This is a very simple conversion, see floatToRationalCast()
1672  return floatToRationalCast(static_cast<float>(value_.at(n)));
1673 }
1674 
1675 template <typename T>
1677  return sizeDataArea_;
1678 }
1679 
1680 template <typename T>
1682  return {pDataArea_, sizeDataArea_};
1683 }
1684 
1685 template <typename T>
1686 int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1687  byte* tmp = nullptr;
1688  if (len > 0) {
1689  tmp = new byte[len];
1690  std::memcpy(tmp, buf, len);
1691  }
1692  delete[] pDataArea_;
1693  pDataArea_ = tmp;
1694  sizeDataArea_ = len;
1695  return 0;
1696 }
1697 } // namespace Exiv2
1698 
1699 #endif // #ifndef VALUE_HPP_
Exif SHORT type, 16-bit (2-byte) unsigned integer.
Definition: types.hpp:73
Exif SLONG type, a 32-bit (4-byte) signed (twos-complement) integer.
Definition: types.hpp:79
CharsetId charsetId_
Charset id.
Definition: value.hpp:468
EXIV2API Rational floatToRationalCast(float f)
Very simple conversion of a float to a Rational.
Definition: types.cpp:607
int32_t day
Day.
Definition: value.hpp:917
Information pertaining to the defined character sets.
Definition: value.hpp:467
~ValueType() override
Virtual destructor.
Definition: value.hpp:1478
ValueType value_
Map to store the language alternative values. The language qualifier is used as the key for the map e...
Definition: value.hpp:890
TypeId getType< uint16_t >()
Specialization for an unsigned short.
Definition: value.hpp:1084
XmpArrayType
XMP array types.
Definition: value.hpp:579
EXIV2API size_t us2Data(byte *buf, uint16_t s, ByteOrder byteOrder)
Convert an unsigned short to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:331
Exif SRATIONAL type, two SLONGs: numerator and denominator of a fraction.
Definition: types.hpp:80
DataBuf dataArea() const override
Return a copy of the data area in a DataBuf. The caller owns this copy and DataBuf ensures that it wi...
Definition: value.hpp:1681
std::map< std::string, std::string, LangAltValueComparator > ValueType
Type used to store language alternative arrays.
Definition: value.hpp:884
int read(const std::string &buf) override
Read the value from buf. This default implementation uses buf as it is.
Definition: value.cpp:177
ByteOrder
Type to express the byte order (little or big endian)
Definition: types.hpp:34
Template for a Value of a basic type. This is used for unsigned and signed short, long and rationals...
Definition: value.hpp:1131
virtual std::ostream & write(std::ostream &os) const =0
Write the value to an output stream. You do not usually have to use this function; it is used for the...
Value type suitable for simple XMP properties and XMP nodes of complex types which are not parsed int...
Definition: value.hpp:638
int32_t minute
Minute.
Definition: value.hpp:1007
T getValue(const byte *buf, ByteOrder byteOrder)
Read a value of type T from the data buffer.
Definition: value.hpp:1332
Simple Date helper structure.
Definition: value.hpp:914
Value(TypeId typeId)
Constructor, taking a type id to initialize the base class with.
Definition: value.cpp:18
TypeId
Exiv2 value type identifiers.
Definition: types.hpp:70
EXIV2API size_t f2Data(byte *buf, float f, ByteOrder byteOrder)
Convert a single precision floating point (IEEE 754 binary32) float to data, write the data to the bu...
Definition: types.cpp:410
std::unique_ptr< ValueType< T >> UniquePtr
Shortcut for a ValueType auto pointer.
Definition: value.hpp:1136
int read(const byte *buf, size_t len, ByteOrder byteOrder) override
Read the value from a character buffer.
Definition: value.hpp:1502
size_t count() const override
Return the number of components of the value.
Definition: value.hpp:1538
EXIV2API double getDouble(const byte *buf, ByteOrder byteOrder)
Read an 8 byte double precision floating point value (IEEE 754 binary64) from the data buffer...
Definition: types.cpp:308
static size_t typeSize(TypeId typeId)
Return the size in bytes of one element of this type.
Definition: types.cpp:83
EXIV2API int16_t getShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte signed short value from the data buffer.
Definition: types.cpp:276
std::string toString() const
Return the value as a string. Implemented in terms of write(std::ostream& os) const of the concrete c...
Definition: value.cpp:73
uint8_t byte
1 byte unsigned integer type.
Definition: types.hpp:26
Value for simple ISO 8601 times.
Definition: value.hpp:991
Value & operator=(const Value &)=default
Assignment operator. Protected so that it can only be used by subclasses but not directly.
Value for an Ascii string type.
Definition: value.hpp:411
Value type for simple arrays. Each item in the array is a simple value, without qualifiers. The array may be an ordered (seq), unordered (bag) or alternative array (alt). The array items must not contain qualifiers. For language alternatives use LangAltValue.
Definition: value.hpp:727
std::string toString(const T &arg)
Utility function to convert the argument of any type to a string.
Definition: types.hpp:456
Utility class containing a character array. All it does is to take care of memory allocation and dele...
Definition: types.hpp:124
Exif UNDEFINED type, an 8-bit byte that may contain anything.
Definition: types.hpp:77
typename std::vector< T >::const_iterator const_iterator
Const iterator type defined for convenience.
Definition: value.hpp:1205
Value type for XMP language alternative properties.
Definition: value.hpp:811
ValueList value_
The container for all values. In your application, if you know what subclass of Value you're dealing ...
Definition: value.hpp:1214
Charset information lookup functions. Implemented as a static class.
Definition: value.hpp:474
XMP bag type.
Definition: types.hpp:94
int32_t month
Month.
Definition: value.hpp:916
int32_t second
Second.
Definition: value.hpp:1008
Exif LONG type, 32-bit (4-byte) unsigned integer.
Definition: types.hpp:74
EXIV2API URational getURational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte unsigned rational value from the data buffer.
Definition: types.cpp:270
Rational toRational(size_t n=0) const override
Convert the n-th component of the value to a Rational. The behaviour of this method may be undefined ...
Definition: value.hpp:1644
uint32_t toUint32(size_t n=0) const override
Convert the n-th component of the value to a float. The behaviour of this method may be undefined if ...
Definition: value.hpp:1577
std::string value_
Stores the string value.
Definition: value.hpp:368
TypeId getType< int16_t >()
Specialization for a signed short.
Definition: value.hpp:1099
LangAltValueComparator
Definition: value.hpp:792
std::ostream & write(std::ostream &os) const override
Write the value to an output stream. You do not usually have to use this function; it is used for the...
Definition: value.hpp:1553
std::pair< int32_t, int32_t > Rational
8 byte signed rational type.
Definition: types.hpp:31
int64_t toInt64(size_t n=0) const override
Convert the n-th component of the value to an int64_t. The behaviour of this method may be undefined ...
Definition: value.hpp:1572
TypeId getType()
Template to determine the TypeId for a type T.
EXIV2API size_t r2Data(byte *buf, Rational l, ByteOrder byteOrder)
Convert a signed rational to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:404
Exif RATIONAL type, two LONGs: numerator and denominator of a fraction.
Definition: types.hpp:75
TypeId getType< uint32_t >()
Specialization for an unsigned long.
Definition: value.hpp:1089
Value for an undefined data type.
Definition: value.hpp:247
TypeId typeId() const
Return the type identifier (Exif data format type).
Definition: value.hpp:85
size_t toData(byte *buf, T t, ByteOrder byteOrder)
Convert a value of type T to data, write the data to the data buffer.
EXIV2API size_t l2Data(byte *buf, int32_t l, ByteOrder byteOrder)
Convert a signed long to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:389
ValueType()
Default Constructor.
Definition: value.hpp:1451
TIFF DOUBLE type, double precision (8-byte) IEEE format.
Definition: types.hpp:82
int read(const byte *buf, size_t len, ByteOrder byteOrder=invalidByteOrder) override
Definition: value.cpp:462
Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
Definition: types.hpp:78
XmpStruct
XMP structure indicator.
Definition: value.hpp:581
Value for an Exif comment.
Definition: value.hpp:462
std::string value_
Stores the string values.
Definition: value.hpp:714
TIFF FLOAT type, single precision (4-byte) IEEE format.
Definition: types.hpp:81
int32_t tzHour
Hours ahead or behind UTC.
Definition: value.hpp:1009
EXIV2API size_t ur2Data(byte *buf, URational l, ByteOrder byteOrder)
Convert an unsigned rational to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:372
Base class for all Exiv2 values used to store XMP property values.
Definition: value.hpp:571
EXIV2API int32_t getLong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte signed long value from the data buffer.
Definition: types.cpp:283
int32_t hour
Hour.
Definition: value.hpp:1006
int32_t year
Year.
Definition: value.hpp:915
EXIV2API uint32_t getULong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte unsigned long value from the data buffer.
Definition: types.cpp:250
std::vector< T > ValueList
Container for values.
Definition: value.hpp:1201
Common interface for all types of values used with metadata.
Definition: value.hpp:33
size_t copy(byte *buf, ByteOrder byteOrder) const override
Write value to a data buffer.
Definition: value.hpp:1529
const char * name_
Name of the charset.
Definition: value.hpp:469
int setDataArea(const byte *buf, size_t len) override
Set the data area. This method copies (clones) the buffer pointed to by buf.
Definition: value.hpp:1686
ValueType< T > & operator=(const ValueType< T > &rhs)
Assignment operator.
Definition: value.hpp:1483
Class CrwImage to access Canon CRW images. References: The Canon RAW (CRW) File Format by Phil Harv...
Definition: asfvideo.hpp:15
CharsetId
Character set identifiers for the character sets defined by Exif.
Definition: value.hpp:465
float toFloat(size_t n=0) const override
Convert the n-th component of the value to a float. The behaviour of this method may be undefined if ...
Definition: value.hpp:1622
std::pair< uint32_t, uint32_t > URational
8 byte unsigned rational type.
Definition: types.hpp:29
EXIV2API std::ostream & operator<<(std::ostream &os, const DataSet &dataSet)
Output operator for dataSet.
Definition: datasets.cpp:592
EXIV2API size_t d2Data(byte *buf, double d, ByteOrder byteOrder)
Convert a double precision floating point (IEEE 754 binary64) double to data, write the data to the b...
Definition: types.cpp:422
const char * code_
Code of the charset.
Definition: value.hpp:470
Exiv2 type for the Exif user comment.
Definition: types.hpp:90
TypeId getType< double >()
Specialization for a double.
Definition: value.hpp:1119
EXIV2API size_t s2Data(byte *buf, int16_t s, ByteOrder byteOrder)
Convert a signed short to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:378
size_t sizeDataArea() const override
Return the size of the data area.
Definition: value.hpp:1676
size_t size() const override
Return the size of the value in bytes.
Definition: value.hpp:1543
Abstract base class for a string based Value type.
Definition: value.hpp:314
Value for simple ISO 8601 dates
Definition: value.hpp:900
EXIV2API Rational getRational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte signed rational value from the data buffer.
Definition: types.cpp:290
Value for string type.
Definition: value.hpp:379
TypeId getType< Rational >()
Specialization for a signed rational.
Definition: value.hpp:1109
int32_t tzMinute
Minutes ahead or behind UTC.
Definition: value.hpp:1010
EXIV2API size_t ul2Data(byte *buf, uint32_t l, ByteOrder byteOrder)
Convert an unsigned long to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:342
Simple Time helper structure.
Definition: value.hpp:1005
std::unique_ptr< Value > UniquePtr
Shortcut for a Value auto pointer.
Definition: value.hpp:36
TypeId getType< float >()
Specialization for a float.
Definition: value.hpp:1114
EXIV2API float getFloat(const byte *buf, ByteOrder byteOrder)
Read a 4 byte single precision floating point value (IEEE 754 binary32) from the data buffer...
Definition: types.cpp:296
bool ok() const
Check the ok status indicator. After a to conversion, this indicator shows whether the conversi...
Definition: value.hpp:181
bool operator()(const std::string &str1, const std::string &str2) const
LangAltValueComparator comparison case insensitive function.
Definition: value.hpp:794
TypeId getType< int32_t >()
Specialization for a signed long.
Definition: value.hpp:1104
UniquePtr clone() const
Return an auto-pointer to a copy of itself (deep copy). The caller owns this copy and the auto-pointe...
Definition: value.hpp:93
typename std::vector< T >::iterator iterator
Iterator type defined for convenience.
Definition: value.hpp:1203
EXIV2API uint16_t getUShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte unsigned short value from the data buffer.
Definition: types.cpp:246
TypeId getType< URational >()
Specialization for an unsigned rational.
Definition: value.hpp:1094