From 8551c935f869e4bb164679ba51c2584d77fd853f Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Thu, 14 Oct 2004 16:42:57 +0000 Subject: [PATCH] Changed MakerNote class hierarchy to use std::auto_ptr where appropriate --- src/canonmn.cpp | 23 +++++++----- src/canonmn.hpp | 37 +++++++++++------- src/exif.cpp | 92 ++++++++++++++++++++++----------------------- src/exif.hpp | 11 +++--- src/fujimn.cpp | 31 ++++++++------- src/fujimn.hpp | 35 ++++++++++------- src/makernote.cpp | 64 ++++++++++++++++++------------- src/makernote.hpp | 96 ++++++++++++++++++++++++++--------------------- src/nikonmn.cpp | 57 +++++++++++++++++----------- src/nikonmn.hpp | 55 ++++++++++++++++++--------- src/sigmamn.cpp | 35 +++++++++-------- src/sigmamn.hpp | 35 ++++++++++------- src/taglist.cpp | 13 +++---- src/tags.cpp | 60 ++++++++++++++--------------- src/tags.hpp | 6 ++- 15 files changed, 373 insertions(+), 277 deletions(-) diff --git a/src/canonmn.cpp b/src/canonmn.cpp index 2a76ba8c..4920dee0 100644 --- a/src/canonmn.cpp +++ b/src/canonmn.cpp @@ -20,7 +20,7 @@ */ /* File: canonmn.cpp - Version: $Name: $ $Revision: 1.14 $ + Version: $Name: $ $Revision: 1.15 $ Author(s): Andreas Huggel (ahu) History: 18-Feb-04, ahu: created 07-Mar-04, ahu: isolated as a separate component @@ -30,7 +30,7 @@ */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.14 $ $RCSfile: canonmn.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.15 $ $RCSfile: canonmn.cpp,v $"); // ***************************************************************************** // included header files @@ -72,7 +72,12 @@ namespace Exiv2 { { } - CanonMakerNote* CanonMakerNote::clone(bool alloc) const + CanonMakerNote::AutoPtr CanonMakerNote::clone(bool alloc) const + { + return AutoPtr(clone_(alloc)); + } + + CanonMakerNote* CanonMakerNote::clone_(bool alloc) const { return new CanonMakerNote(alloc); } @@ -656,13 +661,13 @@ namespace Exiv2 { // ***************************************************************************** // free functions - MakerNote* createCanonMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset) + MakerNote::AutoPtr createCanonMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset) { - return new CanonMakerNote(alloc); + return MakerNote::AutoPtr(new CanonMakerNote(alloc)); } } // namespace Exiv2 diff --git a/src/canonmn.hpp b/src/canonmn.hpp index 1f341977..c71011f4 100644 --- a/src/canonmn.hpp +++ b/src/canonmn.hpp @@ -23,7 +23,7 @@ @brief Canon MakerNote implemented according to the specification EXIF MakerNote of Canon by David Burren - @version $Name: $ $Revision: 1.12 $ + @version $Name: $ $Revision: 1.13 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 18-Feb-04, ahu: created
@@ -40,6 +40,7 @@ // + standard includes #include #include +#include // ***************************************************************************** // namespace extensions @@ -53,9 +54,10 @@ namespace Exiv2 { // free functions /*! - @brief Return a pointer to a newly created empty MakerNote initialized to - operate in the memory management model indicated. The caller owns - this copy and is responsible to delete it! + @brief Return an auto-pointer to a newly created empty MakerNote + initialized to operate in the memory management model indicated. + The caller owns this copy and the auto-pointer ensures that it + will be deleted. @param alloc Memory management model for the new MakerNote. Determines if memory required to store data should be allocated and deallocated @@ -69,14 +71,15 @@ namespace Exiv2 { @param offset Offset from the start of the TIFF header of the makernote buffer (not used). - @return A pointer to a newly created empty MakerNote. The caller owns - this copy and is responsible to delete it! + @return An auto-pointer to a newly created empty MakerNote. The caller + owns this copy and the auto-pointer ensures that it will be + deleted. */ - MakerNote* createCanonMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset); + MakerNote::AutoPtr createCanonMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset); // ***************************************************************************** // class definitions @@ -84,6 +87,9 @@ namespace Exiv2 { //! MakerNote for Canon cameras class CanonMakerNote : public IfdMakerNote { public: + //! Shortcut for a %CanonMakerNote auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ /*! @@ -96,8 +102,8 @@ namespace Exiv2 { //@} //! @name Accessors - //@{ - CanonMakerNote* clone(bool alloc =true) const; + //@{ + CanonMakerNote::AutoPtr clone(bool alloc =true) const; //! Return the name of the makernote item ("Canon") std::string ifdItem() const { return ifdItem_; } std::ostream& printTag(std::ostream& os, @@ -170,6 +176,9 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + CanonMakerNote* clone_(bool alloc =true) const; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -177,7 +186,7 @@ namespace Exiv2 { { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("Canon", "*", createCanonMakerNote); - mnf.registerMakerNote(new CanonMakerNote); + mnf.registerMakerNote(MakerNote::AutoPtr(new CanonMakerNote)); } }; /*! diff --git a/src/exif.cpp b/src/exif.cpp index 5ce5bcd0..0dffffc2 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -20,14 +20,14 @@ */ /* File: exif.cpp - Version: $Name: $ $Revision: 1.64 $ + Version: $Name: $ $Revision: 1.65 $ Author(s): Andreas Huggel (ahu) History: 26-Jan-04, ahu: created 11-Feb-04, ahu: isolated as a component */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.64 $ $RCSfile: exif.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.65 $ $RCSfile: exif.cpp,v $"); // Define DEBUG_MAKERNOTE to output debug information to std::cerr #undef DEBUG_MAKERNOTE @@ -494,7 +494,7 @@ namespace Exiv2 { } ExifData::ExifData() - : pThumbnail_(0), pMakerNote_(0), ifd0_(ifd0Id, 0, false), + : pThumbnail_(0), ifd0_(ifd0Id, 0, false), exifIfd_(exifIfdId, 0, false), iopIfd_(iopIfdId, 0, false), gpsIfd_(gpsIfdId, 0, false), ifd1_(ifd1Id, 0, false), size_(0), pData_(0), compatible_(true) @@ -503,7 +503,6 @@ namespace Exiv2 { ExifData::~ExifData() { - delete pMakerNote_; delete pThumbnail_; delete[] pData_; } @@ -559,33 +558,32 @@ namespace Exiv2 { MakerNoteFactory& mnf = MakerNoteFactory::instance(); // Todo: The conversion to string assumes that there is a \0 at the end // Todo: How to avoid the cast (is that a MSVC thing?) - pMakerNote_ = mnf.create(reinterpret_cast(make->data()), - reinterpret_cast(model->data()), - false, - pos->data(), - pos->size(), - byteOrder(), - exifIfd_.offset() + pos->offset()); + makerNote_ = mnf.create(reinterpret_cast(make->data()), + reinterpret_cast(model->data()), + false, + pos->data(), + pos->size(), + byteOrder(), + exifIfd_.offset() + pos->offset()); } // Read the MakerNote - if (pMakerNote_) { - rc = pMakerNote_->read(pos->data(), - pos->size(), - byteOrder(), - exifIfd_.offset() + pos->offset()); + if (makerNote_.get() != 0) { + rc = makerNote_->read(pos->data(), + pos->size(), + byteOrder(), + exifIfd_.offset() + pos->offset()); if (rc) { // Todo: How to handle debug output like this std::cerr << "Warning: Failed to read " - << pMakerNote_->ifdItem() + << makerNote_->ifdItem() << " Makernote, rc = " << rc << "\n"; - delete pMakerNote_; - pMakerNote_ = 0; + makerNote_.reset(); } } // If we successfully parsed the MakerNote, delete the raw MakerNote, // the parsed MakerNote is the primary MakerNote from now on - if (pMakerNote_) { + if (makerNote_.get() != 0) { exifIfd_.erase(pos); } // Find and read Interoperability IFD in ExifIFD @@ -618,8 +616,8 @@ namespace Exiv2 { exifMetadata_.clear(); add(ifd0_.begin(), ifd0_.end(), byteOrder()); add(exifIfd_.begin(), exifIfd_.end(), byteOrder()); - if (pMakerNote_) { - add(pMakerNote_->begin(), pMakerNote_->end(), pMakerNote_->byteOrder()); + if (makerNote_.get() != 0) { + add(makerNote_->begin(), makerNote_->end(), makerNote_->byteOrder()); } add(iopIfd_.begin(), iopIfd_.end(), byteOrder()); add(gpsIfd_.begin(), gpsIfd_.end(), byteOrder()); @@ -699,17 +697,19 @@ namespace Exiv2 { // Build Exif IFD from metadata Ifd exifIfd(exifIfdId); addToIfd(exifIfd, begin(), end(), byteOrder()); - MakerNote* pMakerNote = 0; - if (pMakerNote_) { + MakerNote::AutoPtr makerNote; + if (makerNote_.get() != 0) { // Build MakerNote from metadata - pMakerNote = pMakerNote_->clone(); - addToMakerNote(pMakerNote, begin(), end(), pMakerNote_->byteOrder()); + makerNote = makerNote_->clone(); + addToMakerNote(makerNote.get(), + begin(), end(), + makerNote_->byteOrder()); // Create a placeholder MakerNote entry of the correct size and // add it to the Exif IFD (because we don't know the offset yet) Entry e; e.setIfdId(exifIfd.ifdId()); e.setTag(0x927c); - DataBuf buf(pMakerNote->size()); + DataBuf buf(makerNote->size()); memset(buf.pData_, 0x0, buf.size_); e.setValue(undefined, buf.size_, buf.pData_, buf.size_); exifIfd.erase(0x927c); @@ -787,17 +787,15 @@ namespace Exiv2 { ifd0.copy(buf + ifd0Offset, byteOrder(), ifd0Offset); exifIfd.sortByTag(); exifIfd.copy(buf + exifIfdOffset, byteOrder(), exifIfdOffset); - if (pMakerNote) { + if (makerNote.get() != 0) { // Copy the MakerNote over the placeholder data Entries::iterator mn = exifIfd.findTag(0x927c); // Do _not_ sort the makernote; vendors (at least Canon), don't seem // to bother about this TIFF standard requirement, so writing the // makernote as is might result in fewer deviations from the original - pMakerNote->copy(buf + exifIfdOffset + mn->offset(), - byteOrder(), - exifIfdOffset + mn->offset()); - delete pMakerNote; - pMakerNote = 0; + makerNote->copy(buf + exifIfdOffset + mn->offset(), + byteOrder(), + exifIfdOffset + mn->offset()); } iopIfd.sortByTag(); iopIfd.copy(buf + iopIfdOffset, byteOrder(), iopIfdOffset); @@ -878,13 +876,13 @@ namespace Exiv2 { void ExifData::add(const Exifdatum& exifdatum) { if (exifdatum.ifdId() == makerIfdId) { - if ( pMakerNote_ - && pMakerNote_->ifdItem() != exifdatum.groupName()) { + if ( makerNote_.get() != 0 + && makerNote_->ifdItem() != exifdatum.groupName()) { throw Error("Inconsistent MakerNote"); } - if (!pMakerNote_) { + if (makerNote_.get() == 0) { MakerNoteFactory& mnf = MakerNoteFactory::instance(); - pMakerNote_ = mnf.create(exifdatum.groupName()); + makerNote_ = mnf.create(exifdatum.groupName()); } } // allow duplicates @@ -980,9 +978,9 @@ namespace Exiv2 { maxOffset = std::max(maxOffset, exifIfd_.offset()); maxOffset = std::max(maxOffset, exifIfd_.dataOffset() + exifIfd_.dataSize()); - if (pMakerNote_) { - maxOffset = std::max(maxOffset, pMakerNote_->offset() - + pMakerNote_->size()); + if (makerNote_.get() != 0) { + maxOffset = std::max(maxOffset, makerNote_->offset() + + makerNote_->size()); } maxOffset = std::max(maxOffset, iopIfd_.offset()); maxOffset = std::max(maxOffset, iopIfd_.dataOffset() @@ -1030,10 +1028,10 @@ namespace Exiv2 { bool compatible = true; compatible &= updateRange(ifd0_.begin(), ifd0_.end(), byteOrder()); compatible &= updateRange(exifIfd_.begin(), exifIfd_.end(), byteOrder()); - if (pMakerNote_) { - compatible &= updateRange(pMakerNote_->begin(), - pMakerNote_->end(), - pMakerNote_->byteOrder()); + if (makerNote_.get() != 0) { + compatible &= updateRange(makerNote_->begin(), + makerNote_->end(), + makerNote_->byteOrder()); } compatible &= updateRange(iopIfd_.begin(), iopIfd_.end(), byteOrder()); compatible &= updateRange(gpsIfd_.begin(), gpsIfd_.end(), byteOrder()); @@ -1105,9 +1103,9 @@ namespace Exiv2 { Entries::const_iterator entry; std::pair rc(false, entry); - if (ifdId == makerIfdId && pMakerNote_) { - entry = pMakerNote_->findIdx(idx); - if (entry != pMakerNote_->end()) { + if (ifdId == makerIfdId && makerNote_.get() != 0) { + entry = makerNote_->findIdx(idx); + if (entry != makerNote_->end()) { rc.first = true; rc.second = entry; } diff --git a/src/exif.hpp b/src/exif.hpp index 7e8e30f2..83daf483 100644 --- a/src/exif.hpp +++ b/src/exif.hpp @@ -21,7 +21,7 @@ /*! @file exif.hpp @brief Encoding and decoding of Exif data - @version $Name: $ $Revision: 1.55 $ + @version $Name: $ $Revision: 1.56 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created @@ -42,6 +42,7 @@ // + standard includes #include #include +#include // ***************************************************************************** // namespace extensions @@ -799,10 +800,10 @@ namespace Exiv2 { // DATA TiffHeader tiffHeader_; ExifMetadata exifMetadata_; - Thumbnail* pThumbnail_; //!< Pointer to the Exif thumbnail image - MakerNote* pMakerNote_; //!< Pointer to the MakerNote - // Todo: implement reference counting instead - // of making ExifData own this pointer + //! Pointer to the Exif thumbnail image + Thumbnail* pThumbnail_; + //! Pointer to the MakerNote + std::auto_ptr makerNote_; Ifd ifd0_; Ifd exifIfd_; diff --git a/src/fujimn.cpp b/src/fujimn.cpp index 796e2ffb..3264ae24 100644 --- a/src/fujimn.cpp +++ b/src/fujimn.cpp @@ -20,7 +20,7 @@ */ /* File: fujimn.cpp - Version: $Name: $ $Revision: 1.12 $ + Version: $Name: $ $Revision: 1.13 $ Author(s): Andreas Huggel (ahu) History: 18-Feb-04, ahu: created 07-Mar-04, ahu: isolated as a separate component @@ -31,7 +31,7 @@ */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.12 $ $RCSfile: fujimn.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.13 $ $RCSfile: fujimn.cpp,v $"); // ***************************************************************************** // included header files @@ -114,12 +114,17 @@ namespace Exiv2 { return rc; } - FujiMakerNote* FujiMakerNote::clone(bool alloc) const + FujiMakerNote::AutoPtr FujiMakerNote::clone(bool alloc) const { - FujiMakerNote* pMakerNote = new FujiMakerNote(alloc); - assert(pMakerNote); - pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_); - return pMakerNote; + return AutoPtr(clone_(alloc)); + } + + FujiMakerNote* FujiMakerNote::clone_(bool alloc) const + { + AutoPtr makerNote = AutoPtr(new FujiMakerNote(alloc)); + assert(makerNote.get() != 0); + makerNote->readHeader(header_.pData_, header_.size_, byteOrder_); + return makerNote.release(); } std::ostream& FujiMakerNote::printTag(std::ostream& os, @@ -259,13 +264,13 @@ namespace Exiv2 { // ***************************************************************************** // free functions - MakerNote* createFujiMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset) + MakerNote::AutoPtr createFujiMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset) { - return new FujiMakerNote(alloc); + return MakerNote::AutoPtr(new FujiMakerNote(alloc)); } } // namespace Exiv2 diff --git a/src/fujimn.hpp b/src/fujimn.hpp index 1223511f..32744fcc 100644 --- a/src/fujimn.hpp +++ b/src/fujimn.hpp @@ -24,7 +24,7 @@ in Appendix 4: Makernote of Fujifilm of the document Exif file format by TsuruZoh Tachibanaya - @version $Name: $ $Revision: 1.9 $ + @version $Name: $ $Revision: 1.10 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 11-Feb-04, ahu: created @@ -40,6 +40,7 @@ // + standard includes #include #include +#include // ***************************************************************************** // namespace extensions @@ -53,9 +54,10 @@ namespace Exiv2 { // free functions /*! - @brief Return a pointer to a newly created empty MakerNote initialized to - operate in the memory management model indicated. The caller owns - this copy and is responsible to delete it! + @brief Return an auto-pointer to a newly created empty MakerNote + initialized to operate in the memory management model indicated. + The caller owns this copy and the auto-pointer ensures that it + will be deleted. @param alloc Memory management model for the new MakerNote. Determines if memory required to store data should be allocated and deallocated @@ -69,14 +71,15 @@ namespace Exiv2 { @param offset Offset from the start of the TIFF header of the makernote buffer (not used). - @return A pointer to a newly created empty MakerNote. The caller owns - this copy and is responsible to delete it! + @return An auto-pointer to a newly created empty MakerNote. The caller + owns this copy and the auto-pointer ensures that it will be + deleted. */ - MakerNote* createFujiMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset); + MakerNote::AutoPtr createFujiMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset); // ***************************************************************************** // class definitions @@ -84,6 +87,9 @@ namespace Exiv2 { //! MakerNote for Fujifilm cameras class FujiMakerNote : public IfdMakerNote { public: + //! Shortcut for a %FujiMakerNote auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ /*! @@ -105,7 +111,7 @@ namespace Exiv2 { //! @name Accessors //@{ int checkHeader() const; - FujiMakerNote* clone(bool alloc =true) const; + FujiMakerNote::AutoPtr clone(bool alloc =true) const; //! Return the name of the makernote item ("Fujifilm") std::string ifdItem() const { return ifdItem_; } std::ostream& printTag(std::ostream& os, @@ -134,6 +140,9 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + FujiMakerNote* clone_(bool alloc =true) const; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -141,7 +150,7 @@ namespace Exiv2 { { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("FUJIFILM", "*", createFujiMakerNote); - mnf.registerMakerNote(new FujiMakerNote); + mnf.registerMakerNote(MakerNote::AutoPtr(new FujiMakerNote)); } }; /*! diff --git a/src/makernote.cpp b/src/makernote.cpp index 99a5822e..7eb3bb19 100644 --- a/src/makernote.cpp +++ b/src/makernote.cpp @@ -20,13 +20,13 @@ */ /* File: makernote.cpp - Version: $Name: $ $Revision: 1.28 $ + Version: $Name: $ $Revision: 1.29 $ Author(s): Andreas Huggel (ahu) History: 18-Feb-04, ahu: created */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.28 $ $RCSfile: makernote.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.29 $ $RCSfile: makernote.cpp,v $"); // Define DEBUG_* to output debug information to std::cerr #undef DEBUG_MAKERNOTE @@ -60,6 +60,11 @@ namespace Exiv2 { { } + MakerNote::AutoPtr MakerNote::clone(bool alloc) const + { + return AutoPtr(clone_(alloc)); + } + std::string MakerNote::tagName(uint16_t tag) const { std::string tagName; @@ -133,7 +138,6 @@ namespace Exiv2 { << tagDesc(tag); } // MakerNote::writeMnTagInfo - IfdMakerNote::IfdMakerNote(const MakerNote::MnTagInfo* pMnTagInfo, bool alloc) : MakerNote(pMnTagInfo, alloc), @@ -233,6 +237,11 @@ namespace Exiv2 { return headerSize() + ifd_.size() + ifd_.dataSize(); } + IfdMakerNote::AutoPtr IfdMakerNote::clone(bool alloc) const + { + return AutoPtr(clone_(alloc)); + } + MakerNoteFactory* MakerNoteFactory::pInstance_ = 0; MakerNoteFactory& MakerNoteFactory::instance() @@ -243,17 +252,18 @@ namespace Exiv2 { return *pInstance_; } // MakerNoteFactory::instance - void MakerNoteFactory::registerMakerNote(MakerNote* pMakerNote) + void MakerNoteFactory::registerMakerNote(MakerNote::AutoPtr makerNote) { + MakerNote* pMakerNote = makerNote.release(); assert(pMakerNote); ifdItemRegistry_[pMakerNote->ifdItem()] = pMakerNote; } // MakerNoteFactory::registerMakerNote - MakerNote* MakerNoteFactory::create(const std::string& ifdItem, - bool alloc) const + MakerNote::AutoPtr MakerNoteFactory::create(const std::string& ifdItem, + bool alloc) const { IfdItemRegistry::const_iterator i = ifdItemRegistry_.find(ifdItem); - if (i == ifdItemRegistry_.end()) return 0; + if (i == ifdItemRegistry_.end()) return MakerNote::AutoPtr(0); assert(i->second); return i->second->clone(alloc); } // MakerNoteFactory::create @@ -270,40 +280,40 @@ namespace Exiv2 { // Todo: use case insensitive make and model comparisons // Find or create a registry entry for make - ModelRegistry* modelRegistry = 0; + ModelRegistry* pModelRegistry = 0; Registry::const_iterator end1 = registry_.end(); Registry::const_iterator pos1; for (pos1 = registry_.begin(); pos1 != end1; ++pos1) { if (pos1->first == make) break; } if (pos1 != end1) { - modelRegistry = pos1->second; + pModelRegistry = pos1->second; } else { - modelRegistry = new ModelRegistry; - registry_.push_back(std::make_pair(make, modelRegistry)); + pModelRegistry = new ModelRegistry; + registry_.push_back(std::make_pair(make, pModelRegistry)); } // Find or create a registry entry for model - ModelRegistry::iterator end2 = modelRegistry->end(); + ModelRegistry::iterator end2 = pModelRegistry->end(); ModelRegistry::iterator pos2; - for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) { + for (pos2 = pModelRegistry->begin(); pos2 != end2; ++pos2) { if (pos2->first == model) break; } if (pos2 != end2) { pos2->second = createMakerNote; } else { - modelRegistry->push_back(std::make_pair(model, createMakerNote)); + pModelRegistry->push_back(std::make_pair(model, createMakerNote)); } } // MakerNoteFactory::registerMakerNote - MakerNote* MakerNoteFactory::create(const std::string& make, - const std::string& model, - bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset) const + MakerNote::AutoPtr MakerNoteFactory::create(const std::string& make, + const std::string& model, + bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset) const { #ifdef DEBUG_REGISTRY std::cerr << "Entering MakerNoteFactory::create(\"" @@ -312,7 +322,7 @@ namespace Exiv2 { #endif // loop through each make of the registry to find the best matching make int score = 0; - ModelRegistry* modelRegistry = 0; + ModelRegistry* pModelRegistry = 0; #ifdef DEBUG_REGISTRY std::string makeMatch; std::cerr << "Searching make registry...\n"; @@ -326,10 +336,10 @@ namespace Exiv2 { #ifdef DEBUG_REGISTRY makeMatch = pos1->first; #endif - modelRegistry = pos1->second; + pModelRegistry = pos1->second; } } - if (modelRegistry == 0) return 0; + if (pModelRegistry == 0) return MakerNote::AutoPtr(0); #ifdef DEBUG_REGISTRY std::cerr << "Best match is \"" << makeMatch << "\".\n"; #endif @@ -341,9 +351,9 @@ namespace Exiv2 { std::string modelMatch; std::cerr << "Searching model registry...\n"; #endif - ModelRegistry::const_iterator end2 = modelRegistry->end(); + ModelRegistry::const_iterator end2 = pModelRegistry->end(); ModelRegistry::const_iterator pos2; - for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) { + for (pos2 = pModelRegistry->begin(); pos2 != end2; ++pos2) { int rc = match(pos2->first, model); if (rc > score) { score = rc; @@ -353,7 +363,7 @@ namespace Exiv2 { createMakerNote = pos2->second; } } - if (createMakerNote == 0) return 0; + if (createMakerNote == 0) return MakerNote::AutoPtr(0); #ifdef DEBUG_REGISTRY std::cerr << "Best match is \"" << modelMatch << "\".\n"; #endif diff --git a/src/makernote.hpp b/src/makernote.hpp index af81d9f1..07379570 100644 --- a/src/makernote.hpp +++ b/src/makernote.hpp @@ -22,7 +22,7 @@ @file makernote.hpp @brief Contains the Exif %MakerNote interface, IFD %MakerNote and a MakerNote factory - @version $Name: $ $Revision: 1.24 $ + @version $Name: $ $Revision: 1.25 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 18-Feb-04, ahu: created @@ -41,6 +41,7 @@ #include #include #include +#include // ***************************************************************************** // namespace extensions @@ -50,12 +51,6 @@ namespace Exiv2 { // class declarations class Value; -// ***************************************************************************** -// type definitions - - //! Type for a pointer to a function creating a makernote - typedef MakerNote* (*CreateFct)(bool, const byte*, long, ByteOrder, long); - // ***************************************************************************** // class definitions @@ -106,6 +101,8 @@ namespace Exiv2 { //@} public: + //! Shortcut for a %MakerNote auto pointer. + typedef std::auto_ptr AutoPtr; //! MakerNote Tag information struct MnTagInfo { @@ -169,6 +166,18 @@ namespace Exiv2 { ByteOrder byteOrder() const { return byteOrder_; } //! Return the offset of the makernote from the start of the TIFF header long offset() const { return offset_; } + /*! + @brief Return a pointer to an newly created, empty instance of the + same type as this. The makernote entries are not copied. + The caller owns the new object and is responsible to delete it! + + @param alloc Memory management model for the clone. Indicates if + memory required to store data should be allocated and deallocated + (true) or not (false). If false, only pointers to the buffer + provided to read() will be kept. See Ifd for more background on + this concept. + */ + MakerNote::AutoPtr clone(bool alloc =true) const; /*! @brief Return the name of a makernote tag. The default implementation looks up the makernote info tag array if one is set, else @@ -199,18 +208,6 @@ namespace Exiv2 { @brief Write the makernote tag info of tag to the output stream os. */ virtual std::ostream& writeMnTagInfo(std::ostream& os, uint16_t tag) const; - /*! - @brief Return a pointer to an newly created, empty instance of the - same type as this. The makernote entries are not copied. - The caller owns the new object and is responsible to delete it! - - @param alloc Memory management model for the clone. Indicates if - memory required to store data should be allocated and deallocated - (true) or not (false). If false, only pointers to the buffer - provided to read() will be kept. See Ifd for more background on - this concept. - */ - virtual MakerNote* clone(bool alloc =true) const =0; //! The first makernote entry virtual Entries::const_iterator begin() const =0; //! End of the makernote entries @@ -248,8 +245,14 @@ namespace Exiv2 { */ ByteOrder byteOrder_; + private: + //! Internal virtual copy constructor. + virtual MakerNote* clone_(bool alloc =true) const =0; + }; // class MakerNote + //! Type for a pointer to a function creating a makernote + typedef MakerNote::AutoPtr (*CreateFct)(bool, const byte*, long, ByteOrder, long); /*! @brief Interface for MakerNotes in IFD format. See MakerNote. */ @@ -261,6 +264,9 @@ namespace Exiv2 { //@} public: + //! Shortcut for an %IfdMakerNote auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ /*! @@ -303,6 +309,7 @@ namespace Exiv2 { Entries::const_iterator end() const { return ifd_.end(); } Entries::const_iterator findIdx(int idx) const; long size() const; + IfdMakerNote::AutoPtr clone(bool alloc =true) const; /*! @brief Check the makernote header. This will typically check if a required prefix string is present in the header. Return 0 if @@ -323,7 +330,6 @@ namespace Exiv2 { buffer. */ virtual long headerSize() const; - virtual IfdMakerNote* clone(bool alloc =true) const =0; virtual std::string ifdItem() const =0; virtual std::ostream& printTag(std::ostream& os, uint16_t tag, @@ -351,6 +357,9 @@ namespace Exiv2 { //! The makernote IFD Ifd ifd_; + private: + virtual IfdMakerNote* clone_(bool alloc =true) const =0; + }; // class IfdMakerNote /*! @@ -394,7 +403,7 @@ namespace Exiv2 { CreateFct createMakerNote); //! Register a %MakerNote prototype in the IFD item registry. - void registerMakerNote(MakerNote* pMakerNote); + void registerMakerNote(MakerNote::AutoPtr makerNote); //@} //! @name Accessors @@ -402,8 +411,8 @@ namespace Exiv2 { /*! @brief Create the appropriate %MakerNote based on camera make and model and possibly the contents of the makernote itself, return - a pointer to the newly created MakerNote instance. Return 0 if - no %MakerNote is defined for the camera model. + an auto-pointer to the newly created MakerNote instance. Return + 0 if no %MakerNote is defined for the camera model. The method searches the make-model tree for a make and model combination in the registry that matches the search key. The search is @@ -411,17 +420,17 @@ namespace Exiv2 { wildcards in the registry entries are supported. First the best matching make is searched, then the best matching model for this make is searched. If there is no matching make or no matching model within - the models registered for the best matching make, then no maker note + the models registered for the best matching make, then no makernote is created and the function returns 0. If a match is found, the - function invokes the registered create function and returns a pointer - to the newly created MakerNote. The makernote pointed to is owned by - the caller of the function, i.e., the caller is responsible to delete - the returned makernote when it is no longer needed. The best match is - an exact match, then a match is rated according to the number of - matching characters. The makernote buffer is passed on to the create - function, which can based on its content, automatically determine the - correct version or flavour of the makernote required. This is used, - e.g., to determine which of the three Nikon makernotes to create. + function invokes the registered create function and returns an + auto-pointer to the newly created MakerNote. The makernote pointed to + is owned by the caller of the function and the auto-pointer ensures + that it is deleted. The best match is an exact match, then a match is + rated according to the number of matching characters. The makernote + buffer is passed on to the create function, which can based on its + content, automatically determine the correct version or flavour of the + makernote required. This is used, e.g., to determine which of the + three Nikon makernotes to create. @param make Camera manufacturer. (Typically the string from the Exif make tag.) @@ -439,19 +448,20 @@ namespace Exiv2 { @param offset Offset from the start of the TIFF header of the makernote buffer. - @return A pointer that owns a %MakerNote for the camera model. If the - camera is not supported, the pointer is 0. + @return An auto-pointer that owns a %MakerNote for the camera model. + If the camera is not supported, the pointer is 0. */ - MakerNote* create(const std::string& make, - const std::string& model, - bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset) const; + MakerNote::AutoPtr create(const std::string& make, + const std::string& model, + bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset) const; //! Create a %MakerNote based on its IFD item string. - MakerNote* create(const std::string& ifdItem, bool alloc =true) const; + MakerNote::AutoPtr create(const std::string& ifdItem, + bool alloc =true) const; //@} /*! diff --git a/src/nikonmn.cpp b/src/nikonmn.cpp index 00db81f7..8b627924 100644 --- a/src/nikonmn.cpp +++ b/src/nikonmn.cpp @@ -20,14 +20,14 @@ */ /* File: nikonmn.cpp - Version: $Name: $ $Revision: 1.9 $ + Version: $Name: $ $Revision: 1.10 $ Author(s): Andreas Huggel (ahu) History: 17-May-04, ahu: created 25-May-04, ahu: combined all Nikon formats in one component */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: nikonmn.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: nikonmn.cpp,v $"); // ***************************************************************************** // included header files @@ -77,7 +77,12 @@ namespace Exiv2 { { } - Nikon1MakerNote* Nikon1MakerNote::clone(bool alloc) const + Nikon1MakerNote::AutoPtr Nikon1MakerNote::clone(bool alloc) const + { + return AutoPtr(clone_(alloc)); + } + + Nikon1MakerNote* Nikon1MakerNote::clone_(bool alloc) const { return new Nikon1MakerNote(alloc); } @@ -232,12 +237,17 @@ namespace Exiv2 { return rc; } - Nikon2MakerNote* Nikon2MakerNote::clone(bool alloc) const + Nikon2MakerNote::AutoPtr Nikon2MakerNote::clone(bool alloc) const + { + return AutoPtr(clone_(alloc)); + } + + Nikon2MakerNote* Nikon2MakerNote::clone_(bool alloc) const { - Nikon2MakerNote* pMakerNote = new Nikon2MakerNote(alloc); - assert(pMakerNote); - pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_); - return pMakerNote; + AutoPtr makerNote = AutoPtr(new Nikon2MakerNote(alloc)); + assert(makerNote.get() != 0); + makerNote->readHeader(header_.pData_, header_.size_, byteOrder_); + return makerNote.release(); } std::ostream& Nikon2MakerNote::printTag(std::ostream& os, @@ -428,12 +438,17 @@ namespace Exiv2 { return rc; } - Nikon3MakerNote* Nikon3MakerNote::clone(bool alloc) const + Nikon3MakerNote::AutoPtr Nikon3MakerNote::clone(bool alloc) const { - Nikon3MakerNote* pMakerNote = new Nikon3MakerNote(alloc); - assert(pMakerNote); - pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_); - return pMakerNote; + return AutoPtr(clone_(alloc)); + } + + Nikon3MakerNote* Nikon3MakerNote::clone_(bool alloc) const + { + AutoPtr makerNote = AutoPtr(new Nikon3MakerNote(alloc)); + assert(makerNote.get() != 0); + makerNote->readHeader(header_.pData_, header_.size_, byteOrder_); + return makerNote.release(); } std::ostream& Nikon3MakerNote::printTag(std::ostream& os, @@ -535,26 +550,26 @@ namespace Exiv2 { // ***************************************************************************** // free functions - MakerNote* createNikonMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset) + MakerNote::AutoPtr createNikonMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset) { // If there is no "Nikon" string it must be Nikon1 format if (len < 6 || std::string(reinterpret_cast(buf), 6) != std::string("Nikon\0", 6)) { - return new Nikon1MakerNote(alloc); + return MakerNote::AutoPtr(new Nikon1MakerNote(alloc)); } // If the "Nikon" string is not followed by a TIFF header, we assume // Nikon2 format TiffHeader tiffHeader; if ( len < 18 || tiffHeader.read(buf + 10) != 0 || tiffHeader.tag() != 0x002a) { - return new Nikon2MakerNote(alloc); + return MakerNote::AutoPtr(new Nikon2MakerNote(alloc)); } // Else we have a Nikon3 makernote - return new Nikon3MakerNote(alloc); + return MakerNote::AutoPtr(new Nikon3MakerNote(alloc)); } } // namespace Exiv2 diff --git a/src/nikonmn.hpp b/src/nikonmn.hpp index 6b55a3bf..6596a587 100644 --- a/src/nikonmn.hpp +++ b/src/nikonmn.hpp @@ -28,7 +28,7 @@ Exif file format by TsuruZoh Tachibanaya.
Format 3: "EXIFutils Field Reference Guide". - @version $Name: $ $Revision: 1.6 $ + @version $Name: $ $Revision: 1.7 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 17-May-04, ahu: created
@@ -45,6 +45,7 @@ // + standard includes #include #include +#include // ***************************************************************************** // namespace extensions @@ -58,9 +59,10 @@ namespace Exiv2 { // free functions /*! - @brief Return a pointer to a newly created empty MakerNote initialized to - operate in the memory management model indicated. The caller owns - this copy and is responsible to delete it! + @brief Return an auto-pointer to a newly created empty MakerNote + initialized to operate in the memory management model indicated. + The caller owns this copy and the auto-pointer ensures that it + will be deleted. @param alloc Memory management model for the new MakerNote. Determines if memory required to store data should be allocated and deallocated @@ -74,14 +76,15 @@ namespace Exiv2 { @param offset Offset from the start of the TIFF header of the makernote buffer (not used). - @return A pointer to a newly created empty MakerNote. The caller owns - this copy and is responsible to delete it! + @return An auto-pointer to a newly created empty MakerNote. The caller + owns this copy and the auto-pointer ensures that it will be + deleted. */ - MakerNote* createNikonMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset); + MakerNote::AutoPtr createNikonMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset); // ***************************************************************************** // class definitions @@ -89,6 +92,9 @@ namespace Exiv2 { //! A MakerNote format used by Nikon cameras, such as the E990 and D1. class Nikon1MakerNote : public IfdMakerNote { public: + //! Shortcut for a %Nikon1MakerNote auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ /*! @@ -102,7 +108,7 @@ namespace Exiv2 { //! @name Accessors //@{ - Nikon1MakerNote* clone(bool alloc =true) const; + Nikon1MakerNote::AutoPtr clone(bool alloc =true) const; //! Return the name of the makernote item ("Nikon1") std::string ifdItem() const { return ifdItem_; } std::ostream& printTag(std::ostream& os, @@ -125,6 +131,9 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + Nikon1MakerNote* clone_(bool alloc =true) const; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -132,7 +141,7 @@ namespace Exiv2 { { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("NIKON*", "*", createNikonMakerNote); - mnf.registerMakerNote(new Nikon1MakerNote); + mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon1MakerNote)); } }; // DATA @@ -161,6 +170,9 @@ namespace Exiv2 { */ class Nikon2MakerNote : public IfdMakerNote { public: + //! Shortcut for a %Nikon2MakerNote auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ /*! @@ -182,7 +194,7 @@ namespace Exiv2 { //! @name Accessors //@{ int checkHeader() const; - Nikon2MakerNote* clone(bool alloc =true) const; + Nikon2MakerNote::AutoPtr clone(bool alloc =true) const; //! Return the name of the makernote item ("Nikon2") std::string ifdItem() const { return ifdItem_; } std::ostream& printTag(std::ostream& os, @@ -207,13 +219,16 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + Nikon2MakerNote* clone_(bool alloc =true) const; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor RegisterMakerNote() { MakerNoteFactory& mnf = MakerNoteFactory::instance(); - mnf.registerMakerNote(new Nikon2MakerNote); + mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon2MakerNote)); } }; // DATA @@ -239,6 +254,9 @@ namespace Exiv2 { //! A third MakerNote format used by Nikon cameras, e.g., E5400, SQ, D2H, D70 class Nikon3MakerNote : public IfdMakerNote { public: + //! Shortcut for a %Nikon3MakerNote auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ /*! @@ -260,7 +278,7 @@ namespace Exiv2 { //! @name Accessors //@{ int checkHeader() const; - Nikon3MakerNote* clone(bool alloc =true) const; + Nikon3MakerNote::AutoPtr clone(bool alloc =true) const; //! Return the name of the makernote item ("Nikon3") std::string ifdItem() const { return ifdItem_; } std::ostream& printTag(std::ostream& os, @@ -283,13 +301,16 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + Nikon3MakerNote* clone_(bool alloc =true) const; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor RegisterMakerNote() { MakerNoteFactory& mnf = MakerNoteFactory::instance(); - mnf.registerMakerNote(new Nikon3MakerNote); + mnf.registerMakerNote(MakerNote::AutoPtr(new Nikon3MakerNote)); } }; // DATA diff --git a/src/sigmamn.cpp b/src/sigmamn.cpp index c175213e..24fbaec4 100644 --- a/src/sigmamn.cpp +++ b/src/sigmamn.cpp @@ -20,7 +20,7 @@ */ /* File: sigmamn.cpp - Version: $Name: $ $Revision: 1.11 $ + Version: $Name: $ $Revision: 1.12 $ Author(s): Andreas Huggel (ahu) History: 02-Apr-04, ahu: created Credits: Sigma and Foveon MakerNote implemented according to the specification @@ -29,7 +29,7 @@ */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.11 $ $RCSfile: sigmamn.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.12 $ $RCSfile: sigmamn.cpp,v $"); // ***************************************************************************** // included header files @@ -121,17 +121,22 @@ namespace Exiv2 { return rc; } - SigmaMakerNote* SigmaMakerNote::clone(bool alloc) const + SigmaMakerNote::AutoPtr SigmaMakerNote::clone(bool alloc) const { - SigmaMakerNote* pMakerNote = new SigmaMakerNote(alloc); - assert(pMakerNote); - pMakerNote->readHeader(header_.pData_, header_.size_, byteOrder_); - return pMakerNote; + return AutoPtr(clone_(alloc)); + } + + SigmaMakerNote* SigmaMakerNote::clone_(bool alloc) const + { + AutoPtr makerNote = AutoPtr(new SigmaMakerNote(alloc)); + assert(makerNote.get() != 0); + makerNote->readHeader(header_.pData_, header_.size_, byteOrder_); + return makerNote.release(); } std::ostream& SigmaMakerNote::printTag(std::ostream& os, - uint16_t tag, - const Value& value) const + uint16_t tag, + const Value& value) const { switch (tag) { case 0x000c: // fallthrough @@ -193,13 +198,13 @@ namespace Exiv2 { // ***************************************************************************** // free functions - MakerNote* createSigmaMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset) + MakerNote::AutoPtr createSigmaMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset) { - return new SigmaMakerNote(alloc); + return MakerNote::AutoPtr(new SigmaMakerNote(alloc)); } } // namespace Exiv2 diff --git a/src/sigmamn.hpp b/src/sigmamn.hpp index afb74783..c1797f18 100644 --- a/src/sigmamn.hpp +++ b/src/sigmamn.hpp @@ -23,7 +23,7 @@ @brief Sigma and Foveon MakerNote implemented according to the specification SIGMA and FOVEON EXIF MakerNote Documentation by Foveon. - @version $Name: $ $Revision: 1.9 $ + @version $Name: $ $Revision: 1.10 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 02-Apr-04, ahu: created @@ -39,6 +39,7 @@ // + standard includes #include #include +#include // ***************************************************************************** // namespace extensions @@ -52,9 +53,10 @@ namespace Exiv2 { // free functions /*! - @brief Return a pointer to a newly created empty MakerNote initialized to - operate in the memory management model indicated. The caller owns - this copy and is responsible to delete it! + @brief Return an auto-pointer to a newly created empty MakerNote + initialized to operate in the memory management model indicated. + The caller owns this copy and the auto-pointer ensures that it + will be deleted. @param alloc Memory management model for the new MakerNote. Determines if memory required to store data should be allocated and deallocated @@ -68,14 +70,15 @@ namespace Exiv2 { @param offset Offset from the start of the TIFF header of the makernote buffer (not used). - @return A pointer to a newly created empty MakerNote. The caller owns - this copy and is responsible to delete it! + @return An auto-pointer to a newly created empty MakerNote. The caller + owns this copy and the auto-pointer ensures that it will be + deleted. */ - MakerNote* createSigmaMakerNote(bool alloc, - const byte* buf, - long len, - ByteOrder byteOrder, - long offset); + MakerNote::AutoPtr createSigmaMakerNote(bool alloc, + const byte* buf, + long len, + ByteOrder byteOrder, + long offset); // ***************************************************************************** // class definitions @@ -83,6 +86,9 @@ namespace Exiv2 { //! MakerNote for Sigma (Foveon) cameras class SigmaMakerNote : public IfdMakerNote { public: + //! Shortcut for a %SigmaMakerNote auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ /*! @@ -104,7 +110,7 @@ namespace Exiv2 { //! @name Accessors //@{ int checkHeader() const; - SigmaMakerNote* clone(bool alloc =true) const; + SigmaMakerNote::AutoPtr clone(bool alloc =true) const; //! Return the name of the makernote item ("Sigma") std::string ifdItem() const { return ifdItem_; } std::ostream& printTag(std::ostream& os, @@ -123,6 +129,9 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + SigmaMakerNote* clone_(bool alloc =true) const; + //! Structure used to auto-register the MakerNote. struct RegisterMakerNote { //! Default constructor @@ -131,7 +140,7 @@ namespace Exiv2 { MakerNoteFactory& mnf = MakerNoteFactory::instance(); mnf.registerMakerNote("SIGMA", "*", createSigmaMakerNote); mnf.registerMakerNote("FOVEON", "*", createSigmaMakerNote); - mnf.registerMakerNote(new SigmaMakerNote); + mnf.registerMakerNote(MakerNote::AutoPtr(new SigmaMakerNote)); } }; // DATA diff --git a/src/taglist.cpp b/src/taglist.cpp index ab0d469e..fac48030 100644 --- a/src/taglist.cpp +++ b/src/taglist.cpp @@ -3,13 +3,13 @@ Abstract: Print a simple comma separated list of tags defined in Exiv2 File: taglist.cpp - Version: $Name: $ $Revision: 1.10 $ + Version: $Name: $ $Revision: 1.11 $ Author(s): Andreas Huggel (ahu) History: 07-Jan-04, ahu: created */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: taglist.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.11 $ $RCSfile: taglist.cpp,v $"); #include "makernote.hpp" #include "tags.hpp" @@ -28,18 +28,15 @@ try { switch (argc) { case 2: { - MakerNote* pMakerNote = 0; std::string item(argv[1]); if (item == "Iptc") { IptcDataSets::dataSetList(std::cout); break; } - pMakerNote = MakerNoteFactory::instance().create(item); - if (pMakerNote) { - pMakerNote->taglist(std::cout); - delete pMakerNote; - pMakerNote = 0; + MakerNote::AutoPtr makerNote = MakerNoteFactory::instance().create(item); + if (makerNote.get() != 0) { + makerNote->taglist(std::cout); } else { rc = 2; diff --git a/src/tags.cpp b/src/tags.cpp index 7d79ca5b..db735756 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -20,13 +20,13 @@ */ /* File: tags.cpp - Version: $Name: $ $Revision: 1.37 $ + Version: $Name: $ $Revision: 1.38 $ Author(s): Andreas Huggel (ahu) History: 15-Jan-04, ahu: created */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.37 $ $RCSfile: tags.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.38 $ $RCSfile: tags.cpp,v $"); // ***************************************************************************** // included header files @@ -396,38 +396,38 @@ namespace Exiv2 { ExifKey::ExifKey(const std::string& key) : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), - idx_(0), pMakerNote_(0), key_(key) + idx_(0), key_(key) { decomposeKey(); } ExifKey::ExifKey(uint16_t tag, const std::string& ifdItem) : tag_(0), ifdId_(ifdIdNotSet), ifdItem_(""), - idx_(0), pMakerNote_(0), key_("") + idx_(0), key_("") { IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); if (ifdId == makerIfdId) throw Error("Invalid key"); - MakerNote* pMakerNote = 0; + MakerNote::AutoPtr makerNote; if (ifdId == ifdIdNotSet) { - pMakerNote = MakerNoteFactory::instance().create(ifdItem); - if (pMakerNote) ifdId = makerIfdId; + makerNote = MakerNoteFactory::instance().create(ifdItem); + if (makerNote.get() != 0) ifdId = makerIfdId; else throw Error("Invalid key"); } tag_ = tag; ifdId_ = ifdId; ifdItem_ = ifdItem; - pMakerNote_ = pMakerNote; + makerNote_ = makerNote; makeKey(); } ExifKey::ExifKey(const Entry& e) : tag_(e.tag()), ifdId_(e.ifdId()), ifdItem_(""), - idx_(e.idx()), pMakerNote_(0), key_("") + idx_(e.idx()), key_("") { if (ifdId_ == makerIfdId) { if (e.makerNote()) { ifdItem_ = e.makerNote()->ifdItem(); - pMakerNote_ = e.makerNote()->clone(); + makerNote_ = e.makerNote()->clone(); } else throw Error("Invalid Key"); } @@ -440,14 +440,14 @@ namespace Exiv2 { ExifKey::ExifKey(const ExifKey& rhs) : tag_(rhs.tag_), ifdId_(rhs.ifdId_), ifdItem_(rhs.ifdItem_), idx_(rhs.idx_), - pMakerNote_(rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0), + makerNote_(rhs.makerNote_.get() != 0 ? rhs.makerNote_->clone() + : MakerNote::AutoPtr(0)), key_(rhs.key_) { } ExifKey::~ExifKey() { - delete pMakerNote_; } ExifKey& ExifKey::operator=(const ExifKey& rhs) @@ -458,7 +458,8 @@ namespace Exiv2 { ifdId_ = rhs.ifdId_; ifdItem_ = rhs.ifdItem_; idx_ = rhs.idx_; - pMakerNote_ = rhs.pMakerNote_ ? rhs.pMakerNote_->clone() : 0; + makerNote_ = rhs.makerNote_.get() != 0 ? rhs.makerNote_->clone() + : MakerNote::AutoPtr(0); key_ = rhs.key_; return *this; } @@ -466,8 +467,8 @@ namespace Exiv2 { std::string ExifKey::tagName() const { if (ifdId_ == makerIfdId) { - assert(pMakerNote_); - return pMakerNote_->tagName(tag_); + assert(makerNote_.get() != 0); + return makerNote_->tagName(tag_); } return ExifTags::tagName(tag_, ifdId_); } @@ -480,8 +481,8 @@ namespace Exiv2 { std::string ExifKey::sectionName() const { if (ifdId_ == makerIfdId) { - assert(pMakerNote_); - return pMakerNote_->ifdItem(); + assert(makerNote_.get() != 0); + return makerNote_->ifdItem(); } return ExifTags::sectionName(tag(), ifdId()); } @@ -506,24 +507,23 @@ namespace Exiv2 { // Find IfdId IfdId ifdId = ExifTags::ifdIdByIfdItem(ifdItem); if (ifdId == makerIfdId) throw Error("Invalid key"); - MakerNote* pMakerNote = 0; + MakerNote::AutoPtr makerNote; if (ifdId == ifdIdNotSet) { - pMakerNote = MakerNoteFactory::instance().create(ifdItem); - if (pMakerNote) ifdId = makerIfdId; + makerNote = MakerNoteFactory::instance().create(ifdItem); + if (makerNote.get() != 0) ifdId = makerIfdId; else throw Error("Invalid key"); } // Convert tag - uint16_t tag = pMakerNote ? - pMakerNote->tag(tagName) : ExifTags::tag(tagName, ifdId); + uint16_t tag = makerNote.get() != 0 ? makerNote->tag(tagName) + : ExifTags::tag(tagName, ifdId); // Translate hex tag name (0xabcd) to a real tag name if there is one - tagName = pMakerNote ? - pMakerNote->tagName(tag) : ExifTags::tagName(tag, ifdId); - + tagName = makerNote.get() != 0 ? makerNote->tagName(tag) + : ExifTags::tagName(tag, ifdId); tag_ = tag; ifdId_ = ifdId; ifdItem_ = ifdItem; - pMakerNote_ = pMakerNote; + makerNote_ = makerNote; key_ = familyName + "." + ifdItem + "." + tagName; } @@ -531,15 +531,15 @@ namespace Exiv2 { { key_ = std::string(familyName_) + "." + ifdItem_ - + "." + (pMakerNote_ ? - pMakerNote_->tagName(tag_) : ExifTags::tagName(tag_, ifdId_)); + + "." + (makerNote_.get() != 0 ? makerNote_->tagName(tag_) + : ExifTags::tagName(tag_, ifdId_)); } std::ostream& ExifKey::printTag(std::ostream& os, const Value& value) const { if (ifdId_ == makerIfdId) { - assert(pMakerNote_); - return pMakerNote_->printTag(os, tag(), value); + assert(makerNote_.get() != 0); + return makerNote_->printTag(os, tag(), value); } return ExifTags::printTag(os, tag(), ifdId(), value); } diff --git a/src/tags.hpp b/src/tags.hpp index ca6fb2ab..669fcdb5 100644 --- a/src/tags.hpp +++ b/src/tags.hpp @@ -21,7 +21,7 @@ /*! @file tags.hpp @brief Exif tag and type information - @version $Name: $ $Revision: 1.28 $ + @version $Name: $ $Revision: 1.29 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 15-Jan-04, ahu: created
@@ -39,6 +39,7 @@ #include #include // for std::pair #include +#include // ***************************************************************************** // namespace extensions @@ -288,7 +289,8 @@ namespace Exiv2 { IfdId ifdId_; //!< The IFD associated with this tag std::string ifdItem_; //!< The IFD item int idx_; //!< Unique id of an entry within one IFD - MakerNote* pMakerNote_; //!< Pointer to the associated MakerNote + //! Auto-pointer to the associated MakerNote + std::auto_ptr makerNote_; std::string key_; //!< Key }; // class ExifKey