Blame include/exiv2/error.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    error.hpp
Packit Service 21b5d1
  @brief   Error class for exceptions, log message class
Packit Service 21b5d1
  @author  Andreas Huggel (ahu)
Packit Service 21b5d1
           ahuggel@gmx.net
Packit Service 21b5d1
  @date    15-Jan-04, ahu: created
Packit Service 21b5d1
           11-Feb-04, ahu: isolated as a component
Packit Service 21b5d1
 */
Packit Service 21b5d1
#ifndef ERROR_HPP_
Packit Service 21b5d1
#define ERROR_HPP_
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
#include "exiv2lib_export.h"
Packit Service 21b5d1
Packit Service 21b5d1
// included header files
Packit Service 21b5d1
#include "types.hpp"
Packit Service 21b5d1
Packit Service 21b5d1
// + standard includes
Packit Service 21b5d1
#include <exception>
Packit Service 21b5d1
#include <string>
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
// class definitions
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Class for a log message, used by the library. Applications can set
Packit Service 21b5d1
             the log level and provide a customer log message handler (callback
Packit Service 21b5d1
             function).
Packit Service 21b5d1
Packit Service 21b5d1
             This class is meant to be used as a temporary object with the
Packit Service 21b5d1
             related macro-magic like this:
Packit Service 21b5d1
Packit Service 21b5d1
             
Packit Service 21b5d1
             EXV_WARNING << "Warning! Something looks fishy.\n";
Packit Service 21b5d1
             
Packit Service 21b5d1
Packit Service 21b5d1
             which translates to
Packit Service 21b5d1
Packit Service 21b5d1
             
Packit Service 21b5d1
             if (LogMsg::warn >= LogMsg::level() && LogMsg::handler())
Packit Service 21b5d1
                 LogMsg(LogMsg::warn).os() << "Warning! Something looks fishy.\n";
Packit Service 21b5d1
             
Packit Service 21b5d1
Packit Service 21b5d1
             The macros EXV_DEBUG, EXV_INFO, EXV_WARNING and EXV_ERROR are
Packit Service 21b5d1
             shorthands and ensure efficient use of the logging facility: If a
Packit Service 21b5d1
             log message doesn't need to be generated because of the log level
Packit Service 21b5d1
             setting, the temp object is not even created.
Packit Service 21b5d1
Packit Service 21b5d1
             Caveat: The entire log message is not processed in this case. So don't
