From 595665be33084c792a21f74df1b38eb458043e48 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Mon, 15 Oct 2007 10:07:39 +0000 Subject: [PATCH] Added reg command to utility, fixed set command to wrok better with XMP arrays, modified LangAlt write method to write default first, fixed registerNs bug. --- src/actions.cpp | 18 +++++++++++++++-- src/actions.hpp | 2 ++ src/exiv2.cpp | 52 +++++++++++++++++++++++++------------------------ src/exiv2.hpp | 2 +- src/value.cpp | 17 +++++++++++----- src/xmp.cpp | 5 ++++- 6 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 03c94543..093b97f8 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -1268,8 +1268,11 @@ namespace Action { case del: delMetadatum(pImage, *i); break; + case reg: + regNamespace(*i); + break; case invalidCmdId: - // Todo: complain + assert(invalidCmdId == i->cmdId_); break; } } @@ -1342,7 +1345,9 @@ namespace Action { if (metadatum) { value = metadatum->getValue(); } - if (modifyCmd.explicitType_ || value.get() == 0) { + if ( value.get() == 0 + || ( modifyCmd.explicitType_ + && modifyCmd.typeId_ != value->typeId())) { value = Exiv2::Value::create(modifyCmd.typeId_); } if (0 == value->read(modifyCmd.value_)) { @@ -1402,6 +1407,15 @@ namespace Action { } } + void Modify::regNamespace(const ModifyCmd& modifyCmd) + { + if (Params::instance().verbose_) { + std::cout << _("Reg ") << modifyCmd.key_ << "=\"" + << modifyCmd.value_ << "\"" << std::endl; + } + Exiv2::XmpProperties::registerNs(modifyCmd.value_, modifyCmd.key_); + } + Modify::AutoPtr Modify::clone() const { return AutoPtr(clone_()); diff --git a/src/actions.hpp b/src/actions.hpp index 7922cb1d..1eb10c88 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -339,6 +339,8 @@ namespace Action { //! Delete a metadatum from \em pImage according to \em modifyCmd static void delMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd); + //! Register an XMP namespace according to \em modifyCmd + static void regNamespace(const ModifyCmd& modifyCmd); }; // class Modify diff --git a/src/exiv2.cpp b/src/exiv2.cpp index e701225e..91784abe 100644 --- a/src/exiv2.cpp +++ b/src/exiv2.cpp @@ -60,6 +60,7 @@ namespace { { add, "add" }, { set, "set" }, { del, "del" }, + { reg, "reg" }, { invalidCmdId, "invalidCmd" } // End of list marker }; @@ -886,35 +887,36 @@ namespace { Exiv2::TypeId defaultType = Exiv2::invalidTypeId; std::string key(line.substr(keyStart, keyEnd-keyStart)); MetadataId metadataId = invalidMetadataId; - try { - Exiv2::IptcKey iptcKey(key); - metadataId = iptc; - defaultType = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), - iptcKey.record()); - } - catch (const Exiv2::AnyError&) {} - if (metadataId == invalidMetadataId) { + if (cmdId != reg) { try { - Exiv2::ExifKey exifKey(key); - metadataId = exif; - defaultType = Exiv2::ExifTags::tagType(exifKey.tag(), - exifKey.ifdId()); + Exiv2::IptcKey iptcKey(key); + metadataId = iptc; + defaultType = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), + iptcKey.record()); } catch (const Exiv2::AnyError&) {} - } - if (metadataId == invalidMetadataId) { - try { - Exiv2::XmpKey xmpKey(key); - metadataId = xmp; - defaultType = Exiv2::XmpProperties::propertyType(xmpKey); + if (metadataId == invalidMetadataId) { + try { + Exiv2::ExifKey exifKey(key); + metadataId = exif; + defaultType = Exiv2::ExifTags::tagType(exifKey.tag(), + exifKey.ifdId()); + } + catch (const Exiv2::AnyError&) {} + } + if (metadataId == invalidMetadataId) { + try { + Exiv2::XmpKey xmpKey(key); + metadataId = xmp; + defaultType = Exiv2::XmpProperties::propertyType(xmpKey); + } + catch (const Exiv2::AnyError&) {} + } + if (metadataId == invalidMetadataId) { + throw Exiv2::Error(1, Exiv2::toString(num) + + ": " + _("Invalid key") + " `" + key + "'"); } - catch (const Exiv2::AnyError&) {} - } - if (metadataId == invalidMetadataId) { - throw Exiv2::Error(1, Exiv2::toString(num) - + ": " + _("Invalid key") + " `" + key + "'"); } - std::string value; Exiv2::TypeId type = defaultType; bool explicitType = false; @@ -934,7 +936,7 @@ namespace { + ": " + _("Invalid command line") + " " ); } - if (typeEnd != std::string::npos) { + if (cmdId != reg && typeEnd != std::string::npos) { std::string typeStr(line.substr(typeStart, typeEnd-typeStart)); Exiv2::TypeId tmpType = Exiv2::TypeInfo::typeId(typeStr); if (tmpType != Exiv2::invalidTypeId) { diff --git a/src/exiv2.hpp b/src/exiv2.hpp index 16bfad62..bce57ddb 100644 --- a/src/exiv2.hpp +++ b/src/exiv2.hpp @@ -43,7 +43,7 @@ // class definitions //! Command identifiers -enum CmdId { invalidCmdId, add, set, del }; +enum CmdId { invalidCmdId, add, set, del, reg }; //! Metadata identifiers enum MetadataId { invalidMetadataId, iptc, exif, xmp }; //! Structure for one parsed modification command diff --git a/src/value.cpp b/src/value.cpp index 2edfa38b..38d4ce24 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -637,11 +637,18 @@ namespace Exiv2 { std::ostream& LangAltValue::write(std::ostream& os) const { - for (ValueType::const_iterator i = value_.begin(); - i != value_.end(); ++i) { - if (i != value_.begin()) os << ", "; - os << "lang=\"" << i->first << "\" " - << i->second; + bool first = true; + // Write the default entry first + ValueType::const_iterator i = value_.find("x-default"); + if (i != value_.end()) { + os << "lang=\"" << i->first << "\" " << i->second; + first = false; + } + for (i = value_.begin(); i != value_.end(); ++i) { + if (i->first == "x-default") continue; + if (!first) os << ", "; + os << "lang=\"" << i->first << "\" " << i->second; + first = false; } return os; } diff --git a/src/xmp.cpp b/src/xmp.cpp index e6a2998a..5635e640 100644 --- a/src/xmp.cpp +++ b/src/xmp.cpp @@ -381,7 +381,7 @@ namespace Exiv2 { bool XmpParser::registerNs(const std::string& ns, const std::string& prefix) - { + { try { initialize(); #ifdef EXV_HAVE_XMP_TOOLKIT return SXMPMeta::RegisterNamespace(ns.c_str(), prefix.c_str(), 0); @@ -389,6 +389,9 @@ namespace Exiv2 { return true; #endif } + catch (const XMP_Error& e) { + throw Error(40, e.GetID(), e.GetErrMsg()); + }} // XmpParser::registerNs #ifdef EXV_HAVE_XMP_TOOLKIT int XmpParser::decode( XmpData& xmpData,