diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index ead0d73c..b654891d 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -27,6 +27,7 @@ #include "exiv2lib_export.h" // included header files +#include "error.hpp" #include "types.hpp" // + standard includes @@ -142,6 +143,17 @@ namespace Exiv2 { 0 if failure; */ virtual long read(byte* buf, long rcount) = 0; + /*! + @brief Safe version of `read()` that checks for errors and throws + an exception if the read was unsuccessful. + @param buf Pointer to a block of memory into which the read data + is stored. The memory block must be at least \em rcount bytes + long. + @param rcount Maximum number of bytes to read. Fewer bytes may be + read if \em rcount bytes are not available. + @param err Error code to use if an exception is thrown. + */ + void readOrThrow(byte* buf, long rcount, ErrorCode err); /*! @brief Read one byte from the IO source. Current IO position is advanced by one byte. @@ -176,6 +188,19 @@ namespace Exiv2 { #else virtual int seek(long offset, Position pos) = 0; #endif + /*! + @brief Safe version of `seek()` that checks for errors and throws + an exception if the seek was unsuccessful. + @param offset Number of bytes to move the position relative + to the starting position specified by \em pos + @param pos Position from which the seek should start + @param err Error code to use if an exception is thrown. + */ +#if defined(_MSC_VER) + void seekOrThrow(int64_t offset, Position pos, ErrorCode err); +#else + void seekOrThrow(long offset, Position pos, ErrorCode err); +#endif /*! @brief Direct access to the IO data. For files, this is done by diff --git a/src/basicio.cpp b/src/basicio.cpp index f0a6e667..f7e699c6 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -28,6 +28,7 @@ #include "futils.hpp" #include "types.hpp" #include "error.hpp" +#include "enforce.hpp" #include "http.hpp" #include "properties.hpp" #include "image_int.hpp" @@ -77,6 +78,21 @@ using nlink_t = short; // ***************************************************************************** // class member definitions namespace Exiv2 { + void BasicIo::readOrThrow(byte* buf, long rcount, ErrorCode err) { + const long nread = read(buf, rcount); + enforce(nread == rcount, err); + enforce(!error(), err); + } + +#if defined(_MSC_VER) + void BasicIo::seekOrThrow(int64_t offset, Position pos, ErrorCode err) { +#else + void BasicIo::seekOrThrow(long offset, Position pos, ErrorCode err) { +#endif + const int r = seek(offset, pos); + enforce(r == 0, err); + } + //! Internal Pimpl structure of class FileIo. class FileIo::Impl { public: diff --git a/src/image.cpp b/src/image.cpp index db6f7a9d..f57ec578 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -140,15 +140,12 @@ namespace { namespace Exiv2 { // BasicIo::read() with error checking static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) { - const long nread = iIo.read(buf, rcount); - enforce(nread == rcount, err); - enforce(!iIo.error(), err); + iIo.readOrThrow(buf, rcount, err); } // BasicIo::seek() with error checking static void seekOrThrow(BasicIo& iIo, long offset, BasicIo::Position pos, ErrorCode err) { - const int r = iIo.seek(offset, pos); - enforce(r == 0, err); + iIo.seekOrThrow(offset, pos, err); } Image::Image(int imageType, uint16_t supportedMetadata, BasicIo::UniquePtr io) diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index f07b48fb..03ded18c 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -96,15 +96,12 @@ namespace Exiv2 { // BasicIo::read() with error checking static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) { - const long nread = iIo.read(buf, rcount); - enforce(nread == rcount, err); - enforce(!iIo.error(), err); + iIo.readOrThrow(buf, rcount, err); } // BasicIo::seek() with error checking static void seekOrThrow(BasicIo& iIo, long offset, BasicIo::Position pos, ErrorCode err) { - const int r = iIo.seek(offset, pos); - enforce(r == 0, err); + iIo.seekOrThrow(offset, pos, err); } static inline bool inRange(int lo,int value, int hi) diff --git a/src/webpimage.cpp b/src/webpimage.cpp index f8a1887b..6f9388eb 100644 --- a/src/webpimage.cpp +++ b/src/webpimage.cpp @@ -58,9 +58,7 @@ namespace Exiv2 { // This static function is a temporary fix in v0.27. In the next version, // it will be added as a method of BasicIo. static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) { - const long nread = iIo.read(buf, rcount); - enforce(nread == rcount, err); - enforce(!iIo.error(), err); + iIo.readOrThrow(buf, rcount, err); } WebPImage::WebPImage(BasicIo::UniquePtr io)