Packit Service 21b5d1
             make that call any logic that always needs to be executed.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    class EXIV2API LogMsg {
Packit Service 21b5d1
        //! Prevent copy-construction: not implemented.
Packit Service 21b5d1
        LogMsg(const LogMsg&);
Packit Service 21b5d1
        //! Prevent assignment: not implemented.
Packit Service 21b5d1
        LogMsg& operator=(const LogMsg&);
Packit Service 21b5d1
    public:
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Defined log levels. To suppress all log messages, either set the
Packit Service 21b5d1
                 log level to \c mute or set the log message handler to 0.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        enum Level { debug = 0, info = 1, warn = 2, error = 3, mute = 4 };
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Type for a log message handler function. The function receives
Packit Service 21b5d1
                 the log level and message and can process it in an application
Packit Service 21b5d1
                 specific way.  The default handler sends the log message to
Packit Service 21b5d1
                 standard error.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        typedef void (*Handler)(int, const char*);
Packit Service 21b5d1
Packit Service 21b5d1
        //! @name Creators
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        //! Constructor, takes the log message type as an argument
Packit Service 21b5d1
        explicit LogMsg(Level msgType);
Packit Service 21b5d1
Packit Service 21b5d1
        //! Destructor, passes the log message to the message handler depending on the log level
Packit Service 21b5d1
        ~LogMsg();
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
        //! @name Manipulators
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        //! Return a reference to the ostringstream which holds the log message
Packit Service 21b5d1
        std::ostringstream& os();
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Set the log level. Only log messages with a level greater or
Packit Service 21b5d1
                 equal \em level are sent to the log message handler. Default
Packit Service 21b5d1
                 log level is \c warn. To suppress all log messages, set the log
Packit Service 21b5d1
                 level to \c mute (or set the log message handler to 0).
Packit Service 21b5d1
        */
Packit Service 21b5d1
        static void setLevel(Level level);
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Set the log message handler. The default handler writes log
Packit Service 21b5d1
                 messages to standard error. To suppress all log messages, set
Packit Service 21b5d1
                 the log message handler to 0 (or set the log level to \c mute).
Packit Service 21b5d1
         */
Packit Service 21b5d1
        static void setHandler(Handler handler);
Packit Service 21b5d1
        //! Return the current log level
Packit Service 21b5d1
        static Level level();
Packit Service 21b5d1
        //! Return the current log message handler
Packit Service 21b5d1
        static Handler handler();
Packit Service 21b5d1
        //! The default log handler. Sends the log message to standard error.
Packit Service 21b5d1
        static void defaultHandler(int level, const char* s);
Packit Service 21b5d1
Packit Service 21b5d1
    private:
Packit Service 21b5d1
        // DATA
Packit Service 21b5d1
        // The output level. Only messages with type >= level_ will be written
Packit Service 21b5d1
        static Level level_;
Packit Service 21b5d1
        // The log handler in use
Packit Service 21b5d1
        static Handler handler_;
Packit Service 21b5d1
        // The type of this log message
Packit Service 21b5d1
        const Level msgType_;
Packit Service 21b5d1
        // Holds the log message until it is passed to the message handler
Packit Service 21b5d1
        std::ostringstream os_;
Packit Service 21b5d1
Packit Service 21b5d1
    }; // class LogMsg
Packit Service 21b5d1
Packit Service 21b5d1
// Macros for simple access
Packit Service 21b5d1
//! Shorthand to create a temp debug log message object and return its ostringstream
Packit Service 21b5d1
#define EXV_DEBUG   if (LogMsg::debug >= LogMsg::level() && LogMsg::handler()) LogMsg(LogMsg::debug).os()
Packit Service 21b5d1
//! Shorthand for a temp info log message object and return its ostringstream
Packit Service 21b5d1
#define EXV_INFO    if (LogMsg::info  >= LogMsg::level() && LogMsg::handler()) LogMsg(LogMsg::info).os()
Packit Service 21b5d1
//! Shorthand for a temp warning log message object and return its ostringstream
Packit Service 21b5d1
#define EXV_WARNING if (LogMsg::warn  >= LogMsg::level() && LogMsg::handler()) LogMsg(LogMsg::warn).os()
Packit Service 21b5d1
//! Shorthand for a temp error log message object and return its ostringstream
Packit Service 21b5d1
#define EXV_ERROR   if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) LogMsg(LogMsg::error).os()
Packit Service 21b5d1
Packit Service 21b5d1
#ifdef _MSC_VER
Packit Service 21b5d1
// Disable MSVC warnings "non - DLL-interface classkey 'identifier' used as base
Packit Service 21b5d1
// for DLL-interface classkey 'identifier'"
Packit Service 21b5d1
# pragma warning( disable : 4275 )
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
    //! Generalised toString function
Packit Service 21b5d1
    template<typename charT, typename T>
Packit Service 21b5d1
    std::basic_string<charT> toBasicString(const T& arg)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        std::basic_ostringstream<charT> 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 Error class interface. Allows the definition and use of a hierarchy
Packit Service 21b5d1
             of error classes which can all be handled in one catch block.
Packit Service 21b5d1
             Inherits from the standard exception base-class, to make life
Packit Service 21b5d1
             easier for library users (they have the option of catching most
Packit Service 21b5d1
             things via std::exception).
Packit Service 21b5d1
     */
