diff --git a/.gitignore b/.gitignore index 702c4fae..c46bd2e7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ doc/html contrib/vms/.vagrant /.vscode .vs/ + +*cppcheck* diff --git a/app/actions.cpp b/app/actions.cpp index 6175a982..09d7dca9 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -83,7 +83,6 @@ namespace { public: //! C'tor Timestamp() = default; - //! Read the timestamp of a file int read(const std::string& path); //! Read the timestamp from a broken-down time in buffer \em tm. int read(struct tm* tm); @@ -176,11 +175,6 @@ namespace Action { registry_.clear(); } - void TaskFactory::registerTask(TaskType type, Task::UniquePtr task) - { - registry_[type] = std::move(task); - } - TaskFactory::TaskFactory() { registry_.emplace(adjust, std::make_unique()); @@ -268,7 +262,7 @@ namespace Action { int Print::printSummary() { - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); return -1; } @@ -284,11 +278,8 @@ namespace Action { std::cout << path_ << std::endl; // Filesize - struct stat buf; - if (0 == stat(path_.c_str(), &buf)) { - printLabel(_("File size")); - std::cout << buf.st_size << " " << _("Bytes") << std::endl; - } + printLabel(_("File size")); + std::cout << fs::file_size(path_) << " " << _("Bytes") << std::endl; // MIME type printLabel(_("MIME type")); @@ -402,7 +393,7 @@ namespace Action { int Print::printList() { - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); return -1; } @@ -596,7 +587,6 @@ namespace Action { if (Params::instance().printItems_ & Params::prHex) { if (!first) std::cout << std::endl; - first = false; Exiv2::DataBuf buf(md.size()); md.copy(buf.data(), pImage->byteOrder()); Exiv2::hexdump(std::cout, buf.c_data(), buf.size()); @@ -607,7 +597,7 @@ namespace Action { int Print::printComment() { - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); return -1; } @@ -624,7 +614,7 @@ namespace Action { int Print::printPreviewList() { - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); return -1; } @@ -658,7 +648,7 @@ namespace Action { int Rename::run(const std::string& path) { try { - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); return -1; } @@ -740,7 +730,7 @@ namespace Action { try { path_ = path; - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); return -1; } @@ -900,7 +890,7 @@ namespace Action { int Extract::writeThumbnail() const { - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); return -1; } @@ -947,7 +937,7 @@ namespace Action { int Extract::writePreviews() const { - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); return -1; } @@ -983,7 +973,7 @@ namespace Action { int Extract::writeIccProfile(const std::string& target) const { int rc = 0; - if (!Exiv2::fileExists(path_, true)) { + if (!Exiv2::fileExists(path_)) { std::cerr << path_ << ": " << _("Failed to open the file\n"); rc = -1; } @@ -1049,7 +1039,7 @@ namespace Action { // -i{tgt}- reading from stdin? bool bStdin = (Params::instance().target_ & Params::ctStdInOut) != 0; - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); return -1; @@ -1106,12 +1096,12 @@ namespace Action { Params::instance().getStdin(xmpBlob); rc = insertXmpPacket(path,xmpBlob,true); } else { - if (!Exiv2::fileExists(xmpPath, true)) { + if (!Exiv2::fileExists(xmpPath)) { std::cerr << xmpPath << ": " << _("Failed to open the file\n"); rc = -1; } - if (rc == 0 && !Exiv2::fileExists(path, true)) { + if (rc == 0 && !Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); rc = -1; @@ -1152,7 +1142,7 @@ namespace Action { Params::instance().getStdin(iccProfile); rc = insertIccProfile(path,std::move(iccProfile)); } else { - if (!Exiv2::fileExists(iccProfilePath, true)) { + if (!Exiv2::fileExists(iccProfilePath)) { std::cerr << iccProfilePath << ": " << _("Failed to open the file\n"); rc = -1; @@ -1168,7 +1158,7 @@ namespace Action { { int rc = 0; // test path exists - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); rc=-1; } @@ -1192,12 +1182,12 @@ namespace Action { int Insert::insertThumbnail(const std::string& path) { std::string thumbPath = newFilePath(path, "-thumb.jpg"); - if (!Exiv2::fileExists(thumbPath, true)) { + if (!Exiv2::fileExists(thumbPath)) { std::cerr << thumbPath << ": " << _("Failed to open the file\n"); return -1; } - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); return -1; @@ -1220,7 +1210,7 @@ namespace Action { int Modify::run(const std::string& path) { try { - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); return -1; } @@ -1452,7 +1442,7 @@ namespace Action { monthAdjustment_ = Params::instance().yodAdjust_[Params::yodMonth].adjustment_; dayAdjustment_ = Params::instance().yodAdjust_[Params::yodDay].adjustment_; - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); return -1; } @@ -1579,7 +1569,7 @@ namespace Action { int FixIso::run(const std::string& path) { try { - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " <<_("Failed to open the file\n"); return -1; } @@ -1632,7 +1622,7 @@ namespace Action { int FixCom::run(const std::string& path) { try { - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " <<_("Failed to open the file\n"); return -1; } @@ -1821,7 +1811,7 @@ namespace { // read the source metadata int rc = -1 ; - if (!Exiv2::fileExists(source, true)) { + if (!Exiv2::fileExists(source)) { std::cerr << source << ": " << _("Failed to open the file\n"); return rc; } @@ -1893,7 +1883,6 @@ namespace { // #1148 use Raw XMP packet if there are no XMP modification commands int tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX - // printTarget("in metacopy",Params::instance().target_,true); if (Params::instance().modifyCmds_.empty() && (Params::instance().target_ & tRawSidecar) == tRawSidecar) { // std::cout << "short cut" << std::endl; // http://www.cplusplus.com/doc/tutorial/files/ @@ -1946,7 +1935,8 @@ namespace { } // delete temporary target - if ( bStdout ) std::remove(target.c_str()); + if ( bStdout ) + fs::remove(target.c_str()); return rc; } // metacopy @@ -2046,14 +2036,7 @@ namespace { std::cout << std::endl; } - // Workaround for MinGW rename which does not overwrite existing files - remove(newPath.c_str()); - if (std::rename(path.c_str(), newPath.c_str()) == -1) { - std::cerr << Params::instance().progname() << ": " << _("Failed to rename") << " " << path << " " << _("to") - << " " << newPath << ": " << Exiv2::strError() << "\n"; - return 1; - } - + fs::rename(path, newPath); return 0; } @@ -2096,7 +2079,7 @@ namespace { int printStructure(std::ostream& out, Exiv2::PrintStructureOption option, const std::string &path) { - if (!Exiv2::fileExists(path, true)) { + if (!Exiv2::fileExists(path)) { std::cerr << path << ": " << _("Failed to open the file\n"); return -1; diff --git a/app/actions.hpp b/app/actions.hpp index 4520f219..b6ff516e 100644 --- a/app/actions.hpp +++ b/app/actions.hpp @@ -123,20 +123,6 @@ namespace Action { */ Task::UniquePtr create(TaskType type); - /*! - @brief Register a task prototype together with its type. - - The task factory creates new tasks of a given type by cloning its - associated prototype. Additional tasks can be registered. If called - for a type which already exists in the list, the corresponding - prototype is replaced. - - @param type Task type. - @param task Pointer to the prototype. Ownership is transferred to the - task factory. That's what the auto pointer indicates. - */ - void registerTask(TaskType type, Task::UniquePtr task); - private: //! Prevent construction other than through instance(). TaskFactory(); diff --git a/app/exiv2.cpp b/app/exiv2.cpp index 182ab7ae..01f6c1c8 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -160,7 +160,6 @@ int main(int argc, char* const argv[]) assert(task); // Process all files - int n = 1; int s = static_cast(params.files_.size()); if (params.action_ & Action::extract && params.target_ & Params::ctStdInOut && s > 1) { std::cerr << params.progname() << ": " << _("Only one file is allowed when extracting to stdout") << std::endl; @@ -168,6 +167,7 @@ int main(int argc, char* const argv[]) } else { int w = s > 9 ? s > 99 ? 3 : 2 : 1; + int n = 1; for (auto&& file : params.files_) { // If extracting to stdout then ignore verbose if (params.verbose_ && !(params.action_ & Action::extract && params.target_ & Params::ctStdInOut)) { @@ -248,25 +248,6 @@ void Params::usage(std::ostream& os) const << _("Image metadata manipulation tool.\n"); } -std::string Params::printTarget(const std::string &before, int target, bool bPrint, std::ostream& out) -{ - std::string t; - if ( target & Params::ctExif ) t+= 'e'; - if ( target & Params::ctXmpSidecar ) t+= 'X'; - if ( target & Params::ctXmpRaw ) t+= target & Params::ctXmpSidecar ? 'X' : 'R' ; - if ( target & Params::ctIptc ) t+= 'i'; - if ( target & Params::ctIccProfile ) t+= 'C'; - if ( target & Params::ctIptcRaw ) t+= 'I'; - if ( target & Params::ctXmp ) t+= 'x'; - if ( target & Params::ctComment ) t+= 'c'; - if ( target & Params::ctThumb ) t+= 't'; - if ( target & Params::ctPreview ) t+= 'p'; - if ( target & Params::ctStdInOut ) t+= '-'; - - if ( bPrint ) out << before << " :" << t << std::endl; - return t; -} - void Params::help(std::ostream& os) const { usage(os); diff --git a/app/exiv2app.hpp b/app/exiv2app.hpp index 97230021..680bb7f2 100644 --- a/app/exiv2app.hpp +++ b/app/exiv2app.hpp @@ -339,10 +339,6 @@ public: //! Print version information to an output stream. static void version(bool verbose = false, std::ostream& os = std::cout); - //! Print target_ - static std::string printTarget(const std::string& before, int target, bool bPrint = false, - std::ostream& out = std::cout); - //! getStdin binary data read from stdin to DataBuf /* stdin can be used by multiple images in the exiv2 command line: diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index bd3c7214..c456344d 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -240,7 +240,7 @@ namespace Exiv2 { comprehensive error messages where only a BasicIo instance is available. */ - virtual std::string path() const =0; + virtual const std::string& path() const noexcept =0; /*! @brief Mark all the bNone blocks to bKnow. This avoids allocating memory @@ -472,7 +472,7 @@ namespace Exiv2 { //! Returns true if the file position has reached the end, otherwise false. bool eof() const override; //! Returns the path of the file - std::string path() const override; + const std::string& path() const noexcept override; /*! @brief Mark all the bNone blocks to bKnow. This avoids allocating memory @@ -654,7 +654,7 @@ namespace Exiv2 { //!Returns true if the IO position has reached the end, otherwise false. bool eof() const override; //! Returns a dummy path, indicating that memory access is used - std::string path() const override; + const std::string& path() const noexcept override; /*! @brief Mark all the bNone blocks to bKnow. This avoids allocating memory @@ -898,7 +898,7 @@ namespace Exiv2 { //!Returns true if the IO position has reached the end, otherwise false. bool eof() const override; //!Returns the URL of the file. - std::string path() const override; + const std::string& path() const noexcept override; /*! @brief Mark all the bNone blocks to bKnow. This avoids allocating memory @@ -1008,12 +1008,6 @@ namespace Exiv2 { @throw Error In case of failure. */ EXIV2API long writeFile(const DataBuf& buf, const std::string& path); - /*! - @brief replace each substring of the subject that matches the given search string with the given replacement. - @return the subject after replacing. - */ - EXIV2API std::string ReplaceStringInPlace(std::string subject, const std::string& search, - const std::string& replace); #ifdef EXV_USE_CURL /*! @brief The callback function is called by libcurl to write the data diff --git a/include/exiv2/bmffimage.hpp b/include/exiv2/bmffimage.hpp index 9630c389..abed178e 100644 --- a/include/exiv2/bmffimage.hpp +++ b/include/exiv2/bmffimage.hpp @@ -25,7 +25,8 @@ // included header files #include "image.hpp" -#include "iostream" + +#include // ***************************************************************************** // namespace extensions @@ -127,7 +128,7 @@ namespace Exiv2 //@{ void readMetadata() override /* override */; void writeMetadata() override /* override */; - void setComment(const std::string& comment) override /* override */; + void setComment(std::string_view comment) override /* override */; void printStructure(std::ostream& out, Exiv2::PrintStructureOption option, int depth) override; //@} diff --git a/include/exiv2/bmpimage.hpp b/include/exiv2/bmpimage.hpp index 6fd46fdf..4966ad9e 100644 --- a/include/exiv2/bmpimage.hpp +++ b/include/exiv2/bmpimage.hpp @@ -85,7 +85,7 @@ namespace Exiv2 { void setIptcData(const IptcData& iptcData) override; /// @throws Error(kerInvalidSettingForImage) - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/config.h b/include/exiv2/config.h index 84e3f8d0..0a777129 100644 --- a/include/exiv2/config.h +++ b/include/exiv2/config.h @@ -6,29 +6,8 @@ ///// Start of Visual Studio Support ///// #ifdef _MSC_VER -#define _MSC_VER_2010 1600 -#define _MSC_VER_2008 1500 - -// Constants required by Microsoft SDKs to define SHGetFolderPathA and others - -#ifndef _WIN32_WINNT -// Visual Studio 2012 and earlier -# if _MSC_VER < 1800 -# define _WIN32_WINNT 0x0501 -# else -# define _WIN32_WINNT 0x0600 -# endif -#endif - -#if _MSC_VER >= _MSC_VER_2008 #pragma warning(disable : 4996) // Disable warnings about 'deprecated' standard functions #pragma warning(disable : 4251) // Disable warnings from std templates about exporting interfaces -#endif - -/* On Microsoft compilers pid_t has to be set to int. */ -#ifndef HAVE_PID_T -typedef int pid_t; -#endif #endif // _MSC_VER ///// End of Visual Studio Support ///// @@ -93,16 +72,4 @@ typedef int pid_t; #endif ////////////////////////////////////// - -// https://softwareengineering.stackexchange.com/questions/291141/how-to-handle-design-changes-for-auto-ptr-deprecation-in-c11 -#if __cplusplus >= 201103L - #include - #include - #ifndef _MSC_VER - #include - #endif - template - using auto_ptr = std::unique_ptr; -#endif - #endif // _CONFIG_H_ diff --git a/include/exiv2/cr2image.hpp b/include/exiv2/cr2image.hpp index 2abfc39d..f8f7990c 100644 --- a/include/exiv2/cr2image.hpp +++ b/include/exiv2/cr2image.hpp @@ -81,7 +81,7 @@ namespace Exiv2 { @brief Not supported. CR2 format does not contain a comment. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/datasets.hpp b/include/exiv2/datasets.hpp index df6f4769..1a63ac1d 100644 --- a/include/exiv2/datasets.hpp +++ b/include/exiv2/datasets.hpp @@ -32,11 +32,6 @@ // included header files #include "metadatum.hpp" -// + standard includes -#include -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/include/exiv2/epsimage.hpp b/include/exiv2/epsimage.hpp index 20360477..ca4c498d 100644 --- a/include/exiv2/epsimage.hpp +++ b/include/exiv2/epsimage.hpp @@ -80,7 +80,7 @@ namespace Exiv2 @brief Not supported. Calling this function will throw an instance of Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/error.hpp b/include/exiv2/error.hpp index 7517023a..8d0f1e56 100644 --- a/include/exiv2/error.hpp +++ b/include/exiv2/error.hpp @@ -34,10 +34,6 @@ // included header files #include "types.hpp" -// + standard includes -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/include/exiv2/futils.hpp b/include/exiv2/futils.hpp index 388d7bf0..ced26270 100644 --- a/include/exiv2/futils.hpp +++ b/include/exiv2/futils.hpp @@ -63,18 +63,7 @@ namespace Exiv2 @note Source: http://www.geekhideout.com/urlcode.shtml @todo This function can probably be hidden into the implementation details */ - EXIV2API std::string urlencode(const char* str); - - /*! - @brief Decode the input url. - @param str The url needs decoding. - @return the url-decoded version of str. - - @note Be sure to 'free' the returned string after use with 'delete []'. - Source: http://www.geekhideout.com/urlcode.shtml - @todo This function can probably be hidden into the implementation details - */ - EXIV2API char* urldecode(const char* str); + EXIV2API std::string urlencode(std::string_view str); /*! @brief Like urlencode(char* str) but accept the input url in the std::string and modify it. @@ -125,15 +114,7 @@ namespace Exiv2 and its type, see stat(2). errno is left unchanged in case of an error. */ - EXIV2API bool fileExists(const std::string& path, bool ct = false); - - /*! - @brief Get the path of file URL. - - @param url The file URL in the format file:///path or file://host/path - @return the path of file URL. - */ - EXIV2API std::string pathOfFileUrl(const std::string& url); + EXIV2API bool fileExists(const std::string& path); /*! @brief Return a system error message and the error code (errno). diff --git a/include/exiv2/gifimage.hpp b/include/exiv2/gifimage.hpp index 97c33b6c..4f1f3d85 100644 --- a/include/exiv2/gifimage.hpp +++ b/include/exiv2/gifimage.hpp @@ -86,7 +86,7 @@ namespace Exiv2 { @brief Not supported. Calling this function will throw an instance of Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/http.hpp b/include/exiv2/http.hpp index 71d33d67..9d46a703 100644 --- a/include/exiv2/http.hpp +++ b/include/exiv2/http.hpp @@ -25,8 +25,6 @@ #include "datasets.hpp" -#include - namespace Exiv2 { /*! diff --git a/include/exiv2/image.hpp b/include/exiv2/image.hpp index 7229cbc7..36adf69e 100644 --- a/include/exiv2/image.hpp +++ b/include/exiv2/image.hpp @@ -30,10 +30,6 @@ #include "image_types.hpp" #include "xmp_exiv2.hpp" -// + standard includes -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { @@ -199,12 +195,10 @@ namespace Exiv2 { writeXmpFromPacket(true) or setXmpPacket(). */ virtual void clearXmpData(); - /*! - @brief Set the image comment. The new comment is not written - to the image until the writeMetadata() method is called. - @param comment String containing comment. - */ - virtual void setComment(const std::string& comment); + + /// @brief Set the image comment. The comment is written to the image when writeMetadata() is called. + virtual void setComment(std::string_view comment); + /*! @brief Erase any buffered comment. Comment is not removed from the actual image until the writeMetadata() method is called. diff --git a/include/exiv2/ini.hpp b/include/exiv2/ini.hpp index c1749a3b..bd717177 100755 --- a/include/exiv2/ini.hpp +++ b/include/exiv2/ini.hpp @@ -32,7 +32,6 @@ #include #include -#include namespace Exiv2 { diff --git a/include/exiv2/jp2image.hpp b/include/exiv2/jp2image.hpp index e303fb30..2a0604db 100644 --- a/include/exiv2/jp2image.hpp +++ b/include/exiv2/jp2image.hpp @@ -80,7 +80,7 @@ namespace Exiv2 @brief Todo: Not supported yet(?). Calling this function will throw an instance of Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/mrwimage.hpp b/include/exiv2/mrwimage.hpp index 6801ee06..0956963f 100644 --- a/include/exiv2/mrwimage.hpp +++ b/include/exiv2/mrwimage.hpp @@ -89,7 +89,7 @@ namespace Exiv2 { @brief Not supported. MRW format does not contain a comment. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/orfimage.hpp b/include/exiv2/orfimage.hpp index bec350da..956e665b 100644 --- a/include/exiv2/orfimage.hpp +++ b/include/exiv2/orfimage.hpp @@ -76,7 +76,7 @@ namespace Exiv2 { @brief Not supported. ORF format does not contain a comment. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/psdimage.hpp b/include/exiv2/psdimage.hpp index 9bcfb01e..2863cfdc 100644 --- a/include/exiv2/psdimage.hpp +++ b/include/exiv2/psdimage.hpp @@ -70,7 +70,7 @@ namespace Exiv2 { /*! @brief Not supported. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/rafimage.hpp b/include/exiv2/rafimage.hpp index 09386a53..9c651c00 100644 --- a/include/exiv2/rafimage.hpp +++ b/include/exiv2/rafimage.hpp @@ -25,11 +25,6 @@ // included header files #include "image.hpp" -#include "basicio.hpp" -#include "types.hpp" - -// + standard includes -#include // ***************************************************************************** // namespace extensions @@ -87,7 +82,7 @@ namespace Exiv2 { @brief Not supported. RAF format does not contain a comment. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/rw2image.hpp b/include/exiv2/rw2image.hpp index 73dccea3..34ecd7fb 100644 --- a/include/exiv2/rw2image.hpp +++ b/include/exiv2/rw2image.hpp @@ -80,7 +80,7 @@ namespace Exiv2 { @brief Not supported. RW2 format does not contain a comment. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/tags.hpp b/include/exiv2/tags.hpp index 8910839e..3670da17 100644 --- a/include/exiv2/tags.hpp +++ b/include/exiv2/tags.hpp @@ -26,11 +26,6 @@ // included header files #include "metadatum.hpp" -// + standard includes -#include -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/include/exiv2/tgaimage.hpp b/include/exiv2/tgaimage.hpp index ce5f07bd..12d87fe3 100644 --- a/include/exiv2/tgaimage.hpp +++ b/include/exiv2/tgaimage.hpp @@ -86,7 +86,7 @@ namespace Exiv2 { @brief Not supported. Calling this function will throw an instance of Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/tiffimage.hpp b/include/exiv2/tiffimage.hpp index 9af0dc20..c2344354 100644 --- a/include/exiv2/tiffimage.hpp +++ b/include/exiv2/tiffimage.hpp @@ -77,7 +77,7 @@ namespace Exiv2 { @brief Not supported. TIFF format does not contain a comment. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index 6d40d2fb..c3182f66 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -27,13 +27,11 @@ #include "slice.hpp" // + standard includes -#include -#include -#include -#include #include +#include #include - +#include +#include /*! @brief Macro to make calls to member functions through a pointer more readable. @@ -42,12 +40,6 @@ */ #define EXV_CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) -#ifndef _MSC_VER -#define EXV_UNUSED [[gnu::unused]] -#else -#define EXV_UNUSED -#endif - // ***************************************************************************** // forward declarations struct tm; @@ -576,11 +568,6 @@ namespace Exiv2 { // This is abs() - given the existence of broken compilers with Koenig // lookup issues and other problems, I code this explicitly. (Remember, // IntType may be a user-defined type). -#ifdef _MSC_VER -#pragma warning( disable : 4146 ) -#undef max -#undef min -#endif if (n < zero) { if (n == std::numeric_limits::min()) { n = std::numeric_limits::max(); @@ -590,9 +577,6 @@ namespace Exiv2 { } if (m < zero) m = -m; -#ifdef _MSC_VER -#pragma warning( default : 4146 ) -#endif // As n and m are now positive, we can be sure that %= returns a // positive value (the standard guarantees this for built-in types, diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp index b51c5642..e75fedc0 100644 --- a/include/exiv2/value.hpp +++ b/include/exiv2/value.hpp @@ -27,11 +27,9 @@ #include "types.hpp" // + standard includes -#include -#include -#include #include -#include +#include +#include // ***************************************************************************** // namespace extensions diff --git a/include/exiv2/webpimage.hpp b/include/exiv2/webpimage.hpp index d3280921..1eb8f653 100644 --- a/include/exiv2/webpimage.hpp +++ b/include/exiv2/webpimage.hpp @@ -65,7 +65,7 @@ namespace Exiv2 { /*! @brief Not supported. Calling this function will throw an Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; void setIptcData(const IptcData& /*iptcData*/) override; //! @name Accessors diff --git a/include/exiv2/xmpsidecar.hpp b/include/exiv2/xmpsidecar.hpp index 5557a331..a6f6b119 100644 --- a/include/exiv2/xmpsidecar.hpp +++ b/include/exiv2/xmpsidecar.hpp @@ -64,7 +64,7 @@ namespace Exiv2 { @brief Not supported. XMP sidecar files do not contain a comment. Calling this function will throw an instance of Error(kerInvalidSettingForImage). */ - void setComment(const std::string& comment) override; + void setComment(std::string_view comment) override; //@} //! @name Accessors diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a4990b4e..1e4917cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,6 +36,7 @@ add_library( exiv2lib_int OBJECT tifffwd_int.hpp timegm.h unused.h + utils.hpp utils.cpp ) set(PUBLIC_HEADERS diff --git a/src/basicio.cpp b/src/basicio.cpp index 4bd2d7e4..807d75c8 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -34,18 +34,22 @@ #include "image_int.hpp" // + standard includes -#include -#include -#include -#include // std::memcpy +#include // _O_BINARY in FileIo::FileIo +#include // for stat, chmod +#include // for stat, chmod + #include -#include // write the temporary file -#include // _O_BINARY in FileIo::FileIo -#include // for remove, rename -#include // for alloc, realloc, free -#include // timestamp for the name of temporary file -#include // for stat, chmod -#include // for stat, chmod +#include // for remove, rename +#include // for alloc, realloc, free +#include // std::memcpy +#include // timestamp for the name of temporary file +#include +#include // write the temporary file +#include +#include +#include + +namespace fs = std::filesystem; #ifdef EXV_HAVE_SYS_MMAN_H # include // for mmap and munmap @@ -63,20 +67,25 @@ #define mode_t unsigned short -// Platform specific headers for handling extended attributes (xattr) -#if defined(__APPLE__) -# include -#endif - #if defined(__MINGW__) || (defined(WIN32) && !defined(__CYGWIN__)) -// Windows doesn't provide nlink_t -using nlink_t = short; # include # include #endif // ***************************************************************************** // class member definitions +namespace { + /// @brief replace each substring of the subject that matches the given search string with the given replacement. + void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace) + { + size_t pos = 0; + while ((pos = subject.find(search, pos)) != std::string::npos) { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + } +} + namespace Exiv2 { void BasicIo::readOrThrow(byte* buf, long rcount, ErrorCode err) { const long nread = read(buf, rcount); @@ -117,7 +126,6 @@ namespace Exiv2 { StructStat() = default; mode_t st_mode{0}; //!< Permissions off_t st_size{0}; //!< Size - nlink_t st_nlink{0}; //!< Number of hard links (broken on Windows, see winNumberOfLinks()) }; // #endif // METHODS @@ -130,12 +138,6 @@ namespace Exiv2 { int switchMode(OpMode opMode); //! stat wrapper for internal use int stat(StructStat& buf) const; - //! copy extended attributes (xattr) from another file - void copyXattrFrom(const FileIo& src); -#if defined WIN32 && !defined __CYGWIN__ - // Windows function to determine the number of hardlinks (on NTFS) - DWORD winNumberOfLinks() const; -#endif // NOT IMPLEMENTED Impl(const Impl& rhs) = delete; //!< Copy constructor Impl& operator=(const Impl& rhs) = delete; //!< Assignment @@ -211,96 +213,11 @@ namespace Exiv2 { ret = ::stat(path_.c_str(), &st); if (0 == ret) { buf.st_size = st.st_size; - buf.st_nlink = st.st_nlink; buf.st_mode = st.st_mode; } return ret; } // FileIo::Impl::stat -#if defined(__APPLE__) - void FileIo::Impl::copyXattrFrom(const FileIo& src) -#else - void FileIo::Impl::copyXattrFrom(const FileIo&) -#endif - { -#if defined(__APPLE__) - ssize_t namebufSize = ::listxattr(src.p_->path_.c_str(), 0, 0, 0); - if (namebufSize < 0) { - throw Error(kerCallFailed, src.p_->path_, strError(), "listxattr"); - } - if (namebufSize == 0) { - // No extended attributes in source file - return; - } - char* namebuf = new char[namebufSize]; - if (::listxattr(src.p_->path_.c_str(), namebuf, namebufSize, 0) != namebufSize) { - throw Error(kerCallFailed, src.p_->path_, strError(), "listxattr"); - } - for (ssize_t namebufPos = 0; namebufPos < namebufSize;) { - const char *name = namebuf + namebufPos; - namebufPos += strlen(name) + 1; - const ssize_t valueSize = ::getxattr(src.p_->path_.c_str(), name, 0, 0, 0, 0); - if (valueSize < 0) { - throw Error(kerCallFailed, src.p_->path_, strError(), "getxattr"); - } - char* value = new char[valueSize]; - if (::getxattr(src.p_->path_.c_str(), name, value, valueSize, 0, 0) != valueSize) { - throw Error(kerCallFailed, src.p_->path_, strError(), "getxattr"); - } -// #906. Mountain Lion 'sandbox' terminates the app when we call setxattr -#ifndef __APPLE__ -#ifdef EXIV2_DEBUG_MESSAGES - EXV_DEBUG << "Copying xattr \"" << name << "\" with value size " << valueSize << "\n"; -#endif - if (::setxattr(path_.c_str(), name, value, valueSize, 0, 0) != 0) { - throw Error(kerCallFailed, path_, strError(), "setxattr"); - } - delete [] value; -#endif - } - delete [] namebuf; -#else - // No xattr support for this platform. -#endif - } // FileIo::Impl::copyXattrFrom - -#if defined WIN32 && !defined __CYGWIN__ - DWORD FileIo::Impl::winNumberOfLinks() const - { - DWORD nlink = 1; - - HANDLE hFd = (HANDLE)_get_osfhandle(fileno(fp_)); - if (hFd != INVALID_HANDLE_VALUE) { - using GetFileInformationByHandle_t = BOOL(WINAPI*)(HANDLE, LPBY_HANDLE_FILE_INFORMATION); - HMODULE hKernel = ::GetModuleHandleA("kernel32.dll"); - if (hKernel) { - GetFileInformationByHandle_t pfcn_GetFileInformationByHandle = (GetFileInformationByHandle_t)GetProcAddress(hKernel, "GetFileInformationByHandle"); - if (pfcn_GetFileInformationByHandle) { - BY_HANDLE_FILE_INFORMATION fi = {0,0,0,0,0,0,0,0,0,0,0,0,0}; - if (pfcn_GetFileInformationByHandle(hFd, &fi)) { - nlink = fi.nNumberOfLinks; - } -#ifdef EXIV2_DEBUG_MESSAGES - else EXV_DEBUG << "GetFileInformationByHandle failed\n"; -#endif - } -#ifdef EXIV2_DEBUG_MESSAGES - else EXV_DEBUG << "GetProcAddress(hKernel, \"GetFileInformationByHandle\") failed\n"; -#endif - } -#ifdef EXIV2_DEBUG_MESSAGES - else EXV_DEBUG << "GetModuleHandleA(\"kernel32.dll\") failed\n"; -#endif - } -#ifdef EXIV2_DEBUG_MESSAGES - else EXV_DEBUG << "_get_osfhandle failed: INVALID_HANDLE_VALUE\n"; -#endif - - return nlink; - } // FileIo::Impl::winNumberOfLinks - -#endif // defined WIN32 && !defined __CYGWIN__ - FileIo::FileIo(const std::string& path) : p_(new Impl(path)) { @@ -435,10 +352,10 @@ namespace Exiv2 { byte buf[4096]; long readCount = 0; - long writeCount = 0; long writeTotal = 0; while ((readCount = src.read(buf, sizeof(buf)))) { - writeTotal += writeCount = static_cast(std::fwrite(buf, 1, readCount, p_->fp_)); + long writeCount = static_cast(std::fwrite(buf, 1, readCount, p_->fp_)); + writeTotal += writeCount; if (writeCount != readCount) { // try to reset back to where write stopped src.seek(writeCount-readCount, BasicIo::cur); @@ -460,56 +377,21 @@ namespace Exiv2 { fileIo->close(); // Check if the file can be written to, if it already exists if (open("a+b") != 0) { - /// \todo Use std::filesystem once C++17 can be used // Remove the (temporary) file - ::remove(fileIo->path().c_str()); + fs::remove(fileIo->path().c_str()); throw Error(kerFileOpenFailed, path(), "a+b", strError()); } close(); bool statOk = true; mode_t origStMode = 0; - std::string spf; - char* pf = nullptr; - spf = path(); - pf = const_cast(spf.c_str()); + auto pf = path().c_str(); - // Get the permissions of the file, or linked-to file, on platforms which have lstat -#ifdef EXV_HAVE_LSTAT - - struct stat buf1; - if (::lstat(pf, &buf1) == -1) { - statOk = false; -#ifndef SUPPRESS_WARNINGS - EXV_WARNING << Error(kerCallFailed, pf, strError(), "::lstat") << "\n"; -#endif - } - origStMode = buf1.st_mode; - DataBuf lbuf; // So that the allocated memory is freed. Must have same scope as pf - // In case path() is a symlink, get the path of the linked-to file - if (statOk && S_ISLNK(buf1.st_mode)) { - lbuf.alloc(buf1.st_size + 1); - lbuf.clear(); - pf = reinterpret_cast(lbuf.data()); - if (::readlink(path().c_str(), pf, lbuf.size() - 1) == -1) { - throw Error(kerCallFailed, path(), strError(), "readlink"); - } - // We need the permissions of the file, not the symlink - if (::stat(pf, &buf1) == -1) { - statOk = false; -#ifndef SUPPRESS_WARNINGS - EXV_WARNING << Error(kerCallFailed, pf, strError(), "::stat") << "\n"; -#endif - } - origStMode = buf1.st_mode; - } -#else // EXV_HAVE_LSTAT Impl::StructStat buf1; if (p_->stat(buf1) == -1) { statOk = false; } origStMode = buf1.st_mode; -#endif // !EXV_HAVE_LSTAT { #if defined(WIN32) && defined(REPLACEFILE_IGNORE_MERGE_ERRORS) @@ -526,10 +408,8 @@ namespace Exiv2 { BOOL ret = pfcn_ReplaceFileA(pf, fileIo->path().c_str(), NULL, REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL); if (ret == 0) { if (GetLastError() == ERROR_FILE_NOT_FOUND) { - if (::rename(fileIo->path().c_str(), pf) == -1) { - throw Error(kerFileRenameFailed, fileIo->path(), pf, strError()); - } - ::remove(fileIo->path().c_str()); + fs::rename(fileIo->path().c_str(), pf); + fs::remove(fileIo->path().c_str()); } else { throw Error(kerFileRenameFailed, fileIo->path(), pf, strError()); @@ -538,22 +418,18 @@ namespace Exiv2 { } else { if (fileExists(pf) && ::remove(pf) != 0) { - throw Error(kerCallFailed, pf, strError(), "::remove"); - } - if (::rename(fileIo->path().c_str(), pf) == -1) { - throw Error(kerFileRenameFailed, fileIo->path(), pf, strError()); + throw Error(kerCallFailed, pf, strError(), "fs::remove"); } - ::remove(fileIo->path().c_str()); + fs::rename(fileIo->path().c_str(), pf); + fs::remove(fileIo->path().c_str()); } } #else - if (fileExists(pf) && ::remove(pf) != 0) { - throw Error(kerCallFailed, pf, strError(), "::remove"); + if (fileExists(pf) && fs::remove(pf) != 0) { + throw Error(kerCallFailed, pf, strError(), "fs::remove"); } - if (::rename(fileIo->path().c_str(), pf) == -1) { - throw Error(kerFileRenameFailed, fileIo->path(), pf, strError()); - } - ::remove(fileIo->path().c_str()); + fs::rename(fileIo->path().c_str(), pf); + fs::remove(fileIo->path().c_str()); #endif // Check permissions of new file struct stat buf2; @@ -720,7 +596,7 @@ namespace Exiv2 { return std::feof(p_->fp_) != 0; } - std::string FileIo::path() const + const std::string& FileIo::path() const noexcept { return p_->path_; } @@ -802,18 +678,17 @@ namespace Exiv2 { { return type_ == bNone; } - bool isInMem () const - { - return type_ == bMemory; - } + bool isKnown () const { return type_ == bKnown; } + byte* getData () const { return data_; } + size_t getSize () const { return size_; @@ -1044,9 +919,10 @@ namespace Exiv2 { return p_->eof_; } - std::string MemIo::path() const + const std::string& MemIo::path() const noexcept { - return "MemIo"; + static std::string _path{"MemIo"}; + return _path; } void MemIo::populateFakeData() { @@ -1107,7 +983,7 @@ namespace Exiv2 { } XPathIo::~XPathIo() { - if (isTemp_ && remove(tempFilePath_.c_str()) != 0) { + if (isTemp_ && !fs::remove(tempFilePath_)) { // error when removing file // printf ("Warning: Unable to remove the temp file %s.\n", tempFilePath_.c_str()); } @@ -1116,13 +992,12 @@ namespace Exiv2 { void XPathIo::transfer(BasicIo& src) { if (isTemp_) { // replace temp path to gent path. - std::string currentPath = path(); - setPath(ReplaceStringInPlace(currentPath, XPathIo::TEMP_FILE_EXT, XPathIo::GEN_FILE_EXT)); - // rename the file + auto currentPath = path(); + ReplaceStringInPlace(currentPath, XPathIo::TEMP_FILE_EXT, XPathIo::GEN_FILE_EXT); + setPath(currentPath); + tempFilePath_ = path(); - if (rename(currentPath.c_str(), tempFilePath_.c_str()) != 0) { - // printf("Warning: Failed to rename the temp file. \n"); - } + fs::rename(currentPath, tempFilePath_); isTemp_ = false; // call super class method FileIo::transfer(src); @@ -1371,21 +1246,18 @@ namespace Exiv2 { size_t left = 0; size_t right = 0; size_t blockIndex = 0; - size_t i = 0; - size_t readCount = 0; - size_t blockSize = 0; - auto buf = new byte [p_->blockSize_]; + std::vector buf(p_->blockSize_); size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_; // find $left src.seek(0, BasicIo::beg); bool findDiff = false; while (blockIndex < nBlocks && !src.eof() && !findDiff) { - blockSize = p_->blocksMap_[blockIndex].getSize(); + size_t blockSize = p_->blocksMap_[blockIndex].getSize(); bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data - readCount = static_cast(src.read(buf, static_cast(blockSize))); + size_t readCount = static_cast(src.read(buf.data(), static_cast(blockSize))); byte* blockData = p_->blocksMap_[blockIndex].getData(); - for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { + for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { if ((!isFakeData && buf[i] != blockData[i]) || (isFakeData && buf[i] != 0)) { findDiff = true; } else { @@ -1400,14 +1272,14 @@ namespace Exiv2 { blockIndex = nBlocks; while (blockIndex > 0 && right < src.size() && !findDiff) { blockIndex--; - blockSize = p_->blocksMap_[blockIndex].getSize(); + size_t blockSize = p_->blocksMap_[blockIndex].getSize(); if(src.seek(-1 * (blockSize + right), BasicIo::end)) { findDiff = true; } else { bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data - readCount = src.read(buf, static_cast(blockSize)); + size_t readCount = src.read(buf.data(), static_cast(blockSize)); byte* blockData = p_->blocksMap_[blockIndex].getData(); - for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { + for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) { if ((!isFakeData && buf[readCount - i - 1] != blockData[blockSize - i - 1]) || (isFakeData && buf[readCount - i - 1] != 0)) { findDiff = true; } else { @@ -1417,8 +1289,6 @@ namespace Exiv2 { } } - delete []buf; - // submit to the remote machine. long dataSize = static_cast(src.size() - left - right); if (dataSize > 0) { @@ -1585,7 +1455,7 @@ namespace Exiv2 { return p_->eof_; } - std::string RemoteIo::path() const + const std::string& RemoteIo::path() const noexcept { return p_->path_; } @@ -1989,15 +1859,6 @@ namespace Exiv2 { return file.write(buf.c_data(), buf.size()); } - std::string ReplaceStringInPlace(std::string subject, const std::string& search, - const std::string& replace) { - size_t pos = 0; - while((pos = subject.find(search, pos)) != std::string::npos) { - subject.replace(pos, search.length(), replace); - pos += replace.length(); - } - return subject; - } #ifdef EXV_USE_CURL size_t curlWriter(char* data, size_t size, size_t nmemb, diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index 1598ca23..c2d6c8ff 100644 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -627,11 +627,11 @@ namespace Exiv2 } } - void BmffImage::setComment(const std::string& /*comment*/) + void BmffImage::setComment(std::string_view /*comment*/) { // bmff files are read-only throw(Error(kerInvalidSettingForImage, "Image comment", "BMFF")); - } // BmffImage::setComment + } void BmffImage::openOrThrow() { diff --git a/src/bmpimage.cpp b/src/bmpimage.cpp index 0e3ea146..4e99d04a 100644 --- a/src/bmpimage.cpp +++ b/src/bmpimage.cpp @@ -61,7 +61,7 @@ namespace Exiv2 throw(Error(kerInvalidSettingForImage, "IPTC metadata", "BMP")); } - void BmpImage::setComment(const std::string& /*comment*/) + void BmpImage::setComment(std::string_view /*comment*/) { throw(Error(kerInvalidSettingForImage, "Image comment", "BMP")); } diff --git a/src/canonmn_int.cpp b/src/canonmn_int.cpp index aa58f8b3..5fc630c9 100644 --- a/src/canonmn_int.cpp +++ b/src/canonmn_int.cpp @@ -437,7 +437,7 @@ namespace Exiv2 { // Categories, tag 0x0023 - EXV_UNUSED constexpr TagDetails canonCategories[] = { + [[maybe_unused]] constexpr TagDetails canonCategories[] = { { 0x0001, N_("People") }, { 0x0002, N_("Scenery") }, { 0x0004, N_("Events") }, @@ -2110,7 +2110,7 @@ namespace Exiv2 { }; //! ManualFlashOutput, tag 0x0029 - EXV_UNUSED constexpr TagDetails canonCsManualFlashOutput[] = { + [[maybe_unused]] constexpr TagDetails canonCsManualFlashOutput[] = { { 0x0000, N_("n/a") }, { 0x0500, N_("Full") }, { 0x0502, N_("Medium") }, diff --git a/src/canonmn_int.hpp b/src/canonmn_int.hpp index 8d2dee22..93a0a23a 100644 --- a/src/canonmn_int.hpp +++ b/src/canonmn_int.hpp @@ -37,11 +37,6 @@ #include "tags.hpp" #include "types.hpp" -// + standard includes -#include -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/casiomn_int.hpp b/src/casiomn_int.hpp index 33f39b9a..4a7cc3c2 100644 --- a/src/casiomn_int.hpp +++ b/src/casiomn_int.hpp @@ -33,10 +33,6 @@ #include "tags.hpp" #include "types.hpp" -// + standard includes -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/convert.cpp b/src/convert.cpp index 2d1ce167..d7348701 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -37,13 +37,14 @@ #include "unused.h" // + standard includes -#include -#include +#include // for snprintf (C99) +#include +#include #include #include +#include #include -#include // for snprintf (C99) -#include +#include #if defined WIN32 && !defined __CYGWIN__ # include @@ -284,8 +285,6 @@ namespace Exiv2 { //@{ //! Get the value of the erase flag, see also setErase(bool on). bool erase() const { return erase_; } - //! Get the value of the overwrite flag, see also setOverwrite(bool on). - bool overwrite() const { return overwrite_; } //@} private: @@ -293,7 +292,6 @@ namespace Exiv2 { bool prepareIptcTarget(const char* to, bool force =false); bool prepareXmpTarget(const char* to, bool force =false); std::string computeExifDigest(bool tiff); - std::string computeIptcDigest(); // DATA static const Conversion conversion_[]; //(min)) * 60.0; min = static_cast(static_cast(min)); - sep2 = ','; } if ( in.bad() || !(ref == 'N' || ref == 'S' || ref == 'E' || ref == 'W') @@ -1256,28 +1253,6 @@ namespace Exiv2 { writeExifDigest(); } - std::string Converter::computeIptcDigest() - { -#ifdef EXV_HAVE_XMP_TOOLKIT - std::ostringstream res; - MD5_CTX context; - unsigned char digest[16]; - - MD5Init(&context); - - DataBuf data = IptcParser::encode(*iptcData_); - MD5Update(&context, data.c_data(), data.size()); - MD5Final(digest, &context); - res << std::setw(2) << std::setfill('0') << std::hex << std::uppercase; - for (auto&& i : digest) { - res << static_cast(i); - } - return res.str(); -#else - return std::string(""); -#endif - } - // ************************************************************************* // free functions @@ -1288,6 +1263,7 @@ namespace Exiv2 { converter.cnvToXmp(); } + /// \todo not used internally. We should at least have unit tests for this. void moveExifToXmp(ExifData& exifData, XmpData& xmpData) { Converter converter(exifData, xmpData); @@ -1301,6 +1277,7 @@ namespace Exiv2 { converter.cnvFromXmp(); } + /// \todo not used internally. We should at least have unit tests for this. void moveXmpToExif(XmpData& xmpData, ExifData& exifData) { Converter converter(exifData, xmpData); @@ -1323,6 +1300,7 @@ namespace Exiv2 { converter.cnvToXmp(); } + /// \todo not used internally. We should at least have unit tests for this. void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData, const char *iptcCharset) { if (!iptcCharset) iptcCharset = iptcData.detectCharset(); @@ -1338,6 +1316,7 @@ namespace Exiv2 { converter.cnvFromXmp(); } + /// \todo not used internally. We should at least have unit tests for this. void moveXmpToIptc(XmpData& xmpData, IptcData& iptcData) { Converter converter(iptcData, xmpData); diff --git a/src/cr2image.cpp b/src/cr2image.cpp index a79c569a..cbbcecbe 100644 --- a/src/cr2image.cpp +++ b/src/cr2image.cpp @@ -81,7 +81,7 @@ namespace Exiv2 { printTiffStructure(io(),out,option,depth-1); } - void Cr2Image::setComment(const std::string& /*comment*/) + void Cr2Image::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "CR2")); diff --git a/src/crwimage.cpp b/src/crwimage.cpp index 5309725c..92b16700 100644 --- a/src/crwimage.cpp +++ b/src/crwimage.cpp @@ -147,9 +147,6 @@ namespace Exiv2 { // Parse the image, starting with a CIFF header component CiffHeader header; header.read(pData, size); -#ifdef EXIV2_DEBUG_MESSAGES - header.print(std::cerr); -#endif header.decode(*pCrwImage); // a hack to get absolute offset of preview image inside CRW structure diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp index e32f056b..c869b325 100644 --- a/src/crwimage_int.cpp +++ b/src/crwimage_int.cpp @@ -21,13 +21,13 @@ #include "crwimage_int.hpp" #include "canonmn_int.hpp" #include "i18n.h" // NLS support. -#include "timegm.h" #include "unused.h" #include "error.hpp" #include "enforce.hpp" #include #include +#include // ***************************************************************************** // local declarations @@ -53,7 +53,6 @@ namespace { // ***************************************************************************** // local definitions namespace { - //! @cond IGNORE constexpr RotationMap::OmList RotationMap::omList_[] = { { 1, 0 }, { 3, 180 }, @@ -87,7 +86,6 @@ namespace { } return d; } - //! @endcond } // namespace namespace Exiv2 { @@ -503,16 +501,6 @@ namespace Exiv2 { } } // CiffComponent::writeDirEntry - void CiffHeader::print(std::ostream& os, const std::string& prefix) const - { - std::ios::fmtflags f( os.flags() ); - os << prefix - << _("Header, offset") << " = 0x" << std::setw(8) << std::setfill('0') - << std::hex << std::right << offset_ << "\n"; - if (pRootDir_) pRootDir_->print(os, byteOrder_, prefix); - os.flags(f); - } // CiffHeader::print - void CiffComponent::print(std::ostream& os, ByteOrder byteOrder, const std::string& prefix) const @@ -617,10 +605,10 @@ namespace Exiv2 { CiffComponent* CiffDirectory::doFindComponent(uint16_t crwTagId, uint16_t crwDir) const { - CiffComponent* cc; for (auto&& component : components_) { - cc = component->findComponent(crwTagId, crwDir); - if (cc) return cc; + auto cc = component->findComponent(crwTagId, crwDir); + if (cc) + return cc; } return nullptr; } // CiffDirectory::doFindComponent diff --git a/src/crwimage_int.hpp b/src/crwimage_int.hpp index 81e80068..935802f6 100644 --- a/src/crwimage_int.hpp +++ b/src/crwimage_int.hpp @@ -26,8 +26,6 @@ #include "image.hpp" // + standard includes -#include -#include #include #include @@ -481,13 +479,7 @@ namespace Exiv2 { @param image Image to add metadata to */ void decode(Image& image) const; - /*! - @brief Print debug info for the CRW image to \em os. - @param os Output stream to write to. - @param prefix Prefix to be written before each line of output. - */ - void print(std::ostream& os, const std::string& prefix ="") const; //! Return the byte order (little or big endian). ByteOrder byteOrder() const { return byteOrder_; } /*! diff --git a/src/epsimage.cpp b/src/epsimage.cpp index eba0c7fe..386508b8 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -32,6 +32,7 @@ #include "basicio.hpp" #include "error.hpp" #include "futils.hpp" +#include "utils.hpp" #include "version.hpp" // + standard includes @@ -103,11 +104,6 @@ namespace { // closing part of all valid XMP trailers const std::string xmpTrailerEnd = "?>"; - constexpr bool startsWith(const std::string_view& s, const std::string_view& start) - { - return s.find(start) == 0; - } - //! Write data into temp file, taking care of errors void writeTemp(BasicIo& tempIo, const byte* data, size_t size) { @@ -1098,7 +1094,7 @@ namespace Exiv2 return "application/postscript"; } - void EpsImage::setComment(const std::string& /*comment*/) + void EpsImage::setComment(std::string_view /*comment*/) { throw Error(kerInvalidSettingForImage, "Image comment", "EPS"); } diff --git a/src/fujimn_int.hpp b/src/fujimn_int.hpp index 9c802790..1f8e6ff8 100644 --- a/src/fujimn_int.hpp +++ b/src/fujimn_int.hpp @@ -24,7 +24,6 @@ // ***************************************************************************** // included header files #include "tags.hpp" -#include "types.hpp" // ***************************************************************************** // namespace extensions diff --git a/src/futils.cpp b/src/futils.cpp index 0024579e..be13d424 100644 --- a/src/futils.cpp +++ b/src/futils.cpp @@ -27,19 +27,23 @@ #include "image_int.hpp" // + standard includes -#include #include +#include + +#include #include -#include #include -#include +#include #include -#include +#include +#include #include -#ifdef EXV_HAVE_UNISTD_H -#include // for stat() +#ifdef EXV_HAVE_UNISTD_H +#include // for stat() #endif +namespace fs = std::filesystem; + #if defined(WIN32) #include #include // For access to GetModuleFileNameEx @@ -101,52 +105,43 @@ namespace Exiv2 { return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; } - std::string urlencode(const char* str) { - const char* pstr = str; - // \todo try to use std::string for buf and avoid the creation of another string for just - // returning the final value - auto buf = new char[strlen(str) * 3 + 1]; - char* pbuf = buf; - while (*pstr) { - if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') - *pbuf++ = *pstr; - else if (*pstr == ' ') - *pbuf++ = '+'; - else - *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); - pstr++; + std::string urlencode(std::string_view str) + { + std::string encoded; + encoded.reserve(str.size() * 3); + for (uint8_t c : str) { + if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') + encoded += c; + else if (c == ' ') + encoded += '+'; + else { + encoded += '%'; + encoded += to_hex(c >> 4); + encoded += to_hex(c & 15); + } } - *pbuf = '\0'; - std::string ret(buf); - delete [] buf; - return ret; + encoded.shrink_to_fit(); + return encoded; } - char* urldecode(const char* str) { - const char* pstr = str; - auto buf = new char[(strlen(str) + 1)]; - char* pbuf = buf; - while (*pstr) { - if (*pstr == '%') { - if (pstr[1] && pstr[2]) { - *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); - pstr += 2; + void urldecode(std::string& str) + { + size_t idxIn{0}, idxOut{0}; + size_t sizeStr = str.size(); + while (idxIn < sizeStr) { + if (str[idxIn] == '%') { + if (str[idxIn+1] && str[idxIn+2]) { + str[idxOut++] = from_hex(str[idxIn+1]) << 4 | from_hex(str[idxIn+2]); + idxIn += 2; } - } else if (*pstr == '+') { - *pbuf++ = ' '; + } else if (str[idxIn] == '+') { + str[idxOut++] = ' '; } else { - *pbuf++ = *pstr; + str[idxOut++] = str[idxIn]; } - pstr++; + idxIn++; } - *pbuf = '\0'; - return buf; - } - - void urldecode(std::string& str) { - char* decodeStr = Exiv2::urldecode(str.c_str()); - str = std::string(decodeStr); - delete [] decodeStr; + str.erase(idxOut); } // https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c @@ -157,7 +152,6 @@ namespace Exiv2 { int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize) { auto encoding_table = base64_encode; - size_t mod_table[] = {0, 2, 1}; size_t output_length = 4 * ((dataLength + 2) / 3); int rc = result && data_buf && output_length < resultSize ? 1 : 0; @@ -177,6 +171,7 @@ namespace Exiv2 { result[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; } + const size_t mod_table[] = {0, 2, 1}; for (size_t i = 0; i < mod_table[dataLength % 3]; i++) result[output_length - 1 - i] = '='; result[output_length]=0; @@ -252,25 +247,12 @@ namespace Exiv2 { return result; } // fileProtocol - bool fileExists(const std::string& path, bool ct) + bool fileExists(const std::string& path) { - // special case: accept "-" (means stdin) - if (path == "-" || fileProtocol(path) != pFile) { + if (fileProtocol(path) != pFile) { return true; } - - struct stat buf; - int ret = ::stat(path.c_str(), &buf); - if (0 != ret) return false; - if (ct && !S_ISREG(buf.st_mode)) return false; - return true; - } // fileExists - - std::string pathOfFileUrl(const std::string& url) { - std::string path = url.substr(7); - size_t found = path.find('/'); - if (found == std::string::npos) return path; - return path.substr(found); + return fs::exists(path); } std::string strError() diff --git a/src/gifimage.cpp b/src/gifimage.cpp index 22d1400c..b9e17bdf 100644 --- a/src/gifimage.cpp +++ b/src/gifimage.cpp @@ -58,7 +58,7 @@ namespace Exiv2 { throw(Error(kerInvalidSettingForImage, "IPTC metadata", "GIF")); } - void GifImage::setComment(const std::string& /*comment*/) + void GifImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "GIF")); diff --git a/src/http.cpp b/src/http.cpp index 9334b81f..5c04fd68 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -239,8 +239,6 @@ int Exiv2::http(Exiv2::Dictionary& request,Exiv2::Dictionary& response,std::stri servername_p = Proxy.Host.c_str(); port_p = Proxy.Port.c_str(); page = url.c_str(); - std::string p(proxy?proxi:PROXI); - // std::cerr << p << '=' << prox << " page = " << page << std::endl; } if ( !port [0] ) port = "80"; if ( !port_p[0] ) port_p = "80"; diff --git a/src/image.cpp b/src/image.cpp index fd6322f9..945747ad 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -135,6 +135,12 @@ namespace { { ImageType::none, nullptr, nullptr, amNone, amNone, amNone, amNone } }; + std::string pathOfFileUrl(const std::string& url) { + std::string path = url.substr(7); + size_t found = path.find('/'); + return (found == std::string::npos) ? path : path.substr(found); + } + } // namespace // ***************************************************************************** @@ -278,6 +284,7 @@ namespace Exiv2 { return Image::byteSwap(v,bSwap); } + /// \todo not used internally. At least we should test it uint64_t Image::byteSwap8(const DataBuf& buf,size_t offset,bool bSwap) { uint64_t v = 0; @@ -367,7 +374,6 @@ namespace Exiv2 { // Break for unknown tag types else we may segfault. if ( !typeValid(type) ) { EXV_ERROR << "invalid type in tiff structure" << type << std::endl; - start = 0; // break from do loop throw Error(kerInvalidTypeValue); } @@ -519,7 +525,6 @@ namespace Exiv2 { out << Internal::indent(depth) << "END " << io.path() << std::endl; } out.flush(); - depth--; } void Image::printTiffStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option,int depth,size_t offset /*=0*/) @@ -576,6 +581,7 @@ namespace Exiv2 { return xmpPacket_; } + /// \todo not used internally. At least we should test it void Image::setMetadata(const Image& image) { if (checkMode(mdExif) & amWrite) { @@ -624,7 +630,6 @@ namespace Exiv2 { void Image::setXmpPacket(const std::string& xmpPacket) { - xmpPacket_ = xmpPacket; if ( XmpParser::decode(xmpData_, xmpPacket) ) { throw Error(kerInvalidXMP); } @@ -657,7 +662,7 @@ namespace Exiv2 { comment_.erase(); } - void Image::setComment(const std::string& comment) + void Image::setComment(std::string_view comment) { comment_ = comment; } @@ -749,6 +754,7 @@ namespace Exiv2 { return ImageFactory::checkType(imageType_, *io_, false); } + /// \todo not used internally. At least we should test it bool Image::supportsMetadata(MetadataId metadataId) const { return (supportedMetadata_ & metadataId) != 0; diff --git a/src/image_int.cpp b/src/image_int.cpp index 8db6de19..84ea26b7 100644 --- a/src/image_int.cpp +++ b/src/image_int.cpp @@ -57,52 +57,6 @@ namespace Exiv2 return result; } - std::string binaryToHex(const byte* data, size_t size) - { - std::stringstream hexOutput; - - auto tl = size_t(size / 16) * 16; - auto tl_offset = size_t(size) - tl; - - for (size_t loop = 0; loop < size; loop++) { - if (data[loop] < 16) { - hexOutput << "0"; - } - hexOutput << std::hex << static_cast(data[loop]); - if ((loop % 8) == 7) { - hexOutput << " "; - } - if ((loop % 16) == 15 || loop == (tl + tl_offset - 1)) { - int max = 15; - if (loop >= tl) { - max = int(tl_offset) - 1; - for (int offset = 0; offset < int(16 - tl_offset); offset++) { - if ((offset % 8) == 7) { - hexOutput << " "; - } - hexOutput << " "; - } - } - hexOutput << " "; - for (int offset = max; offset >= 0; offset--) { - if (offset == (max - 8)) { - hexOutput << " "; - } - byte c = '.'; - if (data[loop - offset] >= 0x20 && data[loop - offset] <= 0x7E) { - c = data[loop - offset]; - } - hexOutput << static_cast(c); - } - hexOutput << std::endl; - } - } - - hexOutput << std::endl << std::endl << std::endl; - - return hexOutput.str(); - } - std::string indent(int32_t d) { std::string result; diff --git a/src/image_int.hpp b/src/image_int.hpp index fe50d62c..7058795c 100644 --- a/src/image_int.hpp +++ b/src/image_int.hpp @@ -120,14 +120,7 @@ namespace Exiv2 { return binaryToStringHelper(sl); } - /*! - @brief format binary for display of raw data . - */ - std::string binaryToHex(const byte *data, size_t size); - - /*! - @brief indent output for kpsRecursive in \em printStructure() \em . - */ + /// @brief indent output for kpsRecursive in \em printStructure() \em . std::string indent(int32_t depth); }} // namespace Internal, Exiv2 diff --git a/src/iptc.cpp b/src/iptc.cpp index d0c63408..776ef9ca 100644 --- a/src/iptc.cpp +++ b/src/iptc.cpp @@ -327,11 +327,13 @@ namespace Exiv2 { FindIptcdatum(dataset, record)); } + /// \todo not used internally. At least we should test it void IptcData::sortByKey() { std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByKey); } + /// \todo not used internally. At least we should test it void IptcData::sortByTag() { std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByTag); @@ -350,8 +352,7 @@ namespace Exiv2 { size_t i = 0; while (i < bytes.size() - 3 && bytes.at(i) != 0x1c) i++; - depth++; - out << Internal::indent(depth) << "Record | DataSet | Name | Length | Data" << std::endl; + out << Internal::indent(++depth) << "Record | DataSet | Name | Length | Data" << std::endl; while (i < bytes.size() - 3) { if (bytes.at(i) != 0x1c) { break; @@ -370,7 +371,6 @@ namespace Exiv2 { << std::endl; i += 5 + len; } - depth--; } const char *IptcData::detectCharset() const diff --git a/src/jp2image.cpp b/src/jp2image.cpp index 5ba66117..078e3a4d 100644 --- a/src/jp2image.cpp +++ b/src/jp2image.cpp @@ -158,11 +158,11 @@ namespace Exiv2 return "image/jp2"; } - void Jp2Image::setComment(const std::string& /*comment*/) + void Jp2Image::setComment(std::string_view /*comment*/) { // Todo: implement me! throw(Error(kerInvalidSettingForImage, "Image comment", "JP2")); - } // Jp2Image::setComment + } static void lf(std::ostream& out,bool& bLF) { @@ -221,7 +221,6 @@ static void boxes_check(size_t b,size_t m) throw Error(kerNotAnImage, "JPEG-2000"); } - long position = 0; Jp2BoxHeader box = {0,0}; Jp2BoxHeader subBox = {0,0}; Jp2ImageHeaderBox ihdr = {0,0,0,0,0,0,0,0}; @@ -231,7 +230,7 @@ static void boxes_check(size_t b,size_t m) while (io_->read(reinterpret_cast(&box), sizeof(box)) == sizeof(box)) { boxes_check(boxes++,boxem ); - position = io_->tell(); + long position = io_->tell(); box.length = getLong(reinterpret_cast(&box.length), bigEndian); box.type = getLong(reinterpret_cast(&box.type), bigEndian); #ifdef EXIV2_DEBUG_MESSAGES @@ -490,7 +489,6 @@ static void boxes_check(size_t b,size_t m) if ( bPrint || bXMP || bICC || bIPTCErase ) { - long position = 0; Jp2BoxHeader box = {1,1}; Jp2BoxHeader subBox = {1,1}; Jp2UuidBox uuid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; @@ -498,7 +496,7 @@ static void boxes_check(size_t b,size_t m) while (box.length && box.type != kJp2BoxTypeClose && io_->read(reinterpret_cast(&box), sizeof(box)) == sizeof(box)) { - position = io_->tell(); + long position = io_->tell(); box.length = getLong(reinterpret_cast(&box.length), bigEndian); box.type = getLong(reinterpret_cast(&box.type), bigEndian); enforce(box.length <= sizeof(box)+io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata); diff --git a/src/makernote_int.cpp b/src/makernote_int.cpp index 5863eb01..0fbb54c0 100644 --- a/src/makernote_int.cpp +++ b/src/makernote_int.cpp @@ -32,11 +32,15 @@ #include "tiffvisitor_int.hpp" #include "tiffimage.hpp" #include "tiffimage_int.hpp" +#include "utils.hpp" // + standard includes -#include +#include +#include #include -#include +#include + +namespace fs = std::filesystem; #if defined(__MINGW32__) || defined(__MINGW64__) #ifndef __MINGW__ @@ -52,25 +56,6 @@ #include #include // _getcwd #include - /* older SDKs not have these */ -# ifndef CSIDL_MYMUSIC -# define CSIDL_MYMUSIC 13 -# endif -# ifndef CSIDL_MYVIDEO -# define CSIDL_MYVIDEO 14 -# endif -# ifndef CSIDL_INTERNET_CACHE -# define CSIDL_INTERNET_CACHE 32 -# endif -# ifndef CSIDL_COMMON_APPDATA -# define CSIDL_COMMON_APPDATA 35 -# endif -# ifndef CSIDL_MYPICTURES -# define CSIDL_MYPICTURES 0x27 -# endif -# ifndef CSIDL_COMMON_DOCUMENTS -# define CSIDL_COMMON_DOCUMENTS 46 -# endif # ifndef CSIDL_PROFILE # define CSIDL_PROFILE 40 # endif @@ -96,7 +81,6 @@ namespace { namespace Exiv2 { namespace Internal { - // C++17 use std::filesystem // Function first looks for a config file in current working directory // on Win the file should be named "exiv2.ini" // on Lin the file should be named ".exiv2" @@ -104,36 +88,27 @@ namespace Exiv2 { // which is the user profile path on win and the home dir on linux std::string getExiv2ConfigPath() { - std::string dir; #if defined(_MSC_VER) || defined(__MINGW__) std::string inifile("exiv2.ini"); #else std::string inifile(".exiv2"); #endif - - // first lets get the current working directory to check if there is a config file - char buffer[1024]; -#if defined(_MSC_VER) || defined(__MINGW__) - auto path = _getcwd(buffer, sizeof(buffer)); -#else - auto path = getcwd(buffer, sizeof(buffer)); -#endif - dir = std::string(path ? path : ""); - auto const filename = dir + EXV_SEPARATOR_CHR + inifile; - // true if the file exists - if (std::ifstream(filename).good()) { - return filename; + auto currentPath = fs::current_path(); + auto iniPath = currentPath / inifile; + if (fs::exists(iniPath)) { + return iniPath.string(); } #if defined(_MSC_VER) || defined(__MINGW__) - if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path))) { - dir = std::string(path); + char buffer[1024]; + if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, buffer))) { + currentPath = buffer; } #else struct passwd* pw = getpwuid(getuid()); - dir = std::string(pw ? pw->pw_dir : ""); + currentPath = std::string(pw ? pw->pw_dir : ""); #endif - return dir + EXV_SEPARATOR_CHR + inifile; + return (currentPath / inifile).string(); } std::string readExiv2Config(const std::string& section, const std::string& value, const std::string& def) @@ -1223,11 +1198,8 @@ namespace Exiv2 { { // Not valid for models beginning std::string model = getExifModel(pRoot); - for (auto& m : { "SLT-", "HV", "ILCA-" }) { - if (model.find(m) == 0) - return -1; - } - return 0; + const std::array strs { "SLT-", "HV", "ILCA-"}; + return std::any_of(strs.begin(), strs.end(), [&model](auto& m){return startsWith(model, m);}) ? -1 : 0; } int sonyMisc2bSelector(uint16_t /*tag*/, const byte* /*pData*/, uint32_t /*size*/, TiffComponent* const pRoot) diff --git a/src/makernote_int.hpp b/src/makernote_int.hpp index df8a1ebd..aea41027 100644 --- a/src/makernote_int.hpp +++ b/src/makernote_int.hpp @@ -24,12 +24,8 @@ // included header files #include "tifffwd_int.hpp" #include "tags_int.hpp" -#include "ini.hpp" #include "types.hpp" -// + standard includes -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/minoltamn_int.cpp b/src/minoltamn_int.cpp index a445369f..6e761fa4 100644 --- a/src/minoltamn_int.cpp +++ b/src/minoltamn_int.cpp @@ -63,7 +63,7 @@ namespace Exiv2 { }; //! Lookup table to translate Minolta image quality values to readable labels - EXV_UNUSED constexpr TagDetails minoltaImageQuality[] = { + [[maybe_unused]] constexpr TagDetails minoltaImageQuality[] = { { 0, N_("Raw") }, { 1, N_("Super Fine") }, { 2, N_("Fine") }, @@ -273,7 +273,7 @@ namespace Exiv2 { }; //! Lookup table to translate Minolta Std camera settings AF points values to readable labels - EXV_UNUSED constexpr TagDetails minoltaAFPointsStd[] = { + [[maybe_unused]] constexpr TagDetails minoltaAFPointsStd[] = { { 0, N_("Center") }, { 1, N_("Top") }, { 2, N_("Top-right") }, @@ -2490,16 +2490,5 @@ namespace Exiv2 { return EXV_PRINT_TAG(minoltaSonyZoneMatching)(os, value, metadata); } - std::ostream& printMinoltaSonyFlashExposureComp(std::ostream& os, const Value& value, const ExifData*) - { - std::ios::fmtflags f( os.flags() ); - if (value.count() != 1 || value.typeId() != signedRational) { - return os << "(" << value << ")"; - } - os << std::fixed << std::setprecision(2) << value.toFloat(0) << " EV"; - os.flags(f); - return os; - } - } // namespace Internal } // namespace Exiv2 diff --git a/src/minoltamn_int.hpp b/src/minoltamn_int.hpp index 1fab3ffd..e8aa9924 100644 --- a/src/minoltamn_int.hpp +++ b/src/minoltamn_int.hpp @@ -136,9 +136,6 @@ namespace Exiv2 { //! Print Minolta/Sony ZoneMatching values to readable labels. std::ostream& printMinoltaSonyZoneMatching(std::ostream&, const Value&, const ExifData*); - //! Print Minolta/Sony FlashExposureComp values to readable labels. - std::ostream& printMinoltaSonyFlashExposureComp(std::ostream&, const Value&, const ExifData*); - // TODO: Added shared methods here. }} // namespace Internal, Exiv2 diff --git a/src/mrwimage.cpp b/src/mrwimage.cpp index 81068cb0..be96c649 100644 --- a/src/mrwimage.cpp +++ b/src/mrwimage.cpp @@ -79,7 +79,7 @@ namespace Exiv2 { throw(Error(kerInvalidSettingForImage, "IPTC metadata", "MRW")); } - void MrwImage::setComment(const std::string& /*comment*/) + void MrwImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "MRW")); diff --git a/src/olympusmn_int.cpp b/src/olympusmn_int.cpp index 2a4e6c02..9c71c469 100644 --- a/src/olympusmn_int.cpp +++ b/src/olympusmn_int.cpp @@ -490,7 +490,7 @@ namespace Exiv2 { }; //! FocusMode, tag 0x0301 - EXV_UNUSED constexpr TagDetails olympusCsFocusMode[] = { + [[maybe_unused]] constexpr TagDetails olympusCsFocusMode[] = { { 0, N_("Single AF") }, { 1, N_("Sequential shooting AF") }, { 2, N_("Continuous AF") }, diff --git a/src/orfimage.cpp b/src/orfimage.cpp index 76f48660..645bb9aa 100644 --- a/src/orfimage.cpp +++ b/src/orfimage.cpp @@ -72,7 +72,7 @@ namespace Exiv2 { return 0; } - void OrfImage::setComment(const std::string& /*comment*/) + void OrfImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "ORF")); diff --git a/src/panasonicmn_int.hpp b/src/panasonicmn_int.hpp index 4951a401..4acde797 100644 --- a/src/panasonicmn_int.hpp +++ b/src/panasonicmn_int.hpp @@ -25,10 +25,6 @@ #include "tags.hpp" #include "types.hpp" -// + standard includes -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/pentaxmn_int.hpp b/src/pentaxmn_int.hpp index 597c9728..ec407027 100644 --- a/src/pentaxmn_int.hpp +++ b/src/pentaxmn_int.hpp @@ -26,10 +26,6 @@ #include "tags_int.hpp" #include "types.hpp" -// + standard includes -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/pngchunk_int.hpp b/src/pngchunk_int.hpp index 66824888..48806bc0 100644 --- a/src/pngchunk_int.hpp +++ b/src/pngchunk_int.hpp @@ -25,11 +25,6 @@ #include "types.hpp" #include "pngimage.hpp" -// + standard includes -#include -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/pngimage.cpp b/src/pngimage.cpp index 4d25d21c..90ece7cf 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -35,6 +35,7 @@ #include "types.hpp" // + standard includes +#include #include #include #include @@ -150,11 +151,11 @@ namespace Exiv2 { static bool tEXtToDataBuf(const byte* bytes,long length,DataBuf& result) { - static const char* hexdigits = "0123456789ABCDEF"; static std::array value; static bool bFirst = true; if ( bFirst ) { value.fill(0); + const char* hexdigits = "0123456789ABCDEF"; for ( int i = 0 ; i < 16 ; i++ ) { value[tolower(hexdigits[i])]=i+1; value[toupper(hexdigits[i])]=i+1; diff --git a/src/preview.cpp b/src/preview.cpp index 52710308..4141ba5b 100644 --- a/src/preview.cpp +++ b/src/preview.cpp @@ -21,6 +21,7 @@ // included header files #include "config.h" +#include #include #include #include diff --git a/src/properties.cpp b/src/properties.cpp index 3a55e5cf..31ed9c39 100644 --- a/src/properties.cpp +++ b/src/properties.cpp @@ -3943,6 +3943,7 @@ namespace Exiv2 { XmpProperties::NsRegistry XmpProperties::nsRegistry_; std::mutex XmpProperties::mutex_; + /// \todo not used internally. At least we should test it const XmpNsInfo* XmpProperties::lookupNsRegistry(const XmpNsInfo::Prefix& prefix) { std::lock_guard scoped_read_lock(mutex_); @@ -4095,6 +4096,7 @@ namespace Exiv2 { return pi; } + /// \todo not used internally. At least we should test it const char* XmpProperties::nsDesc(const std::string& prefix) { return nsInfo(prefix)->desc_; diff --git a/src/psdimage.cpp b/src/psdimage.cpp index 9a159fe6..6b509344 100644 --- a/src/psdimage.cpp +++ b/src/psdimage.cpp @@ -127,7 +127,7 @@ namespace Exiv2 { return "image/x-photoshop"; } - void PsdImage::setComment(const std::string& /*comment*/) + void PsdImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "Photoshop")); @@ -399,13 +399,15 @@ namespace Exiv2 { #endif // Copy colorData uint32_t readTotal = 0; - long toRead = 0; while (readTotal < colorDataLength) { - toRead = static_cast(colorDataLength - readTotal) < lbuf.size() - ? static_cast(colorDataLength - readTotal) : lbuf.size(); - if (io_->read(lbuf.data(), toRead) != toRead) throw Error(kerNotAnImage, "Photoshop"); + long toRead = static_cast(colorDataLength - readTotal) < lbuf.size() + ? static_cast(colorDataLength - readTotal) + : lbuf.size(); + if (io_->read(lbuf.data(), toRead) != toRead) + throw Error(kerNotAnImage, "Photoshop"); readTotal += toRead; - if (outIo.write(lbuf.c_data(), toRead) != toRead) throw Error(kerImageWriteFailed); + if (outIo.write(lbuf.c_data(), toRead) != toRead) + throw Error(kerImageWriteFailed); } if (outIo.error()) throw Error(kerImageWriteFailed); @@ -505,15 +507,17 @@ namespace Exiv2 { if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed); readTotal = 0; - toRead = 0; while (readTotal < pResourceSize) { - toRead = static_cast(pResourceSize - readTotal) < lbuf.size() - ? static_cast(pResourceSize - readTotal) : lbuf.size(); + /// \todo almost same code as in lines 403-410. Factor out & reuse! + long toRead = static_cast(pResourceSize - readTotal) < lbuf.size() + ? static_cast(pResourceSize - readTotal) + : lbuf.size(); if (io_->read(lbuf.data(), toRead) != toRead) { throw Error(kerNotAnImage, "Photoshop"); } readTotal += toRead; - if (outIo.write(lbuf.c_data(), toRead) != toRead) throw Error(kerImageWriteFailed); + if (outIo.write(lbuf.c_data(), toRead) != toRead) + throw Error(kerImageWriteFailed); } if (outIo.error()) throw Error(kerImageWriteFailed); newResLength += pResourceSize + adjResourceNameLen + 12; @@ -532,13 +536,11 @@ namespace Exiv2 { // Append ExifInfo resource block, if not yet written if (!exifDone) { newResLength += writeExifData(exifData_, outIo); - exifDone = true; } // Append XmpPacket resource block, if not yet written if (!xmpDone) { newResLength += writeXmpData(xmpData_, outIo); - xmpDone = true; } // Populate the fake data, only make sense for remoteio, httpio and sshio. diff --git a/src/rafimage.cpp b/src/rafimage.cpp index c4258510..4dc9a2b1 100644 --- a/src/rafimage.cpp +++ b/src/rafimage.cpp @@ -81,7 +81,7 @@ namespace Exiv2 { throw(Error(kerInvalidSettingForImage, "IPTC metadata", "RAF")); } - void RafImage::setComment(const std::string& /*comment*/) + void RafImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "RAF")); @@ -96,12 +96,11 @@ namespace Exiv2 { if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); throw Error(kerNotAnImage, "RAF"); } - size_t address = 0 ; - size_t address2 = 0 ; + const bool bPrint = option==kpsBasic || option==kpsRecursive; if ( bPrint ) { io_->seek(0,BasicIo::beg); // rewind - address = io_->tell(); + size_t address = io_->tell(); const char* format = " %8d | %8d | "; { @@ -174,7 +173,7 @@ namespace Exiv2 { byte jpg_img_offset [4]; io_->read(jpg_img_offset, 4); byte jpg_img_length [4]; - address2 = io_->tell(); + size_t address2 = io_->tell(); io_->read(jpg_img_length, 4); long jpg_img_off = Exiv2::getULong(jpg_img_offset, bigEndian); diff --git a/src/rw2image.cpp b/src/rw2image.cpp index 0d56216d..6a0e51c6 100644 --- a/src/rw2image.cpp +++ b/src/rw2image.cpp @@ -83,7 +83,7 @@ namespace Exiv2 { throw(Error(kerInvalidSettingForImage, "IPTC metadata", "RW2")); } - void Rw2Image::setComment(const std::string& /*comment*/) + void Rw2Image::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "RW2")); diff --git a/src/rw2image_int.hpp b/src/rw2image_int.hpp index fe1838c0..c7443857 100644 --- a/src/rw2image_int.hpp +++ b/src/rw2image_int.hpp @@ -23,10 +23,6 @@ // ***************************************************************************** // included header files #include "tiffimage_int.hpp" -#include "types.hpp" - -// + standard includes -#include // ***************************************************************************** // namespace extensions diff --git a/src/samsungmn_int.hpp b/src/samsungmn_int.hpp index 8670821d..dcf4ec82 100644 --- a/src/samsungmn_int.hpp +++ b/src/samsungmn_int.hpp @@ -25,11 +25,6 @@ #include "tags.hpp" #include "types.hpp" -// + standard includes -#include -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/sigmamn_int.hpp b/src/sigmamn_int.hpp index f0b18134..03467a94 100644 --- a/src/sigmamn_int.hpp +++ b/src/sigmamn_int.hpp @@ -25,11 +25,6 @@ #include "tags.hpp" #include "types.hpp" -// + standard includes -#include -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/sonymn_int.hpp b/src/sonymn_int.hpp index 7f0d394f..a2de831d 100644 --- a/src/sonymn_int.hpp +++ b/src/sonymn_int.hpp @@ -22,14 +22,8 @@ // ***************************************************************************** // included header files -#include "tags.hpp" -#include "types.hpp" #include "tiffcomposite_int.hpp" -// + standard includes -#include -#include - // ***************************************************************************** // namespace extensions namespace Exiv2 { diff --git a/src/tags.cpp b/src/tags.cpp index c7922964..d2b3dace 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -127,6 +127,7 @@ namespace Exiv2 { return sectionInfo[ti->sectionId_].name_; } + /// \todo not used internally. At least we should test it uint16_t ExifTags::defaultCount(const ExifKey& key) { const TagInfo* ti = tagInfo(key.tag(), static_cast(key.ifdId())); diff --git a/src/tags_int.cpp b/src/tags_int.cpp index e134bef3..f1259729 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -40,6 +40,7 @@ #include "sonymn_int.hpp" #include +#include // ***************************************************************************** // local declarations diff --git a/src/tags_int.hpp b/src/tags_int.hpp index 0f965d2c..8576de3f 100644 --- a/src/tags_int.hpp +++ b/src/tags_int.hpp @@ -22,14 +22,7 @@ // ***************************************************************************** // included header files -#include "types.hpp" #include "tags.hpp" -#include "value.hpp" - -// + standard includes -#include -#include -#include // ***************************************************************************** // namespace extensions diff --git a/src/tgaimage.cpp b/src/tgaimage.cpp index 4db565ec..61031b9d 100644 --- a/src/tgaimage.cpp +++ b/src/tgaimage.cpp @@ -58,7 +58,7 @@ namespace Exiv2 { throw(Error(kerInvalidSettingForImage, "IPTC metadata", "TGA")); } - void TgaImage::setComment(const std::string& /*comment*/) + void TgaImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "TGA")); @@ -133,7 +133,7 @@ namespace Exiv2 { bool isTgaType(BasicIo& iIo, bool /*advance*/) { // not all TARGA files have a signature string, so first just try to match the file name extension - std::string path = iIo.path(); + const std::string& path = iIo.path(); if( path.rfind(".tga") != std::string::npos || path.rfind(".TGA") != std::string::npos) { return true; diff --git a/src/tiffcomposite_int.hpp b/src/tiffcomposite_int.hpp index ee2cca75..604b8b2c 100644 --- a/src/tiffcomposite_int.hpp +++ b/src/tiffcomposite_int.hpp @@ -22,16 +22,9 @@ // ***************************************************************************** // included header files -#include "value.hpp" #include "tifffwd_int.hpp" -#include "types.hpp" -// + standard includes -#include #include -#include -#include -#include // ***************************************************************************** // namespace extensions diff --git a/src/tifffwd_int.hpp b/src/tifffwd_int.hpp index f62ced67..fd355e64 100644 --- a/src/tifffwd_int.hpp +++ b/src/tifffwd_int.hpp @@ -26,9 +26,7 @@ #include "tags_int.hpp" // + standard includes -#include #include -#include // ***************************************************************************** // Exiv2 namespace extensions diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index 1732f665..e693c715 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -162,7 +162,7 @@ namespace Exiv2 { return pixelHeightPrimary_; } - void TiffImage::setComment(const std::string& /*comment*/) + void TiffImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "TIFF")); diff --git a/src/tiffimage_int.cpp b/src/tiffimage_int.cpp index 36849be7..e4cb602f 100644 --- a/src/tiffimage_int.cpp +++ b/src/tiffimage_int.cpp @@ -26,6 +26,8 @@ #include "tiffvisitor_int.hpp" #include "i18n.h" // NLS support. +#include + // Shortcuts for the newTiffBinaryArray templates. #define EXV_BINARY_ARRAY(arrayCfg, arrayDef) (newTiffBinaryArray0<&arrayCfg, EXV_COUNTOF(arrayDef), arrayDef>) #define EXV_SIMPLE_BINARY_ARRAY(arrayCfg) (newTiffBinaryArray1<&arrayCfg>) diff --git a/src/tiffimage_int.hpp b/src/tiffimage_int.hpp index 38a192cd..94292977 100644 --- a/src/tiffimage_int.hpp +++ b/src/tiffimage_int.hpp @@ -25,12 +25,6 @@ #include "tifffwd_int.hpp" #include "tiffcomposite_int.hpp" #include "image.hpp" -#include "tags_int.hpp" -#include "types.hpp" - -// + standard includes -#include -#include // ***************************************************************************** // namespace extensions diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp index 23dc8d9d..8ea7b31a 100644 --- a/src/tiffvisitor_int.cpp +++ b/src/tiffvisitor_int.cpp @@ -469,6 +469,7 @@ namespace Exiv2 { const uint16_t nMasks = (nPoints+15)/(sizeof(uint16_t) * 8); int nStart = 0; + /// \todo make this static struct { uint16_t tag ; uint16_t size ; diff --git a/src/tiffvisitor_int.hpp b/src/tiffvisitor_int.hpp index 872a91e0..f1d3a877 100644 --- a/src/tiffvisitor_int.hpp +++ b/src/tiffvisitor_int.hpp @@ -26,15 +26,7 @@ #include "tifffwd_int.hpp" #include "types.hpp" -// + standard includes #include -#include -#include -#include -#include -#include -#include -#include // ***************************************************************************** // namespace extensions @@ -42,6 +34,8 @@ namespace Exiv2 { class IptcData; class XmpData; + class TiffImageEntry; + class TiffDataEntryBase; namespace Internal { diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 00000000..479d79de --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,9 @@ +#include "utils.hpp" + +namespace Exiv2 +{ + bool startsWith(const std::string_view& s, const std::string_view& start) + { + return s.find(start) == 0; + } +} diff --git a/src/utils.hpp b/src/utils.hpp new file mode 100644 index 00000000..9b790116 --- /dev/null +++ b/src/utils.hpp @@ -0,0 +1,11 @@ +#ifndef EXIV2_UTILS_HPP +#define EXIV2_UTILS_HPP + +#include + +namespace Exiv2 +{ + bool startsWith(const std::string_view& s, const std::string_view& start); +} + +#endif // EXIV2_UTILS_HPP diff --git a/src/value.cpp b/src/value.cpp index bfd330f6..5bc3687f 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -804,7 +804,6 @@ namespace Exiv2 { std::string lang = "x-default"; if (buf.length() > 5 && buf.substr(0, 5) == "lang=") { static const char* ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static const char* ALPHA_NUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; const std::string::size_type pos = buf.find_first_of(' '); if (pos == std::string::npos) { @@ -829,6 +828,7 @@ namespace Exiv2 { // Check language is in the correct format (see https://www.ietf.org/rfc/rfc3066.txt) std::string::size_type charPos = lang.find_first_not_of(ALPHA); if (charPos != std::string::npos) { + static const char* ALPHA_NUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; if (lang.at(charPos) != '-' || lang.find_first_not_of(ALPHA_NUM, charPos+1) != std::string::npos) throw Error(kerInvalidLangAltValue, buf); } @@ -1110,6 +1110,7 @@ namespace Exiv2 { return 1; } + /// \todo not used internally. At least we should test it void TimeValue::setTime( const Time& src ) { std::memcpy(&time_, &src, sizeof(time_)); diff --git a/src/version.cpp b/src/version.cpp index d1982caf..c3e2953a 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -36,13 +36,10 @@ #endif // + standard includes -#include -#include -#include -#include -#include #include #include +#include +#include // #1147 #ifndef WIN32 @@ -139,7 +136,7 @@ static void output(std::ostream& os,const std::vector& greps,const c static bool pushPath(std::string& path,std::vector& libs,std::set& paths) { - bool result = Exiv2::fileExists(path,true) && paths.find(path) == paths.end() && path != "/" ; + bool result = Exiv2::fileExists(path) && paths.find(path) == paths.end() && path != "/" ; if ( result ) { paths.insert(path); libs.push_back(path); @@ -313,7 +310,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector& keys int have_lensdata =0; int have_iconv =0; int have_memory =0; - int have_lstat =0; int have_stdbool =0; int have_stdint =0; int have_stdlib =0; @@ -362,10 +358,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector& keys have_memory=1; #endif -#ifdef EXV_HAVE_LSTAT - have_lstat=1; -#endif - #ifdef EXV_HAVE_STDBOOL_H have_stdbool=1; #endif @@ -492,7 +484,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector& keys output(os,keys,"have_lensdata" ,have_lensdata ); output(os,keys,"have_iconv" ,have_iconv ); output(os,keys,"have_memory" ,have_memory ); - output(os,keys,"have_lstat" ,have_lstat ); output(os,keys,"have_stdbool" ,have_stdbool ); output(os,keys,"have_stdint" ,have_stdint ); output(os,keys,"have_stdlib" ,have_stdlib ); diff --git a/src/webpimage.cpp b/src/webpimage.cpp index 95400819..6562010f 100644 --- a/src/webpimage.cpp +++ b/src/webpimage.cpp @@ -50,6 +50,54 @@ #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) +namespace { + [[maybe_unused]] std::string binaryToHex(const uint8_t* data, size_t size) + { + std::stringstream hexOutput; + + auto tl = size_t(size / 16) * 16; + auto tl_offset = size_t(size) - tl; + + for (size_t loop = 0; loop < size; loop++) { + if (data[loop] < 16) { + hexOutput << "0"; + } + hexOutput << std::hex << static_cast(data[loop]); + if ((loop % 8) == 7) { + hexOutput << " "; + } + if ((loop % 16) == 15 || loop == (tl + tl_offset - 1)) { + int max = 15; + if (loop >= tl) { + max = int(tl_offset) - 1; + for (int offset = 0; offset < int(16 - tl_offset); offset++) { + if ((offset % 8) == 7) { + hexOutput << " "; + } + hexOutput << " "; + } + } + hexOutput << " "; + for (int offset = max; offset >= 0; offset--) { + if (offset == (max - 8)) { + hexOutput << " "; + } + uint8_t c = '.'; + if (data[loop - offset] >= 0x20 && data[loop - offset] <= 0x7E) { + c = data[loop - offset]; + } + hexOutput << static_cast(c); + } + hexOutput << std::endl; + } + } + + hexOutput << std::endl << std::endl << std::endl; + + return hexOutput.str(); + } +} // namespace + // ***************************************************************************** // class member definitions namespace Exiv2 { @@ -96,7 +144,7 @@ namespace Exiv2 { // throw(Error(kerInvalidSettingForImage, "IPTC metadata", "WebP")); } - void WebPImage::setComment(const std::string& /*comment*/) + void WebPImage::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "WebP")); @@ -688,7 +736,7 @@ namespace Exiv2 { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Display Hex Dump [size:" << static_cast(sizePayload) << "]" << std::endl; - std::cout << Internal::binaryToHex(rawExifData.c_data(), sizePayload); + std::cout << binaryToHex(rawExifData.c_data(), sizePayload); #endif if (pos != -1) { @@ -716,7 +764,7 @@ namespace Exiv2 { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Display Hex Dump [size:" << static_cast(payload.size()) << "]" << std::endl; - std::cout << Internal::binaryToHex(payload.c_data(), payload.size()); + std::cout << binaryToHex(payload.c_data(), payload.size()); #endif } } else { @@ -833,8 +881,6 @@ namespace Exiv2 { if (iIo.tell() % 2) { if (iIo.write(&WEBP_PAD_ODD, 1) != 1) throw Error(kerImageWriteFailed); } - - has_icc = false; } } diff --git a/src/xmpsidecar.cpp b/src/xmpsidecar.cpp index 28d405cd..cb709a5c 100644 --- a/src/xmpsidecar.cpp +++ b/src/xmpsidecar.cpp @@ -30,6 +30,7 @@ #include "convert.hpp" // + standard includes +#include #include #include #include @@ -61,7 +62,7 @@ namespace Exiv2 { return "application/rdf+xml"; } - void XmpSidecar::setComment(const std::string& /*comment*/) + void XmpSidecar::setComment(std::string_view /*comment*/) { // not supported throw(Error(kerInvalidSettingForImage, "Image comment", "XMP")); diff --git a/unitTests/test_ImageFactory.cpp b/unitTests/test_ImageFactory.cpp index 85e51a90..a7481101 100644 --- a/unitTests/test_ImageFactory.cpp +++ b/unitTests/test_ImageFactory.cpp @@ -65,7 +65,7 @@ TEST(TheImageFactory, createsInstancesForFewSupportedTypesInFiles) EXPECT_NO_THROW(ImageFactory::create(ImageType::pgf, filePath)); EXPECT_NO_THROW(ImageFactory::create(ImageType::png, filePath)); - EXPECT_EQ(0, std::remove(filePath.c_str())); + EXPECT_TRUE(fs::remove(filePath)); } TEST(TheImageFactory, cannotCreateInstancesForSomeTypesInFiles) diff --git a/unitTests/test_futils.cpp b/unitTests/test_futils.cpp index 2bb4dc81..93bdfa20 100644 --- a/unitTests/test_futils.cpp +++ b/unitTests/test_futils.cpp @@ -23,6 +23,7 @@ #include // Auxiliary headers +#include #include #include #include @@ -30,6 +31,8 @@ #include +namespace fs = std::filesystem; + using namespace Exiv2; TEST(strError, returnSuccessAfterClosingFile) @@ -42,7 +45,7 @@ TEST(strError, returnSuccessAfterClosingFile) std::string tmpFile("tmp.dat"); std::ofstream auxFile(tmpFile.c_str()); auxFile.close(); - std::remove(tmpFile.c_str()); + fs::remove(tmpFile.c_str()); ASSERT_TRUE(strError().find("(errno = 0)") != std::string::npos); } @@ -97,15 +100,6 @@ TEST(urlencode, encodesGivenUrlWithSpace) ASSERT_STREQ("http%3a%2f%2fwww.geekhideout.com%2furl+code.shtml", url.c_str()); } -TEST(urldecode, decodesGivenUrl) -{ - const std::string expectedDecodedUrl ("http://www.geekhideout.com/urlcode.shtml"); - const std::string url ("http%3a%2f%2fwww.geekhideout.com%2furlcode.shtml"); - char * url3 = urldecode(url.c_str()); - ASSERT_STREQ(expectedDecodedUrl.c_str(), url3); - delete [] url3; -} - TEST(urldecode, decodesGivenUrlInPlace) { const std::string expectedDecodedUrl ("http://www.geekhideout.com/urlcode.shtml");