Blame include/exiv2/types.hpp

Packit Service 21b5d1
// ***************************************************************** -*- C++ -*-
Packit Service 21b5d1
/*
Packit Service 21b5d1
 * Copyright (C) 2004-2018 Exiv2 authors
Packit Service 21b5d1
 * This program is part of the Exiv2 distribution.
Packit Service 21b5d1
 *
Packit Service 21b5d1
 * This program is free software; you can redistribute it and/or
Packit Service 21b5d1
 * modify it under the terms of the GNU General Public License
Packit Service 21b5d1
 * as published by the Free Software Foundation; either version 2
Packit Service 21b5d1
 * of the License, or (at your option) any later version.
Packit Service 21b5d1
 *
Packit Service 21b5d1
 * This program is distributed in the hope that it will be useful,
Packit Service 21b5d1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 21b5d1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 21b5d1
 * GNU General Public License for more details.
Packit Service 21b5d1
 *
Packit Service 21b5d1
 * You should have received a copy of the GNU General Public License
Packit Service 21b5d1
 * along with this program; if not, write to the Free Software
Packit Service 21b5d1
 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
Packit Service 21b5d1
 */
Packit Service 21b5d1
/*!
Packit Service 21b5d1
  @file    types.hpp
Packit Service 21b5d1
  @brief   Type definitions for %Exiv2 and related functionality
Packit Service 21b5d1
  @author  Andreas Huggel (ahu)
Packit Service 21b5d1
           ahuggel@gmx.net
Packit Service 21b5d1
  @date    09-Jan-04, ahu: created
Packit Service 21b5d1
           11-Feb-04, ahu: isolated as a component
Packit Service 21b5d1
           31-Jul-04, brad: added Time, Data and String values
Packit Service 21b5d1
 */
Packit Service 21b5d1
#ifndef TYPES_HPP_
Packit Service 21b5d1
#define TYPES_HPP_
Packit Service 21b5d1
Packit Service 21b5d1
#include "exiv2lib_export.h"
Packit Service 21b5d1
Packit Service 21b5d1
// included header files
Packit Service 21b5d1
#include "config.h"
Packit Service 21b5d1
#include "slice.hpp"
Packit Service 21b5d1
Packit Service 21b5d1
// + standard includes
Packit Service 21b5d1
#include <string>
Packit Service 21b5d1
#include <vector>
Packit Service 21b5d1
#include <limits>
Packit Service 21b5d1
#include <algorithm>
Packit Service 21b5d1
#include <sstream>
Packit Service 21b5d1
Packit Service 21b5d1
#ifdef _MSC_VER
Packit Service 21b5d1
// Visual Studio 2010 and later has stdint.h
Packit Service 21b5d1
# if   _MSC_VER >= _MSC_VER_2010
Packit Service 21b5d1
#  include <stdint.h>
Packit Service 21b5d1
# else
Packit Service 21b5d1
// Earlier compilers have MS C99 equivalents such as __int8
Packit Service 21b5d1
   typedef unsigned __int8  uint8_t;
Packit Service 21b5d1
   typedef unsigned __int16 uint16_t;
Packit Service 21b5d1
   typedef unsigned __int32 uint32_t;
Packit Service 21b5d1
   typedef unsigned __int64 uint64_t;
Packit Service 21b5d1
   typedef          __int8  int8_t;
Packit Service 21b5d1
   typedef          __int16 int16_t;
Packit Service 21b5d1
   typedef          __int32 int32_t;
Packit Service 21b5d1
   typedef          __int64 int64_t;
Packit Service 21b5d1
# endif
Packit Service 21b5d1
#else
Packit Service 21b5d1
  #ifdef EXV_HAVE_STDINT_H
Packit Service 21b5d1
  # include <stdint.h>
Packit Service 21b5d1
  #endif
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
Packit Service 21b5d1
// MSVC macro to convert a string to a wide string
Packit Service 21b5d1
#ifdef EXV_UNICODE_PATH
Packit Service 21b5d1
# define EXV_WIDEN(t) L ## t
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
/*!
Packit Service 21b5d1
  @brief Macro to make calls to member functions through a pointer more readable.
Packit Service 21b5d1
         See the C++ FAQ LITE, item
Packit Service 21b5d1
         [33.5] How can I avoid syntax errors when calling a member function using a pointer-to-member-function?.
Packit Service 21b5d1
 */
