Exiv2
Loading...
Searching...
No Matches
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
21namespace Exiv2 {
22// *****************************************************************************
23// class definitions
24
33class EXIV2API Value {
34 public:
36 using UniquePtr = std::unique_ptr<Value>;
37
39
40
41 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
85 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
242inline std::ostream& operator<<(std::ostream& os, const Value& value) {
243 return value.write(os);
244}
245
247class 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
314class EXIV2API StringValueBase : public Value {
315 using Value::Value;
316
317 public:
319 using UniquePtr = std::unique_ptr<StringValueBase>;
320
322
323
324 StringValueBase(TypeId typeId, const std::string& buf);
326
328
329
330 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
379class EXIV2API StringValue : public StringValueBase {
380 public:
382 using UniquePtr = std::unique_ptr<StringValue>;
383
385
386
387 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
411class EXIV2API AsciiValue : public StringValueBase {
412 public:
414 using UniquePtr = std::unique_ptr<AsciiValue>;
415
417
418
419 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
462class EXIV2API CommentValue : public StringValueBase {
463 public:
465 enum CharsetId { ascii, jis, unicode, undefined, invalidCharsetId, lastCharsetId };
469 const char* name_;
470 const char* code_;
471 };
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
495 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
571class 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
586 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
609 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
638class EXIV2API XmpTextValue : public XmpValue {
639 public:
641 using UniquePtr = std::unique_ptr<XmpTextValue>;
642
644
645
646 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
727class EXIV2API XmpArrayValue : public XmpValue {
728 public:
730 using UniquePtr = std::unique_ptr<XmpArrayValue>;
731
733
734
735 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
811class EXIV2API LangAltValue : public XmpValue {
812 public:
814 using UniquePtr = std::unique_ptr<LangAltValue>;
815
817
818
819 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
900class EXIV2API DateValue : public Value {
901 public:
903 using UniquePtr = std::unique_ptr<DateValue>;
904
906
907
908 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
991class EXIV2API TimeValue : public Value {
992 public:
994 using UniquePtr = std::unique_ptr<TimeValue>;
995
997
998
999 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
1070 TimeValue* clone_() const override;
1072
1073 // DATA
1074 Time time_;
1075
1076}; // class TimeValue
1077
1079template <typename T>
1081
1083template <>
1085 return unsignedShort;
1086}
1088template <>
1090 return unsignedLong;
1091}
1093template <>
1095 return unsignedRational;
1096}
1098template <>
1100 return signedShort;
1101}
1103template <>
1105 return signedLong;
1106}
1108template <>
1110 return signedRational;
1111}
1113template <>
1115 return tiffFloat;
1116}
1118template <>
1120 return tiffDouble;
1121}
1122
1123// No default implementation: let the compiler/linker complain
1124// template<typename T> inline TypeId getType() { return invalid; }
1125
1130template <typename T>
1131class ValueType : public Value {
1132 using Value::Value;
1133
1134 public:
1136 using UniquePtr = std::unique_ptr<ValueType<T>>;
1137
1139
1140
1141 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
1155 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::lround(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 || (defined(_MSVC_LANG) && (_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 || (defined(_MSVC_LANG) && (_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
1328template <typename T>
1329T getValue(const byte* buf, ByteOrder byteOrder);
1330// Specialization for a 2 byte unsigned short value.
1331template <>
1332inline uint16_t getValue(const byte* buf, ByteOrder byteOrder) {
1333 return getUShort(buf, byteOrder);
1334}
1335// Specialization for a 4 byte unsigned long value.
1336template <>
1337inline uint32_t getValue(const byte* buf, ByteOrder byteOrder) {
1338 return getULong(buf, byteOrder);
1339}
1340// Specialization for an 8 byte unsigned rational value.
1341template <>
1342inline URational getValue(const byte* buf, ByteOrder byteOrder) {
1343 return getURational(buf, byteOrder);
1344}
1345// Specialization for a 2 byte signed short value.
1346template <>
1347inline int16_t getValue(const byte* buf, ByteOrder byteOrder) {
1348 return getShort(buf, byteOrder);
1349}
1350// Specialization for a 4 byte signed long value.
1351template <>
1352inline int32_t getValue(const byte* buf, ByteOrder byteOrder) {
1353 return getLong(buf, byteOrder);
1354}
1355// Specialization for an 8 byte signed rational value.
1356template <>
1357inline Rational getValue(const byte* buf, ByteOrder byteOrder) {
1358 return getRational(buf, byteOrder);
1359}
1360// Specialization for a 4 byte float value.
1361template <>
1362inline float getValue(const byte* buf, ByteOrder byteOrder) {
1363 return getFloat(buf, byteOrder);
1364}
1365// Specialization for a 8 byte double value.
1366template <>
1367inline double getValue(const byte* buf, ByteOrder byteOrder) {
1368 return getDouble(buf, byteOrder);
1369}
1370
1383template <typename T>
1384size_t toData(byte* buf, T t, ByteOrder byteOrder);
1389template <>
1390inline size_t toData(byte* buf, uint16_t t, ByteOrder byteOrder) {
1391 return us2Data(buf, t, byteOrder);
1392}
1397template <>
1398inline size_t toData(byte* buf, uint32_t t, ByteOrder byteOrder) {
1399 return ul2Data(buf, t, byteOrder);
1400}
1405template <>
1406inline size_t toData(byte* buf, URational t, ByteOrder byteOrder) {
1407 return ur2Data(buf, t, byteOrder);
1408}
1413template <>
1414inline size_t toData(byte* buf, int16_t t, ByteOrder byteOrder) {
1415 return s2Data(buf, t, byteOrder);
1416}
1421template <>
1422inline size_t toData(byte* buf, int32_t t, ByteOrder byteOrder) {
1423 return l2Data(buf, t, byteOrder);
1424}
1429template <>
1430inline size_t toData(byte* buf, Rational t, ByteOrder byteOrder) {
1431 return r2Data(buf, t, byteOrder);
1432}
1437template <>
1438inline size_t toData(byte* buf, float t, ByteOrder byteOrder) {
1439 return f2Data(buf, t, byteOrder);
1440}
1445template <>
1446inline size_t toData(byte* buf, double t, ByteOrder byteOrder) {
1447 return d2Data(buf, t, byteOrder);
1448}
1449
1450template <typename T>
1453
1454template <typename T>
1455ValueType<T>::ValueType(const byte* buf, size_t len, ByteOrder byteOrder, TypeId typeId) : Value(typeId) {
1456 read(buf, len, byteOrder);
1457}
1458
1459template <typename T>
1460ValueType<T>::ValueType(const T& val, TypeId typeId) : Value(typeId) {
1461 value_.push_back(val);
1462}
1463
1464template <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
1477template <typename T>
1479 delete[] pDataArea_;
1480}
1481
1482template <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
1501template <typename T>
1502int 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
1513template <typename T>
1514int 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
1528template <typename T>
1529size_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
1537template <typename T>
1538size_t ValueType<T>::count() const {
1539 return value_.size();
1540}
1541
1542template <typename T>
1543size_t ValueType<T>::size() const {
1544 return TypeInfo::typeSize(typeId()) * value_.size();
1545}
1546
1547template <typename T>
1549 return new ValueType<T>(*this);
1550}
1551
1552template <typename T>
1553std::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
1564template <typename T>
1565std::string ValueType<T>::toString(size_t n) const {
1566 ok_ = true;
1567 return Exiv2::toString<T>(value_.at(n));
1568}
1569
1570// Default implementation
1571template <typename T>
1572int64_t ValueType<T>::toInt64(size_t n) const {
1573 ok_ = true;
1574 return static_cast<int64_t>(value_.at(n));
1575}
1576template <typename T>
1577uint32_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
1584template <>
1585inline int64_t ValueType<double>::toInt64(size_t n) const {
1586 return float_to_integer_helper<int64_t>(n);
1587}
1588
1589template <>
1590inline uint32_t ValueType<double>::toUint32(size_t n) const {
1591 return float_to_integer_helper<uint32_t>(n);
1592}
1593// Specialization for float
1594template <>
1595inline int64_t ValueType<float>::toInt64(size_t n) const {
1596 return float_to_integer_helper<int64_t>(n);
1597}
1598template <>
1599inline uint32_t ValueType<float>::toUint32(size_t n) const {
1600 return float_to_integer_helper<uint32_t>(n);
1601}
1602// Specialization for rational
1603template <>
1604inline int64_t ValueType<Rational>::toInt64(size_t n) const {
1605 return rational_to_integer_helper<int64_t>(n);
1606}
1607template <>
1608inline uint32_t ValueType<Rational>::toUint32(size_t n) const {
1609 return rational_to_integer_helper<uint32_t>(n);
1610}
1611// Specialization for unsigned rational
1612template <>
1613inline int64_t ValueType<URational>::toInt64(size_t n) const {
1614 return rational_to_integer_helper<int64_t>(n);
1615}
1616template <>
1617inline uint32_t ValueType<URational>::toUint32(size_t n) const {
1618 return rational_to_integer_helper<uint32_t>(n);
1619}
1620// Default implementation
1621template <typename T>
1622float ValueType<T>::toFloat(size_t n) const {
1623 ok_ = true;
1624 return static_cast<float>(value_.at(n));
1625}
1626// Specialization for rational
1627template <>
1628inline 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
1635template <>
1636inline 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
1643template <typename T>
1645 ok_ = true;
1646 return {value_.at(n), 1};
1647}
1648// Specialization for rational
1649template <>
1651 ok_ = true;
1652 return {value_.at(n).first, value_.at(n).second};
1653}
1654// Specialization for unsigned rational
1655template <>
1657 ok_ = true;
1658 return {value_.at(n).first, value_.at(n).second};
1659}
1660// Specialization for float.
1661template <>
1663 ok_ = true;
1664 // Warning: This is a very simple conversion, see floatToRationalCast()
1665 return floatToRationalCast(value_.at(n));
1666}
1667// Specialization for double.
1668template <>
1670 ok_ = true;
1671 // Warning: This is a very simple conversion, see floatToRationalCast()
1672 return floatToRationalCast(static_cast<float>(value_.at(n)));
1673}
1674
1675template <typename T>
1677 return sizeDataArea_;
1678}
1679
1680template <typename T>
1682 return {pDataArea_, sizeDataArea_};
1683}
1684
1685template <typename T>
1686int 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_
Value for an Ascii string type.
Definition value.hpp:411
std::unique_ptr< AsciiValue > UniquePtr
Shortcut for a AsciiValue auto pointer.
Definition value.hpp:414
Charset information lookup functions. Implemented as a static class.
Definition value.hpp:474
Value for an Exif comment.
Definition value.hpp:462
std::unique_ptr< CommentValue > UniquePtr
Shortcut for a CommentValue auto pointer.
Definition value.hpp:490
CharsetId
Character set identifiers for the character sets defined by Exif.
Definition value.hpp:465
Value for an undefined data type.
Definition value.hpp:247
std::unique_ptr< DataValue > UniquePtr
Shortcut for a DataValue auto pointer.
Definition value.hpp:250
Value for simple ISO 8601 dates
Definition value.hpp:900
std::unique_ptr< DateValue > UniquePtr
Shortcut for a DateValue auto pointer.
Definition value.hpp:903
Value type for XMP language alternative properties.
Definition value.hpp:811
std::map< std::string, std::string, LangAltValueComparator > ValueType
Type used to store language alternative arrays.
Definition value.hpp:884
std::unique_ptr< LangAltValue > UniquePtr
Shortcut for a LangAltValue auto pointer.
Definition value.hpp:814
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
Abstract base class for a string based Value type.
Definition value.hpp:314
StringValueBase * clone_() const override=0
Internal virtual copy constructor.
std::unique_ptr< StringValueBase > UniquePtr
Shortcut for a StringValueBase auto pointer.
Definition value.hpp:319
std::string value_
Stores the string value.
Definition value.hpp:368
Value for string type.
Definition value.hpp:379
std::unique_ptr< StringValue > UniquePtr
Shortcut for a StringValue auto pointer.
Definition value.hpp:382
Value for simple ISO 8601 times.
Definition value.hpp:991
std::unique_ptr< TimeValue > UniquePtr
Shortcut for a TimeValue auto pointer.
Definition value.hpp:994
static size_t typeSize(TypeId typeId)
Return the size in bytes of one element of this type.
Definition types.cpp:83
Template for a Value of a basic type. This is used for unsigned and signed short, long and rationals.
Definition value.hpp:1131
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
ValueType< T > & operator=(const ValueType< T > &rhs)
Assignment operator.
Definition value.hpp:1483
typename std::vector< T >::const_iterator const_iterator
Const iterator type defined for convenience.
Definition value.hpp:1205
std::unique_ptr< ValueType< T > > UniquePtr
Shortcut for a ValueType<T> auto pointer.
Definition value.hpp:1136
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
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::vector< T > ValueList
Container for values.
Definition value.hpp:1201
size_t count() const override
Return the number of components of the value.
Definition value.hpp:1538
ValueType()
Default Constructor.
Definition value.hpp:1451
~ValueType() override
Virtual destructor.
Definition value.hpp:1478
size_t size() const override
Return the size of the value in bytes.
Definition value.hpp:1543
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
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
size_t copy(byte *buf, ByteOrder byteOrder) const override
Write value to a data buffer.
Definition value.hpp:1529
size_t sizeDataArea() const override
Return the size of the data area.
Definition value.hpp:1676
typename std::vector< T >::iterator iterator
Iterator type defined for convenience.
Definition value.hpp:1203
ValueList value_
The container for all values. In your application, if you know what subclass of Value you're dealing ...
Definition value.hpp:1214
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
int read(const byte *buf, size_t len, ByteOrder byteOrder) override
Read the value from a character buffer.
Definition value.hpp:1502
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
Common interface for all types of values used with metadata.
Definition value.hpp:33
TypeId typeId() const
Return the type identifier (Exif data format type).
Definition value.hpp:85
virtual ~Value()=default
Virtual destructor.
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...
virtual size_t count() const =0
Return the number of components of the value.
virtual int read(const std::string &buf)=0
Set the value from a string buffer. The format of the string corresponds to that of the write() metho...
virtual int read(const byte *buf, size_t len, ByteOrder byteOrder)=0
Read the value from a character buffer.
bool ok() const
Check the ok status indicator. After a to<Type> conversion, this indicator shows whether the conversi...
Definition value.hpp:181
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
virtual float toFloat(size_t n=0) const =0
Convert the n-th component of the value to a float. The behaviour of this method may be undefined if ...
virtual Rational toRational(size_t n=0) const =0
Convert the n-th component of the value to a Rational. The behaviour of this method may be undefined ...
virtual uint32_t toUint32(size_t n=0) const =0
Convert the n-th component of the value to a float. The behaviour of this method may be undefined if ...
virtual size_t size() const =0
Return the size of the value in bytes.
virtual size_t copy(byte *buf, ByteOrder byteOrder) const =0
Write value to a data buffer.
Value(TypeId typeId)
Constructor, taking a type id to initialize the base class with.
Definition value.cpp:17
virtual int64_t toInt64(size_t n=0) const =0
Convert the n-th component of the value to an int64_t. The behaviour of this method may be undefined ...
Value & operator=(const Value &)=default
Assignment operator. Protected so that it can only be used by subclasses but not directly.
std::unique_ptr< Value > UniquePtr
Shortcut for a Value auto pointer.
Definition value.hpp:36
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
Value type for simple arrays. Each item in the array is a simple value, without qualifiers....
Definition value.hpp:727
std::unique_ptr< XmpArrayValue > UniquePtr
Shortcut for a XmpArrayValue auto pointer.
Definition value.hpp:730
Value type suitable for simple XMP properties and XMP nodes of complex types which are not parsed int...
Definition value.hpp:638
std::unique_ptr< XmpTextValue > UniquePtr
Shortcut for a XmpTextValue auto pointer.
Definition value.hpp:641
std::string value_
Stores the string values.
Definition value.hpp:714
Base class for all Exiv2 values used to store XMP property values.
Definition value.hpp:571
int read(const std::string &buf) override=0
Set the value from a string buffer. The format of the string corresponds to that of the write() metho...
XmpStruct
XMP structure indicator.
Definition value.hpp:581
std::unique_ptr< XmpValue > UniquePtr
Shortcut for a XmpValue auto pointer.
Definition value.hpp:576
XmpArrayType
XMP array types.
Definition value.hpp:579
Class CrwImage to access Canon CRW images. References: The Canon RAW (CRW) File Format by Phil Harv...
Definition asfvideo.hpp:15
std::pair< int32_t, int32_t > Rational
8 byte signed rational type.
Definition types.hpp:31
EXIV2API std::ostream & operator<<(std::ostream &os, const DataSet &dataSet)
Output operator for dataSet.
Definition datasets.cpp:590
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
TypeId getType< int32_t >()
Specialization for a signed long.
Definition value.hpp:1104
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
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
TypeId getType< int16_t >()
Specialization for a signed short.
Definition value.hpp:1099
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 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
EXIV2API Rational floatToRationalCast(float f)
Very simple conversion of a float to a Rational.
Definition types.cpp:607
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
EXIV2API int16_t getShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte signed short value from the data buffer.
Definition types.cpp:276
TypeId getType< uint32_t >()
Specialization for an unsigned long.
Definition value.hpp:1089
EXIV2API uint32_t getULong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte unsigned long value from the data buffer.
Definition types.cpp:250
T getValue(const byte *buf, ByteOrder byteOrder)
Read a value of type T from the data buffer.
std::pair< uint32_t, uint32_t > URational
8 byte unsigned rational type.
Definition types.hpp:29
TypeId
Exiv2 value type identifiers.
Definition types.hpp:70
@ unsignedShort
Exif SHORT type, 16-bit (2-byte) unsigned integer.
Definition types.hpp:73
@ signedRational
Exif SRATIONAL type, two SLONGs: numerator and denominator of a fraction.
Definition types.hpp:80
@ unsignedLong
Exif LONG type, 32-bit (4-byte) unsigned integer.
Definition types.hpp:74
@ signedShort
Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
Definition types.hpp:78
@ signedLong
Exif SLONG type, a 32-bit (4-byte) signed (twos-complement) integer.
Definition types.hpp:79
@ comment
Exiv2 type for the Exif user comment.
Definition types.hpp:90
@ tiffDouble
TIFF DOUBLE type, double precision (8-byte) IEEE format.
Definition types.hpp:82
@ undefined
Exif UNDEFINED type, an 8-bit byte that may contain anything.
Definition types.hpp:77
@ tiffFloat
TIFF FLOAT type, single precision (4-byte) IEEE format.
Definition types.hpp:81
@ unsignedRational
Exif RATIONAL type, two LONGs: numerator and denominator of a fraction.
Definition types.hpp:75
EXIV2API uint16_t getUShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte unsigned short value from the data buffer.
Definition types.cpp:246
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
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
ByteOrder
Type to express the byte order (little or big endian)
Definition types.hpp:34
TypeId getType< uint16_t >()
Specialization for an unsigned short.
Definition value.hpp:1084
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
EXIV2API Rational getRational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte signed rational value from the data buffer.
Definition types.cpp:290
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
TypeId getType< URational >()
Specialization for an unsigned rational.
Definition value.hpp:1094
TypeId getType< float >()
Specialization for a float.
Definition value.hpp:1114
EXIV2API int32_t getLong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte signed long value from the data buffer.
Definition types.cpp:283
TypeId getType< Rational >()
Specialization for a signed rational.
Definition value.hpp:1109
TypeId getType< double >()
Specialization for a double.
Definition value.hpp:1119
TypeId getType()
Template to determine the TypeId for a type T.
EXIV2API URational getURational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte unsigned rational value from the data buffer.
Definition types.cpp:270
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
Information pertaining to the defined character sets.
Definition value.hpp:467
CharsetId charsetId_
Charset id.
Definition value.hpp:468
const char * name_
Name of the charset.
Definition value.hpp:469
const char * code_
Code of the charset.
Definition value.hpp:470
Utility class containing a character array. All it does is to take care of memory allocation and dele...
Definition types.hpp:124
Simple Date helper structure.
Definition value.hpp:914
int32_t month
Month.
Definition value.hpp:916
int32_t day
Day.
Definition value.hpp:917
int32_t year
Year.
Definition value.hpp:915
LangAltValueComparator
Definition value.hpp:792
bool operator()(const std::string &str1, const std::string &str2) const
LangAltValueComparator comparison case insensitive function.
Definition value.hpp:794
Simple Time helper structure.
Definition value.hpp:1005
int32_t hour
Hour.
Definition value.hpp:1006
int32_t tzMinute
Minutes ahead or behind UTC.
Definition value.hpp:1010
int32_t minute
Minute.
Definition value.hpp:1007
int32_t second
Second.
Definition value.hpp:1008
int32_t tzHour
Hours ahead or behind UTC.
Definition value.hpp:1009