From d941fa908722db466394dd1834d4bd7d1d87b714 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 8 Feb 2025 20:29:54 -0800 Subject: [PATCH] remove some ostringstreams Looks like they're slow under Cygwin. Signed-off-by: Rosen Penev --- src/convert.cpp | 44 ++++++++++++++++++++------------------------ src/futils.cpp | 14 +++++++------- src/tags.cpp | 5 ++--- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/convert.cpp b/src/convert.cpp index 55ed8e8194..565e220976 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -742,11 +742,13 @@ void Converter::cnvExifVersion(const char* from, const char* to) { return; if (!prepareXmpTarget(to)) return; - std::ostringstream value; - for (size_t i = 0; i < pos->count(); ++i) { - value << static_cast(pos->toInt64(i)); + auto count = pos->count(); + std::string value; + value.reserve(count); + for (size_t i = 0; i < count; ++i) { + value += static_cast(pos->toInt64(i)); } - (*xmpData_)[to] = value.str(); + (*xmpData_)[to] = value; if (erase_) exifData_->erase(pos); } @@ -826,9 +828,7 @@ void Converter::cnvExifGPSCoord(const char* from, const char* to) { double min = (deg[0] * 60.0) + deg[1] + (deg[2] / 60.0); auto ideg = static_cast(min / 60.0); min -= ideg * 60; - std::ostringstream oss; - oss << ideg << "," << std::fixed << std::setprecision(7) << min << refPos->toString().c_str()[0]; - (*xmpData_)[to] = oss.str(); + (*xmpData_)[to] = stringFormat("{},{:.7f}{}", ideg, min, refPos->toString().front()); if (erase_) exifData_->erase(pos); @@ -883,7 +883,7 @@ void Converter::cnvXmpArray(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); if (pos == xmpData_->end()) return; - std::ostringstream array; + std::string array; for (size_t i = 0; i < pos->count(); ++i) { std::string value = pos->toString(i); if (!pos->value().ok()) { @@ -892,11 +892,11 @@ void Converter::cnvXmpArray(const char* from, const char* to) { #endif return; } - array << value; + array += value; if (i != pos->count() - 1) - array << " "; + array += " "; } - (*exifData_)[to] = array.str(); + (*exifData_)[to] = array; if (erase_) xmpData_->erase(pos); } @@ -997,12 +997,9 @@ void Converter::cnvXmpVersion(const char* from, const char* to) { #endif return; } - std::ostringstream array; - array << static_cast(value[0]) << " " << static_cast(value[1]) << " " << static_cast(value[2]) << " " - << static_cast(value[3]); - - (*exifData_)[to] = array.str(); + (*exifData_)[to] = stringFormat("{} {} {} {}", static_cast(value[0]), static_cast(value[1]), + static_cast(value[2]), static_cast(value[3])); if (erase_) xmpData_->erase(pos); } @@ -1234,7 +1231,7 @@ void Converter::cnvXmpValueToIptc(const char* from, const char* to) { #ifdef EXV_HAVE_XMP_TOOLKIT std::string Converter::computeExifDigest(bool tiff) { - std::ostringstream res; + std::string res; MD5_CTX context; unsigned char digest[16]; @@ -1247,9 +1244,9 @@ std::string Converter::computeExifDigest(bool tiff) { if (!tiff && key.groupName() == "Image") continue; - if (!res.str().empty()) - res << ','; - res << key.tag(); + if (!res.empty()) + res += ','; + res += key.tag(); auto pos = exifData_->findKey(key); if (pos == exifData_->end()) continue; @@ -1259,12 +1256,11 @@ std::string Converter::computeExifDigest(bool tiff) { } } MD5Final(digest, &context); - res << ';'; - res << std::setw(2) << std::setfill('0') << std::hex << std::uppercase; + res += ';'; for (const auto& i : digest) { - res << static_cast(i); + res += stringFormat("{:02X}", i); } - return res.str(); + return res; } #else std::string Converter::computeExifDigest(bool) { diff --git a/src/futils.cpp b/src/futils.cpp index 25796c98f1..159d8ea089 100644 --- a/src/futils.cpp +++ b/src/futils.cpp @@ -5,6 +5,7 @@ #include "config.h" #include "enforce.hpp" +#include "image_int.hpp" #include "utils.hpp" // + standard includes @@ -240,7 +241,7 @@ bool fileExists(const std::string& path) { std::string strError() { int error = errno; - std::ostringstream os; + std::string os; #ifdef EXV_HAVE_STRERROR_R const size_t n = 1024; #ifdef EXV_STRERROR_R_CHAR_P @@ -251,17 +252,16 @@ std::string strError() { const int ret = strerror_r(error, buf, n); Internal::enforce(ret != ERANGE, Exiv2::ErrorCode::kerCallFailed); #endif - os << buf; + os = buf; // Issue# 908. // report strerror() if strerror_r() returns empty - if (!buf[0]) { - os << strerror(error); + if (os.empty()) { + os = std::strerror(error); } #else - os << std::strerror(error); + os = std::strerror(error); #endif - os << " (errno = " << error << ")"; - return os.str(); + return stringFormat("{} (errno = {})", os, error); } // strError void Uri::Decode(Uri& uri) { diff --git a/src/tags.cpp b/src/tags.cpp index e84d5164a8..293cab2d4c 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -5,6 +5,7 @@ #include "error.hpp" #include "i18n.h" // NLS support. +#include "image_int.hpp" #include "tags_int.hpp" #include "types.hpp" @@ -179,9 +180,7 @@ std::string ExifKey::Impl::tagName() const { if (tagInfo_ && tagInfo_->tag_ != 0xffff) { return tagInfo_->name_; } - std::ostringstream os; - os << "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << tag_; - return os.str(); + return stringFormat("0x{:04x}", tag_); } void ExifKey::Impl::decomposeKey(const std::string& key) {