Packit Service 21b5d1
#define EXV_CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))
Packit Service 21b5d1
Packit Service 21b5d1
// Simple min and max macros
Packit Service 21b5d1
//! Simple common min macro
Packit Service 21b5d1
#define EXV_MIN(a,b) ((a) < (b) ? (a) : (b))
Packit Service 21b5d1
//! Simple common max macro
Packit Service 21b5d1
#define EXV_MAX(a,b) ((a) > (b) ? (a) : (b))
Packit Service 21b5d1
Packit Service 21b5d1
#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__clang__)
Packit Service 21b5d1
#define EXV_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
Packit Service 21b5d1
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
Packit Service 21b5d1
#define EXV_WARN_UNUSED_RESULT _Check_return_
Packit Service 21b5d1
#else
Packit Service 21b5d1
#define EXV_WARN_UNUSED_RESULT
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// forward declarations
Packit Service 21b5d1
struct tm;
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// namespace extensions
Packit Service 21b5d1
namespace Exiv2 {
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// type definitions
Packit Service 21b5d1
Packit Service 21b5d1
    //! 1 byte unsigned integer type.
Packit Service 21b5d1
    typedef uint8_t byte;
Packit Service 21b5d1
Packit Service 21b5d1
    //! 8 byte unsigned rational type.
Packit Service 21b5d1
    typedef std::pair<uint32_t, uint32_t> URational;
Packit Service 21b5d1
    //! 8 byte signed rational type.
Packit Service 21b5d1
    typedef std::pair<int32_t, int32_t> Rational;
Packit Service 21b5d1
Packit Service 21b5d1
    //! Type to express the byte order (little or big endian)
Packit Service 21b5d1
    enum ByteOrder { invalidByteOrder, littleEndian, bigEndian };
Packit Service 21b5d1
Packit Service 21b5d1
    //! Type to indicate write method used by TIFF parsers
Packit Service 21b5d1
    enum WriteMethod { wmIntrusive, wmNonIntrusive };
Packit Service 21b5d1
Packit Service 21b5d1
    //! An identifier for each type of metadata
Packit Service 21b5d1
    enum MetadataId { mdNone=0, mdExif=1, mdIptc=2, mdComment=4, mdXmp=8, mdIccProfile=16 };
Packit Service 21b5d1
Packit Service 21b5d1
    //! An identifier for each mode of metadata support
Packit Service 21b5d1
    enum AccessMode { amNone=0, amRead=1, amWrite=2, amReadWrite=3 };
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief %Exiv2 value type identifiers.
Packit Service 21b5d1
Packit Service 21b5d1
      Used primarily as identifiers when creating %Exiv2 Value instances.
Packit Service 21b5d1
      See Value::create. 0x0000 to 0xffff are reserved for TIFF (Exif) types.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    enum TypeId {
Packit Service 21b5d1
        unsignedByte       = 1, //!< Exif BYTE type, 8-bit unsigned integer.
Packit Service 21b5d1
        asciiString        = 2, //!< Exif ASCII type, 8-bit byte.
Packit Service 21b5d1
        unsignedShort      = 3, //!< Exif SHORT type, 16-bit (2-byte) unsigned integer.
Packit Service 21b5d1
        unsignedLong       = 4, //!< Exif LONG type, 32-bit (4-byte) unsigned integer.
Packit Service 21b5d1
        unsignedRational   = 5, //!< Exif RATIONAL type, two LONGs: numerator and denumerator of a fraction.
Packit Service 21b5d1
        signedByte         = 6, //!< Exif SBYTE type, an 8-bit signed (twos-complement) integer.
Packit Service 21b5d1
        undefined          = 7, //!< Exif UNDEFINED type, an 8-bit byte that may contain anything.
Packit Service 21b5d1
        signedShort        = 8, //!< Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
Packit Service 21b5d1
        signedLong         = 9, //!< Exif SLONG type, a 32-bit (4-byte) signed (twos-complement) integer.
Packit Service 21b5d1
        signedRational     =10, //!< Exif SRATIONAL type, two SLONGs: numerator and denumerator of a fraction.
Packit Service 21b5d1
        tiffFloat          =11, //!< TIFF FLOAT type, single precision (4-byte) IEEE format.
Packit Service 21b5d1
        tiffDouble         =12, //!< TIFF DOUBLE type, double precision (8-byte) IEEE format.
Packit Service 21b5d1
        tiffIfd            =13, //!< TIFF IFD type, 32-bit (4-byte) unsigned integer.
Packit Service 21b5d1
        unsignedLongLong   =16, //!< Exif LONG LONG type, 64-bit (8-byte) unsigned integer.
Packit Service 21b5d1
        signedLongLong     =17, //!< Exif LONG LONG type, 64-bit (8-byte) signed integer.
Packit Service 21b5d1
        tiffIfd8           =18, //!< TIFF IFD type, 64-bit (8-byte) unsigned integer.
Packit Service 21b5d1
        string        =0x10000, //!< IPTC string type.
Packit Service 21b5d1
        date          =0x10001, //!< IPTC date type.
Packit Service 21b5d1
        time          =0x10002, //!< IPTC time type.
Packit Service 21b5d1
        comment       =0x10003, //!< %Exiv2 type for the Exif user comment.
Packit Service 21b5d1
        directory     =0x10004, //!< %Exiv2 type for a CIFF directory.
Packit Service 21b5d1
        xmpText       =0x10005, //!< XMP text type.
Packit Service 21b5d1
        xmpAlt        =0x10006, //!< XMP alternative type.
Packit Service 21b5d1
        xmpBag        =0x10007, //!< XMP bag type.
Packit Service 21b5d1
        xmpSeq        =0x10008, //!< XMP sequence type.
Packit Service 21b5d1
        langAlt       =0x10009, //!< XMP language alternative type.
Packit Service 21b5d1
        invalidTypeId =0x1fffe, //!< Invalid type id.
Packit Service 21b5d1
        lastTypeId    =0x1ffff  //!< Last type id.
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    //! Container for binary data
Packit Service 21b5d1
    typedef std::vector<byte> Blob;
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// class definitions
Packit Service 21b5d1
Packit Service 21b5d1
    //! Type information lookup functions. Implemented as a static class.
Packit Service 21b5d1
    class EXIV2API TypeInfo {
Packit Service 21b5d1
        //! Prevent construction: not implemented.
Packit Service 21b5d1
        TypeInfo();
Packit Service 21b5d1
        //! Prevent copy-construction: not implemented.
Packit Service 21b5d1
        TypeInfo(const TypeInfo& rhs);
Packit Service 21b5d1
        //! Prevent assignment: not implemented.
Packit Service 21b5d1
        TypeInfo& operator=(const TypeInfo& rhs);
Packit Service 21b5d1
Packit Service 21b5d1
    public:
Packit Service 21b5d1
        //! Return the name of the type, 0 if unknown.
Packit Service 21b5d1
        static const char* typeName(TypeId typeId);
Packit Service 21b5d1
        //! Return the type id for a type name
Packit Service 21b5d1
        static TypeId typeId(const std::string& typeName);
Packit Service 21b5d1
        //! Return the size in bytes of one element of this type
Packit Service 21b5d1
        static long typeSize(TypeId typeId);
Packit Service 21b5d1
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Auxiliary type to enable copies and assignments, similar to
Packit Service 21b5d1
             std::auto_ptr_ref. See http://www.josuttis.com/libbook/auto_ptr.html
Packit Service 21b5d1
             for a discussion.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    struct EXIV2API DataBufRef {
Packit Service 21b5d1
        //! Constructor
Packit Service 21b5d1
        explicit DataBufRef(std::pair<byte*, long> rhs) : p(rhs) {}
Packit Service 21b5d1
        //! Pointer to a byte array and its size
Packit Service 21b5d1
        std::pair<byte*, long> p;
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Utility class containing a character array. All it does is to take
Packit Service 21b5d1
             care of memory allocation and deletion. Its primary use is meant to
Packit Service 21b5d1
             be as a stack variable in functions that need a temporary data
Packit Service 21b5d1
             buffer.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    class EXIV2API DataBuf {
Packit Service 21b5d1
    public:
Packit Service 21b5d1
        //! @name Creators
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        //! Default constructor
Packit Service 21b5d1
        DataBuf();
Packit Service 21b5d1
        //! Constructor with an initial buffer size
Packit Service 21b5d1
        explicit DataBuf(long size);
Packit Service 21b5d1
        //! Constructor, copies an existing buffer
Packit Service 21b5d1
        DataBuf(const byte* pData, long size);
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Copy constructor. Transfers the buffer to the newly created
Packit Service 21b5d1
                 object similar to std::auto_ptr, i.e., the original object is
Packit Service 21b5d1
                 modified.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        DataBuf(DataBuf& rhs);
Packit Service 21b5d1
        //! Destructor, deletes the allocated buffer
Packit Service 21b5d1
        ~DataBuf();
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
        //! @name Manipulators
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Assignment operator. Transfers the buffer and releases the
Packit Service 21b5d1
                 buffer at the original object similar to std::auto_ptr, i.e.,
Packit Service 21b5d1
                 the original object is modified.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        DataBuf& operator=(DataBuf& rhs);
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Allocate a data buffer of at least the given size. Note that if
Packit Service 21b5d1
                 the requested \em size is less than the current buffer size, no
Packit Service 21b5d1
                 new memory is allocated and the buffer size doesn't change.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        void alloc(long size);
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Release ownership of the buffer to the caller. Returns the
Packit Service 21b5d1
                 buffer as a data pointer and size pair, resets the internal
Packit Service 21b5d1
                 buffer.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        EXV_WARN_UNUSED_RESULT std::pair<byte*, long> release();
Packit Service 21b5d1
Packit Service 21b5d1
         /*!
Packit Service 21b5d1
           @brief Free the internal buffer and reset the size to 0.
Packit Service 21b5d1
          */
Packit Service 21b5d1
        void free();
Packit Service 21b5d1
Packit Service 21b5d1
        //! Reset value
Packit Service 21b5d1
        void reset(std::pair<byte*, long> =std::make_pair((byte*)(0),long(0)));
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @name Conversions
Packit Service 21b5d1
Packit Service 21b5d1
          Special conversions with auxiliary type to enable copies
Packit Service 21b5d1
          and assignments, similar to those used for std::auto_ptr.
Packit Service 21b5d1
          See http://www.josuttis.com/libbook/auto_ptr.html for a discussion.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        DataBuf(const DataBufRef& rhs);
Packit Service 21b5d1
        DataBuf& operator=(DataBufRef rhs);
Packit Service 21b5d1
        operator DataBufRef();
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
        // DATA
Packit Service 21b5d1
        //! Pointer to the buffer, 0 if none has been allocated
Packit Service 21b5d1
        byte* pData_;
Packit Service 21b5d1
        //! The current size of the buffer
Packit Service 21b5d1
        long size_;
Packit Service 21b5d1
    }; // class DataBuf
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
     * @brief Create a new Slice from a DataBuf given the bounds.
Packit Service 21b5d1
     *
Packit Service 21b5d1
     * @param[in] begin, end  Bounds of the new Slice. `begin` must be smaller
Packit Service 21b5d1
     *     than `end` and both must not be larger than LONG_MAX.
Packit Service 21b5d1
     * @param[in] buf  The DataBuf from which' data the Slice will be
Packit Service 21b5d1
     *     constructed
Packit Service 21b5d1
     *
Packit Service 21b5d1
     * @throw std::invalid_argument when `end` is larger than `LONG_MAX` or
Packit Service 21b5d1
     * anything that the constructor of @ref Slice throws
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API Slice<byte*> makeSlice(DataBuf& buf, size_t begin, size_t end);
Packit Service 21b5d1
Packit Service 21b5d1
    //! Overload of makeSlice for `const DataBuf`, returning an immutable Slice
Packit Service 21b5d1
    EXIV2API Slice<const byte*> makeSlice(const DataBuf& buf, size_t begin, size_t end);
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// free functions
Packit Service 21b5d1
Packit Service 21b5d1
    //! Read a 2 byte unsigned short value from the data buffer
Packit Service 21b5d1
    EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read a 2 byte unsigned short value from a Slice
Packit Service 21b5d1
    template <typename T>
Packit Service 21b5d1
    uint16_t getUShort(const Slice<T>& buf, ByteOrder byteOrder)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        if (byteOrder == littleEndian) {
Packit Service 21b5d1
            return static_cast<byte>(buf.at(1)) << 8 | static_cast<byte>(buf.at(0));
Packit Service 21b5d1
        } else {
Packit Service 21b5d1
            return static_cast<byte>(buf.at(0)) << 8 | static_cast<byte>(buf.at(1));
Packit Service 21b5d1
        }
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    //! Read a 4 byte unsigned long value from the data buffer
Packit Service 21b5d1
    EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read a 8 byte unsigned long value from the data buffer
Packit Service 21b5d1
    EXIV2API uint64_t getULongLong(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read an 8 byte unsigned rational value from the data buffer
Packit Service 21b5d1
    EXIV2API URational getURational(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read a 2 byte signed short value from the data buffer
Packit Service 21b5d1
    EXIV2API int16_t getShort(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read a 4 byte signed long value from the data buffer
Packit Service 21b5d1
    EXIV2API int32_t getLong(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read an 8 byte signed rational value from the data buffer
Packit Service 21b5d1
    EXIV2API Rational getRational(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read a 4 byte single precision floating point value (IEEE 754 binary32) from the data buffer
Packit Service 21b5d1
    EXIV2API float getFloat(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
    //! Read an 8 byte double precision floating point value (IEEE 754 binary64) from the data buffer
Packit Service 21b5d1
    EXIV2API double getDouble(const byte* buf, ByteOrder byteOrder);
Packit Service 21b5d1
Packit Service 21b5d1
    //! Output operator for our fake rational
Packit Service 21b5d1
    EXIV2API std::ostream& operator<<(std::ostream& os, const Rational& r);
Packit Service 21b5d1
    //! Input operator for our fake rational
Packit Service 21b5d1
    EXIV2API std::istream& operator>>(std::istream& is, Rational& r);
Packit Service 21b5d1
    //! Output operator for our fake unsigned rational
Packit Service 21b5d1
    EXIV2API std::ostream& operator<<(std::ostream& os, const URational& r);
Packit Service 21b5d1
    //! Input operator for our fake unsigned rational
Packit Service 21b5d1
    EXIV2API std::istream& operator>>(std::istream& is, URational& r);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert an unsigned short to data, write the data to the buffer,
Packit Service 21b5d1
             return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder);
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert an unsigned long to data, write the data to the buffer,
Packit Service 21b5d1
             return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long ul2Data(byte* buf, uint32_t l, ByteOrder byteOrder);
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert an unsigned rational to data, write the data to the buffer,
Packit Service 21b5d1
             return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long ur2Data(byte* buf, URational l, ByteOrder byteOrder);
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert a signed short to data, write the data to the buffer,
Packit Service 21b5d1
             return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long s2Data(byte* buf, int16_t s, ByteOrder byteOrder);
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert a signed long to data, write the data to the buffer,
Packit Service 21b5d1
             return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long l2Data(byte* buf, int32_t l, ByteOrder byteOrder);
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert a signed rational to data, write the data to the buffer,
Packit Service 21b5d1
             return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long r2Data(byte* buf, Rational l, ByteOrder byteOrder);
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert a single precision floating point (IEEE 754 binary32) float
Packit Service 21b5d1
             to data, write the data to the buffer, return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long f2Data(byte* buf, float f, ByteOrder byteOrder);
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Convert a double precision floating point (IEEE 754 binary64) double
Packit Service 21b5d1
             to data, write the data to the buffer, return number of bytes written.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API long d2Data(byte* buf, double d, ByteOrder byteOrder);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Print len bytes from buf in hex and ASCII format to the given
Packit Service 21b5d1
             stream, prefixed with the position in the buffer adjusted by
Packit Service 21b5d1
             offset.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API void hexdump(std::ostream& os, const byte* buf, long len, long offset =0);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Return true if str is a hex number starting with prefix followed
Packit Service 21b5d1
             by size hex digits, false otherwise. If size is 0, any number of
Packit Service 21b5d1
             digits is allowed and all are checked.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API bool isHex(const std::string& str,
Packit Service 21b5d1
               size_t size =0,
Packit Service 21b5d1
               const std::string& prefix ="");
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Converts a string in the form "%Y:%m:%d %H:%M:%S", e.g.,
Packit Service 21b5d1
             "2007:05:24 12:31:55" to broken down time format,
Packit Service 21b5d1
             returns 0 if successful, else 1.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API int exifTime(const char* buf, struct tm* tm);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Translate a string using the gettext framework. This wrapper hides
Packit Service 21b5d1
             all the implementation details from the interface.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API const char* exvGettext(const char* str);
Packit Service 21b5d1
Packit Service 21b5d1
#ifdef EXV_UNICODE_PATH
Packit Service 21b5d1
    //! Convert an std::string s to a unicode string returned as a std::wstring.
Packit Service 21b5d1
    EXIV2API std::wstring s2ws(const std::string& s);
Packit Service 21b5d1
    //! Convert a unicode std::wstring s to an std::string.
Packit Service 21b5d1
    EXIV2API std::string ws2s(const std::wstring& s);
Packit Service 21b5d1
#endif
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Return a \em long set to the value represented by \em s.
Packit Service 21b5d1
Packit Service 21b5d1
      Besides strings that represent \em long values, the function also
Packit Service 21b5d1
      handles \em float, \em Rational and boolean
Packit Service 21b5d1
      (see also: stringTo(const std::string& s, bool& ok)).
Packit Service 21b5d1
Packit Service 21b5d1
      @param  s  String to parse
Packit Service 21b5d1
      @param  ok Output variable indicating the success of the operation.
Packit Service 21b5d1
      @return Returns the \em long value represented by \em s and sets \em ok
Packit Service 21b5d1
              to \c true if the conversion was successful or \c false if not.
Packit Service 21b5d1
    */
Packit Service 21b5d1
    EXIV2API long parseLong(const std::string& s, bool& ok);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Return a \em float set to the value represented by \em s.
Packit Service 21b5d1
Packit Service 21b5d1
      Besides strings that represent \em float values, the function also
Packit Service 21b5d1
      handles \em long, \em Rational and boolean
Packit Service 21b5d1
      (see also: stringTo(const std::string& s, bool& ok)).
Packit Service 21b5d1
Packit Service 21b5d1
      @param  s  String to parse
Packit Service 21b5d1
      @param  ok Output variable indicating the success of the operation.
Packit Service 21b5d1
      @return Returns the \em float value represented by \em s and sets \em ok
Packit Service 21b5d1
              to \c true if the conversion was successful or \c false if not.
Packit Service 21b5d1
    */
Packit Service 21b5d1
    EXIV2API float parseFloat(const std::string& s, bool& ok);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Return a \em Rational set to the value represented by \em s.
Packit Service 21b5d1
Packit Service 21b5d1
      Besides strings that represent \em Rational values, the function also
Packit Service 21b5d1
      handles \em long, \em float and boolean
Packit Service 21b5d1
      (see also: stringTo(const std::string& s, bool& ok)).
Packit Service 21b5d1
      Uses floatToRationalCast(float f) if the string can be parsed into a
Packit Service 21b5d1
      \em float.
Packit Service 21b5d1
Packit Service 21b5d1
      @param  s  String to parse
Packit Service 21b5d1
      @param  ok Output variable indicating the success of the operation.
Packit Service 21b5d1
      @return Returns the \em Rational value represented by \em s and sets \em ok
Packit Service 21b5d1
              to \c true if the conversion was successful or \c false if not.
Packit Service 21b5d1
    */
Packit Service 21b5d1
    EXIV2API Rational parseRational(const std::string& s, bool& ok);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Very simple conversion of a \em float to a \em Rational.
Packit Service 21b5d1
Packit Service 21b5d1
      Test it with the values that you expect and check the implementation
Packit Service 21b5d1
      to see if this is really what you want!
Packit Service 21b5d1
     */
Packit Service 21b5d1
    EXIV2API Rational floatToRationalCast(float f);
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// template and inline definitions
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Find an element that matches \em key in the array \em src.
Packit Service 21b5d1
Packit Service 21b5d1
      Designed to be used with lookup tables as shown in the example below.
Packit Service 21b5d1
      Requires a %Key structure (ideally in the array) and a comparison operator
Packit Service 21b5d1
      to compare a key with an array element.  The size of the array is
Packit Service 21b5d1
      determined automagically. Thanks to Stephan Broennimann for this nifty
Packit Service 21b5d1
      implementation.
Packit Service 21b5d1
Packit Service 21b5d1
      @code
Packit Service 21b5d1
      struct Bar {
Packit Service 21b5d1
          int i;
Packit Service 21b5d1
          int k;
Packit Service 21b5d1
          const char* data;
Packit Service 21b5d1
Packit Service 21b5d1
          struct Key;
Packit Service 21b5d1
          bool operator==(const Bar::Key& rhs) const;
Packit Service 21b5d1
      };
Packit Service 21b5d1
Packit Service 21b5d1
      struct Bar::Key {
Packit Service 21b5d1
          Key(int a, int b) : i(a), k(b) {}
Packit Service 21b5d1
          int i;
Packit Service 21b5d1
          int k;
Packit Service 21b5d1
      };
Packit Service 21b5d1
Packit Service 21b5d1
      bool Bar::operator==(const Bar::Key& key) const // definition
Packit Service 21b5d1
      {
Packit Service 21b5d1
          return i == key.i && k == key.k;
Packit Service 21b5d1
      }
Packit Service 21b5d1
Packit Service 21b5d1
      const Bar bars[] = {
Packit Service 21b5d1
          { 1, 1, "bar data 1" },
Packit Service 21b5d1
          { 1, 2, "bar data 2" },
Packit Service 21b5d1
          { 1, 3, "bar data 3" }
Packit Service 21b5d1
      };
Packit Service 21b5d1
Packit Service 21b5d1
      int main ( void ) {
Packit Service 21b5d1
          const Bar* bar = find(bars, Bar::Key(1, 3));
Packit Service 21b5d1
          if (bar) std::cout << bar->data << "\n";
Packit Service 21b5d1
          else std::cout << "Key not found.\n";
Packit Service 21b5d1
          return 0;
Packit Service 21b5d1
      }
Packit Service 21b5d1
      @endcode
Packit Service 21b5d1
    */
Packit Service 21b5d1
    template<typename T, typename K, int N>
Packit Service 21b5d1
    const T* find(T (&src)[N], const K& key)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        const T* rc = std::find(src, src + N, key);
Packit Service 21b5d1
        return rc == src + N ? 0 : rc;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    //! Template used in the COUNTOF macro to determine the size of an array
Packit Service 21b5d1
    template <typename T, int N> char (&sizer(T (&)[N]))[N];
Packit Service 21b5d1
//! Macro to determine the size of an array
Packit Service 21b5d1
#define EXV_COUNTOF(a) (sizeof(Exiv2::sizer(a)))
Packit Service 21b5d1
Packit Service 21b5d1
    //! Utility function to convert the argument of any type to a string
Packit Service 21b5d1
    template<typename T>
Packit Service 21b5d1
    std::string toString(const T& arg)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        std::ostringstream os;
Packit Service 21b5d1
        os << arg;
Packit Service 21b5d1
        return os.str();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Utility function to convert a string to a value of type \c T.
Packit Service 21b5d1
Packit Service 21b5d1
      The string representation of the value must match that recognized by
Packit Service 21b5d1
      the input operator for \c T for this function to succeed.
Packit Service 21b5d1
Packit Service 21b5d1
      @param  s  String to convert
Packit Service 21b5d1
      @param  ok Output variable indicating the success of the operation.
Packit Service 21b5d1
      @return Returns the converted value and sets \em ok to \c true if the
Packit Service 21b5d1
              conversion was successful or \c false if not.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    template<typename T>
Packit Service 21b5d1
    T stringTo(const std::string& s, bool& ok)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        std::istringstream is(s);
Packit Service 21b5d1
        T tmp;
Packit Service 21b5d1
        ok = (is >> tmp) ? true : false;
Packit Service 21b5d1
        std::string rest;
Packit Service 21b5d1
        is >> std::skipws >> rest;
Packit Service 21b5d1
        if (!rest.empty()) ok = false;
Packit Service 21b5d1
        return tmp;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Specialization of stringTo(const std::string& s, bool& ok) for \em bool.
Packit Service 21b5d1
Packit Service 21b5d1
      Handles the same string values as the XMP SDK. Converts the string to lowercase
Packit Service 21b5d1
      and returns \c true if it is "true", "t" or "1", and \c false if it is
Packit Service 21b5d1
      "false", "f" or "0".
Packit Service 21b5d1
     */
Packit Service 21b5d1
    template<>
Packit Service 21b5d1
    bool stringTo<bool>(const std::string& s, bool& ok);
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Return the greatest common denominator of n and m.
Packit Service 21b5d1
             (Implementation from Boost rational.hpp)
Packit Service 21b5d1
Packit Service 21b5d1
      @note We use n and m as temporaries in this function, so there is no
Packit Service 21b5d1
            value in using const IntType& as we would only need to make a copy
Packit Service 21b5d1
            anyway...
Packit Service 21b5d1
     */
Packit Service 21b5d1
    template <typename IntType>
Packit Service 21b5d1
    IntType gcd(IntType n, IntType m)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        // Avoid repeated construction
Packit Service 21b5d1
        IntType zero(0);
Packit Service 21b5d1
Packit Service 21b5d1
        // This is abs() - given the existence of broken compilers with Koenig
Packit Service 21b5d1
        // lookup issues and other problems, I code this explicitly. (Remember,
Packit Service 21b5d1
        // IntType may be a user-defined type).
Packit Service 21b5d1
#ifdef _MSC_VER
Packit Service 21b5d1
#pragma warning( disable : 4146 )
Packit Service 21b5d1
#undef max
Packit Service 21b5d1
#undef min
Packit Service 21b5d1
#endif
Packit Service 21b5d1
        if (n < zero) {
Packit Service 21b5d1
            if (n == std::numeric_limits<IntType>::min()) {
Packit Service 21b5d1
                n = std::numeric_limits<IntType>::max();
Packit Service 21b5d1
            } else {
Packit Service 21b5d1
                n = -n;
Packit Service 21b5d1
            }
Packit Service 21b5d1
        }
Packit Service 21b5d1
        if (m < zero)
Packit Service 21b5d1
            m = -m;
Packit Service 21b5d1
#ifdef _MSC_VER
Packit Service 21b5d1
#pragma warning( default : 4146 )
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
        // As n and m are now positive, we can be sure that %= returns a
Packit Service 21b5d1
        // positive value (the standard guarantees this for built-in types,
Packit Service 21b5d1
        // and we require it of user-defined types).
Packit Service 21b5d1
        for(;;) {
Packit Service 21b5d1
            if(m == zero)
Packit Service 21b5d1
                return n;
Packit Service 21b5d1
            n %= m;
Packit Service 21b5d1
            if(n == zero)
Packit Service 21b5d1
                return m;
Packit Service 21b5d1
            m %= n;
Packit Service 21b5d1
        }
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
}                                       // namespace Exiv2
Packit Service 21b5d1
Packit Service 21b5d1
#endif                                  // #ifndef TYPES_HPP_