Packit Service 21b5d1
    class EXIV2API AnyError : public std::exception {
Packit Service 21b5d1
    public:
Packit Service 21b5d1
        AnyError();
Packit Service 21b5d1
        AnyError(const AnyError& o);
Packit Service 21b5d1
Packit Service 21b5d1
        virtual ~AnyError() throw();
Packit Service 21b5d1
        ///@brief  Return the error code.
Packit Service 21b5d1
        virtual int code() const throw() =0;
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    //! %AnyError output operator
Packit Service 21b5d1
    inline std::ostream& operator<<(std::ostream& os, const AnyError& error)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        return os << error.what();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    //! Complete list of all Exiv2 error codes
Packit Service 21b5d1
    enum ErrorCode {
Packit Service 21b5d1
        kerGeneralError = -1,
Packit Service 21b5d1
        kerSuccess = 0,
Packit Service 21b5d1
        kerErrorMessage,
Packit Service 21b5d1
        kerCallFailed,
Packit Service 21b5d1
        kerNotAnImage,
Packit Service 21b5d1
        kerInvalidDataset,
Packit Service 21b5d1
        kerInvalidRecord,
Packit Service 21b5d1
        kerInvalidKey,
Packit Service 21b5d1
        kerInvalidTag,
Packit Service 21b5d1
        kerValueNotSet,
Packit Service 21b5d1
        kerDataSourceOpenFailed,
Packit Service 21b5d1
        kerFileOpenFailed,
Packit Service 21b5d1
        kerFileContainsUnknownImageType,
Packit Service 21b5d1
        kerMemoryContainsUnknownImageType,
Packit Service 21b5d1
        kerUnsupportedImageType,
Packit Service 21b5d1
        kerFailedToReadImageData,
Packit Service 21b5d1
        kerNotAJpeg,
Packit Service 21b5d1
        kerFailedToMapFileForReadWrite,
Packit Service 21b5d1
        kerFileRenameFailed,
Packit Service 21b5d1
        kerTransferFailed,
Packit Service 21b5d1
        kerMemoryTransferFailed,
Packit Service 21b5d1
        kerInputDataReadFailed,
Packit Service 21b5d1
        kerImageWriteFailed,
Packit Service 21b5d1
        kerNoImageInInputData,
Packit Service 21b5d1
        kerInvalidIfdId,
Packit Service 21b5d1
        //! Entry::setValue: Value too large
Packit Service 21b5d1
        kerValueTooLarge,
Packit Service 21b5d1
        //! Entry::setDataArea: Value too large
Packit Service 21b5d1
        kerDataAreaValueTooLarge,
Packit Service 21b5d1
        kerOffsetOutOfRange,
Packit Service 21b5d1
        kerUnsupportedDataAreaOffsetType,
Packit Service 21b5d1
        kerInvalidCharset,
Packit Service 21b5d1
        kerUnsupportedDateFormat,
Packit Service 21b5d1
        kerUnsupportedTimeFormat,
Packit Service 21b5d1
        kerWritingImageFormatUnsupported,
Packit Service 21b5d1
        kerInvalidSettingForImage,
Packit Service 21b5d1
        kerNotACrwImage,
Packit Service 21b5d1
        kerFunctionNotSupported,
Packit Service 21b5d1
        kerNoNamespaceInfoForXmpPrefix,
Packit Service 21b5d1
        kerNoPrefixForNamespace,
Packit Service 21b5d1
        kerTooLargeJpegSegment,
Packit Service 21b5d1
        kerUnhandledXmpdatum,
Packit Service 21b5d1
        kerUnhandledXmpNode,
Packit Service 21b5d1
        kerXMPToolkitError,
Packit Service 21b5d1
        kerDecodeLangAltPropertyFailed,
Packit Service 21b5d1
        kerDecodeLangAltQualifierFailed,
Packit Service 21b5d1
        kerEncodeLangAltPropertyFailed,
Packit Service 21b5d1
        kerPropertyNameIdentificationFailed,
Packit Service 21b5d1
        kerSchemaNamespaceNotRegistered,
Packit Service 21b5d1
        kerNoNamespaceForPrefix,
Packit Service 21b5d1
        kerAliasesNotSupported,
Packit Service 21b5d1
        kerInvalidXmpText,
Packit Service 21b5d1
        kerTooManyTiffDirectoryEntries,
Packit Service 21b5d1
        kerMultipleTiffArrayElementTagsInDirectory,
Packit Service 21b5d1
        kerWrongTiffArrayElementTagType,
Packit Service 21b5d1
        kerInvalidKeyXmpValue,
Packit Service 21b5d1
        kerInvalidIccProfile,
Packit Service 21b5d1
        kerInvalidXMP,
Packit Service 21b5d1
        kerTiffDirectoryTooLarge,
Packit Service 21b5d1
        kerInvalidTypeValue,
Packit Service 21b5d1
        kerInvalidMalloc,
Packit Service 21b5d1
        kerCorruptedMetadata,
Packit Service 21b5d1
        kerArithmeticOverflow,
Packit Service 21b5d1
        kerMallocFailed,
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Simple error class used for exceptions. An output operator is
Packit Service 21b5d1
             provided to print errors to a stream.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    template<typename charT>
Packit Service 21b5d1
    class EXIV2API BasicError : public AnyError {
Packit Service 21b5d1
    public:
Packit Service 21b5d1
        //! @name Creators
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        //! Constructor taking only an error code
Packit Service 21b5d1
        explicit inline BasicError(ErrorCode code);
Packit Service 21b5d1
Packit Service 21b5d1
        //! Constructor taking an error code and one argument
Packit Service 21b5d1
        template<typename A>
Packit Service 21b5d1
        inline BasicError(ErrorCode code, const A& arg1);
Packit Service 21b5d1
Packit Service 21b5d1
        //! Constructor taking an error code and two arguments
Packit Service 21b5d1
        template<typename A, typename B>
Packit Service 21b5d1
        inline BasicError(ErrorCode code, const A& arg1, const B& arg2);
Packit Service 21b5d1
Packit Service 21b5d1
        //! Constructor taking an error code and three arguments
Packit Service 21b5d1
        template<typename A, typename B, typename C>
Packit Service 21b5d1
        inline BasicError(ErrorCode code, const A& arg1, const B& arg2, const C& arg3);
Packit Service 21b5d1
Packit Service 21b5d1
        //! Virtual destructor. (Needed because of throw())
Packit Service 21b5d1
        virtual inline ~BasicError() throw();
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
        //! @name Accessors
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        virtual inline int code() const throw();
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Return the error message as a C-string. The pointer returned by what()
Packit Service 21b5d1
                 is valid only as long as the BasicError object exists.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        virtual inline const char* what() const throw();
Packit Service 21b5d1
#ifdef EXV_UNICODE_PATH
Packit Service 21b5d1
        /*!
Packit Service 21b5d1
          @brief Return the error message as a wchar_t-string. The pointer returned by
Packit Service 21b5d1
                 wwhat() is valid only as long as the BasicError object exists.
Packit Service 21b5d1
         */
Packit Service 21b5d1
        virtual inline const wchar_t* wwhat() const throw();
Packit Service 21b5d1
#endif
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
    private:
Packit Service 21b5d1
        //! @name Manipulators
Packit Service 21b5d1
        //@{
Packit Service 21b5d1
        //! Assemble the error message from the arguments
Packit Service 21b5d1
        void setMsg();
Packit Service 21b5d1
        //@}
Packit Service 21b5d1
Packit Service 21b5d1
        // DATA
Packit Service 21b5d1
        ErrorCode code_;                       //!< Error code
Packit Service 21b5d1
        int count_;                             //!< Number of arguments
Packit Service 21b5d1
        std::basic_string<charT> arg1_;         //!< First argument
Packit Service 21b5d1
        std::basic_string<charT> arg2_;         //!< Second argument
Packit Service 21b5d1
        std::basic_string<charT> arg3_;         //!< Third argument
Packit Service 21b5d1
        std::string              msg_;          //!< Complete error message
Packit Service 21b5d1
#ifdef EXV_UNICODE_PATH
Packit Service 21b5d1
        std::wstring             wmsg_;         //!< Complete error message as a wide string
Packit Service 21b5d1
#endif
Packit Service 21b5d1
    }; // class BasicError
Packit Service 21b5d1
Packit Service 21b5d1
    //! Error class used for exceptions (std::string based)
Packit Service 21b5d1
    typedef BasicError<char> Error;
Packit Service 21b5d1
#ifdef EXV_UNICODE_PATH
Packit Service 21b5d1
    //! Error class used for exceptions (std::wstring based)
Packit Service 21b5d1
    typedef BasicError<wchar_t> WError;
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// free functions, template and inline definitions
Packit Service 21b5d1
Packit Service 21b5d1
    //! Return the error message for the error with code \em code.
Packit Service 21b5d1
    const char* errMsg(int code);
Packit Service 21b5d1
Packit Service 21b5d1
    template<typename charT>
Packit Service 21b5d1
    BasicError<charT>::BasicError(ErrorCode code)
Packit Service 21b5d1
        : code_(code), count_(0)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        setMsg();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    template<typename charT> template<typename A>
Packit Service 21b5d1
    BasicError<charT>::BasicError(ErrorCode code, const A& arg1)
Packit Service 21b5d1
        : code_(code), count_(1), arg1_(toBasicString<charT>(arg1))
Packit Service 21b5d1
    {
Packit Service 21b5d1
        setMsg();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    template<typename charT> template<typename A, typename B>
Packit Service 21b5d1
    BasicError<charT>::BasicError(ErrorCode code, const A& arg1, const B& arg2)
Packit Service 21b5d1
        : code_(code), count_(2),
Packit Service 21b5d1
          arg1_(toBasicString<charT>(arg1)),
Packit Service 21b5d1
          arg2_(toBasicString<charT>(arg2))
Packit Service 21b5d1
    {
Packit Service 21b5d1
        setMsg();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    template<typename charT> template<typename A, typename B, typename C>
Packit Service 21b5d1
    BasicError<charT>::BasicError(ErrorCode code, const A& arg1, const B& arg2, const C& arg3)
Packit Service 21b5d1
        : code_(code), count_(3),
Packit Service 21b5d1
          arg1_(toBasicString<charT>(arg1)),
Packit Service 21b5d1
          arg2_(toBasicString<charT>(arg2)),
Packit Service 21b5d1
          arg3_(toBasicString<charT>(arg3))
Packit Service 21b5d1
    {
Packit Service 21b5d1
        setMsg();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    template<typename charT>
Packit Service 21b5d1
    BasicError<charT>::~BasicError() throw()
Packit Service 21b5d1
    {
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    template<typename charT>
Packit Service 21b5d1
    int BasicError<charT>::code() const throw()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        return code_;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    template<typename charT>
Packit Service 21b5d1
    const char* BasicError<charT>::what() const throw()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        return msg_.c_str();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
#ifdef EXV_UNICODE_PATH
Packit Service 21b5d1
    template<typename charT>
Packit Service 21b5d1
    const wchar_t* BasicError<charT>::wwhat() const throw()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        return wmsg_.c_str();
Packit Service 21b5d1
    }
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
#ifdef _MSC_VER
Packit Service 21b5d1
# pragma warning( default : 4275 )
Packit Service 21b5d1
#endif
Packit Service 21b5d1
Packit Service 21b5d1
}                                       // namespace Exiv2
Packit Service 21b5d1
#endif                                  // #ifndef ERROR_HPP_