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.
File: addmoddel.cpp
Version: $Name: $ $Revision: 1.4 $
Version: $Name: $ $Revision: 1.5 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
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,7 +53,7 @@ try {
if (pos == exifData.end()) throw Exiv2::Error("Key not found");
// Modify the value
std::string date = pos->toString();
date.replace(0,4,"2000");
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<Exiv2::URationalValue*>(v);
if (rv == 0) throw Exiv2::Error("Downcast failed");
Exiv2::URationalValue* prv = dynamic_cast<Exiv2::URationalValue*>(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";

@ -20,14 +20,14 @@
*/
/*
File: exif.cpp
Version: $Name: $ $Revision: 1.66 $
Version: $Name: $ $Revision: 1.67 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
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));
}

@ -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)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@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

@ -20,13 +20,13 @@
*/
/*
File: iptc.cpp
Version: $Name: $ $Revision: 1.8 $
Version: $Name: $ $Revision: 1.9 $
Author(s): Brad Schick (brad) <schick@robotbattle.com>
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;
}

@ -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)
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
@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
'<b>Iptc</b>.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

@ -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) <schick@robotbattle.com>
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);

@ -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)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@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.

@ -20,7 +20,7 @@
*/
/*
File: value.cpp
Version: $Name: $ $Revision: 1.14 $
Version: $Name: $ $Revision: 1.15 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
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<uint16_t>;
value = AutoPtr(new ValueType<uint16_t>);
break;
case unsignedLong:
value = new ValueType<uint32_t>;
value = AutoPtr(new ValueType<uint32_t>);
break;
case unsignedRational:
value = new ValueType<URational>;
value = AutoPtr(new ValueType<URational>);
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<int16_t>;
value = AutoPtr(new ValueType<int16_t>);
break;
case signedLong:
value = new ValueType<int32_t>;
value = AutoPtr(new ValueType<int32_t>);
break;
case signedRational:
value = new ValueType<Rational>;
value = AutoPtr(new ValueType<Rational>);
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<long>(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);
}

@ -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)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 09-Jan-04, ahu: created
@ -40,6 +40,7 @@
#include <vector>
#include <iostream>
#include <sstream>
#include <memory>
// *****************************************************************************
// namespace extensions
@ -59,6 +60,9 @@ namespace Exiv2 {
*/
class Value {
public:
//! Shortcut for a %Value auto pointer.
typedef std::auto_ptr<Value> 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:<BR><BR>
<TABLE>
<TR><TD><B>typeId</B></TD><TD><B>%Value subclass</B></TD></TR>
<TR><TD>invalidTypeId</TD><TD>%DataValue(invalidTypeId)</TD></TR>
<TR><TD>unsignedByte</TD><TD>%DataValue(unsignedByte)</TD></TR>
<TR><TD>asciiString</TD><TD>%AsciiValue</TD></TR>
<TR><TD>string</TD><TD>%StringValue</TD></TR>
<TR><TD>unsignedShort</TD><TD>%ValueType &lt; uint16_t &gt;</TD></TR>
<TR><TD>unsignedLong</TD><TD>%ValueType &lt; uint32_t &gt;</TD></TR>
<TR><TD>unsignedRational</TD><TD>%ValueType &lt; URational &gt;</TD></TR>
<TR><TD>invalid6</TD><TD>%DataValue(invalid6)</TD></TR>
<TR><TD>undefined</TD><TD>%DataValue</TD></TR>
<TR><TD>signedShort</TD><TD>%ValueType &lt; int16_t &gt;</TD></TR>
<TR><TD>signedLong</TD><TD>%ValueType &lt; int32_t &gt;</TD></TR>
<TR><TD>signedRational</TD><TD>%ValueType &lt; Rational &gt;</TD></TR>
<TR><TD>date</TD><TD>%DateValue</TD></TR>
<TR><TD>time</TD><TD>%TimeValue</TD></TR>
<TR><TD><EM>default:</EM></TD><TD>%DataValue(typeId)</TD></TR>
<TR><TD class="indexkey"><B>typeId</B></TD><TD class="indexvalue"><B>%Value subclass</B></TD></TR>
<TR><TD class="indexkey">invalidTypeId</TD><TD class="indexvalue">%DataValue(invalidTypeId)</TD></TR>
<TR><TD class="indexkey">unsignedByte</TD><TD class="indexvalue">%DataValue(unsignedByte)</TD></TR>
<TR><TD class="indexkey">asciiString</TD><TD class="indexvalue">%AsciiValue</TD></TR>
<TR><TD class="indexkey">string</TD><TD class="indexvalue">%StringValue</TD></TR>
<TR><TD class="indexkey">unsignedShort</TD><TD class="indexvalue">%ValueType &lt; uint16_t &gt;</TD></TR>
<TR><TD class="indexkey">unsignedLong</TD><TD class="indexvalue">%ValueType &lt; uint32_t &gt;</TD></TR>
<TR><TD class="indexkey">unsignedRational</TD><TD class="indexvalue">%ValueType &lt; URational &gt;</TD></TR>
<TR><TD class="indexkey">invalid6</TD><TD class="indexvalue">%DataValue(invalid6)</TD></TR>
<TR><TD class="indexkey">undefined</TD><TD class="indexvalue">%DataValue</TD></TR>
<TR><TD class="indexkey">signedShort</TD><TD class="indexvalue">%ValueType &lt; int16_t &gt;</TD></TR>
<TR><TD class="indexkey">signedLong</TD><TD class="indexvalue">%ValueType &lt; int32_t &gt;</TD></TR>
<TR><TD class="indexkey">signedRational</TD><TD class="indexvalue">%ValueType &lt; Rational &gt;</TD></TR>
<TR><TD class="indexkey">date</TD><TD class="indexvalue">%DateValue</TD></TR>
<TR><TD class="indexkey">time</TD><TD class="indexvalue">%TimeValue</TD></TR>
<TR><TD class="indexkey"><EM>default:</EM></TD><TD class="indexvalue">%DataValue(typeId)</TD></TR>
</TABLE>
@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<DataValue> AutoPtr;
//! @name Creators
//@{
//! Default constructor.
@ -240,6 +251,7 @@ 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<byte> value_;
}; // class DataValue
@ -277,6 +291,9 @@ namespace Exiv2 {
*/
class StringValueBase : public Value {
public:
//! Shortcut for a %StringValueBase auto pointer.
typedef std::auto_ptr<StringValueBase> 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<StringValue> 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<AsciiValue> 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<DateValue> 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<TimeValue> 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<typename T>
class ValueType : public Value {
public:
//! Shortcut for a %ValueType<T> auto pointer.
typedef std::auto_ptr<ValueType<T> > 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<long>(value_.size()); }
virtual long size() const;
virtual ValueType<T>* 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<T>::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<T>* clone_() const;
}; // class ValueType
//! Unsigned short value type
@ -895,7 +949,7 @@ namespace Exiv2 {
}
template<typename T>
ValueType<T>* ValueType<T>::clone() const
ValueType<T>* ValueType<T>::clone_() const
{
return new ValueType<T>(*this);
}

Loading…
Cancel
Save