diff --git a/src/addmoddel.cpp b/src/addmoddel.cpp index 8117e8eb..5da934d4 100644 --- a/src/addmoddel.cpp +++ b/src/addmoddel.cpp @@ -3,7 +3,7 @@ Abstract: Sample program showing how to add, modify and delete Exif metadata. File: addmoddel.cpp - Version: $Name: $ $Revision: 1.4 $ + Version: $Name: $ $Revision: 1.5 $ Author(s): Andreas Huggel (ahu) History: 26-Jan-04, ahu: created */ @@ -24,19 +24,16 @@ try { // Add to the Exif data // Create a ASCII string value (note the use of create) - Exiv2::Value* v = Exiv2::Value::create(Exiv2::asciiString); + Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::asciiString); // Set the value to a string v->read("1999:12:31 23:59:59"); // Add the value together with its key to the Exif data container Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal"); - exifData.add(key, v); - + exifData.add(key, v.get()); std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n"; - // Delete the memory allocated by Value::create - delete v; // Now create a more interesting value (without using the create method) - Exiv2::URationalValue* rv = new Exiv2::URationalValue; + Exiv2::URationalValue::AutoPtr rv(new Exiv2::URationalValue); // Set two rational components from a string rv->read("1/2 1/3"); // Add more elements through the extended interface of rational value @@ -44,11 +41,8 @@ try { rv->value_.push_back(std::make_pair(3,4)); // Add the key and value pair to the Exif data key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); - exifData.add(key, rv); - + exifData.add(key, rv.get()); std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n"; - // Delete memory allocated on the heap - delete rv; // ************************************************************************* // Modify Exif data @@ -59,8 +53,8 @@ try { if (pos == exifData.end()) throw Exiv2::Error("Key not found"); // Modify the value std::string date = pos->toString(); - date.replace(0,4,"2000"); - pos->setValue(date); + date.replace(0, 4, "2000"); + pos->setValue(date); std::cout << "Modified key \"" << key << "\", new value \"" << pos->value() << "\"\n"; @@ -71,14 +65,13 @@ try { // Get a pointer to a copy of the value v = pos->getValue(); // Downcast the Value pointer to its actual type - rv = dynamic_cast(v); - if (rv == 0) throw Exiv2::Error("Downcast failed"); + Exiv2::URationalValue* prv = dynamic_cast(v.release()); + if (prv == 0) throw Exiv2::Error("Downcast failed"); + rv = Exiv2::URationalValue::AutoPtr(prv); // Modify the value directly through the interface of URationalValue rv->value_[2] = std::make_pair(88,77); // Copy the modified value back to the metadatum - pos->setValue(rv); - // Delete the memory allocated by getValue - delete v; + pos->setValue(rv.get()); std::cout << "Modified key \"" << key << "\", new value \"" << pos->value() << "\"\n"; diff --git a/src/exif.cpp b/src/exif.cpp index 22dedd0e..dbc007c2 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -20,14 +20,14 @@ */ /* File: exif.cpp - Version: $Name: $ $Revision: 1.66 $ + Version: $Name: $ $Revision: 1.67 $ 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.66 $ $RCSfile: exif.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.67 $ $RCSfile: exif.cpp,v $"); // Define DEBUG_MAKERNOTE to output debug information to std::cerr #undef DEBUG_MAKERNOTE @@ -74,28 +74,27 @@ namespace { namespace Exiv2 { Exifdatum::Exifdatum(const Entry& e, ByteOrder byteOrder) - : key_(ExifKey::AutoPtr(new ExifKey(e))), pValue_(0) + : key_(ExifKey::AutoPtr(new ExifKey(e))) { - pValue_ = Value::create(TypeId(e.type())); - pValue_->read(e.data(), e.count() * e.typeSize(), byteOrder); + value_ = Value::create(TypeId(e.type())); + value_->read(e.data(), e.count() * e.typeSize(), byteOrder); } Exifdatum::Exifdatum(const ExifKey& key, const Value* pValue) - : key_(key.clone()), pValue_(0) + : key_(key.clone()) { - if (pValue) pValue_ = pValue->clone(); + if (pValue) value_ = pValue->clone(); } Exifdatum::~Exifdatum() { - delete pValue_; } Exifdatum::Exifdatum(const Exifdatum& rhs) - : Metadatum(rhs), pValue_(0) + : Metadatum(rhs) { if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy - if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy + if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy } Exifdatum& Exifdatum::operator=(const Exifdatum& rhs) @@ -106,30 +105,28 @@ namespace Exiv2 { key_.reset(); if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy - delete pValue_; - pValue_ = 0; - if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy + value_.reset(); + if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy return *this; } // Exifdatum::operator= void Exifdatum::setValue(const Value* pValue) { - delete pValue_; - pValue_ = pValue->clone(); + value_.reset(); + if (pValue) value_ = pValue->clone(); } void Exifdatum::setValue(const Entry& e, ByteOrder byteOrder) { - delete pValue_; - pValue_ = Value::create(TypeId(e.type())); - pValue_->read(e.data(), e.count() * e.typeSize(), byteOrder); + value_ = Value::create(TypeId(e.type())); + value_->read(e.data(), e.count() * e.typeSize(), byteOrder); } void Exifdatum::setValue(const std::string& buf) { - if (pValue_ == 0) pValue_ = Value::create(asciiString); - pValue_->read(buf); + if (value_.get() == 0) value_ = Value::create(asciiString); + value_->read(buf); } TiffThumbnail::TiffThumbnail() @@ -443,9 +440,8 @@ namespace Exiv2 { ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat"); ExifData::iterator pos = exifData.findKey(key); if (pos == exifData.end()) { - Value* value = Value::create(unsignedLong); - exifData.add(key, value); - delete value; + Value::AutoPtr value = Value::create(unsignedLong); + exifData.add(key, value.get()); pos = exifData.findKey(key); } pos->setValue(toString(offset_)); @@ -453,9 +449,8 @@ namespace Exiv2 { ExifKey key2("Exif.Thumbnail.JPEGInterchangeFormatLength"); pos = exifData.findKey(key2); if (pos == exifData.end()) { - Value *value = Value::create(unsignedLong); - exifData.add(key2, value); - delete value; + Value::AutoPtr value = Value::create(unsignedLong); + exifData.add(key2, value.get()); pos = exifData.findKey(key2); } pos->setValue(toString(size_)); @@ -866,7 +861,7 @@ namespace Exiv2 { } } - void ExifData::add(const ExifKey& key, Value* pValue) + void ExifData::add(const ExifKey& key, const Value* pValue) { add(Exifdatum(key, pValue)); } diff --git a/src/exif.hpp b/src/exif.hpp index 3e768c69..7afe43dd 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.57 $ + @version $Name: $ $Revision: 1.58 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created @@ -148,10 +148,10 @@ namespace Exiv2 { @return Number of characters written. */ long copy(byte* buf, ByteOrder byteOrder) const - { return pValue_ == 0 ? 0 : pValue_->copy(buf, byteOrder); } + { return value_.get() == 0 ? 0 : value_->copy(buf, byteOrder); } //! Return the type id of the value TypeId typeId() const - { return pValue_ == 0 ? invalidTypeId : pValue_->typeId(); } + { return value_.get() == 0 ? invalidTypeId : value_->typeId(); } //! Return the name of the type const char* typeName() const { return TypeInfo::typeName(typeId()); } @@ -160,13 +160,13 @@ namespace Exiv2 { { return TypeInfo::typeSize(typeId()); } //! Return the number of components in the value long count() const - { return pValue_ == 0 ? 0 : pValue_->count(); } + { return value_.get() == 0 ? 0 : value_->count(); } //! Return the size of the value in bytes long size() const - { return pValue_ == 0 ? 0 : pValue_->size(); } + { return value_.get() == 0 ? 0 : value_->size(); } //! Return the value as a string. std::string toString() const - { return pValue_ == 0 ? "" : pValue_->toString(); } + { return value_.get() == 0 ? "" : value_->toString(); } /*! @brief Return the n-th component of the value converted to long. The return value is -1 if the value of the Exifdatum is not set and @@ -174,7 +174,7 @@ namespace Exiv2 { component. */ long toLong(long n =0) const - { return pValue_ == 0 ? -1 : pValue_->toLong(n); } + { return value_.get() == 0 ? -1 : value_->toLong(n); } /*! @brief Return the n-th component of the value converted to float. The return value is -1 if the value of the Exifdatum is not set and @@ -182,7 +182,7 @@ namespace Exiv2 { component. */ float toFloat(long n =0) const - { return pValue_ == 0 ? -1 : pValue_->toFloat(n); } + { return value_.get() == 0 ? -1 : value_->toFloat(n); } /*! @brief Return the n-th component of the value converted to Rational. The return value is -1/1 if the value of the @@ -190,7 +190,7 @@ namespace Exiv2 { undefined if there is no n-th component. */ Rational toRational(long n =0) const - { return pValue_ == 0 ? Rational(-1, 1) : pValue_->toRational(n); } + { return value_.get() == 0 ? Rational(-1, 1) : value_->toRational(n); } /*! @brief Return a pointer to a copy (clone) of the value. The caller is responsible to delete this copy when it's no longer needed. @@ -203,8 +203,8 @@ namespace Exiv2 { @return A pointer to a copy (clone) of the value, 0 if the value is not set. */ - Value* getValue() const - { return pValue_ == 0 ? 0 : pValue_->clone(); } + Value::AutoPtr getValue() const + { return value_.get() == 0 ? Value::AutoPtr(0) : value_->clone(); } /*! @brief Return a constant reference to the value. @@ -225,13 +225,13 @@ namespace Exiv2 { @throw Error ("Value not set") if the value is not set. */ const Value& value() const - { if (pValue_) return *pValue_; throw Error("Value not set"); } + { if (value_.get() != 0) return *value_; throw Error("Value not set"); } //@} private: // DATA - ExifKey::AutoPtr key_; //!< Key - Value* pValue_; //!< Pointer to the value + ExifKey::AutoPtr key_; //!< Key + Value::AutoPtr value_; //!< Value }; // class Exifdatum @@ -582,7 +582,7 @@ namespace Exiv2 { performed, i.e., it is possible to add multiple metadata with the same key. */ - void add(const ExifKey& key, Value* pValue); + void add(const ExifKey& key, const Value* pValue); /*! @brief Add a copy of the Exifdatum to the Exif metadata. No duplicate checks are performed, i.e., it is possible to add diff --git a/src/iptc.cpp b/src/iptc.cpp index c291353b..2b5af627 100644 --- a/src/iptc.cpp +++ b/src/iptc.cpp @@ -20,13 +20,13 @@ */ /* File: iptc.cpp - Version: $Name: $ $Revision: 1.8 $ + Version: $Name: $ $Revision: 1.9 $ Author(s): Brad Schick (brad) History: 31-July-04, brad: created */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: iptc.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: iptc.cpp,v $"); // Define DEBUG_MAKERNOTE to output debug information to std::cerr #undef DEBUG_MAKERNOTE @@ -49,22 +49,21 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: iptc.cpp,v $"); namespace Exiv2 { Iptcdatum::Iptcdatum(const IptcKey& key, - const Value* value) - : key_(key.clone()), pValue_(0), modified_(false) + const Value* pValue) + : key_(key.clone()), modified_(false) { - if (value) pValue_ = value->clone(); + if (pValue) value_ = pValue->clone(); } Iptcdatum::Iptcdatum(const Iptcdatum& rhs) - : Metadatum(rhs), pValue_(0), modified_(false) + : Metadatum(rhs), modified_(false) { if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy - if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy + if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy } Iptcdatum::~Iptcdatum() { - delete pValue_; } Iptcdatum& Iptcdatum::operator=(const Iptcdatum& rhs) @@ -76,9 +75,8 @@ namespace Exiv2 { key_.reset(); if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy - delete pValue_; - pValue_ = 0; - if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy + value_.reset(); + if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy return *this; } // Iptcdatum::operator= @@ -86,15 +84,15 @@ namespace Exiv2 { void Iptcdatum::setValue(const Value* pValue) { modified_ = true; - delete pValue_; - pValue_ = pValue->clone(); + value_.reset(); + if (pValue) value_ = pValue->clone(); } void Iptcdatum::setValue(const std::string& buf) { modified_ = true; - if (pValue_ == 0) pValue_ = Value::create(string); - pValue_->read(buf); + if (value_.get() == 0) value_ = Value::create(string); + value_->read(buf); } const byte IptcData::marker_ = 0x1C; // Dataset marker @@ -179,23 +177,21 @@ namespace Exiv2 { int IptcData::readData(uint16_t dataSet, uint16_t record, const byte* data, uint32_t sizeData) { - Value* val = 0; + Value::AutoPtr value; try { - // If the type is unknown or the parse failes then + // If the type is unknown or the parse fails then // default to undefined type below. TypeId type = IptcDataSets::dataSetType(dataSet, record); - val = Value::create(type); - val->read(data, sizeData, bigEndian); + value = Value::create(type); + value->read(data, sizeData, bigEndian); } catch (const Error&) { // Default to loading as raw bytes - delete val; - val = Value::create(undefined); - val->read(data, sizeData, bigEndian); + value = Value::create(undefined); + value->read(data, sizeData, bigEndian); } IptcKey key(dataSet, record); - add(key, val); - delete val; + add(key, value.get()); return 0; } diff --git a/src/iptc.hpp b/src/iptc.hpp index d5480bf6..07159cd1 100644 --- a/src/iptc.hpp +++ b/src/iptc.hpp @@ -21,7 +21,7 @@ /*! @file iptc.hpp @brief Encoding and decoding of Iptc data - @version $Name: $ $Revision: 1.8 $ + @version $Name: $ $Revision: 1.9 $ @author Brad Schick (brad) schick@robotbattle.com @date 31-Jul-04, brad: created @@ -68,7 +68,7 @@ namespace Exiv2 { to a tag number and record id. */ explicit Iptcdatum(const IptcKey& key, - const Value* value =0); + const Value* pValue =0); //! Copy constructor Iptcdatum(const Iptcdatum& rhs); //! Destructor @@ -106,7 +106,7 @@ namespace Exiv2 { @return Number of characters written. */ long copy(byte* buf, ByteOrder byteOrder) const - { return pValue_ == 0 ? 0 : pValue_->copy(buf, byteOrder); } + { return value_.get() == 0 ? 0 : value_->copy(buf, byteOrder); } /*! @brief Return the key of the Iptcdatum. The key is of the form 'Iptc.recordName.datasetName'. Note however that the key @@ -139,20 +139,20 @@ namespace Exiv2 { { return key_.get() == 0 ? 0 : key_->tag(); } //! Return the type id of the value TypeId typeId() const - { return pValue_ == 0 ? invalidTypeId : pValue_->typeId(); } + { return value_.get() == 0 ? invalidTypeId : value_->typeId(); } //! Return the name of the type const char* typeName() const { return TypeInfo::typeName(typeId()); } //! Return the size in bytes of one component of this type long typeSize() const { return TypeInfo::typeSize(typeId()); } //! Return the number of components in the value - long count() const { return pValue_ == 0 ? 0 : pValue_->count(); } + long count() const { return value_.get() == 0 ? 0 : value_->count(); } //! Return the size of the value in bytes - long size() const { return pValue_ == 0 ? 0 : pValue_->size(); } + long size() const { return value_.get() == 0 ? 0 : value_->size(); } //! Return true if value was modified, otherwise false bool modified() const { return modified_; } //! Return the value as a string. std::string toString() const - { return pValue_ == 0 ? "" : pValue_->toString(); } + { return value_.get() == 0 ? "" : value_->toString(); } /*! @brief Return the n-th component of the value converted to long. The return value is -1 if the value of the Iptcdatum is not set and @@ -160,7 +160,7 @@ namespace Exiv2 { component. */ long toLong(long n =0) const - { return pValue_ == 0 ? -1 : pValue_->toLong(n); } + { return value_.get() == 0 ? -1 : value_->toLong(n); } /*! @brief Return the n-th component of the value converted to float. The return value is -1 if the value of the Iptcdatum is not set and @@ -168,7 +168,7 @@ namespace Exiv2 { component. */ float toFloat(long n =0) const - { return pValue_ == 0 ? -1 : pValue_->toFloat(n); } + { return value_.get() == 0 ? -1 : value_->toFloat(n); } /*! @brief Return the n-th component of the value converted to Rational. The return value is -1/1 if the value of the @@ -176,7 +176,7 @@ namespace Exiv2 { undefined if there is no n-th component. */ Rational toRational(long n =0) const - { return pValue_ == 0 ? Rational(-1, 1) : pValue_->toRational(n); } + { return value_.get() == 0 ? Rational(-1, 1) : value_->toRational(n); } /*! @brief Return a pointer to a copy (clone) of the value. The caller is responsible to delete this copy when it's no longer needed. @@ -189,7 +189,8 @@ namespace Exiv2 { @return A pointer to a copy (clone) of the value, 0 if the value is not set. */ - Value* getValue() const { return pValue_ == 0 ? 0 : pValue_->clone(); } + Value::AutoPtr getValue() const + { return value_.get() == 0 ? Value::AutoPtr(0) : value_->clone(); } /*! @brief Return a constant reference to the value. @@ -210,7 +211,7 @@ namespace Exiv2 { @throw Error ("Value not set") if the value is not set. */ const Value& value() const - { if (pValue_) return *pValue_; throw Error("Value not set"); } + { if (value_.get() != 0) return *value_; throw Error("Value not set"); } //@} /*! @@ -221,9 +222,9 @@ namespace Exiv2 { private: // DATA - IptcKey::AutoPtr key_; //!< Key - Value* pValue_; //!< Pointer to the value - bool modified_; //!< Change indicator + IptcKey::AutoPtr key_; //!< Key + Value::AutoPtr value_; //!< Value + bool modified_; //!< Change indicator }; // class Iptcdatum diff --git a/src/iptctest.cpp b/src/iptctest.cpp index 5f849d02..3e3702e5 100644 --- a/src/iptctest.cpp +++ b/src/iptctest.cpp @@ -4,7 +4,7 @@ This is not designed to be a robust application. File : iptctest.cpp - Version : $Name: $ $Revision: 1.4 $ + Version : $Name: $ $Revision: 1.5 $ Author(s): Brad Schick (brad) History : 01-Aug-04, brad: created */ @@ -113,10 +113,10 @@ void processAdd(const std::string& line, int num) data = data.substr(1, data.size()-2); } TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); - Value *val = Value::create(type); - val->read(data); + Value::AutoPtr value = Value::create(type); + value->read(data); - int rc = g_iptcData.add(iptcKey, val); + int rc = g_iptcData.add(iptcKey, value.get()); if (rc) { std::string error = IptcData::strError(rc, "Input file"); throw Error(error); @@ -166,15 +166,15 @@ void processModify(const std::string& line, int num) data = data.substr(1, data.size()-2); } TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); - Value *val = Value::create(type); - val->read(data); + Value::AutoPtr value = Value::create(type); + value->read(data); IptcData::iterator iter = g_iptcData.findId(iptcKey.tag(), iptcKey.record()); if (iter != g_iptcData.end()) { - iter->setValue(val); + iter->setValue(value.get()); } else { - int rc = g_iptcData.add(iptcKey, val); + int rc = g_iptcData.add(iptcKey, value.get()); if (rc) { std::string error = IptcData::strError(rc, "Input file"); throw Error(error); diff --git a/src/metadatum.hpp b/src/metadatum.hpp index c70194d4..c7efd157 100644 --- a/src/metadatum.hpp +++ b/src/metadatum.hpp @@ -21,7 +21,7 @@ /*! @file metadatum.hpp @brief Provides abstract base classes Metadatum and Key - @version $Name: $ $Revision: 1.4 $ + @version $Name: $ $Revision: 1.5 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Brad Schick (brad) @@ -208,18 +208,19 @@ namespace Exiv2 { */ virtual Rational toRational(long n =0) const =0; /*! - @brief Return a pointer to a copy (clone) of the value. The caller - is responsible to delete this copy when it's no longer needed. + @brief Return an auto-pointer to a copy (clone) of the value. The + caller owns this copy and the auto-poiner ensures that it will + be deleted. This method is provided for users who need full control over the value. A caller may, e.g., downcast the pointer to the appropriate subclass of Value to make use of the interface of the subclass to set or modify its contents. - @return A pointer to a copy (clone) of the value, 0 if the value is - not set. + @return An auto-pointer containing a pointer to a copy (clone) of the + value, 0 if the value is not set. */ - virtual Value* getValue() const =0; + virtual Value::AutoPtr getValue() const =0; /*! @brief Return a constant reference to the value. diff --git a/src/value.cpp b/src/value.cpp index 5a73b61b..7623f144 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -20,7 +20,7 @@ */ /* File: value.cpp - Version: $Name: $ $Revision: 1.14 $ + Version: $Name: $ $Revision: 1.15 $ Author(s): Andreas Huggel (ahu) History: 26-Jan-04, ahu: created 11-Feb-04, ahu: isolated as a component @@ -28,7 +28,7 @@ */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.14 $ $RCSfile: value.cpp,v $"); +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.15 $ $RCSfile: value.cpp,v $"); // ***************************************************************************** // included header files @@ -54,54 +54,54 @@ namespace Exiv2 { return *this; } - Value* Value::create(TypeId typeId) + Value::AutoPtr Value::create(TypeId typeId) { - Value* value = 0; + AutoPtr value; switch (typeId) { case invalidTypeId: - value = new DataValue(invalidTypeId); + value = AutoPtr(new DataValue(invalidTypeId)); break; case unsignedByte: - value = new DataValue(unsignedByte); + value = AutoPtr(new DataValue(unsignedByte)); break; case asciiString: - value = new AsciiValue; + value = AutoPtr(new AsciiValue); break; case unsignedShort: - value = new ValueType; + value = AutoPtr(new ValueType); break; case unsignedLong: - value = new ValueType; + value = AutoPtr(new ValueType); break; case unsignedRational: - value = new ValueType; + value = AutoPtr(new ValueType); break; case invalid6: - value = new DataValue(invalid6); + value = AutoPtr(new DataValue(invalid6)); break; case undefined: - value = new DataValue; + value = AutoPtr(new DataValue); break; case signedShort: - value = new ValueType; + value = AutoPtr(new ValueType); break; case signedLong: - value = new ValueType; + value = AutoPtr(new ValueType); break; case signedRational: - value = new ValueType; + value = AutoPtr(new ValueType); break; case string: - value = new StringValue; + value = AutoPtr(new StringValue); break; case date: - value = new DateValue; + value = AutoPtr(new DateValue); break; case time: - value = new TimeValue; + value = AutoPtr(new TimeValue); break; default: - value = new DataValue(typeId); + value = AutoPtr(new DataValue(typeId)); break; } return value; @@ -151,7 +151,7 @@ namespace Exiv2 { return static_cast(value_.size()); } - DataValue* DataValue::clone() const + DataValue* DataValue::clone_() const { return new DataValue(*this); } @@ -209,7 +209,7 @@ namespace Exiv2 { return *this; } - StringValue* StringValue::clone() const + StringValue* StringValue::clone_() const { return new StringValue(*this); } @@ -234,7 +234,7 @@ namespace Exiv2 { if (value_[value_.size()-1] != '\0') value_ += '\0'; } - AsciiValue* AsciiValue::clone() const + AsciiValue* AsciiValue::clone_() const { return new AsciiValue(*this); } @@ -311,7 +311,7 @@ namespace Exiv2 { return 8; } - DateValue* DateValue::clone() const + DateValue* DateValue::clone_() const { return new DateValue(*this); } @@ -419,7 +419,7 @@ namespace Exiv2 { return 11; } - TimeValue* TimeValue::clone() const + TimeValue* TimeValue::clone_() const { return new TimeValue(*this); } diff --git a/src/value.hpp b/src/value.hpp index 8b04befb..1b5ec772 100644 --- a/src/value.hpp +++ b/src/value.hpp @@ -21,7 +21,7 @@ /*! @file value.hpp @brief Value interface and concrete subclasses - @version $Name: $ $Revision: 1.16 $ + @version $Name: $ $Revision: 1.17 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created @@ -40,6 +40,7 @@ #include #include #include +#include // ***************************************************************************** // namespace extensions @@ -59,6 +60,9 @@ namespace Exiv2 { */ class Value { public: + //! Shortcut for a %Value auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ //! Constructor, taking a type id to initialize the base class with @@ -101,6 +105,12 @@ namespace Exiv2 { write(std::ostream& os) const of the concrete class. */ std::string toString() const; + /*! + @brief Return an auto-pointer to a copy of itself (deep copy). + The caller owns this copy and the auto-pointer ensures that + it will be deleted. + */ + AutoPtr clone() const { return AutoPtr(clone_()); } /*! @brief Write value to a data buffer. @@ -116,11 +126,6 @@ namespace Exiv2 { virtual long count() const =0; //! Return the size of the value in bytes virtual long size() const =0; - /*! - @brief Return a pointer to a copy of itself (deep copy). - The caller owns this copy and is responsible to delete it! - */ - virtual Value* clone() const =0; /*! @brief Write the value to an output stream. You do not usually have to use this function; it is used for the implementation of @@ -159,29 +164,29 @@ namespace Exiv2 { The following Value subclasses are created depending on typeId:

- - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +
typeId%Value subclass
invalidTypeId%DataValue(invalidTypeId)
unsignedByte%DataValue(unsignedByte)
asciiString%AsciiValue
string%StringValue
unsignedShort%ValueType < uint16_t >
unsignedLong%ValueType < uint32_t >
unsignedRational%ValueType < URational >
invalid6%DataValue(invalid6)
undefined%DataValue
signedShort%ValueType < int16_t >
signedLong%ValueType < int32_t >
signedRational%ValueType < Rational >
date%DateValue
time%TimeValue
default:%DataValue(typeId)
typeId%Value subclass
invalidTypeId%DataValue(invalidTypeId)
unsignedByte%DataValue(unsignedByte)
asciiString%AsciiValue
string%StringValue
unsignedShort%ValueType < uint16_t >
unsignedLong%ValueType < uint32_t >
unsignedRational%ValueType < URational >
invalid6%DataValue(invalid6)
undefined%DataValue
signedShort%ValueType < int16_t >
signedLong%ValueType < int32_t >
signedRational%ValueType < Rational >
date%DateValue
time%TimeValue
default:%DataValue(typeId)
@param typeId Type of the value. - @return Pointer to the newly created Value. - The caller owns this copy and is responsible to delete it! + @return Auto-pointer to the newly created Value. The caller owns this + copy and the auto-pointer ensures that it will be deleted. */ - static Value* create(TypeId typeId); + static AutoPtr create(TypeId typeId); protected: /*! @@ -191,6 +196,9 @@ namespace Exiv2 { Value& operator=(const Value& rhs); private: + //! Internal virtual copy constructor. + virtual Value* clone_() const =0; + // DATA TypeId type_; //!< Type of the data }; // class Value @@ -204,6 +212,9 @@ namespace Exiv2 { //! %Value for an undefined data type. class DataValue : public Value { public: + //! Shortcut for a %DataValue auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ //! Default constructor. @@ -239,7 +250,8 @@ namespace Exiv2 { //@} //! @name Accessors - //@{ + //@{ + AutoPtr clone() const { return AutoPtr(clone_()); } /*! @brief Write value to a character data buffer. @@ -256,7 +268,6 @@ namespace Exiv2 { virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const; virtual long count() const { return size(); } virtual long size() const; - virtual DataValue* clone() const; virtual std::ostream& write(std::ostream& os) const; virtual long toLong(long n =0) const { return value_[n]; } virtual float toFloat(long n =0) const { return value_[n]; } @@ -265,6 +276,9 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + virtual DataValue* clone_() const; + // DATA std::vector value_; }; // class DataValue @@ -277,6 +291,9 @@ namespace Exiv2 { */ class StringValueBase : public Value { public: + //! Shortcut for a %StringValueBase auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ //! Constructor for subclasses @@ -316,6 +333,7 @@ namespace Exiv2 { //! @name Accessors //@{ + AutoPtr clone() const { return AutoPtr(clone_()); } /*! @brief Write value to a character data buffer. @@ -337,11 +355,12 @@ namespace Exiv2 { virtual Rational toRational(long n =0) const { return Rational(value_[n], 1); } virtual std::ostream& write(std::ostream& os) const; - - virtual StringValueBase* clone() const =0; //@} protected: + //! Internal virtual copy constructor. + virtual StringValueBase* clone_() const =0; + // DATA std::string value_; //!< Stores the string value. }; // class StringValueBase @@ -355,6 +374,9 @@ namespace Exiv2 { */ class StringValue : public StringValueBase { public: + //! Shortcut for a %StringValue auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ //! Default constructor. @@ -377,9 +399,13 @@ namespace Exiv2 { //! @name Accessors //@{ - virtual StringValue* clone() const; + AutoPtr clone() const { return AutoPtr(clone_()); } //@} + private: + //! Internal virtual copy constructor. + virtual StringValue* clone_() const; + }; // class StringValue /*! @@ -390,6 +416,9 @@ namespace Exiv2 { */ class AsciiValue : public StringValueBase { public: + //! Shortcut for a %AsciiValue auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ //! Default constructor. @@ -433,7 +462,7 @@ namespace Exiv2 { //! @name Accessors //@{ - virtual AsciiValue* clone() const; + AutoPtr clone() const { return AutoPtr(clone_()); } /*! @brief Write the value to an output stream. Any trailing '\\0' characters of the ASCII value are stripped and not written to @@ -441,6 +470,11 @@ namespace Exiv2 { */ virtual std::ostream& write(std::ostream& os) const; //@} + + private: + //! Internal virtual copy constructor. + virtual AsciiValue* clone_() const; + }; // class AsciiValue /*! @@ -451,6 +485,9 @@ namespace Exiv2 { */ class DateValue : public Value { public: + //! Shortcut for a %DateValue auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ //! Default constructor. @@ -496,6 +533,7 @@ namespace Exiv2 { //! @name Accessors //@{ + AutoPtr clone() const { return AutoPtr(clone_()); } /*! @brief Write value to a character data buffer. @@ -514,7 +552,6 @@ namespace Exiv2 { virtual const Date& getDate() const { return date_; } virtual long count() const { return size(); } virtual long size() const; - virtual DateValue* clone() const; /*! @brief Write the value to an output stream. . */ @@ -527,6 +564,9 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + virtual DateValue* clone_() const; + // DATA Date date_; }; // class DateValue @@ -541,6 +581,9 @@ namespace Exiv2 { */ class TimeValue : public Value { public: + //! Shortcut for a %TimeValue auto pointer. + typedef std::auto_ptr AutoPtr; + //! @name Creators //@{ //! Default constructor. @@ -590,6 +633,7 @@ namespace Exiv2 { //! @name Accessors //@{ + AutoPtr clone() const { return AutoPtr(clone_()); } /*! @brief Write value to a character data buffer. @@ -608,7 +652,6 @@ namespace Exiv2 { virtual const Time& getTime() const { return time_; } virtual long count() const { return size(); } virtual long size() const; - virtual TimeValue* clone() const; /*! @brief Write the value to an output stream. . */ @@ -621,6 +664,9 @@ namespace Exiv2 { //@} private: + //! Internal virtual copy constructor. + virtual TimeValue* clone_() const; + // DATA Time time_; }; // class TimeValue @@ -650,6 +696,9 @@ namespace Exiv2 { template class ValueType : public Value { public: + //! Shortcut for a %ValueType auto pointer. + typedef std::auto_ptr > AutoPtr; + //! @name Creators //@{ //! Default constructor. @@ -679,10 +728,10 @@ namespace Exiv2 { //! @name Accessors //@{ + AutoPtr clone() const { return AutoPtr(clone_()); } virtual long copy(byte* buf, ByteOrder byteOrder) const; virtual long count() const { return static_cast(value_.size()); } virtual long size() const; - virtual ValueType* clone() const; virtual std::ostream& write(std::ostream& os) const; virtual long toLong(long n =0) const; virtual float toFloat(long n =0) const; @@ -696,6 +745,7 @@ namespace Exiv2 { //! Const iterator type defined for convenience. typedef typename std::vector::const_iterator const_iterator; + // DATA /*! @brief The container for all values. In your application, if you know what subclass of Value you're dealing with (and possibly the T) @@ -704,6 +754,10 @@ namespace Exiv2 { */ ValueList value_; + private: + //! Internal virtual copy constructor. + virtual ValueType* clone_() const; + }; // class ValueType //! Unsigned short value type @@ -895,7 +949,7 @@ namespace Exiv2 { } template - ValueType* ValueType::clone() const + ValueType* ValueType::clone_() const { return new ValueType(*this); }