Converted Value hierarchy to use std::auto_ptr where appropriate

v0.27.3
Andreas Huggel 21 years ago
parent bf31f186e0
commit 44d0deac92

@ -3,7 +3,7 @@
Abstract: Sample program showing how to add, modify and delete Exif metadata. Abstract: Sample program showing how to add, modify and delete Exif metadata.
File: addmoddel.cpp File: addmoddel.cpp
Version: $Name: $ $Revision: 1.4 $ Version: $Name: $ $Revision: 1.5 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 26-Jan-04, ahu: created History: 26-Jan-04, ahu: created
*/ */
@ -24,19 +24,16 @@ try {
// Add to the Exif data // Add to the Exif data
// Create a ASCII string value (note the use of create) // 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 // Set the value to a string
v->read("1999:12:31 23:59:59"); v->read("1999:12:31 23:59:59");
// Add the value together with its key to the Exif data container // Add the value together with its key to the Exif data container
Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal"); Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal");
exifData.add(key, v); exifData.add(key, v.get());
std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n"; 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) // 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 // Set two rational components from a string
rv->read("1/2 1/3"); rv->read("1/2 1/3");
// Add more elements through the extended interface of rational value // Add more elements through the extended interface of rational value
@ -44,11 +41,8 @@ try {
rv->value_.push_back(std::make_pair(3,4)); rv->value_.push_back(std::make_pair(3,4));
// Add the key and value pair to the Exif data // Add the key and value pair to the Exif data
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
exifData.add(key, rv); exifData.add(key, rv.get());
std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n"; std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n";
// Delete memory allocated on the heap
delete rv;
// ************************************************************************* // *************************************************************************
// Modify Exif data // Modify Exif data
@ -59,8 +53,8 @@ try {
if (pos == exifData.end()) throw Exiv2::Error("Key not found"); if (pos == exifData.end()) throw Exiv2::Error("Key not found");
// Modify the value // Modify the value
std::string date = pos->toString(); std::string date = pos->toString();
date.replace(0,4,"2000"); date.replace(0, 4, "2000");
pos->setValue(date); pos->setValue(date);
std::cout << "Modified key \"" << key std::cout << "Modified key \"" << key
<< "\", new value \"" << pos->value() << "\"\n"; << "\", new value \"" << pos->value() << "\"\n";
@ -71,14 +65,13 @@ try {
// Get a pointer to a copy of the value // Get a pointer to a copy of the value
v = pos->getValue(); v = pos->getValue();
// Downcast the Value pointer to its actual type // Downcast the Value pointer to its actual type
rv = dynamic_cast<Exiv2::URationalValue*>(v); Exiv2::URationalValue* prv = dynamic_cast<Exiv2::URationalValue*>(v.release());
if (rv == 0) throw Exiv2::Error("Downcast failed"); if (prv == 0) throw Exiv2::Error("Downcast failed");
rv = Exiv2::URationalValue::AutoPtr(prv);
// Modify the value directly through the interface of URationalValue // Modify the value directly through the interface of URationalValue
rv->value_[2] = std::make_pair(88,77); rv->value_[2] = std::make_pair(88,77);
// Copy the modified value back to the metadatum // Copy the modified value back to the metadatum
pos->setValue(rv); pos->setValue(rv.get());
// Delete the memory allocated by getValue
delete v;
std::cout << "Modified key \"" << key std::cout << "Modified key \"" << key
<< "\", new value \"" << pos->value() << "\"\n"; << "\", new value \"" << pos->value() << "\"\n";

@ -20,14 +20,14 @@
*/ */
/* /*
File: exif.cpp File: exif.cpp
Version: $Name: $ $Revision: 1.66 $ Version: $Name: $ $Revision: 1.67 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 26-Jan-04, ahu: created History: 26-Jan-04, ahu: created
11-Feb-04, ahu: isolated as a component 11-Feb-04, ahu: isolated as a component
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #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 // Define DEBUG_MAKERNOTE to output debug information to std::cerr
#undef DEBUG_MAKERNOTE #undef DEBUG_MAKERNOTE
@ -74,28 +74,27 @@ namespace {
namespace Exiv2 { namespace Exiv2 {
Exifdatum::Exifdatum(const Entry& e, ByteOrder byteOrder) 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())); value_ = Value::create(TypeId(e.type()));
pValue_->read(e.data(), e.count() * e.typeSize(), byteOrder); value_->read(e.data(), e.count() * e.typeSize(), byteOrder);
} }
Exifdatum::Exifdatum(const ExifKey& key, const Value* pValue) 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() Exifdatum::~Exifdatum()
{ {
delete pValue_;
} }
Exifdatum::Exifdatum(const Exifdatum& rhs) Exifdatum::Exifdatum(const Exifdatum& rhs)
: Metadatum(rhs), pValue_(0) : Metadatum(rhs)
{ {
if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy 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) Exifdatum& Exifdatum::operator=(const Exifdatum& rhs)
@ -106,30 +105,28 @@ namespace Exiv2 {
key_.reset(); key_.reset();
if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy
delete pValue_; value_.reset();
pValue_ = 0; if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy
if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy
return *this; return *this;
} // Exifdatum::operator= } // Exifdatum::operator=
void Exifdatum::setValue(const Value* pValue) void Exifdatum::setValue(const Value* pValue)
{ {
delete pValue_; value_.reset();
pValue_ = pValue->clone(); if (pValue) value_ = pValue->clone();
} }
void Exifdatum::setValue(const Entry& e, ByteOrder byteOrder) void Exifdatum::setValue(const Entry& e, ByteOrder byteOrder)
{ {
delete pValue_; value_ = Value::create(TypeId(e.type()));
pValue_ = Value::create(TypeId(e.type())); value_->read(e.data(), e.count() * e.typeSize(), byteOrder);
pValue_->read(e.data(), e.count() * e.typeSize(), byteOrder);
} }
void Exifdatum::setValue(const std::string& buf) void Exifdatum::setValue(const std::string& buf)
{ {
if (pValue_ == 0) pValue_ = Value::create(asciiString); if (value_.get() == 0) value_ = Value::create(asciiString);
pValue_->read(buf); value_->read(buf);
} }
TiffThumbnail::TiffThumbnail() TiffThumbnail::TiffThumbnail()
@ -443,9 +440,8 @@ namespace Exiv2 {
ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat"); ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat");
ExifData::iterator pos = exifData.findKey(key); ExifData::iterator pos = exifData.findKey(key);
if (pos == exifData.end()) { if (pos == exifData.end()) {
Value* value = Value::create(unsignedLong); Value::AutoPtr value = Value::create(unsignedLong);
exifData.add(key, value); exifData.add(key, value.get());
delete value;
pos = exifData.findKey(key); pos = exifData.findKey(key);
} }
pos->setValue(toString(offset_)); pos->setValue(toString(offset_));
@ -453,9 +449,8 @@ namespace Exiv2 {
ExifKey key2("Exif.Thumbnail.JPEGInterchangeFormatLength"); ExifKey key2("Exif.Thumbnail.JPEGInterchangeFormatLength");
pos = exifData.findKey(key2); pos = exifData.findKey(key2);
if (pos == exifData.end()) { if (pos == exifData.end()) {
Value *value = Value::create(unsignedLong); Value::AutoPtr value = Value::create(unsignedLong);
exifData.add(key2, value); exifData.add(key2, value.get());
delete value;
pos = exifData.findKey(key2); pos = exifData.findKey(key2);
} }
pos->setValue(toString(size_)); 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)); add(Exifdatum(key, pValue));
} }

@ -21,7 +21,7 @@
/*! /*!
@file exif.hpp @file exif.hpp
@brief Encoding and decoding of Exif data @brief Encoding and decoding of Exif data
@version $Name: $ $Revision: 1.57 $ @version $Name: $ $Revision: 1.58 $
@author Andreas Huggel (ahu) @author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a> <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 09-Jan-04, ahu: created @date 09-Jan-04, ahu: created
@ -148,10 +148,10 @@ namespace Exiv2 {
@return Number of characters written. @return Number of characters written.
*/ */
long copy(byte* buf, ByteOrder byteOrder) const 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 //! Return the type id of the value
TypeId typeId() const TypeId typeId() const
{ return pValue_ == 0 ? invalidTypeId : pValue_->typeId(); } { return value_.get() == 0 ? invalidTypeId : value_->typeId(); }
//! Return the name of the type //! Return the name of the type
const char* typeName() const const char* typeName() const
{ return TypeInfo::typeName(typeId()); } { return TypeInfo::typeName(typeId()); }
@ -160,13 +160,13 @@ namespace Exiv2 {
{ return TypeInfo::typeSize(typeId()); } { return TypeInfo::typeSize(typeId()); }
//! Return the number of components in the value //! Return the number of components in the value
long count() const long count() const
{ return pValue_ == 0 ? 0 : pValue_->count(); } { return value_.get() == 0 ? 0 : value_->count(); }
//! Return the size of the value in bytes //! Return the size of the value in bytes
long size() const long size() const
{ return pValue_ == 0 ? 0 : pValue_->size(); } { return value_.get() == 0 ? 0 : value_->size(); }
//! Return the value as a string. //! Return the value as a string.
std::string toString() const 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 @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 return value is -1 if the value of the Exifdatum is not set and
@ -174,7 +174,7 @@ namespace Exiv2 {
component. component.
*/ */
long toLong(long n =0) const 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 @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 return value is -1 if the value of the Exifdatum is not set and
@ -182,7 +182,7 @@ namespace Exiv2 {
component. component.
*/ */
float toFloat(long n =0) const 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 @brief Return the n-th component of the value converted to
Rational. The return value is -1/1 if the value of the 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. undefined if there is no n-th component.
*/ */
Rational toRational(long n =0) const 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 @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. 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 @return A pointer to a copy (clone) of the value, 0 if the value is
not set. not set.
*/ */
Value* getValue() const Value::AutoPtr getValue() const
{ return pValue_ == 0 ? 0 : pValue_->clone(); } { return value_.get() == 0 ? Value::AutoPtr(0) : value_->clone(); }
/*! /*!
@brief Return a constant reference to the value. @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. @throw Error ("Value not set") if the value is not set.
*/ */
const Value& value() const 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: private:
// DATA // DATA
ExifKey::AutoPtr key_; //!< Key ExifKey::AutoPtr key_; //!< Key
Value* pValue_; //!< Pointer to the value Value::AutoPtr value_; //!< Value
}; // class Exifdatum }; // class Exifdatum
@ -582,7 +582,7 @@ namespace Exiv2 {
performed, i.e., it is possible to add multiple metadata with performed, i.e., it is possible to add multiple metadata with
the same key. 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 @brief Add a copy of the Exifdatum to the Exif metadata. No
duplicate checks are performed, i.e., it is possible to add duplicate checks are performed, i.e., it is possible to add

@ -20,13 +20,13 @@
*/ */
/* /*
File: iptc.cpp File: iptc.cpp
Version: $Name: $ $Revision: 1.8 $ Version: $Name: $ $Revision: 1.9 $
Author(s): Brad Schick (brad) <schick@robotbattle.com> Author(s): Brad Schick (brad) <schick@robotbattle.com>
History: 31-July-04, brad: created History: 31-July-04, brad: created
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #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 // Define DEBUG_MAKERNOTE to output debug information to std::cerr
#undef DEBUG_MAKERNOTE #undef DEBUG_MAKERNOTE
@ -49,22 +49,21 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: iptc.cpp,v $");
namespace Exiv2 { namespace Exiv2 {
Iptcdatum::Iptcdatum(const IptcKey& key, Iptcdatum::Iptcdatum(const IptcKey& key,
const Value* value) const Value* pValue)
: key_(key.clone()), pValue_(0), modified_(false) : key_(key.clone()), modified_(false)
{ {
if (value) pValue_ = value->clone(); if (pValue) value_ = pValue->clone();
} }
Iptcdatum::Iptcdatum(const Iptcdatum& rhs) 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.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() Iptcdatum::~Iptcdatum()
{ {
delete pValue_;
} }
Iptcdatum& Iptcdatum::operator=(const Iptcdatum& rhs) Iptcdatum& Iptcdatum::operator=(const Iptcdatum& rhs)
@ -76,9 +75,8 @@ namespace Exiv2 {
key_.reset(); key_.reset();
if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy
delete pValue_; value_.reset();
pValue_ = 0; if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy
if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy
return *this; return *this;
} // Iptcdatum::operator= } // Iptcdatum::operator=
@ -86,15 +84,15 @@ namespace Exiv2 {
void Iptcdatum::setValue(const Value* pValue) void Iptcdatum::setValue(const Value* pValue)
{ {
modified_ = true; modified_ = true;
delete pValue_; value_.reset();
pValue_ = pValue->clone(); if (pValue) value_ = pValue->clone();
} }
void Iptcdatum::setValue(const std::string& buf) void Iptcdatum::setValue(const std::string& buf)
{ {
modified_ = true; modified_ = true;
if (pValue_ == 0) pValue_ = Value::create(string); if (value_.get() == 0) value_ = Value::create(string);
pValue_->read(buf); value_->read(buf);
} }
const byte IptcData::marker_ = 0x1C; // Dataset marker const byte IptcData::marker_ = 0x1C; // Dataset marker
@ -179,23 +177,21 @@ namespace Exiv2 {
int IptcData::readData(uint16_t dataSet, uint16_t record, int IptcData::readData(uint16_t dataSet, uint16_t record,
const byte* data, uint32_t sizeData) const byte* data, uint32_t sizeData)
{ {
Value* val = 0; Value::AutoPtr value;
try { 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. // default to undefined type below.
TypeId type = IptcDataSets::dataSetType(dataSet, record); TypeId type = IptcDataSets::dataSetType(dataSet, record);
val = Value::create(type); value = Value::create(type);
val->read(data, sizeData, bigEndian); value->read(data, sizeData, bigEndian);
} }
catch (const Error&) { catch (const Error&) {
// Default to loading as raw bytes // Default to loading as raw bytes
delete val; value = Value::create(undefined);
val = Value::create(undefined); value->read(data, sizeData, bigEndian);
val->read(data, sizeData, bigEndian);
} }
IptcKey key(dataSet, record); IptcKey key(dataSet, record);
add(key, val); add(key, value.get());
delete val;
return 0; return 0;
} }

@ -21,7 +21,7 @@
/*! /*!
@file iptc.hpp @file iptc.hpp
@brief Encoding and decoding of Iptc data @brief Encoding and decoding of Iptc data
@version $Name: $ $Revision: 1.8 $ @version $Name: $ $Revision: 1.9 $
@author Brad Schick (brad) @author Brad Schick (brad)
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a> <a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
@date 31-Jul-04, brad: created @date 31-Jul-04, brad: created
@ -68,7 +68,7 @@ namespace Exiv2 {
to a tag number and record id. to a tag number and record id.
*/ */
explicit Iptcdatum(const IptcKey& key, explicit Iptcdatum(const IptcKey& key,
const Value* value =0); const Value* pValue =0);
//! Copy constructor //! Copy constructor
Iptcdatum(const Iptcdatum& rhs); Iptcdatum(const Iptcdatum& rhs);
//! Destructor //! Destructor
@ -106,7 +106,7 @@ namespace Exiv2 {
@return Number of characters written. @return Number of characters written.
*/ */
long copy(byte* buf, ByteOrder byteOrder) const 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 @brief Return the key of the Iptcdatum. The key is of the form
'<b>Iptc</b>.recordName.datasetName'. Note however that the key '<b>Iptc</b>.recordName.datasetName'. Note however that the key
@ -139,20 +139,20 @@ namespace Exiv2 {
{ return key_.get() == 0 ? 0 : key_->tag(); } { return key_.get() == 0 ? 0 : key_->tag(); }
//! Return the type id of the value //! Return the type id of the value
TypeId typeId() const TypeId typeId() const
{ return pValue_ == 0 ? invalidTypeId : pValue_->typeId(); } { return value_.get() == 0 ? invalidTypeId : value_->typeId(); }
//! Return the name of the type //! Return the name of the type
const char* typeName() const { return TypeInfo::typeName(typeId()); } const char* typeName() const { return TypeInfo::typeName(typeId()); }
//! Return the size in bytes of one component of this type //! Return the size in bytes of one component of this type
long typeSize() const { return TypeInfo::typeSize(typeId()); } long typeSize() const { return TypeInfo::typeSize(typeId()); }
//! Return the number of components in the value //! 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 //! 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 //! Return true if value was modified, otherwise false
bool modified() const { return modified_; } bool modified() const { return modified_; }
//! Return the value as a string. //! Return the value as a string.
std::string toString() const 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 @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 return value is -1 if the value of the Iptcdatum is not set and
@ -160,7 +160,7 @@ namespace Exiv2 {
component. component.
*/ */
long toLong(long n =0) const 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 @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 return value is -1 if the value of the Iptcdatum is not set and
@ -168,7 +168,7 @@ namespace Exiv2 {
component. component.
*/ */
float toFloat(long n =0) const 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 @brief Return the n-th component of the value converted to
Rational. The return value is -1/1 if the value of the 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. undefined if there is no n-th component.
*/ */
Rational toRational(long n =0) const 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 @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. 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 @return A pointer to a copy (clone) of the value, 0 if the value is
not set. 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. @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. @throw Error ("Value not set") if the value is not set.
*/ */
const Value& value() const 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: private:
// DATA // DATA
IptcKey::AutoPtr key_; //!< Key IptcKey::AutoPtr key_; //!< Key
Value* pValue_; //!< Pointer to the value Value::AutoPtr value_; //!< Value
bool modified_; //!< Change indicator bool modified_; //!< Change indicator
}; // class Iptcdatum }; // class Iptcdatum

@ -4,7 +4,7 @@
This is not designed to be a robust application. This is not designed to be a robust application.
File : iptctest.cpp File : iptctest.cpp
Version : $Name: $ $Revision: 1.4 $ Version : $Name: $ $Revision: 1.5 $
Author(s): Brad Schick (brad) <schick@robotbattle.com> Author(s): Brad Schick (brad) <schick@robotbattle.com>
History : 01-Aug-04, brad: created 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); data = data.substr(1, data.size()-2);
} }
TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
Value *val = Value::create(type); Value::AutoPtr value = Value::create(type);
val->read(data); value->read(data);
int rc = g_iptcData.add(iptcKey, val); int rc = g_iptcData.add(iptcKey, value.get());
if (rc) { if (rc) {
std::string error = IptcData::strError(rc, "Input file"); std::string error = IptcData::strError(rc, "Input file");
throw Error(error); throw Error(error);
@ -166,15 +166,15 @@ void processModify(const std::string& line, int num)
data = data.substr(1, data.size()-2); data = data.substr(1, data.size()-2);
} }
TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record()); TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
Value *val = Value::create(type); Value::AutoPtr value = Value::create(type);
val->read(data); value->read(data);
IptcData::iterator iter = g_iptcData.findId(iptcKey.tag(), iptcKey.record()); IptcData::iterator iter = g_iptcData.findId(iptcKey.tag(), iptcKey.record());
if (iter != g_iptcData.end()) { if (iter != g_iptcData.end()) {
iter->setValue(val); iter->setValue(value.get());
} }
else { else {
int rc = g_iptcData.add(iptcKey, val); int rc = g_iptcData.add(iptcKey, value.get());
if (rc) { if (rc) {
std::string error = IptcData::strError(rc, "Input file"); std::string error = IptcData::strError(rc, "Input file");
throw Error(error); throw Error(error);

@ -21,7 +21,7 @@
/*! /*!
@file metadatum.hpp @file metadatum.hpp
@brief Provides abstract base classes Metadatum and Key @brief Provides abstract base classes Metadatum and Key
@version $Name: $ $Revision: 1.4 $ @version $Name: $ $Revision: 1.5 $
@author Andreas Huggel (ahu) @author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a> <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@author Brad Schick (brad) @author Brad Schick (brad)
@ -208,18 +208,19 @@ namespace Exiv2 {
*/ */
virtual Rational toRational(long n =0) const =0; virtual Rational toRational(long n =0) const =0;
/*! /*!
@brief Return a pointer to a copy (clone) of the value. The caller @brief Return an auto-pointer to a copy (clone) of the value. The
is responsible to delete this copy when it's no longer needed. 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 This method is provided for users who need full control over the
value. A caller may, e.g., downcast the pointer to the appropriate 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 subclass of Value to make use of the interface of the subclass to set
or modify its contents. or modify its contents.
@return A pointer to a copy (clone) of the value, 0 if the value is @return An auto-pointer containing a pointer to a copy (clone) of the
not set. 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. @brief Return a constant reference to the value.

@ -20,7 +20,7 @@
*/ */
/* /*
File: value.cpp File: value.cpp
Version: $Name: $ $Revision: 1.14 $ Version: $Name: $ $Revision: 1.15 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 26-Jan-04, ahu: created History: 26-Jan-04, ahu: created
11-Feb-04, ahu: isolated as a component 11-Feb-04, ahu: isolated as a component
@ -28,7 +28,7 @@
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #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 // included header files
@ -54,54 +54,54 @@ namespace Exiv2 {
return *this; return *this;
} }
Value* Value::create(TypeId typeId) Value::AutoPtr Value::create(TypeId typeId)
{ {
Value* value = 0; AutoPtr value;
switch (typeId) { switch (typeId) {
case invalidTypeId: case invalidTypeId:
value = new DataValue(invalidTypeId); value = AutoPtr(new DataValue(invalidTypeId));
break; break;
case unsignedByte: case unsignedByte:
value = new DataValue(unsignedByte); value = AutoPtr(new DataValue(unsignedByte));
break; break;
case asciiString: case asciiString:
value = new AsciiValue; value = AutoPtr(new AsciiValue);
break; break;
case unsignedShort: case unsignedShort:
value = new ValueType<uint16_t>; value = AutoPtr(new ValueType<uint16_t>);
break; break;
case unsignedLong: case unsignedLong:
value = new ValueType<uint32_t>; value = AutoPtr(new ValueType<uint32_t>);
break; break;
case unsignedRational: case unsignedRational:
value = new ValueType<URational>; value = AutoPtr(new ValueType<URational>);
break; break;
case invalid6: case invalid6:
value = new DataValue(invalid6); value = AutoPtr(new DataValue(invalid6));
break; break;
case undefined: case undefined:
value = new DataValue; value = AutoPtr(new DataValue);
break; break;
case signedShort: case signedShort:
value = new ValueType<int16_t>; value = AutoPtr(new ValueType<int16_t>);
break; break;
case signedLong: case signedLong:
value = new ValueType<int32_t>; value = AutoPtr(new ValueType<int32_t>);
break; break;
case signedRational: case signedRational:
value = new ValueType<Rational>; value = AutoPtr(new ValueType<Rational>);
break; break;
case string: case string:
value = new StringValue; value = AutoPtr(new StringValue);
break; break;
case date: case date:
value = new DateValue; value = AutoPtr(new DateValue);
break; break;
case time: case time:
value = new TimeValue; value = AutoPtr(new TimeValue);
break; break;
default: default:
value = new DataValue(typeId); value = AutoPtr(new DataValue(typeId));
break; break;
} }
return value; return value;
@ -151,7 +151,7 @@ namespace Exiv2 {
return static_cast<long>(value_.size()); return static_cast<long>(value_.size());
} }
DataValue* DataValue::clone() const DataValue* DataValue::clone_() const
{ {
return new DataValue(*this); return new DataValue(*this);
} }
@ -209,7 +209,7 @@ namespace Exiv2 {
return *this; return *this;
} }
StringValue* StringValue::clone() const StringValue* StringValue::clone_() const
{ {
return new StringValue(*this); return new StringValue(*this);
} }
@ -234,7 +234,7 @@ namespace Exiv2 {
if (value_[value_.size()-1] != '\0') value_ += '\0'; if (value_[value_.size()-1] != '\0') value_ += '\0';
} }
AsciiValue* AsciiValue::clone() const AsciiValue* AsciiValue::clone_() const
{ {
return new AsciiValue(*this); return new AsciiValue(*this);
} }
@ -311,7 +311,7 @@ namespace Exiv2 {
return 8; return 8;
} }
DateValue* DateValue::clone() const DateValue* DateValue::clone_() const
{ {
return new DateValue(*this); return new DateValue(*this);
} }
@ -419,7 +419,7 @@ namespace Exiv2 {
return 11; return 11;
} }
TimeValue* TimeValue::clone() const TimeValue* TimeValue::clone_() const
{ {
return new TimeValue(*this); return new TimeValue(*this);
} }

@ -21,7 +21,7 @@
/*! /*!
@file value.hpp @file value.hpp
@brief Value interface and concrete subclasses @brief Value interface and concrete subclasses
@version $Name: $ $Revision: 1.16 $ @version $Name: $ $Revision: 1.17 $
@author Andreas Huggel (ahu) @author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a> <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 09-Jan-04, ahu: created @date 09-Jan-04, ahu: created
@ -40,6 +40,7 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
@ -59,6 +60,9 @@ namespace Exiv2 {
*/ */
class Value { class Value {
public: public:
//! Shortcut for a %Value auto pointer.
typedef std::auto_ptr<Value> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Constructor, taking a type id to initialize the base class with //! 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. write(std::ostream& os) const of the concrete class.
*/ */
std::string toString() const; 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. @brief Write value to a data buffer.
@ -116,11 +126,6 @@ namespace Exiv2 {
virtual long count() const =0; virtual long count() const =0;
//! Return the size of the value in bytes //! Return the size of the value in bytes
virtual long size() const =0; 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 @brief Write the value to an output stream. You do not usually have
to use this function; it is used for the implementation of 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:<BR><BR> The following Value subclasses are created depending on typeId:<BR><BR>
<TABLE> <TABLE>
<TR><TD><B>typeId</B></TD><TD><B>%Value subclass</B></TD></TR> <TR><TD class="indexkey"><B>typeId</B></TD><TD class="indexvalue"><B>%Value subclass</B></TD></TR>
<TR><TD>invalidTypeId</TD><TD>%DataValue(invalidTypeId)</TD></TR> <TR><TD class="indexkey">invalidTypeId</TD><TD class="indexvalue">%DataValue(invalidTypeId)</TD></TR>
<TR><TD>unsignedByte</TD><TD>%DataValue(unsignedByte)</TD></TR> <TR><TD class="indexkey">unsignedByte</TD><TD class="indexvalue">%DataValue(unsignedByte)</TD></TR>
<TR><TD>asciiString</TD><TD>%AsciiValue</TD></TR> <TR><TD class="indexkey">asciiString</TD><TD class="indexvalue">%AsciiValue</TD></TR>
<TR><TD>string</TD><TD>%StringValue</TD></TR> <TR><TD class="indexkey">string</TD><TD class="indexvalue">%StringValue</TD></TR>
<TR><TD>unsignedShort</TD><TD>%ValueType &lt; uint16_t &gt;</TD></TR> <TR><TD class="indexkey">unsignedShort</TD><TD class="indexvalue">%ValueType &lt; uint16_t &gt;</TD></TR>
<TR><TD>unsignedLong</TD><TD>%ValueType &lt; uint32_t &gt;</TD></TR> <TR><TD class="indexkey">unsignedLong</TD><TD class="indexvalue">%ValueType &lt; uint32_t &gt;</TD></TR>
<TR><TD>unsignedRational</TD><TD>%ValueType &lt; URational &gt;</TD></TR> <TR><TD class="indexkey">unsignedRational</TD><TD class="indexvalue">%ValueType &lt; URational &gt;</TD></TR>
<TR><TD>invalid6</TD><TD>%DataValue(invalid6)</TD></TR> <TR><TD class="indexkey">invalid6</TD><TD class="indexvalue">%DataValue(invalid6)</TD></TR>
<TR><TD>undefined</TD><TD>%DataValue</TD></TR> <TR><TD class="indexkey">undefined</TD><TD class="indexvalue">%DataValue</TD></TR>
<TR><TD>signedShort</TD><TD>%ValueType &lt; int16_t &gt;</TD></TR> <TR><TD class="indexkey">signedShort</TD><TD class="indexvalue">%ValueType &lt; int16_t &gt;</TD></TR>
<TR><TD>signedLong</TD><TD>%ValueType &lt; int32_t &gt;</TD></TR> <TR><TD class="indexkey">signedLong</TD><TD class="indexvalue">%ValueType &lt; int32_t &gt;</TD></TR>
<TR><TD>signedRational</TD><TD>%ValueType &lt; Rational &gt;</TD></TR> <TR><TD class="indexkey">signedRational</TD><TD class="indexvalue">%ValueType &lt; Rational &gt;</TD></TR>
<TR><TD>date</TD><TD>%DateValue</TD></TR> <TR><TD class="indexkey">date</TD><TD class="indexvalue">%DateValue</TD></TR>
<TR><TD>time</TD><TD>%TimeValue</TD></TR> <TR><TD class="indexkey">time</TD><TD class="indexvalue">%TimeValue</TD></TR>
<TR><TD><EM>default:</EM></TD><TD>%DataValue(typeId)</TD></TR> <TR><TD class="indexkey"><EM>default:</EM></TD><TD class="indexvalue">%DataValue(typeId)</TD></TR>
</TABLE> </TABLE>
@param typeId Type of the value. @param typeId Type of the value.
@return Pointer to the newly created Value. @return Auto-pointer to the newly created Value. The caller owns this
The caller owns this copy and is responsible to delete it! copy and the auto-pointer ensures that it will be deleted.
*/ */
static Value* create(TypeId typeId); static AutoPtr create(TypeId typeId);
protected: protected:
/*! /*!
@ -191,6 +196,9 @@ namespace Exiv2 {
Value& operator=(const Value& rhs); Value& operator=(const Value& rhs);
private: private:
//! Internal virtual copy constructor.
virtual Value* clone_() const =0;
// DATA
TypeId type_; //!< Type of the data TypeId type_; //!< Type of the data
}; // class Value }; // class Value
@ -204,6 +212,9 @@ namespace Exiv2 {
//! %Value for an undefined data type. //! %Value for an undefined data type.
class DataValue : public Value { class DataValue : public Value {
public: public:
//! Shortcut for a %DataValue auto pointer.
typedef std::auto_ptr<DataValue> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Default constructor. //! Default constructor.
@ -239,7 +250,8 @@ namespace Exiv2 {
//@} //@}
//! @name Accessors //! @name Accessors
//@{ //@{
AutoPtr clone() const { return AutoPtr(clone_()); }
/*! /*!
@brief Write value to a character data buffer. @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 copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
virtual long count() const { return size(); } virtual long count() const { return size(); }
virtual long size() const; virtual long size() const;
virtual DataValue* clone() const;
virtual std::ostream& write(std::ostream& os) const; virtual std::ostream& write(std::ostream& os) const;
virtual long toLong(long n =0) const { return value_[n]; } virtual long toLong(long n =0) const { return value_[n]; }
virtual float toFloat(long n =0) const { return value_[n]; } virtual float toFloat(long n =0) const { return value_[n]; }
@ -265,6 +276,9 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
virtual DataValue* clone_() const;
// DATA
std::vector<byte> value_; std::vector<byte> value_;
}; // class DataValue }; // class DataValue
@ -277,6 +291,9 @@ namespace Exiv2 {
*/ */
class StringValueBase : public Value { class StringValueBase : public Value {
public: public:
//! Shortcut for a %StringValueBase auto pointer.
typedef std::auto_ptr<StringValueBase> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Constructor for subclasses //! Constructor for subclasses
@ -316,6 +333,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
AutoPtr clone() const { return AutoPtr(clone_()); }
/*! /*!
@brief Write value to a character data buffer. @brief Write value to a character data buffer.
@ -337,11 +355,12 @@ namespace Exiv2 {
virtual Rational toRational(long n =0) const virtual Rational toRational(long n =0) const
{ return Rational(value_[n], 1); } { return Rational(value_[n], 1); }
virtual std::ostream& write(std::ostream& os) const; virtual std::ostream& write(std::ostream& os) const;
virtual StringValueBase* clone() const =0;
//@} //@}
protected: protected:
//! Internal virtual copy constructor.
virtual StringValueBase* clone_() const =0;
// DATA
std::string value_; //!< Stores the string value. std::string value_; //!< Stores the string value.
}; // class StringValueBase }; // class StringValueBase
@ -355,6 +374,9 @@ namespace Exiv2 {
*/ */
class StringValue : public StringValueBase { class StringValue : public StringValueBase {
public: public:
//! Shortcut for a %StringValue auto pointer.
typedef std::auto_ptr<StringValue> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Default constructor. //! Default constructor.
@ -377,9 +399,13 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
virtual StringValue* clone() const; AutoPtr clone() const { return AutoPtr(clone_()); }
//@} //@}
private:
//! Internal virtual copy constructor.
virtual StringValue* clone_() const;
}; // class StringValue }; // class StringValue
/*! /*!
@ -390,6 +416,9 @@ namespace Exiv2 {
*/ */
class AsciiValue : public StringValueBase { class AsciiValue : public StringValueBase {
public: public:
//! Shortcut for a %AsciiValue auto pointer.
typedef std::auto_ptr<AsciiValue> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Default constructor. //! Default constructor.
@ -433,7 +462,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
virtual AsciiValue* clone() const; AutoPtr clone() const { return AutoPtr(clone_()); }
/*! /*!
@brief Write the value to an output stream. Any trailing '\\0' @brief Write the value to an output stream. Any trailing '\\0'
characters of the ASCII value are stripped and not written to 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; virtual std::ostream& write(std::ostream& os) const;
//@} //@}
private:
//! Internal virtual copy constructor.
virtual AsciiValue* clone_() const;
}; // class AsciiValue }; // class AsciiValue
/*! /*!
@ -451,6 +485,9 @@ namespace Exiv2 {
*/ */
class DateValue : public Value { class DateValue : public Value {
public: public:
//! Shortcut for a %DateValue auto pointer.
typedef std::auto_ptr<DateValue> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Default constructor. //! Default constructor.
@ -496,6 +533,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
AutoPtr clone() const { return AutoPtr(clone_()); }
/*! /*!
@brief Write value to a character data buffer. @brief Write value to a character data buffer.
@ -514,7 +552,6 @@ namespace Exiv2 {
virtual const Date& getDate() const { return date_; } virtual const Date& getDate() const { return date_; }
virtual long count() const { return size(); } virtual long count() const { return size(); }
virtual long size() const; virtual long size() const;
virtual DateValue* clone() const;
/*! /*!
@brief Write the value to an output stream. . @brief Write the value to an output stream. .
*/ */
@ -527,6 +564,9 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
virtual DateValue* clone_() const;
// DATA
Date date_; Date date_;
}; // class DateValue }; // class DateValue
@ -541,6 +581,9 @@ namespace Exiv2 {
*/ */
class TimeValue : public Value { class TimeValue : public Value {
public: public:
//! Shortcut for a %TimeValue auto pointer.
typedef std::auto_ptr<TimeValue> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Default constructor. //! Default constructor.
@ -590,6 +633,7 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
AutoPtr clone() const { return AutoPtr(clone_()); }
/*! /*!
@brief Write value to a character data buffer. @brief Write value to a character data buffer.
@ -608,7 +652,6 @@ namespace Exiv2 {
virtual const Time& getTime() const { return time_; } virtual const Time& getTime() const { return time_; }
virtual long count() const { return size(); } virtual long count() const { return size(); }
virtual long size() const; virtual long size() const;
virtual TimeValue* clone() const;
/*! /*!
@brief Write the value to an output stream. . @brief Write the value to an output stream. .
*/ */
@ -621,6 +664,9 @@ namespace Exiv2 {
//@} //@}
private: private:
//! Internal virtual copy constructor.
virtual TimeValue* clone_() const;
// DATA
Time time_; Time time_;
}; // class TimeValue }; // class TimeValue
@ -650,6 +696,9 @@ namespace Exiv2 {
template<typename T> template<typename T>
class ValueType : public Value { class ValueType : public Value {
public: public:
//! Shortcut for a %ValueType<T> auto pointer.
typedef std::auto_ptr<ValueType<T> > AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Default constructor. //! Default constructor.
@ -679,10 +728,10 @@ namespace Exiv2 {
//! @name Accessors //! @name Accessors
//@{ //@{
AutoPtr clone() const { return AutoPtr(clone_()); }
virtual long copy(byte* buf, ByteOrder byteOrder) const; virtual long copy(byte* buf, ByteOrder byteOrder) const;
virtual long count() const { return static_cast<long>(value_.size()); } virtual long count() const { return static_cast<long>(value_.size()); }
virtual long size() const; virtual long size() const;
virtual ValueType<T>* clone() const;
virtual std::ostream& write(std::ostream& os) const; virtual std::ostream& write(std::ostream& os) const;
virtual long toLong(long n =0) const; virtual long toLong(long n =0) const;
virtual float toFloat(long n =0) const; virtual float toFloat(long n =0) const;
@ -696,6 +745,7 @@ namespace Exiv2 {
//! Const iterator type defined for convenience. //! Const iterator type defined for convenience.
typedef typename std::vector<T>::const_iterator const_iterator; typedef typename std::vector<T>::const_iterator const_iterator;
// DATA
/*! /*!
@brief The container for all values. In your application, if you know @brief The container for all values. In your application, if you know
what subclass of Value you're dealing with (and possibly the T) what subclass of Value you're dealing with (and possibly the T)
@ -704,6 +754,10 @@ namespace Exiv2 {
*/ */
ValueList value_; ValueList value_;
private:
//! Internal virtual copy constructor.
virtual ValueType<T>* clone_() const;
}; // class ValueType }; // class ValueType
//! Unsigned short value type //! Unsigned short value type
@ -895,7 +949,7 @@ namespace Exiv2 {
} }
template<typename T> template<typename T>
ValueType<T>* ValueType<T>::clone() const ValueType<T>* ValueType<T>::clone_() const
{ {
return new ValueType<T>(*this); return new ValueType<T>(*this);
} }

Loading…
Cancel
Save