Exiv2
value.hpp
1 // ***************************************************************** -*- C++ -*-
2 /*
3  * Copyright (C) 2004-2021 Exiv2 authors
4  * This program is part of the Exiv2 distribution.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
19  */
20 #ifndef VALUE_HPP_
21 #define VALUE_HPP_
22 
23 // *****************************************************************************
24 #include "exiv2lib_export.h"
25 
26 // included header files
27 #include "types.hpp"
28 
29 // + standard includes
30 #include <map>
31 #include <iomanip>
32 #include <memory>
33 #include <cstring>
34 #include <climits>
35 
36 // *****************************************************************************
37 // namespace extensions
38 namespace Exiv2 {
39 
40 // *****************************************************************************
41 // class definitions
42 
51  class EXIV2API Value {
52  public:
54  typedef std::auto_ptr<Value> AutoPtr;
55 
57 
58  explicit Value(TypeId typeId);
61  virtual ~Value();
63 
65 
74  virtual int read(const byte* buf, long len, ByteOrder byteOrder) =0;
85  virtual int read(const std::string& buf) =0;
98  virtual int setDataArea(const byte* buf, long len);
100 
102 
103  TypeId typeId() const { return type_; }
110  AutoPtr clone() const { return AutoPtr(clone_()); }
121  virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
123  virtual long count() const =0;
125  virtual long size() const =0;
132  virtual std::ostream& write(std::ostream& os) const =0;
137  std::string toString() const;
144  virtual std::string toString(long n) const;
152  virtual long toLong(long n =0) const =0;
160  virtual float toFloat(long n =0) const =0;
168  virtual Rational toRational(long n =0) const =0;
170  virtual long sizeDataArea() const;
183  virtual DataBuf dataArea() const;
188  bool ok() const { return ok_; }
190 
227  static AutoPtr create(TypeId typeId);
228 
229  protected:
234  Value& operator=(const Value& rhs);
235  // DATA
236  mutable bool ok_;
237 
238  private:
240  virtual Value* clone_() const =0;
241  // DATA
242  TypeId type_;
243 
244  }; // class Value
245 
247  inline std::ostream& operator<<(std::ostream& os, const Value& value)
248  {
249  return value.write(os);
250  }
251 
253  class EXIV2API DataValue : public Value {
254  public:
256  typedef std::auto_ptr<DataValue> AutoPtr;
257 
258  explicit DataValue(TypeId typeId =undefined);
259 
260  DataValue(const byte* buf,
261  long len, ByteOrder byteOrder =invalidByteOrder,
262  TypeId typeId =undefined);
263 
264  virtual ~DataValue();
265 
267 
268 
280  virtual int read(const byte* buf,
281  long len,
282  ByteOrder byteOrder =invalidByteOrder);
284  virtual int read(const std::string& buf);
286 
288 
289  AutoPtr clone() const { return AutoPtr(clone_()); }
303  virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
304  virtual long count() const;
305  virtual long size() const;
306  virtual std::ostream& write(std::ostream& os) const;
312  virtual std::string toString(long n) const;
313  virtual long toLong(long n =0) const;
314  virtual float toFloat(long n =0) const;
315  virtual Rational toRational(long n =0) const;
317 
318  private:
320  virtual DataValue* clone_() const;
321 
323  typedef std::vector<byte> ValueType;
324  // DATA
325  ValueType value_;
326 
327  }; // class DataValue
328 
335  class EXIV2API StringValueBase : public Value {
336  public:
338  typedef std::auto_ptr<StringValueBase> AutoPtr;
339 
341 
342  explicit StringValueBase(TypeId typeId);
345  StringValueBase(TypeId typeId, const std::string& buf);
347  StringValueBase(const StringValueBase& rhs);
349  virtual ~StringValueBase();
351 
353 
354  virtual int read(const std::string& buf);
368  virtual int read(const byte* buf,
369  long len,
370  ByteOrder byteOrder =invalidByteOrder);
372 
374 
375  AutoPtr clone() const { return AutoPtr(clone_()); }
389  virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
390  virtual long count() const;
391  virtual long size() const;
392  virtual long toLong(long n =0) const;
393  virtual float toFloat(long n =0) const;
394  virtual Rational toRational(long n =0) const;
395  virtual std::ostream& write(std::ostream& os) const;
397 
398  protected:
400  StringValueBase& operator=(const StringValueBase& rhs);
402  virtual StringValueBase* clone_() const =0;
403 
404  public:
405  // DATA
406  std::string value_;
407 
408  }; // class StringValueBase
409 
417  class EXIV2API StringValue : public StringValueBase {
418  public:
420  typedef std::auto_ptr<StringValue> AutoPtr;
421 
423 
424  StringValue();
427  explicit StringValue(const std::string& buf);
429  virtual ~StringValue();
431 
433 
434  AutoPtr clone() const { return AutoPtr(clone_()); }
436 
437  private:
439  virtual StringValue* clone_() const;
440 
441  }; // class StringValue
442 
449  class EXIV2API AsciiValue : public StringValueBase {
450  public:
452  typedef std::auto_ptr<AsciiValue> AutoPtr;
453 
455 
456  AsciiValue();
459  explicit AsciiValue(const std::string& buf);
461  virtual ~AsciiValue();
463 
465 
466  using StringValueBase::read;
472  virtual int read(const std::string& buf);
474 
476 
477  AutoPtr clone() const { return AutoPtr(clone_()); }
483  virtual std::ostream& write(std::ostream& os) const;
485 
486  private:
488  virtual AsciiValue* clone_() const;
489 
490  }; // class AsciiValue
491 
500  class EXIV2API CommentValue : public StringValueBase {
501  public:
503  enum CharsetId { ascii, jis, unicode, undefined,
504  invalidCharsetId, lastCharsetId };
506  struct CharsetTable {
508  CharsetTable(CharsetId charsetId,
509  const char* name,
510  const char* code);
512  const char* name_;
513  const char* code_;
514  }; // struct CharsetTable
515 
517  class EXIV2API CharsetInfo {
519  CharsetInfo() {}
521  CharsetInfo(const CharsetInfo&);
523  CharsetInfo& operator=(const CharsetInfo&);
524 
525  public:
527  static const char* name(CharsetId charsetId);
529  static const char* code(CharsetId charsetId);
531  static CharsetId charsetIdByName(const std::string& name);
533  static CharsetId charsetIdByCode(const std::string& code);
534 
535  private:
536  static const CharsetTable charsetTable_[];
537  }; // class CharsetInfo
538 
540  typedef std::auto_ptr<CommentValue> AutoPtr;
541 
543 
544  CommentValue();
547  explicit CommentValue(const std::string& comment);
549  virtual ~CommentValue();
551 
553 
554 
566  int read(const std::string& comment);
570  int read(const byte* buf, long len, ByteOrder byteOrder);
572 
574 
575  AutoPtr clone() const { return AutoPtr(clone_()); }
576  long copy(byte* buf, ByteOrder byteOrder) const;
581  std::ostream& write(std::ostream& os) const;
596  std::string comment(const char* encoding =0) const;
606  const char* detectCharset(std::string& c) const;
608  CharsetId charsetId() const;
610 
611  private:
613  virtual CommentValue* clone_() const;
614 
615  public:
616  // DATA
618 
619  }; // class CommentValue
620 
624  class EXIV2API XmpValue : public Value {
625  public:
627  typedef std::auto_ptr<XmpValue> AutoPtr;
628 
630  enum XmpArrayType { xaNone, xaAlt, xaBag, xaSeq };
632  enum XmpStruct { xsNone, xsStruct };
633 
635 
636  explicit XmpValue(TypeId typeId);
638 
640 
641  XmpArrayType xmpArrayType() const;
644  XmpStruct xmpStruct() const;
645  virtual long size() const;
659  virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
661 
663 
664  void setXmpArrayType(XmpArrayType xmpArrayType);
667  void setXmpStruct(XmpStruct xmpStruct =xsStruct);
682  virtual int read(const byte* buf,
683  long len,
684  ByteOrder byteOrder =invalidByteOrder);
685  virtual int read(const std::string& buf) =0;
687 
692  static XmpArrayType xmpArrayType(TypeId typeId);
693 
694  protected:
699  XmpValue& operator=(const XmpValue& rhs);
700 
701  private:
702  // DATA
703  XmpArrayType xmpArrayType_;
704  XmpStruct xmpStruct_;
705 
706  }; // class XmpValue
707 
715  class EXIV2API XmpTextValue : public XmpValue {
716  public:
718  typedef std::auto_ptr<XmpTextValue> AutoPtr;
719 
721 
722  XmpTextValue();
725  explicit XmpTextValue(const std::string& buf);
727 
729 
730  using XmpValue::read;
746  virtual int read(const std::string& buf);
748 
750 
751  AutoPtr clone() const;
752  long size() const;
753  virtual long count() const;
760  virtual long toLong(long n =0) const;
767  virtual float toFloat(long n =0) const;
774  virtual Rational toRational(long n =0) const;
775  virtual std::ostream& write(std::ostream& os) const;
777 
778  private:
780  virtual XmpTextValue* clone_() const;
781 
782  public:
783  // DATA
784  std::string value_;
785 
786  }; // class XmpTextValue
787 
797  class EXIV2API XmpArrayValue : public XmpValue {
798  public:
800  typedef std::auto_ptr<XmpArrayValue> AutoPtr;
801 
803 
804  explicit XmpArrayValue(TypeId typeId =xmpBag);
807 
809 
810  using XmpValue::read;
821  virtual int read(const std::string& buf);
823 
825 
826  AutoPtr clone() const;
827  virtual long count() const;
833  virtual std::string toString(long n) const;
834  virtual long toLong(long n =0) const;
835  virtual float toFloat(long n =0) const;
836  virtual Rational toRational(long n =0) const;
843  virtual std::ostream& write(std::ostream& os) const;
845 
846  private:
848  virtual XmpArrayValue* clone_() const;
849 
850  std::vector<std::string> value_;
851 
852  }; // class XmpArrayValue
853 
863  bool operator() (const std::string& str1, const std::string& str2) const
864  {
865  int result = str1.size() < str2.size() ? 1
866  : str1.size() > str2.size() ? -1
867  : 0
868  ;
869  std::string::const_iterator c1 = str1.begin();
870  std::string::const_iterator c2 = str2.begin();
871  if ( result==0 ) for (
872  ; result==0 && c1 != str1.end()
873  ; ++c1, ++c2
874  ) {
875  result = tolower(*c1) < tolower(*c2) ? 1
876  : tolower(*c1) > tolower(*c2) ? -1
877  : 0
878  ;
879  }
880  return result < 0 ;
881  }
882  };
883 
890  class EXIV2API LangAltValue : public XmpValue {
891  public:
893  typedef std::auto_ptr<LangAltValue> AutoPtr;
894 
896 
897  LangAltValue();
900  explicit LangAltValue(const std::string& buf);
902 
904 
905  using XmpValue::read;
923  virtual int read(const std::string& buf);
925 
927 
928  AutoPtr clone() const;
929  virtual long count() const;
937  virtual std::string toString(long n) const;
943  std::string toString(const std::string& qualifier) const;
944  virtual long toLong(long n =0) const;
945  virtual float toFloat(long n =0) const;
946  virtual Rational toRational(long n =0) const;
953  virtual std::ostream& write(std::ostream& os) const;
955 
956  private:
958  virtual LangAltValue* clone_() const;
959 
960  public:
962  typedef std::map<std::string, std::string,LangAltValueComparator> ValueType;
963  // DATA
969 
970  }; // class LangAltValue
971 
978  class EXIV2API DateValue : public Value {
979  public:
981  typedef std::auto_ptr<DateValue> AutoPtr;
982 
984 
985  DateValue();
988  DateValue(int year, int month, int day);
990  virtual ~DateValue();
992 
994  struct EXIV2API Date {
995  Date() : year(0), month(0), day(0) {}
996  int year;
997  int month;
998  int day;
999  };
1000 
1002 
1003 
1016  virtual int read(const byte* buf,
1017  long len,
1018  ByteOrder byteOrder =invalidByteOrder);
1027  virtual int read(const std::string& buf);
1029  void setDate(const Date& src);
1031 
1033 
1034  AutoPtr clone() const { return AutoPtr(clone_()); }
1048  virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
1050  virtual const Date& getDate() const;
1051  virtual long count() const;
1052  virtual long size() const;
1053  virtual std::ostream& write(std::ostream& os) const;
1055  virtual long toLong(long n =0) const;
1057  virtual float toFloat(long n =0) const;
1059  virtual Rational toRational(long n =0) const;
1061 
1062  private:
1064  virtual DateValue* clone_() const;
1065 
1066  // DATA
1067  Date date_;
1068 
1069  }; // class DateValue
1070 
1079  class EXIV2API TimeValue : public Value {
1080  public:
1082  typedef std::auto_ptr<TimeValue> AutoPtr;
1083 
1085 
1086  TimeValue();
1089  TimeValue(int hour, int minute, int second =0,
1090  int tzHour =0, int tzMinute =0);
1091 
1093  virtual ~TimeValue();
1095 
1097  struct Time
1098  {
1099  Time() : hour(0), minute(0), second(0), tzHour(0), tzMinute(0) {}
1100 
1101  int hour;
1102  int minute;
1103  int second;
1104  int tzHour;
1105  int tzMinute;
1106  };
1107 
1109 
1110 
1123  virtual int read(const byte* buf,
1124  long len,
1125  ByteOrder byteOrder =invalidByteOrder);
1134  virtual int read(const std::string& buf);
1136  void setTime(const Time& src);
1138 
1140 
1141  AutoPtr clone() const { return AutoPtr(clone_()); }
1155  virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
1157  virtual const Time& getTime() const;
1158  virtual long count() const;
1159  virtual long size() const;
1160  virtual std::ostream& write(std::ostream& os) const;
1162  virtual long toLong(long n =0) const;
1164  virtual float toFloat(long n =0) const;
1166  virtual Rational toRational(long n =0) const;
1168 
1169  private:
1171 
1172 
1182  int scanTime3(const char* buf, const char* format);
1193  int scanTime6(const char* buf, const char* format);
1195 
1197 
1198  virtual TimeValue* clone_() const;
1201 
1202  // DATA
1203  Time time_;
1204 
1205  }; // class TimeValue
1206 
1208  template<typename T> TypeId getType();
1209 
1211  template<> inline TypeId getType<uint16_t>() { return unsignedShort; }
1213  template<> inline TypeId getType<uint32_t>() { return unsignedLong; }
1215  template<> inline TypeId getType<URational>() { return unsignedRational; }
1217  template<> inline TypeId getType<int16_t>() { return signedShort; }
1219  template<> inline TypeId getType<int32_t>() { return signedLong; }
1221  template<> inline TypeId getType<Rational>() { return signedRational; }
1223  template<> inline TypeId getType<float>() { return tiffFloat; }
1225  template<> inline TypeId getType<double>() { return tiffDouble; }
1226 
1227  // No default implementation: let the compiler/linker complain
1228  // template<typename T> inline TypeId getType() { return invalid; }
1229 
1234  template<typename T>
1235  class ValueType : public Value {
1236  public:
1238  typedef std::auto_ptr<ValueType<T> > AutoPtr;
1239 
1241 
1242  ValueType();
1245  // The default c'tor and this one can be combined, but that causes MSVC 7.1 to fall on its nose
1246  explicit ValueType(TypeId typeId);
1248  ValueType(const byte* buf, long len, ByteOrder byteOrder, TypeId typeId =getType<T>());
1250  explicit ValueType(const T& val, TypeId typeId =getType<T>());
1252  ValueType(const ValueType<T>& rhs);
1254  virtual ~ValueType();
1256 
1258 
1259  ValueType<T>& operator=(const ValueType<T>& rhs);
1261  virtual int read(const byte* buf, long len, ByteOrder byteOrder);
1268  virtual int read(const std::string& buf);
1273  virtual int setDataArea(const byte* buf, long len);
1275 
1277 
1278  AutoPtr clone() const { return AutoPtr(clone_()); }
1279  virtual long copy(byte* buf, ByteOrder byteOrder) const;
1280  virtual long count() const;
1281  virtual long size() const;
1282  virtual std::ostream& write(std::ostream& os) const;
1289  virtual std::string toString(long n) const;
1290  virtual long toLong(long n =0) const;
1291  virtual float toFloat(long n =0) const;
1292  virtual Rational toRational(long n =0) const;
1294  virtual long sizeDataArea() const;
1299  virtual DataBuf dataArea() const;
1301 
1303  typedef std::vector<T> ValueList;
1305  typedef typename std::vector<T>::iterator iterator;
1307  typedef typename std::vector<T>::const_iterator const_iterator;
1308 
1309  // DATA
1317 
1318  private:
1320  virtual ValueType<T>* clone_() const;
1321 
1322  // DATA
1324  byte* pDataArea_;
1326  long sizeDataArea_;
1327  }; // class ValueType
1328 
1345 
1346 // *****************************************************************************
1347 // free functions, template and inline definitions
1348 
1360  template<typename T> T getValue(const byte* buf, ByteOrder byteOrder);
1361  // Specialization for a 2 byte unsigned short value.
1362  template<>
1363  inline uint16_t getValue(const byte* buf, ByteOrder byteOrder)
1364  {
1365  return getUShort(buf, byteOrder);
1366  }
1367  // Specialization for a 4 byte unsigned long value.
1368  template<>
1369  inline uint32_t getValue(const byte* buf, ByteOrder byteOrder)
1370  {
1371  return getULong(buf, byteOrder);
1372  }
1373  // Specialization for an 8 byte unsigned rational value.
1374  template<>
1375  inline URational getValue(const byte* buf, ByteOrder byteOrder)
1376  {
1377  return getURational(buf, byteOrder);
1378  }
1379  // Specialization for a 2 byte signed short value.
1380  template<>
1381  inline int16_t getValue(const byte* buf, ByteOrder byteOrder)
1382  {
1383  return getShort(buf, byteOrder);
1384  }
1385  // Specialization for a 4 byte signed long value.
1386  template<>
1387  inline int32_t getValue(const byte* buf, ByteOrder byteOrder)
1388  {
1389  return getLong(buf, byteOrder);
1390  }
1391  // Specialization for an 8 byte signed rational value.
1392  template<>
1393  inline Rational getValue(const byte* buf, ByteOrder byteOrder)
1394  {
1395  return getRational(buf, byteOrder);
1396  }
1397  // Specialization for a 4 byte float value.
1398  template<>
1399  inline float getValue(const byte* buf, ByteOrder byteOrder)
1400  {
1401  return getFloat(buf, byteOrder);
1402  }
1403  // Specialization for a 8 byte double value.
1404  template<>
1405  inline double getValue(const byte* buf, ByteOrder byteOrder)
1406  {
1407  return getDouble(buf, byteOrder);
1408  }
1409 
1422  template<typename T> long toData(byte* buf, T t, ByteOrder byteOrder);
1427  template<>
1428  inline long toData(byte* buf, uint16_t t, ByteOrder byteOrder)
1429  {
1430  return us2Data(buf, t, byteOrder);
1431  }
1436  template<>
1437  inline long toData(byte* buf, uint32_t t, ByteOrder byteOrder)
1438  {
1439  return ul2Data(buf, t, byteOrder);
1440  }
1445  template<>
1446  inline long toData(byte* buf, URational t, ByteOrder byteOrder)
1447  {
1448  return ur2Data(buf, t, byteOrder);
1449  }
1454  template<>
1455  inline long toData(byte* buf, int16_t t, ByteOrder byteOrder)
1456  {
1457  return s2Data(buf, t, byteOrder);
1458  }
1463  template<>
1464  inline long toData(byte* buf, int32_t t, ByteOrder byteOrder)
1465  {
1466  return l2Data(buf, t, byteOrder);
1467  }
1472  template<>
1473  inline long toData(byte* buf, Rational t, ByteOrder byteOrder)
1474  {
1475  return r2Data(buf, t, byteOrder);
1476  }
1481  template<>
1482  inline long toData(byte* buf, float t, ByteOrder byteOrder)
1483  {
1484  return f2Data(buf, t, byteOrder);
1485  }
1490  template<>
1491  inline long toData(byte* buf, double t, ByteOrder byteOrder)
1492  {
1493  return d2Data(buf, t, byteOrder);
1494  }
1495 
1496  template<typename T>
1498  : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0)
1499  {
1500  }
1501 
1502  template<typename T>
1504  : Value(typeId), pDataArea_(0), sizeDataArea_(0)
1505  {
1506  }
1507 
1508  template<typename T>
1509  ValueType<T>::ValueType(const byte* buf, long len, ByteOrder byteOrder, TypeId typeId)
1510  : Value(typeId), pDataArea_(0), sizeDataArea_(0)
1511  {
1512  read(buf, len, byteOrder);
1513  }
1514 
1515  template<typename T>
1516  ValueType<T>::ValueType(const T& val, TypeId typeId)
1517  : Value(typeId), pDataArea_(0), sizeDataArea_(0)
1518  {
1519  value_.push_back(val);
1520  }
1521 
1522  template<typename T>
1524  : Value(rhs), value_(rhs.value_), pDataArea_(0), sizeDataArea_(0)
1525  {
1526  if (rhs.sizeDataArea_ > 0) {
1527  pDataArea_ = new byte[rhs.sizeDataArea_];
1528  std::memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea_);
1529  sizeDataArea_ = rhs.sizeDataArea_;
1530  }
1531  }
1532 
1533  template<typename T>
1535  {
1536  delete[] pDataArea_;
1537  }
1538 
1539  template<typename T>
1541  {
1542  if (this == &rhs) return *this;
1543  Value::operator=(rhs);
1544  value_ = rhs.value_;
1545 
1546  byte* tmp = 0;
1547  if (rhs.sizeDataArea_ > 0) {
1548  tmp = new byte[rhs.sizeDataArea_];
1549  std::memcpy(tmp, rhs.pDataArea_, rhs.sizeDataArea_);
1550  }
1551  delete[] pDataArea_;
1552  pDataArea_ = tmp;
1553  sizeDataArea_ = rhs.sizeDataArea_;
1554 
1555  return *this;
1556  }
1557 
1558  template<typename T>
1559  int ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
1560  {
1561  value_.clear();
1562  long ts = TypeInfo::typeSize(typeId());
1563  if (ts > 0)
1564  if (len % ts != 0) len = (len / ts) * ts;
1565  for (long i = 0; i < len; i += ts) {
1566  value_.push_back(getValue<T>(buf + i, byteOrder));
1567  }
1568  return 0;
1569  }
1570 
1571  template<typename T>
1572  int ValueType<T>::read(const std::string& buf)
1573  {
1574  std::istringstream is(buf);
1575  T tmp = T();
1576  ValueList val;
1577  while (!(is.eof())) {
1578  is >> tmp;
1579  if (is.fail()) return 1;
1580  val.push_back(tmp);
1581  }
1582  value_.swap(val);
1583  return 0;
1584  }
1585 
1586  template<typename T>
1587  long ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const
1588  {
1589  long offset = 0;
1590  typename ValueList::const_iterator end = value_.end();
1591  for (typename ValueList::const_iterator i = value_.begin(); i != end; ++i) {
1592  offset += toData(buf + offset, *i, byteOrder);
1593  }
1594  return offset;
1595  }
1596 
1597  template<typename T>
1598  long ValueType<T>::count() const
1599  {
1600  return static_cast<long>(value_.size());
1601  }
1602 
1603  template<typename T>
1604  long ValueType<T>::size() const
1605  {
1606  return static_cast<long>(TypeInfo::typeSize(typeId()) * value_.size());
1607  }
1608 
1609  template<typename T>
1611  {
1612  return new ValueType<T>(*this);
1613  }
1614 
1615  template<typename T>
1616  std::ostream& ValueType<T>::write(std::ostream& os) const
1617  {
1618  typename ValueList::const_iterator end = value_.end();
1619  typename ValueList::const_iterator i = value_.begin();
1620  while (i != end) {
1621  os << std::setprecision(15) << *i;
1622  if (++i != end) os << " ";
1623  }
1624  return os;
1625  }
1626 
1627  template<typename T>
1628  std::string ValueType<T>::toString(long n) const
1629  {
1630  ok_ = true;
1631  return Exiv2::toString<T>(value_.at(n));
1632  }
1633 
1634  // Default implementation
1635  template<typename T>
1636  long ValueType<T>::toLong(long n) const
1637  {
1638  ok_ = true;
1639  return static_cast<long>(value_.at(n));
1640  }
1641 // #55 crash when value_.at(n).first == LONG_MIN
1642 #define LARGE_INT 1000000
1643  // Specialization for double
1644  template<>
1645  inline long ValueType<double>::toLong(long n) const
1646  {
1647  const double v = value_.at(n);
1648  ok_ = (INT_MIN <= v && v <= INT_MAX);
1649  if (!ok_) return 0;
1650  return static_cast<long>(v);
1651  }
1652  // Specialization for float
1653  template<>
1654  inline long ValueType<float>::toLong(long n) const
1655  {
1656  const double v = value_.at(n);
1657  ok_ = (INT_MIN <= v && v <= INT_MAX);
1658  if (!ok_) return 0;
1659  return static_cast<long>(v);
1660  }
1661  // Specialization for rational
1662  template<>
1663  inline long ValueType<Rational>::toLong(long n) const
1664  {
1665  ok_ = (value_.at(n).second > 0 && INT_MIN < value_.at(n).first && value_.at(n).first < INT_MAX );
1666  if (!ok_) return 0;
1667  return value_.at(n).first / value_.at(n).second;
1668  }
1669  // Specialization for unsigned rational
1670  template<>
1671  inline long ValueType<URational>::toLong(long n) const
1672  {
1673  ok_ = (value_.at(n).second > 0 && value_.at(n).first < LARGE_INT);
1674  if (!ok_) return 0;
1675  return value_.at(n).first / value_.at(n).second;
1676  }
1677  // Default implementation
1678  template<typename T>
1679  float ValueType<T>::toFloat(long n) const
1680  {
1681  ok_ = true;
1682  return static_cast<float>(value_.at(n));
1683  }
1684  // Specialization for rational
1685  template<>
1686  inline float ValueType<Rational>::toFloat(long n) const
1687  {
1688  ok_ = (value_.at(n).second != 0);
1689  if (!ok_) return 0.0f;
1690  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1691  }
1692  // Specialization for unsigned rational
1693  template<>
1694  inline float ValueType<URational>::toFloat(long n) const
1695  {
1696  ok_ = (value_.at(n).second != 0);
1697  if (!ok_) return 0.0f;
1698  return static_cast<float>(value_.at(n).first) / value_.at(n).second;
1699  }
1700  // Default implementation
1701  template<typename T>
1703  {
1704  ok_ = true;
1705  return Rational(value_.at(n), 1);
1706  }
1707  // Specialization for rational
1708  template<>
1710  {
1711  ok_ = true;
1712  return Rational(value_.at(n).first, value_.at(n).second);
1713  }
1714  // Specialization for unsigned rational
1715  template<>
1717  {
1718  ok_ = true;
1719  return Rational(value_.at(n).first, value_.at(n).second);
1720  }
1721  // Specialization for float.
1722  template<>
1724  {
1725  ok_ = true;
1726  // Warning: This is a very simple conversion, see floatToRationalCast()
1727  return floatToRationalCast(value_.at(n));
1728  }
1729  // Specialization for double.
1730  template<>
1732  {
1733  ok_ = true;
1734  // Warning: This is a very simple conversion, see floatToRationalCast()
1735  return floatToRationalCast(static_cast<float>(value_.at(n)));
1736  }
1737 
1738  template<typename T>
1740  {
1741  return sizeDataArea_;
1742  }
1743 
1744  template<typename T>
1746  {
1747  return DataBuf(pDataArea_, sizeDataArea_);
1748  }
1749 
1750  template<typename T>
1751  int ValueType<T>::setDataArea(const byte* buf, long len)
1752  {
1753  byte* tmp = 0;
1754  if (len > 0) {
1755  tmp = new byte[len];
1756  std::memcpy(tmp, buf, len);
1757  }
1758  delete[] pDataArea_;
1759  pDataArea_ = tmp;
1760  sizeDataArea_ = len;
1761  return 0;
1762  }
1763 } // namespace Exiv2
1764 
1765 #endif // #ifndef VALUE_HPP_
Value for an Ascii string type.
Definition: value.hpp:449
std::auto_ptr< AsciiValue > AutoPtr
Shortcut for a AsciiValue auto pointer.
Definition: value.hpp:452
Charset information lookup functions. Implemented as a static class.
Definition: value.hpp:517
Value for an Exif comment.
Definition: value.hpp:500
ByteOrder byteOrder_
Byte order of the comment string that was read.
Definition: value.hpp:617
std::auto_ptr< CommentValue > AutoPtr
Shortcut for a CommentValue auto pointer.
Definition: value.hpp:540
CharsetId
Character set identifiers for the character sets defined by Exif.
Definition: value.hpp:503
Utility class containing a character array. All it does is to take care of memory allocation and dele...
Definition: types.hpp:193
Value for an undefined data type.
Definition: value.hpp:253
std::auto_ptr< DataValue > AutoPtr
Shortcut for a DataValue auto pointer.
Definition: value.hpp:256
Value for simple ISO 8601 dates
Definition: value.hpp:978
std::auto_ptr< DateValue > AutoPtr
Shortcut for a DateValue auto pointer.
Definition: value.hpp:981
Value type for XMP language alternative properties.
Definition: value.hpp:890
std::auto_ptr< LangAltValue > AutoPtr
Shortcut for a LangAltValue auto pointer.
Definition: value.hpp:893
std::map< std::string, std::string, LangAltValueComparator > ValueType
Type used to store language alternative arrays.
Definition: value.hpp:962
ValueType value_
Map to store the language alternative values. The language qualifier is used as the key for the map e...
Definition: value.hpp:968
Abstract base class for a string based Value type.
Definition: value.hpp:335
std::string value_
Stores the string value.
Definition: value.hpp:406
std::auto_ptr< StringValueBase > AutoPtr
Shortcut for a StringValueBase auto pointer.
Definition: value.hpp:338
virtual int read(const std::string &buf)
Read the value from buf. This default implementation uses buf as it is.
Definition: value.cpp:314
virtual StringValueBase * clone_() const =0
Internal virtual copy constructor.
Value for string type.
Definition: value.hpp:417
std::auto_ptr< StringValue > AutoPtr
Shortcut for a StringValue auto pointer.
Definition: value.hpp:420
Value for simple ISO 8601 times.
Definition: value.hpp:1079
std::auto_ptr< TimeValue > AutoPtr
Shortcut for a TimeValue auto pointer.
Definition: value.hpp:1082
static long typeSize(TypeId typeId)
Return the size in bytes of one element of this type.
Definition: types.cpp:116
Template for a Value of a basic type. This is used for unsigned and signed short, long and rationals.
Definition: value.hpp:1235
ValueType< T > & operator=(const ValueType< T > &rhs)
Assignment operator.
Definition: value.hpp:1540
std::auto_ptr< ValueType< T > > AutoPtr
Shortcut for a ValueType<T> auto pointer.
Definition: value.hpp:1238
virtual long toLong(long n=0) const
Convert the n-th component of the value to a long. The behaviour of this method may be undefined if t...
Definition: value.hpp:1636
virtual long count() const
Return the number of components of the value.
Definition: value.hpp:1598
virtual int setDataArea(const byte *buf, long len)
Set the data area. This method copies (clones) the buffer pointed to by buf.
Definition: value.hpp:1751
std::vector< T >::iterator iterator
Iterator type defined for convenience.
Definition: value.hpp:1305
virtual long size() const
Return the size of the value in bytes.
Definition: value.hpp:1604
virtual long sizeDataArea() const
Return the size of the data area.
Definition: value.hpp:1739
virtual ~ValueType()
Virtual destructor.
Definition: value.hpp:1534
virtual int read(const byte *buf, long len, ByteOrder byteOrder)
Read the value from a character buffer.
Definition: value.hpp:1559
std::vector< T > ValueList
Container for values.
Definition: value.hpp:1303
virtual DataBuf dataArea() const
Return a copy of the data area in a DataBuf. The caller owns this copy and DataBuf ensures that it wi...
Definition: value.hpp:1745
ValueType()
Default Constructor.
Definition: value.hpp:1497
virtual Rational toRational(long n=0) const
Convert the n-th component of the value to a Rational. The behaviour of this method may be undefined ...
Definition: value.hpp:1702
virtual std::ostream & write(std::ostream &os) const
Write the value to an output stream. You do not usually have to use this function; it is used for the...
Definition: value.hpp:1616
std::vector< T >::const_iterator const_iterator
Const iterator type defined for convenience.
Definition: value.hpp:1307
virtual float toFloat(long n=0) const
Convert the n-th component of the value to a float. The behaviour of this method may be undefined if ...
Definition: value.hpp:1679
ValueList value_
The container for all values. In your application, if you know what subclass of Value you're dealing ...
Definition: value.hpp:1316
virtual long copy(byte *buf, ByteOrder byteOrder) const
Write value to a data buffer.
Definition: value.hpp:1587
Common interface for all types of values used with metadata.
Definition: value.hpp:51
TypeId typeId() const
Return the type identifier (Exif data format type).
Definition: value.hpp:104
std::auto_ptr< Value > AutoPtr
Shortcut for a Value auto pointer.
Definition: value.hpp:54
AutoPtr 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:110
virtual float toFloat(long 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 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 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 long size() const =0
Return the size of the value in bytes.
virtual long copy(byte *buf, ByteOrder byteOrder) const =0
Write value to a data buffer.
virtual long toLong(long n=0) const =0
Convert the n-th component of the value to a long. The behaviour of this method may be undefined if t...
bool ok_
Indicates the status of the previous to<Type> conversion.
Definition: value.hpp:236
bool ok() const
Check the ok status indicator. After a to<Type> conversion, this indicator shows whether the conversi...
Definition: value.hpp:188
virtual Rational toRational(long n=0) const =0
Convert the n-th component of the value to a Rational. The behaviour of this method may be undefined ...
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:168
Value & operator=(const Value &rhs)
Assignment operator. Protected so that it can only be used by subclasses but not directly.
Definition: value.cpp:85
virtual int read(const byte *buf, long len, ByteOrder byteOrder)=0
Read the value from a character buffer.
virtual long count() const =0
Return the number of components of the value.
Value type for simple arrays. Each item in the array is a simple value, without qualifiers....
Definition: value.hpp:797
std::auto_ptr< XmpArrayValue > AutoPtr
Shortcut for a XmpArrayValue auto pointer.
Definition: value.hpp:800
Value type suitable for simple XMP properties and XMP nodes of complex types which are not parsed int...
Definition: value.hpp:715
std::auto_ptr< XmpTextValue > AutoPtr
Shortcut for a XmpTextValue auto pointer.
Definition: value.hpp:718
std::string value_
Stores the string values.
Definition: value.hpp:784
Base class for all Exiv2 values used to store XMP property values.
Definition: value.hpp:624
std::auto_ptr< XmpValue > AutoPtr
Shortcut for a XmpValue auto pointer.
Definition: value.hpp:627
virtual int read(const byte *buf, long len, ByteOrder byteOrder=invalidByteOrder)
Read the value from a character buffer.
Definition: value.cpp:664
XmpStruct
XMP structure indicator.
Definition: value.hpp:632
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...
XmpArrayType
XMP array types.
Definition: value.hpp:630
Provides classes and functions to encode and decode Exif and Iptc data. The libexiv2 API consists of ...
Definition: asfvideo.hpp:36
EXIV2API std::ostream & operator<<(std::ostream &os, const DataSet &dataSet)
Output operator for dataSet.
Definition: datasets.cpp:709
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:356
TypeId getType< int32_t >()
Specialization for a signed long.
Definition: value.hpp:1219
EXIV2API long 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:464
EXIV2API long 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:478
ValueType< URational > URationalValue
Unsigned rational value type.
Definition: value.hpp:1334
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:342
TypeId getType< int16_t >()
Specialization for a signed short.
Definition: value.hpp:1217
EXIV2API Rational floatToRationalCast(float f)
Very simple conversion of a float to a Rational.
Definition: types.cpp:689
EXIV2API long 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:440
EXIV2API int16_t getShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte signed short value from the data buffer.
Definition: types.cpp:313
ValueType< uint16_t > UShortValue
Unsigned short value type.
Definition: value.hpp:1330
TypeId getType< uint32_t >()
Specialization for an unsigned long.
Definition: value.hpp:1213
EXIV2API uint32_t getULong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte unsigned long value from the data buffer.
Definition: types.cpp:278
EXIV2API long 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:403
ValueType< int32_t > LongValue
Signed long value type.
Definition: value.hpp:1338
T getValue(const byte *buf, ByteOrder byteOrder)
Read a value of type T from the data buffer.
Definition: value.hpp:1363
TypeId
Exiv2 value type identifiers.
Definition: types.hpp:119
@ unsignedShort
Exif SHORT type, 16-bit (2-byte) unsigned integer.
Definition: types.hpp:122
@ signedRational
Exif SRATIONAL type, two SLONGs: numerator and denumerator of a fraction.
Definition: types.hpp:129
@ unsignedLong
Exif LONG type, 32-bit (4-byte) unsigned integer.
Definition: types.hpp:123
@ signedShort
Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
Definition: types.hpp:127
@ signedLong
Exif SLONG type, a 32-bit (4-byte) signed (twos-complement) integer.
Definition: types.hpp:128
@ comment
Exiv2 type for the Exif user comment.
Definition: types.hpp:139
@ tiffDouble
TIFF DOUBLE type, double precision (8-byte) IEEE format.
Definition: types.hpp:131
@ undefined
Exif UNDEFINED type, an 8-bit byte that may contain anything.
Definition: types.hpp:126
@ xmpBag
XMP bag type.
Definition: types.hpp:143
@ tiffFloat
TIFF FLOAT type, single precision (4-byte) IEEE format.
Definition: types.hpp:130
@ unsignedRational
Exif RATIONAL type, two LONGs: numerator and denumerator of a fraction.
Definition: types.hpp:124
long toData(byte *buf, T t, ByteOrder byteOrder)
Convert a value of type T to data, write the data to the data buffer.
EXIV2API uint16_t getUShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte unsigned short value from the data buffer.
Definition: types.cpp:273
ValueType< int16_t > ShortValue
Signed short value type.
Definition: value.hpp:1336
ValueType< float > FloatValue
Float value type.
Definition: value.hpp:1342
ByteOrder
Type to express the byte order (little or big endian)
Definition: types.hpp:102
std::pair< int32_t, int32_t > Rational
8 byte signed rational type.
Definition: types.hpp:99
TypeId getType< uint16_t >()
Specialization for an unsigned short.
Definition: value.hpp:1211
ValueType< uint32_t > ULongValue
Unsigned long value type.
Definition: value.hpp:1332
ValueType< Rational > RationalValue
Signed rational value type.
Definition: value.hpp:1340
EXIV2API Rational getRational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte signed rational value from the data buffer.
Definition: types.cpp:335
EXIV2API long 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:457
TypeId getType< URational >()
Specialization for an unsigned rational.
Definition: value.hpp:1215
TypeId getType< float >()
Specialization for a float.
Definition: value.hpp:1223
EXIV2API long 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:420
EXIV2API int32_t getLong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte signed long value from the data buffer.
Definition: types.cpp:323
TypeId getType< Rational >()
Specialization for a signed rational.
Definition: value.hpp:1221
TypeId getType< double >()
Specialization for a double.
Definition: value.hpp:1225
EXIV2API long 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:427
std::string toString(const T &arg)
Utility function to convert the argument of any type to a string.
Definition: types.hpp:510
std::pair< uint32_t, uint32_t > URational
8 byte unsigned rational type.
Definition: types.hpp:97
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:306
ValueType< double > DoubleValue
Double value type.
Definition: value.hpp:1344
EXIV2API long 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:390
Information pertaining to the defined character sets.
Definition: value.hpp:506
CharsetId charsetId_
Charset id.
Definition: value.hpp:511
const char * name_
Name of the charset.
Definition: value.hpp:512
const char * code_
Code of the charset.
Definition: value.hpp:513
Simple Date helper structure.
Definition: value.hpp:994
int year
Year.
Definition: value.hpp:996
int month
Month.
Definition: value.hpp:997
int day
Day.
Definition: value.hpp:998
LangAltValueComparator
Definition: value.hpp:861
bool operator()(const std::string &str1, const std::string &str2) const
LangAltValueComparator comparison case insensitive function.
Definition: value.hpp:863
Simple Time helper structure.
Definition: value.hpp:1098
int minute
Minute.
Definition: value.hpp:1102
int second
Second.
Definition: value.hpp:1103
int hour
Hour.
Definition: value.hpp:1101
int tzHour
Hours ahead or behind UTC.
Definition: value.hpp:1104
int tzMinute
Minutes ahead or behind UTC.
Definition: value.hpp:1105