Replace long with int64_t in exiv2app.hpp

main
Kevin Backhouse 3 years ago
parent 2e0ab1a037
commit 1ceddb2962
No known key found for this signature in database
GPG Key ID: 9DD01852EE40366E

@ -179,7 +179,7 @@ int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::stri
ascii.write_uint8(str.size() * 3, 0); ascii.write_uint8(str.size() * 3, 0);
std::copy(str.begin(), str.end(), iccProfile.begin()); std::copy(str.begin(), str.end(), iccProfile.begin());
if (Exiv2::base64encode(iccProfile.c_data(), str.size(), reinterpret_cast<char*>(ascii.data()), str.size() * 3)) { if (Exiv2::base64encode(iccProfile.c_data(), str.size(), reinterpret_cast<char*>(ascii.data()), str.size() * 3)) {
long chunk = 60; const size_t chunk = 60;
std::string code = std::string("data:") + ascii.c_str(); std::string code = std::string("data:") + ascii.c_str();
size_t length = code.size(); size_t length = code.size();
for (size_t start = 0; start < length; start += chunk) { for (size_t start = 0; start < length; start += chunk) {
@ -364,8 +364,8 @@ int Print::printList() {
auto image = Exiv2::ImageFactory::open(path_); auto image = Exiv2::ImageFactory::open(path_);
image->readMetadata(); image->readMetadata();
// Set defaults for metadata types and data columns // Set defaults for metadata types and data columns
if (Params::instance().printTags_ == Exiv2::mdNone) { if (Params::instance().printTags_ == MetadataId::invalid) {
Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp; Params::instance().printTags_ = MetadataId::exif | MetadataId::iptc | MetadataId::xmp;
} }
if (Params::instance().printItems_ == 0) { if (Params::instance().printItems_ == 0) {
Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans; Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans;
@ -376,7 +376,7 @@ int Print::printList() {
int Print::printMetadata(const Exiv2::Image* image) { int Print::printMetadata(const Exiv2::Image* image) {
bool ret = false; bool ret = false;
bool noExif = false; bool noExif = false;
if (Params::instance().printTags_ & Exiv2::mdExif) { if ((Params::instance().printTags_ & MetadataId::exif) == MetadataId::exif) {
const Exiv2::ExifData& exifData = image->exifData(); const Exiv2::ExifData& exifData = image->exifData();
for (auto&& md : exifData) { for (auto&& md : exifData) {
ret |= printMetadatum(md, image); ret |= printMetadatum(md, image);
@ -386,7 +386,7 @@ int Print::printMetadata(const Exiv2::Image* image) {
} }
bool noIptc = false; bool noIptc = false;
if (Params::instance().printTags_ & Exiv2::mdIptc) { if ((Params::instance().printTags_ & MetadataId::iptc) == MetadataId::iptc) {
const Exiv2::IptcData& iptcData = image->iptcData(); const Exiv2::IptcData& iptcData = image->iptcData();
for (auto&& md : iptcData) { for (auto&& md : iptcData) {
ret |= printMetadatum(md, image); ret |= printMetadatum(md, image);
@ -396,7 +396,7 @@ int Print::printMetadata(const Exiv2::Image* image) {
} }
bool noXmp = false; bool noXmp = false;
if (Params::instance().printTags_ & Exiv2::mdXmp) { if ((Params::instance().printTags_ & MetadataId::xmp) == MetadataId::xmp) {
const Exiv2::XmpData& xmpData = image->xmpData(); const Exiv2::XmpData& xmpData = image->xmpData();
for (auto&& md : xmpData) { for (auto&& md : xmpData) {
ret |= printMetadatum(md, image); ret |= printMetadatum(md, image);
@ -1148,23 +1148,23 @@ int Modify::applyCommands(Exiv2::Image* pImage) {
int ret = 0; int ret = 0;
for (auto&& cmd : modifyCmds) { for (auto&& cmd : modifyCmds) {
switch (cmd.cmdId_) { switch (cmd.cmdId_) {
case add: case CmdId::add:
ret = addMetadatum(pImage, cmd); ret = addMetadatum(pImage, cmd);
if (rc == 0) if (rc == 0)
rc = ret; rc = ret;
break; break;
case set: case CmdId::set:
ret = setMetadatum(pImage, cmd); ret = setMetadatum(pImage, cmd);
if (rc == 0) if (rc == 0)
rc = ret; rc = ret;
break; break;
case del: case CmdId::del:
delMetadatum(pImage, cmd); delMetadatum(pImage, cmd);
break; break;
case reg: case CmdId::reg:
regNamespace(cmd); regNamespace(cmd);
break; break;
case invalidCmdId: case CmdId::invalid:
break; break;
} }
} }
@ -1184,13 +1184,13 @@ int Modify::addMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
auto value = Exiv2::Value::create(modifyCmd.typeId_); auto value = Exiv2::Value::create(modifyCmd.typeId_);
int rc = value->read(modifyCmd.value_); int rc = value->read(modifyCmd.value_);
if (0 == rc) { if (0 == rc) {
if (modifyCmd.metadataId_ == exif) { if (modifyCmd.metadataId_ == MetadataId::exif) {
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get()); exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
} }
if (modifyCmd.metadataId_ == iptc) { if (modifyCmd.metadataId_ == MetadataId::iptc) {
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get()); iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
} }
if (modifyCmd.metadataId_ == xmp) { if (modifyCmd.metadataId_ == MetadataId::xmp) {
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get()); xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
} }
} else { } else {
@ -1213,19 +1213,19 @@ int Modify::setMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
Exiv2::IptcData& iptcData = pImage->iptcData(); Exiv2::IptcData& iptcData = pImage->iptcData();
Exiv2::XmpData& xmpData = pImage->xmpData(); Exiv2::XmpData& xmpData = pImage->xmpData();
Exiv2::Metadatum* metadatum = nullptr; Exiv2::Metadatum* metadatum = nullptr;
if (modifyCmd.metadataId_ == exif) { if (modifyCmd.metadataId_ == MetadataId::exif) {
auto pos = exifData.findKey(Exiv2::ExifKey(modifyCmd.key_)); auto pos = exifData.findKey(Exiv2::ExifKey(modifyCmd.key_));
if (pos != exifData.end()) { if (pos != exifData.end()) {
metadatum = &(*pos); metadatum = &(*pos);
} }
} }
if (modifyCmd.metadataId_ == iptc) { if (modifyCmd.metadataId_ == MetadataId::iptc) {
auto pos = iptcData.findKey(Exiv2::IptcKey(modifyCmd.key_)); auto pos = iptcData.findKey(Exiv2::IptcKey(modifyCmd.key_));
if (pos != iptcData.end()) { if (pos != iptcData.end()) {
metadatum = &(*pos); metadatum = &(*pos);
} }
} }
if (modifyCmd.metadataId_ == xmp) { if (modifyCmd.metadataId_ == MetadataId::xmp) {
auto pos = xmpData.findKey(Exiv2::XmpKey(modifyCmd.key_)); auto pos = xmpData.findKey(Exiv2::XmpKey(modifyCmd.key_));
if (pos != xmpData.end()) { if (pos != xmpData.end()) {
metadatum = &(*pos); metadatum = &(*pos);
@ -1246,13 +1246,13 @@ int Modify::setMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
if (metadatum) { if (metadatum) {
metadatum->setValue(value.get()); metadatum->setValue(value.get());
} else { } else {
if (modifyCmd.metadataId_ == exif) { if (modifyCmd.metadataId_ == MetadataId::exif) {
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get()); exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
} }
if (modifyCmd.metadataId_ == iptc) { if (modifyCmd.metadataId_ == MetadataId::iptc) {
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get()); iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
} }
if (modifyCmd.metadataId_ == xmp) { if (modifyCmd.metadataId_ == MetadataId::xmp) {
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get()); xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
} }
} }
@ -1273,21 +1273,21 @@ void Modify::delMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
Exiv2::ExifData& exifData = pImage->exifData(); Exiv2::ExifData& exifData = pImage->exifData();
Exiv2::IptcData& iptcData = pImage->iptcData(); Exiv2::IptcData& iptcData = pImage->iptcData();
Exiv2::XmpData& xmpData = pImage->xmpData(); Exiv2::XmpData& xmpData = pImage->xmpData();
if (modifyCmd.metadataId_ == exif) { if (modifyCmd.metadataId_ == MetadataId::exif) {
Exiv2::ExifData::iterator pos; Exiv2::ExifData::iterator pos;
const Exiv2::ExifKey exifKey(modifyCmd.key_); const Exiv2::ExifKey exifKey(modifyCmd.key_);
while ((pos = exifData.findKey(exifKey)) != exifData.end()) { while ((pos = exifData.findKey(exifKey)) != exifData.end()) {
exifData.erase(pos); exifData.erase(pos);
} }
} }
if (modifyCmd.metadataId_ == iptc) { if (modifyCmd.metadataId_ == MetadataId::iptc) {
Exiv2::IptcData::iterator pos; Exiv2::IptcData::iterator pos;
const Exiv2::IptcKey iptcKey(modifyCmd.key_); const Exiv2::IptcKey iptcKey(modifyCmd.key_);
while ((pos = iptcData.findKey(iptcKey)) != iptcData.end()) { while ((pos = iptcData.findKey(iptcKey)) != iptcData.end()) {
iptcData.erase(pos); iptcData.erase(pos);
} }
} }
if (modifyCmd.metadataId_ == xmp) { if (modifyCmd.metadataId_ == MetadataId::xmp) {
Exiv2::XmpData::iterator pos; Exiv2::XmpData::iterator pos;
const Exiv2::XmpKey xmpKey(modifyCmd.key_); const Exiv2::XmpKey xmpKey(modifyCmd.key_);
if ((pos = xmpData.findKey(xmpKey)) != xmpData.end()) { if ((pos = xmpData.findKey(xmpKey)) != xmpData.end()) {
@ -1617,7 +1617,7 @@ int str2Tm(const std::string& timeStr, struct tm* tm) {
std::memset(tm, 0x0, sizeof(struct tm)); std::memset(tm, 0x0, sizeof(struct tm));
tm->tm_isdst = -1; tm->tm_isdst = -1;
long tmp = 0; int64_t tmp = 0;
if (!Util::strtol(timeStr.substr(0, 4).c_str(), tmp)) if (!Util::strtol(timeStr.substr(0, 4).c_str(), tmp))
return 5; return 5;
// tmp is a 4-digit number so this cast cannot overflow // tmp is a 4-digit number so this cast cannot overflow
@ -1759,7 +1759,7 @@ int metacopy(const std::string& source, const std::string& tgt, Exiv2::ImageType
} }
// #1148 use Raw XMP packet if there are no XMP modification commands // #1148 use Raw XMP packet if there are no XMP modification commands
int tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX Params::CommonTarget tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX
if (Params::instance().modifyCmds_.empty() && (Params::instance().target_ & tRawSidecar) == tRawSidecar) { if (Params::instance().modifyCmds_.empty() && (Params::instance().target_ & tRawSidecar) == tRawSidecar) {
// std::cout << "short cut" << std::endl; // std::cout << "short cut" << std::endl;
// http://www.cplusplus.com/doc/tutorial/files/ // http://www.cplusplus.com/doc/tutorial/files/

@ -187,10 +187,10 @@ class Adjust : public Task {
private: private:
int adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, const std::string& path) const; int adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, const std::string& path) const;
long adjustment_{0}; int64_t adjustment_{0};
long yearAdjustment_{0}; int64_t yearAdjustment_{0};
long monthAdjustment_{0}; int64_t monthAdjustment_{0};
long dayAdjustment_{0}; int64_t dayAdjustment_{0};
}; // class Adjust }; // class Adjust

@ -1,19 +1,26 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "app_utils.hpp"
#include <climits> #include <climits>
#include <cstdlib> #include <cstdlib>
#include <limits>
namespace Util { namespace Util {
bool strtol(const char* nptr, long& n) { bool strtol(const char* nptr, int64_t& n) {
if (!nptr || *nptr == '\0') if (!nptr || *nptr == '\0')
return false; return false;
char* endptr = nullptr; char* endptr = nullptr;
long tmp = std::strtol(nptr, &endptr, 10); long long tmp = std::strtoll(nptr, &endptr, 10);
if (*endptr != '\0') if (*endptr != '\0')
return false; return false;
if (tmp == LONG_MAX || tmp == LONG_MIN) // strtoll returns LLONG_MAX or LLONG_MIN if an overflow occurs.
if (tmp == LLONG_MAX || tmp == LLONG_MIN)
return false; return false;
n = tmp; if (tmp < std::numeric_limits<int64_t>::min())
return false;
if (tmp > std::numeric_limits<int64_t>::max())
return false;
n = static_cast<int64_t>(tmp);
return true; return true;
} }

@ -3,13 +3,15 @@
#ifndef APP_UTILS_HPP_ #ifndef APP_UTILS_HPP_
#define APP_UTILS_HPP_ #define APP_UTILS_HPP_
#include <cstdint>
namespace Util { namespace Util {
/*! /*!
@brief Convert a C string to a long value, which is returned in n. @brief Convert a C string to an int64_t value, which is returned in n.
Returns true if the conversion is successful, else false. Returns true if the conversion is successful, else false.
n is not modified if the conversion is unsuccessful. See strtol(2). n is not modified if the conversion is unsuccessful. See strtol(2).
*/ */
bool strtol(const char* nptr, long& n); bool strtol(const char* nptr, int64_t& n);
} // namespace Util } // namespace Util
#endif // #ifndef UTILS_HPP_ #endif // #ifndef UTILS_HPP_

@ -42,7 +42,11 @@ const Params::YodAdjust emptyYodAdjust_[] = {
//! List of all command identifiers and corresponding strings //! List of all command identifiers and corresponding strings
const CmdIdAndString cmdIdAndString[] = { const CmdIdAndString cmdIdAndString[] = {
{add, "add"}, {set, "set"}, {del, "del"}, {reg, "reg"}, {invalidCmdId, "invalidCmd"}, // End of list marker {CmdId::add, "add"},
{CmdId::set, "set"},
{CmdId::del, "del"},
{CmdId::reg, "reg"},
{CmdId::invalid, "invalidCmd"}, // End of list marker
}; };
// Return a command Id for a command string // Return a command Id for a command string
@ -50,7 +54,7 @@ CmdId commandId(const std::string& cmdString);
// Evaluate [-]HH[:MM[:SS]], returns true and sets time to the value // Evaluate [-]HH[:MM[:SS]], returns true and sets time to the value
// in seconds if successful, else returns false. // in seconds if successful, else returns false.
bool parseTime(const std::string& ts, long& time); bool parseTime(const std::string& ts, int64_t& time);
/*! /*!
@brief Parse the oparg string into a bitmap of common targets. @brief Parse the oparg string into a bitmap of common targets.
@ -58,7 +62,7 @@ bool parseTime(const std::string& ts, long& time);
@param action Action being processed @param action Action being processed
@return A bitmap of common targets or -1 in case of a parse error @return A bitmap of common targets or -1 in case of a parse error
*/ */
int parseCommonTargets(const std::string& optArg, const std::string& action); int64_t parseCommonTargets(const std::string& optArg, const std::string& action);
/*! /*!
@brief Parse numbers separated by commas into container @brief Parse numbers separated by commas into container
@ -672,13 +676,13 @@ int Params::evalPrintFlags(const std::string& optArg) {
for (auto&& i : optArg) { for (auto&& i : optArg) {
switch (i) { switch (i) {
case 'E': case 'E':
printTags_ |= Exiv2::mdExif; printTags_ |= MetadataId::exif;
break; break;
case 'I': case 'I':
printTags_ |= Exiv2::mdIptc; printTags_ |= MetadataId::iptc;
break; break;
case 'X': case 'X':
printTags_ |= Exiv2::mdXmp; printTags_ |= MetadataId::xmp;
break; break;
case 'x': case 'x':
printItems_ |= prTag; printItems_ |= prTag;
@ -735,81 +739,71 @@ int Params::evalPrintFlags(const std::string& optArg) {
} // Params::evalPrintFlags } // Params::evalPrintFlags
int Params::evalDelete(const std::string& optArg) { int Params::evalDelete(const std::string& optArg) {
int rc = 0;
switch (action_) { switch (action_) {
case Action::none: case Action::none:
action_ = Action::erase; action_ = Action::erase;
target_ = 0; target_ = CommonTarget(0);
// fallthrough // fallthrough
case Action::erase: case Action::erase: {
rc = parseCommonTargets(optArg, "erase"); const auto rc = parseCommonTargets(optArg, "erase");
if (rc > 0) { if (rc > 0) {
target_ |= rc; target_ |= CommonTarget(rc);
rc = 0; return 0;
} else { } else {
rc = 1; return 1;
}
} }
break;
default: default:
std::cerr << progname() << ": " << _("Option -d is not compatible with a previous option\n"); std::cerr << progname() << ": " << _("Option -d is not compatible with a previous option\n");
rc = 1; return 1;
break;
} }
return rc;
} // Params::evalDelete } // Params::evalDelete
int Params::evalExtract(const std::string& optArg) { int Params::evalExtract(const std::string& optArg) {
int rc = 0;
switch (action_) { switch (action_) {
case Action::none: case Action::none:
case Action::modify: case Action::modify:
action_ = Action::extract; action_ = Action::extract;
target_ = 0; target_ = CommonTarget(0);
// fallthrough // fallthrough
case Action::extract: case Action::extract: {
rc = parseCommonTargets(optArg, "extract"); const auto rc = parseCommonTargets(optArg, "extract");
if (rc > 0) { if (rc > 0) {
target_ |= rc; target_ |= CommonTarget(rc);
rc = 0; return 0;
} else { } else {
rc = 1; return 1;
}
} }
break;
default: default:
std::cerr << progname() << ": " << _("Option -e is not compatible with a previous option\n"); std::cerr << progname() << ": " << _("Option -e is not compatible with a previous option\n");
rc = 1; return 1;
break;
} }
return rc;
} // Params::evalExtract } // Params::evalExtract
int Params::evalInsert(const std::string& optArg) { int Params::evalInsert(const std::string& optArg) {
int rc = 0;
switch (action_) { switch (action_) {
case Action::none: case Action::none:
case Action::modify: case Action::modify:
action_ = Action::insert; action_ = Action::insert;
target_ = 0; target_ = CommonTarget(0);
// fallthrough // fallthrough
case Action::insert: case Action::insert: {
rc = parseCommonTargets(optArg, "insert"); const auto rc = parseCommonTargets(optArg, "insert");
if (rc > 0) { if (rc > 0) {
target_ |= rc; target_ |= CommonTarget(rc);
rc = 0; return 0;
} else { } else {
rc = 1; return 1;
}
} }
break;
default: default:
std::cerr << progname() << ": " << _("Option -i is not compatible with a previous option\n"); std::cerr << progname() << ": " << _("Option -i is not compatible with a previous option\n");
rc = 1; return 1;
break;
} }
return rc;
} // Params::evalInsert } // Params::evalInsert
int Params::evalModify(int opt, const std::string& optArg) { int Params::evalModify(int opt, const std::string& optArg) {
int rc = 0;
switch (action_) { switch (action_) {
case Action::none: case Action::none:
action_ = Action::modify; action_ = Action::modify;
@ -823,14 +817,12 @@ int Params::evalModify(int opt, const std::string& optArg) {
cmdFiles_.push_back(optArg); // parse the files later cmdFiles_.push_back(optArg); // parse the files later
if (opt == 'M') if (opt == 'M')
cmdLines_.push_back(optArg); // parse the commands later cmdLines_.push_back(optArg); // parse the commands later
break; return 0;
default: default:
std::cerr << progname() << ": " << _("Option") << " -" << static_cast<char>(opt) << " " std::cerr << progname() << ": " << _("Option") << " -" << static_cast<char>(opt) << " "
<< _("is not compatible with a previous option\n"); << _("is not compatible with a previous option\n");
rc = 1; return 1;
break;
} }
return rc;
} // Params::evalModify } // Params::evalModify
int Params::nonoption(const std::string& argv) { int Params::nonoption(const std::string& argv) {
@ -1090,7 +1082,7 @@ cleanup:
// ***************************************************************************** // *****************************************************************************
// local implementations // local implementations
namespace { namespace {
bool parseTime(const std::string& ts, long& time) { bool parseTime(const std::string& ts, int64_t& time) {
std::string hstr, mstr, sstr; std::string hstr, mstr, sstr;
auto cts = new char[ts.length() + 1]; auto cts = new char[ts.length() + 1];
strcpy(cts, ts.c_str()); strcpy(cts, ts.c_str());
@ -1106,7 +1098,7 @@ bool parseTime(const std::string& ts, long& time) {
delete[] cts; delete[] cts;
int sign = 1; int sign = 1;
long hh(0), mm(0), ss(0); int64_t hh(0), mm(0), ss(0);
// [-]HH part // [-]HH part
if (!Util::strtol(hstr.c_str(), hh)) if (!Util::strtol(hstr.c_str(), hh))
return false; return false;
@ -1145,11 +1137,11 @@ void printUnrecognizedArgument(const char argc, const std::string& action) {
<< argc << "'\n"; << argc << "'\n";
} }
int parseCommonTargets(const std::string& optArg, const std::string& action) { int64_t parseCommonTargets(const std::string& optArg, const std::string& action) {
int rc = 0; int64_t rc = 0;
int target = 0; Params::CommonTarget target = Params::CommonTarget(0);
int all = Params::ctExif | Params::ctIptc | Params::ctComment | Params::ctXmp; Params::CommonTarget all = Params::ctExif | Params::ctIptc | Params::ctComment | Params::ctXmp;
int extra = Params::ctXmpSidecar | Params::ctExif | Params::ctIptc | Params::ctXmp; Params::CommonTarget extra = Params::ctXmpSidecar | Params::ctExif | Params::ctIptc | Params::ctXmp;
for (size_t i = 0; rc == 0 && i < optArg.size(); ++i) { for (size_t i = 0; rc == 0 && i < optArg.size(); ++i) {
switch (optArg[i]) { switch (optArg[i]) {
case 'e': case 'e':
@ -1183,7 +1175,7 @@ int parseCommonTargets(const std::string& optArg, const std::string& action) {
target |= extra; // -eX target |= extra; // -eX
if (i > 0) { // -eXX or -iXX if (i > 0) { // -eXX or -iXX
target |= Params::ctXmpRaw; target |= Params::ctXmpRaw;
target &= ~extra; // turn off those bits target = Params::CommonTarget(target & ~extra); // turn off those bits
} }
break; break;
@ -1204,7 +1196,7 @@ int parseCommonTargets(const std::string& optArg, const std::string& action) {
break; break;
} }
} }
return rc ? rc : target; return rc ? rc : int64_t(target);
} }
int parsePreviewNumbers(Params::PreviewNumbers& previewNumbers, const std::string& optArg, int j) { int parsePreviewNumbers(Params::PreviewNumbers& previewNumbers, const std::string& optArg, int j) {
@ -1334,38 +1326,38 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
std::string cmd(line.substr(cmdStart, cmdEnd - cmdStart)); std::string cmd(line.substr(cmdStart, cmdEnd - cmdStart));
CmdId cmdId = commandId(cmd); CmdId cmdId = commandId(cmd);
if (cmdId == invalidCmdId) { if (cmdId == CmdId::invalid) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Invalid command") + " `" + cmd + "'"); Exiv2::toString(num) + ": " + _("Invalid command") + " `" + cmd + "'");
} }
Exiv2::TypeId defaultType = Exiv2::invalidTypeId; Exiv2::TypeId defaultType = Exiv2::invalidTypeId;
std::string key(line.substr(keyStart, keyEnd - keyStart)); std::string key(line.substr(keyStart, keyEnd - keyStart));
MetadataId metadataId = invalidMetadataId; MetadataId metadataId = MetadataId::invalid;
if (cmdId != reg) { if (cmdId != CmdId::reg) {
try { try {
Exiv2::IptcKey iptcKey(key); Exiv2::IptcKey iptcKey(key);
metadataId = iptc; metadataId = MetadataId::iptc;
defaultType = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); defaultType = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
} catch (const Exiv2::Error&) { } catch (const Exiv2::Error&) {
} }
if (metadataId == invalidMetadataId) { if (metadataId == MetadataId::invalid) {
try { try {
Exiv2::ExifKey exifKey(key); Exiv2::ExifKey exifKey(key);
metadataId = exif; metadataId = MetadataId::exif;
defaultType = exifKey.defaultTypeId(); defaultType = exifKey.defaultTypeId();
} catch (const Exiv2::Error&) { } catch (const Exiv2::Error&) {
} }
} }
if (metadataId == invalidMetadataId) { if (metadataId == MetadataId::invalid) {
try { try {
Exiv2::XmpKey xmpKey(key); Exiv2::XmpKey xmpKey(key);
metadataId = xmp; metadataId = MetadataId::xmp;
defaultType = Exiv2::XmpProperties::propertyType(xmpKey); defaultType = Exiv2::XmpProperties::propertyType(xmpKey);
} catch (const Exiv2::Error&) { } catch (const Exiv2::Error&) {
} }
} }
if (metadataId == invalidMetadataId) { if (metadataId == MetadataId::invalid) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Invalid key") + " `" + key + "'"); Exiv2::toString(num) + ": " + _("Invalid key") + " `" + key + "'");
} }
@ -1373,7 +1365,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
std::string value; std::string value;
Exiv2::TypeId type = defaultType; Exiv2::TypeId type = defaultType;
bool explicitType = false; bool explicitType = false;
if (cmdId != del) { if (cmdId != CmdId::del) {
// Get type and value // Get type and value
std::string::size_type typeStart = std::string::npos; std::string::size_type typeStart = std::string::npos;
if (keyEnd != std::string::npos) if (keyEnd != std::string::npos)
@ -1386,12 +1378,12 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
if (valStart != std::string::npos) if (valStart != std::string::npos)
valEnd = line.find_last_not_of(delim); valEnd = line.find_last_not_of(delim);
if (cmdId == reg && (keyEnd == std::string::npos || valStart == std::string::npos)) { if (cmdId == CmdId::reg && (keyEnd == std::string::npos || valStart == std::string::npos)) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Invalid command line") + " "); Exiv2::toString(num) + ": " + _("Invalid command line") + " ");
} }
if (cmdId != reg && typeStart != std::string::npos && typeEnd != std::string::npos) { if (cmdId != CmdId::reg && typeStart != std::string::npos && typeEnd != std::string::npos) {
std::string typeStr(line.substr(typeStart, typeEnd - typeStart)); std::string typeStr(line.substr(typeStart, typeEnd - typeStart));
Exiv2::TypeId tmpType = Exiv2::TypeInfo::typeId(typeStr); Exiv2::TypeId tmpType = Exiv2::TypeInfo::typeId(typeStr);
if (tmpType != Exiv2::invalidTypeId) { if (tmpType != Exiv2::invalidTypeId) {
@ -1421,7 +1413,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
modifyCmd.explicitType_ = explicitType; modifyCmd.explicitType_ = explicitType;
modifyCmd.value_ = value; modifyCmd.value_ = value;
if (cmdId == reg) { if (cmdId == CmdId::reg) {
if (value.empty()) { if (value.empty()) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Empty value for key") + +" `" + key + "'"); Exiv2::toString(num) + ": " + _("Empty value for key") + +" `" + key + "'");
@ -1437,7 +1429,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
CmdId commandId(const std::string& cmdString) { CmdId commandId(const std::string& cmdString) {
int i = 0; int i = 0;
while (cmdIdAndString[i].first != invalidCmdId && cmdIdAndString[i].second != cmdString) { while (cmdIdAndString[i].first != CmdId::invalid && cmdIdAndString[i].second != cmdString) {
++i; ++i;
} }
return cmdIdAndString[i].first; return cmdIdAndString[i].first;

@ -21,28 +21,40 @@
#include <set> #include <set>
//! Command identifiers //! Command identifiers
enum CmdId { enum class CmdId {
invalidCmdId, invalid,
add, add,
set, set,
del, del,
reg, reg,
}; };
//! Metadata identifiers //! Metadata identifiers
enum MetadataId { enum class MetadataId : uint32_t {
invalidMetadataId = Exiv2::mdNone, // 0 invalid = Exiv2::mdNone, // 0
exif = Exiv2::mdExif, // 1 exif = Exiv2::mdExif, // 1
iptc = Exiv2::mdIptc, // 2 iptc = Exiv2::mdIptc, // 2
xmp = Exiv2::mdXmp, // 8 xmp = Exiv2::mdXmp, // 8
}; };
inline MetadataId operator&(MetadataId x, MetadataId y) {
return (MetadataId)(uint32_t(x) & uint32_t(y));
}
inline MetadataId operator|(MetadataId x, MetadataId y) {
return (MetadataId)(uint32_t(x) | uint32_t(y));
}
inline MetadataId& operator|=(MetadataId& x, MetadataId y) {
return x = x | y;
}
//! Structure for one parsed modification command //! Structure for one parsed modification command
struct ModifyCmd { struct ModifyCmd {
//! C'tor //! C'tor
ModifyCmd() = default; ModifyCmd() = default;
CmdId cmdId_{invalidCmdId}; //!< Command identifier CmdId cmdId_{CmdId::invalid}; //!< Command identifier
std::string key_; //!< Exiv2 key string std::string key_; //!< Exiv2 key string
MetadataId metadataId_{invalidMetadataId}; //!< Metadata identifier MetadataId metadataId_{MetadataId::invalid}; //!< Metadata identifier
Exiv2::TypeId typeId_{Exiv2::invalidTypeId}; //!< Exiv2 type identifier Exiv2::TypeId typeId_{Exiv2::invalidTypeId}; //!< Exiv2 type identifier
//! Flag to indicate if the type was explicitly specified (true) //! Flag to indicate if the type was explicitly specified (true)
bool explicitType_{false}; bool explicitType_{false};
@ -125,7 +137,7 @@ class Params : public Util::Getopt {
}; };
//! Individual items to print, bitmap //! Individual items to print, bitmap
enum PrintItem { enum PrintItem : uint32_t {
prTag = 1, prTag = 1,
prGroup = 2, prGroup = 2,
prKey = 4, prKey = 4,
@ -141,7 +153,7 @@ class Params : public Util::Getopt {
}; };
//! Enumerates common targets, bitmap //! Enumerates common targets, bitmap
enum CommonTarget { enum CommonTarget : uint32_t {
ctExif = 1, ctExif = 1,
ctIptc = 2, ctIptc = 2,
ctComment = 4, ctComment = 4,
@ -173,7 +185,7 @@ class Params : public Util::Getopt {
struct YodAdjust { struct YodAdjust {
bool flag_; //!< Adjustment flag. bool flag_; //!< Adjustment flag.
const char* option_; //!< Adjustment option string. const char* option_; //!< Adjustment option string.
long adjustment_; //!< Adjustment value. int64_t adjustment_; //!< Adjustment value.
}; };
bool help_{false}; //!< Help option flag. bool help_{false}; //!< Help option flag.
@ -188,13 +200,13 @@ class Params : public Util::Getopt {
FileExistsPolicy fileExistsPolicy_{askPolicy}; //!< What to do if file to rename exists. FileExistsPolicy fileExistsPolicy_{askPolicy}; //!< What to do if file to rename exists.
bool adjust_{false}; //!< Adjustment flag. bool adjust_{false}; //!< Adjustment flag.
PrintMode printMode_{pmSummary}; //!< Print mode. PrintMode printMode_{pmSummary}; //!< Print mode.
unsigned long printItems_{0}; //!< Print items. PrintItem printItems_{0}; //!< Print items.
unsigned long printTags_{Exiv2::mdNone}; //!< Print tags (bitmap of MetadataId flags). MetadataId printTags_{Exiv2::mdNone}; //!< Print tags (bitmap of MetadataId flags).
//! %Action (integer rather than TaskType to avoid dependency). //! %Action (integer rather than TaskType to avoid dependency).
int action_{0}; int action_{0};
int target_; //!< What common target to process. CommonTarget target_; //!< What common target to process.
long adjustment_{0}; //!< Adjustment in seconds. int64_t adjustment_{0}; //!< Adjustment in seconds.
YodAdjust yodAdjust_[3]; //!< Year, month and day adjustment info. YodAdjust yodAdjust_[3]; //!< Year, month and day adjustment info.
std::string format_; //!< Filename format (-r option arg). std::string format_; //!< Filename format (-r option arg).
bool formatSet_{false}; //!< Whether the format is set with -r bool formatSet_{false}; //!< Whether the format is set with -r
@ -270,4 +282,20 @@ class Params : public Util::Getopt {
}; // class Params }; // class Params
inline Params::CommonTarget operator|(Params::CommonTarget x, Params::CommonTarget y) {
return (Params::CommonTarget)(uint32_t(x) | uint32_t(y));
}
inline Params::CommonTarget& operator|=(Params::CommonTarget& x, Params::CommonTarget y) {
return x = x | y;
}
inline Params::PrintItem operator|(Params::PrintItem x, Params::PrintItem y) {
return (Params::PrintItem)(uint32_t(x) | uint32_t(y));
}
inline Params::PrintItem& operator|=(Params::PrintItem& x, Params::PrintItem y) {
return x = x | y;
}
#endif // #ifndef EXIV2APP_HPP_ #endif // #ifndef EXIV2APP_HPP_

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
from system_tests import CaseMeta, CopyTmpFiles, path
@CopyTmpFiles("$data_path/test_issue_1180.exv")
class test_pr_2244(metaclass=CaseMeta):
filename = path("$tmp_path/test_issue_1180.exv")
commands = [ "$exiv2 -Y 10000000000 $filename",
"$exiv2 -Y -10000000000 $filename",
"$exiv2 -O 10000000000 $filename",
"$exiv2 -O -10000000000 $filename",
"$exiv2 -D 1000000000000000 $filename",
"$exiv2 -D -1000000000000000 $filename"
]
stdout = [ "",
"",
"",
"",
"",
""
]
stderr = [ "Uncaught exception: year adjustment too high\n",
"Uncaught exception: year adjustment too low\n",
"Uncaught exception: month adjustment too high\n",
"Uncaught exception: month adjustment too low\n",
"Uncaught exception: day adjustment too high\n",
"Uncaught exception: day adjustment too low\n"
]
retval = [ 1,
1,
1,
1,
1,
1
]
Loading…
Cancel
Save