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 
301  public:
303  using ValueType = std::vector<byte>;
304  // DATA
306 
307 }; // class DataValue
308 
315 class EXIV2API StringValueBase : public Value {
316  using Value::Value;
317 
318  public:
320  using UniquePtr = std::unique_ptr<StringValueBase>;
321 
323 
324  StringValueBase(TypeId typeId, const std::string& buf);
327 
329 
330  int read(const std::string& buf) override;
332  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
334 
336 
337  UniquePtr clone() const {
338  return UniquePtr(clone_());
339  }
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;
362 
363  protected:
365  StringValueBase* clone_() const override = 0;
366 
367  public:
368  // DATA
369  std::string value_;
370 
371 }; // class StringValueBase
372 
380 class EXIV2API StringValue : public StringValueBase {
381  public:
383  using UniquePtr = std::unique_ptr<StringValue>;
384 
386 
387  StringValue();
390  explicit StringValue(const std::string& buf);
392 
394 
395  UniquePtr clone() const {
396  return UniquePtr(clone_());
397  }
399 
400  private:
402  StringValue* clone_() const override;
403 
404 }; // class StringValue
405 
412 class EXIV2API AsciiValue : public StringValueBase {
413  public:
415  using UniquePtr = std::unique_ptr<AsciiValue>;
416 
418 
419  AsciiValue();
422  explicit AsciiValue(const std::string& buf);
424 
426 
427  using StringValueBase::read;
433  int read(const std::string& buf) override;
435 
437 
438  UniquePtr clone() const {
439  return UniquePtr(clone_());
440  }
446  std::ostream& write(std::ostream& os) const override;
448 
449  private:
451  AsciiValue* clone_() const override;
452 
453 }; // class AsciiValue
454 
463 class EXIV2API CommentValue : public StringValueBase {
464  public:
466  enum CharsetId { ascii, jis, unicode, undefined, invalidCharsetId, lastCharsetId };
468  struct CharsetTable {
470  const char* name_;
471  const char* code_;
472  };
473 
475  class EXIV2API CharsetInfo {
476  public:
478  static const char* name(CharsetId charsetId);
480  static const char* code(CharsetId charsetId);
482  static CharsetId charsetIdByName(const std::string& name);
484  static CharsetId charsetIdByCode(const std::string& code);
485 
486  private:
487  static const CharsetTable charsetTable_[];
488  }; // class CharsetInfo
489 
491  using UniquePtr = std::unique_ptr<CommentValue>;
492 
494 
495  CommentValue();
498  explicit CommentValue(const std::string& comment);
500 
502 
503 
515  int read(const std::string& comment) override;
516  int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
518 
520 
521  UniquePtr clone() const {
522  return UniquePtr(clone_());
523  }
524  size_t copy(byte* buf, ByteOrder byteOrder) const override;
529  std::ostream& write(std::ostream& os) const override;
544  std::string comment(const char* encoding = nullptr) const;
554  const char* detectCharset(std::string& c) const;
556  CharsetId charsetId() const;
558 
559  private:
561  CommentValue* clone_() const override;
562 
563  public:
564  // DATA
565  ByteOrder byteOrder_{littleEndian};
566 
567 }; // class CommentValue
568 
572 class EXIV2API XmpValue : public Value {
573  using Value::Value;
574 
575  public:
577  using UniquePtr = std::unique_ptr<XmpValue>;
578 
580  enum XmpArrayType { xaNone, xaAlt, xaBag, xaSeq };
582  enum XmpStruct { xsNone, xsStruct };
583 
585 
586  XmpArrayType xmpArrayType() const;
589  XmpStruct xmpStruct() const;
590  size_t size() const override;
604  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
606 
608 
609  void setXmpArrayType(XmpArrayType xmpArrayType);
612  void setXmpStruct(XmpStruct xmpStruct = xsStruct);
613 
615  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
616  int read(const std::string& buf) override = 0;
618 
623  static XmpArrayType xmpArrayType(TypeId typeId);
624 
625  private:
626  // DATA
627  XmpArrayType xmpArrayType_{xaNone};
628  XmpStruct xmpStruct_{xsNone};
629 
630 }; // class XmpValue
631 
639 class EXIV2API XmpTextValue : public XmpValue {
640  public:
642  using UniquePtr = std::unique_ptr<XmpTextValue>;
643 
645 
646  XmpTextValue();
649  explicit XmpTextValue(const std::string& buf);
651 
653 
654  using XmpValue::read;
670  int read(const std::string& buf) override;
672 
674 
675  UniquePtr clone() const;
676  size_t size() const override;
677  size_t count() const override;
684  int64_t toInt64(size_t n = 0) const override;
691  uint32_t toUint32(size_t n = 0) const override;
698  float toFloat(size_t n = 0) const override;
705  Rational toRational(size_t n = 0) const override;
706  std::ostream& write(std::ostream& os) const override;
708 
709  private:
711  XmpTextValue* clone_() const override;
712 
713  public:
714  // DATA
715  std::string value_;
716 
717 }; // class XmpTextValue
718 
728 class EXIV2API XmpArrayValue : public XmpValue {
729  public:
731  using UniquePtr = std::unique_ptr<XmpArrayValue>;
732 
734 
735  explicit XmpArrayValue(TypeId typeId = xmpBag);
738 
740 
741  using XmpValue::read;
752  int read(const std::string& buf) override;
754 
756 
757  UniquePtr clone() const;
758  size_t count() const override;
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;
775  std::ostream& write(std::ostream& os) const override;
777 
778  private:
780  XmpArrayValue* clone_() const override;
781 
782  std::vector<std::string> value_;
783 
784 }; // class XmpArrayValue
785 
795  bool operator()(const std::string& str1, const std::string& str2) const {
796  int result = str1.size() < str2.size() ? 1 : str1.size() > str2.size() ? -1 : 0;
797  if (result == 0) {
798  for (auto c1 = str1.begin(), c2 = str2.begin(); result == 0 && c1 != str1.end(); ++c1, ++c2) {
799  result = tolower(*c1) < tolower(*c2) ? 1 : tolower(*c1) > tolower(*c2) ? -1 : 0;
800  }
801  }
802  return result < 0;
803  }
804 };
805 
812 class EXIV2API LangAltValue : public XmpValue {
813  public:
815  using UniquePtr = std::unique_ptr<LangAltValue>;
816 
818 
819  LangAltValue();
822  explicit LangAltValue(const std::string& buf);
824 
826 
827  using XmpValue::read;
845  int read(const std::string& buf) override;
847 
849 
850  UniquePtr clone() const;
851  size_t count() const override;
859  std::string toString(size_t n) const override;
865  std::string toString(const std::string& qualifier) const;
866  int64_t toInt64(size_t n = 0) const override;
867  uint32_t toUint32(size_t n = 0) const override;
868  float toFloat(size_t n = 0) const override;
869  Rational toRational(size_t n = 0) const override;
876  std::ostream& write(std::ostream& os) const override;
878 
879  private:
881  LangAltValue* clone_() const override;
882 
883  public:
885  using ValueType = std::map<std::string, std::string, LangAltValueComparator>;
886  // DATA
892 
893 }; // class LangAltValue
894 
901 class EXIV2API DateValue : public Value {
902  public:
904  using UniquePtr = std::unique_ptr<DateValue>;
905 
907 
908  DateValue();
911  DateValue(int32_t year, int32_t month, int32_t day);
913 
915  struct EXIV2API Date {
916  int32_t year;
917  int32_t month;
918  int32_t day;
919  };
920 
922 
923 
926  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
935  int read(const std::string& buf) override;
937  void setDate(const Date& src);
939 
941 
942  UniquePtr clone() const {
943  return UniquePtr(clone_());
944  }
958  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
959 
961  virtual const Date& getDate() const;
962  size_t count() const override;
963  size_t size() const override;
964  std::ostream& write(std::ostream& os) const override;
966  int64_t toInt64(size_t n = 0) const override;
968  uint32_t toUint32(size_t n = 0) const override;
970  float toFloat(size_t n = 0) const override;
972  Rational toRational(size_t n = 0) const override;
974 
975  private:
977  DateValue* clone_() const override;
978 
979  // DATA
980  Date date_;
981 
982 }; // class DateValue
983 
992 class EXIV2API TimeValue : public Value {
993  public:
995  using UniquePtr = std::unique_ptr<TimeValue>;
996 
998 
999  TimeValue();
1002  TimeValue(int32_t hour, int32_t minute, int32_t second = 0, int32_t tzHour = 0, int32_t tzMinute = 0);
1004 
1006  struct Time {
1007  int32_t hour;
1008  int32_t minute;
1009  int32_t second;
1010  int32_t tzHour;
1011  int32_t tzMinute;
1012  };
1013 
1015 
1016 
1019  int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
1028  int read(const std::string& buf) override;
1030  void setTime(const Time& src);
1032 
1034 
1035  UniquePtr clone() const {
1036  return UniquePtr(clone_());
1037  }
1051  size_t copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
1053  virtual const Time& getTime() const;
1054  size_t count() const override;
1055  size_t size() const override;
1056  std::ostream& write(std::ostream& os) const override;
1058  int64_t toInt64(size_t n = 0) const override;
1060  uint32_t toUint32(size_t n = 0) const override;
1062  float toFloat(size_t n = 0) const override;
1064  Rational toRational(size_t n = 0) const override;
1066 
1067  private:
1069 
1070  TimeValue* clone_() const override;
1073 
1074  // DATA
1075  Time time_;
1076 
1077 }; // class TimeValue
1078 
1080 template <typename T>
1081 TypeId getType();
1082 
1084 template <>
1086  return unsignedShort;
1087 }
1089 template <>
1091  return unsignedLong;
1092 }
1094 template <>
1096  return unsignedRational;
1097 }
1099 template <>
1101  return signedShort;
1102 }
1104 template <>
1106  return signedLong;
1107 }
1109 template <>
1111  return signedRational;
1112 }
1114 template <>
1116  return tiffFloat;
1117 }
1119 template <>
1121  return tiffDouble;
1122 }
1123 
1124 // No default implementation: let the compiler/linker complain
1125 // template<typename T> inline TypeId getType() { return invalid; }
1126 
1131 template <typename T>
1132 class ValueType : public Value {
1133  using Value::Value;
1134 
1135  public:
1137  using UniquePtr = std::unique_ptr<ValueType<T>>;
1138 
1140 
1141  ValueType();
1144  ValueType(const byte* buf, size_t len, ByteOrder byteOrder, TypeId typeId = getType<T>());
1146  explicit ValueType(const T& val, TypeId typeId = getType<T>());
1148  ValueType(const ValueType<T>& rhs);
1150  ~ValueType() override;
1152 
1154 
1155  ValueType<T>& operator=(const ValueType<T>& rhs);
1157  int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
1164  int read(const std::string& buf) override;
1169  int setDataArea(const byte* buf, size_t len) override;
1171 
1173 
1174  UniquePtr clone() const {
1175  return UniquePtr(clone_());
1176  }
1177  size_t copy(byte* buf, ByteOrder byteOrder) const override;
1178  size_t count() const override;
1179  size_t size() const override;
1180  std::ostream& write(std::ostream& os) const override;
1187  std::string toString(size_t n) const override;
1188  int64_t toInt64(size_t n = 0) const override;
1189  uint32_t toUint32(size_t n = 0) const override;
1190  float toFloat(size_t n = 0) const override;
1191  Rational toRational(size_t n = 0) const override;
1193  size_t sizeDataArea() const override;
1198  DataBuf dataArea() const override;
1200 
1202  using ValueList = std::vector<T>;
1204  using iterator = typename std::vector<T>::iterator;
1206  using const_iterator = typename std::vector<T>::const_iterator;
1207 
1208  // DATA
1216 
1217  private:
1219  template <typename I>
1220  inline I float_to_integer_helper(size_t n) const {
1221  const auto v = value_.at(n);
1222  if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
1223  v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
1224  return static_cast<I>(std::lround(v));
1225  }
1226  return 0;
1227  }
1228 
1230  template <typename I>
1231  inline I rational_to_integer_helper(size_t n) const {
1232  auto a = value_.at(n).first;
1233  auto b = value_.at(n).second;
1234 
1235  // Protect against divide-by-zero.
1236  if (b <= 0) {
1237  return 0;
1238  }
1239 
1240  // Check for integer overflow.
1241 #ifdef __cpp_if_constexpr
1242  if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
1243 #else
1244  if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
1245 #endif
1246  // conversion does not change sign
1247  const auto imin = std::numeric_limits<I>::min();
1248  const auto imax = std::numeric_limits<I>::max();
1249  if (imax < b || a < imin || imax < a) {
1250  return 0;
1251  }
1252 #ifdef __cpp_if_constexpr
1253  } else if constexpr (std::is_signed_v<I>) {
1254 #else
1255  } else if (std::is_signed<I>::value) {
1256 #endif
1257  // conversion is from unsigned to signed
1258 #if __cplusplus >= 201402L || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201402L))
1259  const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
1260 #else
1261  const auto imax = static_cast<typename std::make_unsigned<I>::type>(std::numeric_limits<I>::max());
1262 #endif
1263  if (imax < b || imax < a) {
1264  return 0;
1265  }
1266  } else {
1267  // conversion is from signed to unsigned
1268  const auto imax = std::numeric_limits<I>::max();
1269  if (a < 0) {
1270  return 0;
1271  }
1272  // Inputs are not negative so convert them to unsigned.
1273 #if __cplusplus >= 201402L || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201402L))
1274  const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
1275  const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
1276 #else
1277  const auto a_u = static_cast<typename std::make_unsigned<decltype(a)>::type>(a);
1278  const auto b_u = static_cast<typename std::make_unsigned<decltype(b)>::type>(b);
1279 #endif
1280  if (imax < b_u || imax < a_u) {
1281  return 0;
1282  }
1283  }
1284 
1285  return static_cast<I>(a) / static_cast<I>(b);
1286  }
1287 
1289  ValueType<T>* clone_() const override;
1290 
1291  // DATA
1293  byte* pDataArea_{nullptr};
1295  size_t sizeDataArea_{0};
1296 }; // class ValueType
1297 
1314 
1315 // *****************************************************************************
1316 // free functions, template and inline definitions
1317 
1329 template <typename T>
1330 T getValue(const byte* buf, ByteOrder byteOrder);
1331 // Specialization for a 2 byte unsigned short value.
1332 template <>
1333 inline uint16_t getValue(const byte* buf, ByteOrder byteOrder) {
1334  return getUShort(buf, byteOrder);
1335 }
1336 // Specialization for a 4 byte unsigned long value.
1337 template <>
1338 inline uint32_t getValue(const byte* buf, ByteOrder byteOrder) {
1339  return getULong(buf, byteOrder);
1340 }
1341 // Specialization for an 8 byte unsigned rational value.
1342 template <>
1343 inline URational getValue(const byte* buf, ByteOrder byteOrder) {
1344  return getURational(buf, byteOrder);
1345 }
1346 // Specialization for a 2 byte signed short value.
1347 template <>
1348 inline int16_t getValue(const byte* buf, ByteOrder byteOrder) {
1349  return getShort(buf, byteOrder);
1350 }
1351 // Specialization for a 4 byte signed long value.
1352 template <>
1353 inline int32_t getValue(const byte* buf, ByteOrder byteOrder) {
1354  return getLong(buf, byteOrder);
1355 }
1356 // Specialization for an 8 byte signed rational value.
1357 template <>
1358 inline Rational getValue(const byte* buf, ByteOrder byteOrder) {
1359  return getRational(buf, byteOrder);
1360 }
1361 // Specialization for a 4 byte float value.
1362 template <>
1363 inline float getValue(const byte* buf, ByteOrder byteOrder) {
1364  return getFloat(buf, byteOrder);
1365 }
1366 // Specialization for a 8 byte double value.
1367 template <>
1368 inline double getValue(const byte* buf, ByteOrder byteOrder) {
1369  return getDouble(buf, byteOrder);
1370 }
1371 
1384 template <typename T>
1385 size_t toData(byte* buf, T t, ByteOrder byteOrder);
1390 template <>
1391 inline size_t toData(byte* buf, uint16_t t, ByteOrder byteOrder) {
1392  return us2Data(buf, t, byteOrder);
1393 }
1398 template <>
1399 inline size_t toData(byte* buf, uint32_t t, ByteOrder byteOrder) {
1400  return ul2Data(buf, t, byteOrder);
1401 }
1406 template <>
1407 inline size_t toData(byte* buf, URational t, ByteOrder byteOrder) {
1408  return ur2Data(buf, t, byteOrder);
1409 }
1414 template <>
1415 inline size_t toData(byte* buf, int16_t t, ByteOrder byteOrder) {
1416  return s2Data(buf, t, byteOrder);
1417 }
1422 template <>
1423 inline size_t toData(byte* buf, int32_t t, ByteOrder byteOrder) {
1424  return l2Data(buf, t, byteOrder);
1425 }
1430 template <>
1431 inline size_t toData(byte* buf, Rational t, ByteOrder byteOrder) {
1432  return r2Data(buf, t, byteOrder);
1433 }
1438 template <>
1439 inline size_t toData(byte* buf, float t, ByteOrder byteOrder) {
1440  return f2Data(buf, t, byteOrder);
1441 }
1446 template <>
1447 inline size_t toData(byte* buf, double t, ByteOrder byteOrder) {
1448  return d2Data(buf, t, byteOrder);
1449 }
1450 
1451 template <typename T>
1453 }
1454 
1455 template <typename T>
1456 ValueType<T>::ValueType(const byte* buf, size_t len, ByteOrder byteOrder, TypeId typeId) : Value(typeId) {
1457  read(buf, len, byteOrder);
1458 }
1459 
1460 template <typename T>
1461 ValueType<T>::ValueType(const T& val, TypeId typeId) : Value(typeId) {
1462  value_.push_back(val);
1463 }
1464 
1465 template <typename T>
1467  Value(rhs.typeId()),
1468  value_(rhs.value_)
1469 
1470 {
1471  if (rhs.sizeDataArea_ > 0) {
1472  pDataArea_ = new byte[rhs.sizeDataArea_];
1473  std::memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea_);
1474  sizeDataArea_ = rhs.sizeDataArea_;
1475  }
1476 }
1477 
1478 template <typename T>
1480  delete[] pDataArea_;
1481 }
1482 
1483 template <typename T>
1485  if (this == &rhs)
1486  return *this;
1487  Value::operator=(rhs);
1488  value_ = rhs.value_;
1489 
1490  byte* tmp = nullptr;
1491  if (rhs.sizeDataArea_ > 0) {
1492  tmp = new byte[rhs.sizeDataArea_];
1493  std::memcpy(tmp, rhs.pDataArea_, rhs.sizeDataArea_);
1494  }
1495  delete[] pDataArea_;
1496  pDataArea_ = tmp;
1497  sizeDataArea_ = rhs.sizeDataArea_;
1498 
1499  return *this;
1500 }
1501 
1502 template <typename T>
1503 int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
1504  value_.clear();
1505  size_t ts = TypeInfo::typeSize(typeId());
1506  if (ts > 0 && len % ts != 0)
1507  len = (len / ts) * ts;
1508  for (size_t i = 0; i < len; i += ts) {
1509  value_.push_back(getValue<T>(buf + i, byteOrder));
1510  }
1511  return 0;
1512 }
1513 
1514 template <typename T>
1515 int ValueType<T>::read(const std::string& buf) {
1516  std::istringstream is(buf);
1517  T tmp = T();
1518  ValueList val;
1519  while (!(is.eof())) {
1520  is >> tmp;
1521  if (is.fail())
1522  return 1;
1523  val.push_back(tmp);
1524  }
1525  value_.swap(val);
1526  return 0;
1527 }
1528 
1529 template <typename T>
1530 size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
1531  size_t offset = 0;
1532  for (auto i = value_.begin(); i != value_.end(); ++i) {
1533  offset += toData(buf + offset, *i, byteOrder);
1534  }
1535  return offset;
1536 }
1537 
1538 template <typename T>
1539 size_t ValueType<T>::count() const {
1540  return value_.size();
1541 }
1542 
1543 template <typename T>
1544 size_t ValueType<T>::size() const {
1545  return TypeInfo::typeSize(typeId()) * value_.size();
1546 }
1547 
1548 template <typename T>
1550  return new ValueType<T>(*this);
1551 }
1552 
1553 template <typename T>
1554 std::ostream& ValueType<T>::write(std::ostream& os) const {
1555  auto end = value_.end();
1556  auto i = value_.begin();
1557  while (i != end) {
1558  os << std::setprecision(15) << *i;
1559  if (++i != end)
1560  os << " ";
1561  }
1562  return os;
1563 }
1564 
1565 template <typename T>
1566 std::string ValueType<T>::toString(size_t n) const {
1567  ok_ = true;
1568  return Exiv2::toString<T>(value_.at(n));
1569 }
1570 
1571 // Default implementation
1572 template <typename T>
1573 int64_t ValueType<T>::toInt64(size_t n) const {
1574  ok_ = true;
1575  return static_cast<int64_t>(value_.at(n));
1576 }
1577 template <typename T>
1578 uint32_t ValueType<T>::toUint32(size_t n) const {
1579  ok_ = true;
1580  return static_cast<uint32_t>(value_.at(n));
1581 }
1582 // #55 crash when value_.at(n).first == LONG_MIN
1583 #define LARGE_INT 1000000
1584 // Specialization for double
1585 template <>
1586 inline int64_t ValueType<double>::toInt64(size_t n) const {
1587  return float_to_integer_helper<int64_t>(n);
1588 }
1589 
1590 template <>
1591 inline uint32_t ValueType<double>::toUint32(size_t n) const {
1592  return float_to_integer_helper<uint32_t>(n);
1593 }
1594 // Specialization for float
1595 template <>
1596 inline int64_t ValueType<float>::toInt64(size_t n) const {
1597  return float_to_integer_helper<int64_t>(n);
1598 }
1599 template <>
1600 inline uint32_t ValueType<float>::toUint32(size_t n) const {
1601  return float_to_integer_helper<uint32_t>(n);
1602 }
1603 // Specialization for rational
1604 template <>
1605 inline int64_t ValueType<Rational>::toInt64(size_t n) const {
1606  return rational_to_integer_helper<int64_t>(n);
1607 }
1608 template <>
1609 inline uint32_t ValueType<Rational>::toUint32(size_t n) const {
1610  return rational_to_integer_helper<uint32_t>(n);
1611 }
1612 // Specialization for unsigned rational
1613 template <>
1614 inline int64_t ValueType<URational>::toInt64(size_t n) const {
1615  return rational_to_integer_helper<int64_t>(n);
1616 }
1617 template <>
1618 inline uint32_t ValueType<URational>::toUint32(size_t n) const {
1619  return rational_to_integer_helper<uint32_t>(n);
1620 }
1621 // Default implementation
1622 template <typename T>
1623 float ValueType<T>::toFloat(size_t n) const {
1624  ok_ = true;
1625  return static_cast<float>(value_.at(n));
1626 }
1627 // Specialization for rational
1628 template <>
1629 inline float ValueType<Rational>::toFloat(size_t n) const {
1630  ok_ = (value_.at(n).second != 0);
1631  if (!ok_)
1632  return 0.0f;
1633  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1634 }
1635 // Specialization for unsigned rational
1636 template <>
1637 inline float ValueType<URational>::toFloat(size_t n) const {
1638  ok_ = (value_.at(n).second != 0);
1639  if (!ok_)
1640  return 0.0f;
1641  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1642 }
1643 // Default implementation
1644 template <typename T>
1646  ok_ = true;
1647  return {value_.at(n), 1};
1648 }
1649 // Specialization for rational
1650 template <>
1652  ok_ = true;
1653  return {value_.at(n).first, value_.at(n).second};
1654 }
1655 // Specialization for unsigned rational
1656 template <>
1658  ok_ = true;
1659  return {value_.at(n).first, value_.at(n).second};
1660 }
1661 // Specialization for float.
1662 template <>
1663 inline Rational ValueType<float>::toRational(size_t n) const {
1664  ok_ = true;
1665  // Warning: This is a very simple conversion, see floatToRationalCast()
1666  return floatToRationalCast(value_.at(n));
1667 }
1668 // Specialization for double.
1669 template <>
1670 inline Rational ValueType<double>::toRational(size_t n) const {
1671  ok_ = true;
1672  // Warning: This is a very simple conversion, see floatToRationalCast()
1673  return floatToRationalCast(static_cast<float>(value_.at(n)));
1674 }
1675 
1676 template <typename T>
1678  return sizeDataArea_;
1679 }
1680 
1681 template <typename T>
1683  return {pDataArea_, sizeDataArea_};
1684 }
1685 
1686 template <typename T>
1687 int ValueType<T>::setDataArea(const byte* buf, size_t len) {
1688  byte* tmp = nullptr;
1689  if (len > 0) {
1690  tmp = new byte[len];
1691  std::memcpy(tmp, buf, len);
1692  }
1693  delete[] pDataArea_;
1694  pDataArea_ = tmp;
1695  sizeDataArea_ = len;
1696  return 0;
1697 }
1698 } // namespace Exiv2
1699 
1700 #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:469
EXIV2API Rational floatToRationalCast(float f)
Very simple conversion of a float to a Rational.
Definition: types.cpp:611
int32_t day
Day.
Definition: value.hpp:918
Information pertaining to the defined character sets.
Definition: value.hpp:468
~ValueType() override
Virtual destructor.
Definition: value.hpp:1479
ValueType value_
Map to store the language alternative values. The language qualifier is used as the key for the map e...
Definition: value.hpp:891
TypeId getType< uint16_t >()
Specialization for an unsigned short.
Definition: value.hpp:1085
XmpArrayType
XMP array types.
Definition: value.hpp:580
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:335
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:1682
std::map< std::string, std::string, LangAltValueComparator > ValueType
Type used to store language alternative arrays.
Definition: value.hpp:885
int read(const std::string &buf) override
Read the value from buf. This default implementation uses buf as it is.
Definition: value.cpp:176
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:1132
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:639
int32_t minute
Minute.
Definition: value.hpp:1008
T getValue(const byte *buf, ByteOrder byteOrder)
Read a value of type T from the data buffer.
Definition: value.hpp:1333
Simple Date helper structure.
Definition: value.hpp:915
Value(TypeId typeId)
Constructor, taking a type id to initialize the base class with.
Definition: value.cpp:17
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:414
std::unique_ptr< ValueType< T >> UniquePtr
Shortcut for a ValueType auto pointer.
Definition: value.hpp:1137
int read(const byte *buf, size_t len, ByteOrder byteOrder) override
Read the value from a character buffer.
Definition: value.hpp:1503
size_t count() const override
Return the number of components of the value.
Definition: value.hpp:1539
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:312
static size_t typeSize(TypeId typeId)
Return the size in bytes of one element of this type.
Definition: types.cpp:87
EXIV2API int16_t getShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte signed short value from the data buffer.
Definition: types.cpp:280
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:72
uint8_t byte
1 byte unsigned integer type.
Definition: types.hpp:26
Value for simple ISO 8601 times.
Definition: value.hpp:992
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:412
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:728
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:1206
ValueType value_
Stores the data value.
Definition: value.hpp:305
Value type for XMP language alternative properties.
Definition: value.hpp:812
ValueList value_
The container for all values. In your application, if you know what subclass of Value you're dealing ...
Definition: value.hpp:1215
Charset information lookup functions. Implemented as a static class.
Definition: value.hpp:475
XMP bag type.
Definition: types.hpp:94
int32_t month
Month.
Definition: value.hpp:917
int32_t second
Second.
Definition: value.hpp:1009
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:274
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:1645
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:1578
std::string value_
Stores the string value.
Definition: value.hpp:369
TypeId getType< int16_t >()
Specialization for a signed short.
Definition: value.hpp:1100
LangAltValueComparator
Definition: value.hpp:793
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:1554
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:1573
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:408
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:1090
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:393
ValueType()
Default Constructor.
Definition: value.hpp:1452
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:461
Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
Definition: types.hpp:78
XmpStruct
XMP structure indicator.
Definition: value.hpp:582
Value for an Exif comment.
Definition: value.hpp:463
std::string value_
Stores the string values.
Definition: value.hpp:715
TIFF FLOAT type, single precision (4-byte) IEEE format.
Definition: types.hpp:81
int32_t tzHour
Hours ahead or behind UTC.
Definition: value.hpp:1010
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:376
Base class for all Exiv2 values used to store XMP property values.
Definition: value.hpp:572
std::vector< byte > ValueType
Type used to store the data.
Definition: value.hpp:303
EXIV2API int32_t getLong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte signed long value from the data buffer.
Definition: types.cpp:287
int32_t hour
Hour.
Definition: value.hpp:1007
int32_t year
Year.
Definition: value.hpp:916
EXIV2API uint32_t getULong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte unsigned long value from the data buffer.
Definition: types.cpp:254
std::vector< T > ValueList
Container for values.
Definition: value.hpp:1202
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:1530
const char * name_
Name of the charset.
Definition: value.hpp:470
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:1687
ValueType< T > & operator=(const ValueType< T > &rhs)
Assignment operator.
Definition: value.hpp:1484
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:466
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:1623
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:590
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:426
const char * code_
Code of the charset.
Definition: value.hpp:471
Exiv2 type for the Exif user comment.
Definition: types.hpp:90
TypeId getType< double >()
Specialization for a double.
Definition: value.hpp:1120
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:382
size_t sizeDataArea() const override
Return the size of the data area.
Definition: value.hpp:1677
size_t size() const override
Return the size of the value in bytes.
Definition: value.hpp:1544
Abstract base class for a string based Value type.
Definition: value.hpp:315
Value for simple ISO 8601 dates
Definition: value.hpp:901
EXIV2API Rational getRational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte signed rational value from the data buffer.
Definition: types.cpp:294
Value for string type.
Definition: value.hpp:380
TypeId getType< Rational >()
Specialization for a signed rational.
Definition: value.hpp:1110
int32_t tzMinute
Minutes ahead or behind UTC.
Definition: value.hpp:1011
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:346
Simple Time helper structure.
Definition: value.hpp:1006
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:1115
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:300
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:795
TypeId getType< int32_t >()
Specialization for a signed long.
Definition: value.hpp:1105
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:1204
EXIV2API uint16_t getUShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte unsigned short value from the data buffer.
Definition: types.cpp:250
TypeId getType< URational >()
Specialization for an unsigned rational.
Definition: value.hpp:1095