Changed Value::read() to return an int indicating success instead of throwing. Added Support for HHMMSS and H:M:S formats to TimeValue (assumes timezone is UTC). Fixes bug #440.
This commit is contained in:
parent
06e5c0719e
commit
c32e706c36
@ -1065,12 +1065,13 @@ namespace Action {
|
||||
<< ")" << std::endl;
|
||||
}
|
||||
Exiv2::Value::AutoPtr value = Exiv2::Value::create(modifyCmd.typeId_);
|
||||
value->read(modifyCmd.value_);
|
||||
if (modifyCmd.metadataId_ == exif) {
|
||||
image_->exifData().add(Exiv2::ExifKey(modifyCmd.key_), value.get());
|
||||
}
|
||||
if (modifyCmd.metadataId_ == iptc) {
|
||||
image_->iptcData().add(Exiv2::IptcKey(modifyCmd.key_), value.get());
|
||||
if (0 == value->read(modifyCmd.value_)) {
|
||||
if (modifyCmd.metadataId_ == exif) {
|
||||
image_->exifData().add(Exiv2::ExifKey(modifyCmd.key_), value.get());
|
||||
}
|
||||
if (modifyCmd.metadataId_ == iptc) {
|
||||
image_->iptcData().add(Exiv2::IptcKey(modifyCmd.key_), value.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1100,8 +1101,9 @@ namespace Action {
|
||||
if (modifyCmd.explicitType_ || value.get() == 0) {
|
||||
value = Exiv2::Value::create(modifyCmd.typeId_);
|
||||
}
|
||||
value->read(modifyCmd.value_);
|
||||
metadatum->setValue(value.get());
|
||||
if (0 == value->read(modifyCmd.value_)) {
|
||||
metadatum->setValue(value.get());
|
||||
}
|
||||
}
|
||||
|
||||
void Modify::delMetadatum(const ModifyCmd& modifyCmd)
|
||||
|
||||
16
src/iptc.cpp
16
src/iptc.cpp
@ -136,7 +136,6 @@ namespace Exiv2 {
|
||||
const byte* pRead = buf;
|
||||
iptcMetadata_.clear();
|
||||
|
||||
int rc = 0;
|
||||
uint16_t record = 0;
|
||||
uint16_t dataSet = 0;
|
||||
uint32_t sizeData = 0;
|
||||
@ -166,12 +165,11 @@ namespace Exiv2 {
|
||||
sizeData = getUShort(pRead, bigEndian);
|
||||
pRead += 2;
|
||||
}
|
||||
rc = readData(dataSet, record, pRead, sizeData);
|
||||
if( rc ) return rc;
|
||||
readData(dataSet, record, pRead, sizeData);
|
||||
pRead += sizeData;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
} // IptcData::read
|
||||
|
||||
int IptcData::readData(uint16_t dataSet, uint16_t record,
|
||||
@ -180,10 +178,12 @@ namespace Exiv2 {
|
||||
Value::AutoPtr value;
|
||||
TypeId type = IptcDataSets::dataSetType(dataSet, record);
|
||||
value = Value::create(type);
|
||||
value->read(data, sizeData, bigEndian);
|
||||
IptcKey key(dataSet, record);
|
||||
add(key, value.get());
|
||||
return 0;
|
||||
int rc = value->read(data, sizeData, bigEndian);
|
||||
if (0 == rc) {
|
||||
IptcKey key(dataSet, record);
|
||||
add(key, value.get());
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
DataBuf IptcData::copy()
|
||||
|
||||
174
src/value.cpp
174
src/value.cpp
@ -130,13 +130,14 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void DataValue::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
int DataValue::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
{
|
||||
// byteOrder not needed
|
||||
value_.assign(buf, buf + len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DataValue::read(const std::string& buf)
|
||||
int DataValue::read(const std::string& buf)
|
||||
{
|
||||
std::istringstream is(buf);
|
||||
int tmp;
|
||||
@ -144,6 +145,7 @@ namespace Exiv2 {
|
||||
while (is >> tmp) {
|
||||
value_.push_back(static_cast<byte>(tmp));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long DataValue::copy(byte* buf, ByteOrder byteOrder) const
|
||||
@ -181,15 +183,17 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void StringValueBase::read(const std::string& buf)
|
||||
int StringValueBase::read(const std::string& buf)
|
||||
{
|
||||
value_ = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void StringValueBase::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
int StringValueBase::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
{
|
||||
// byteOrder not needed
|
||||
value_ = std::string(reinterpret_cast<const char*>(buf), len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long StringValueBase::copy(byte* buf, ByteOrder byteOrder) const
|
||||
@ -229,10 +233,11 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AsciiValue::read(const std::string& buf)
|
||||
int AsciiValue::read(const std::string& buf)
|
||||
{
|
||||
value_ = buf;
|
||||
if (value_[value_.size()-1] != '\0') value_ += '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
AsciiValue* AsciiValue::clone_() const
|
||||
@ -307,23 +312,28 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CommentValue::read(const std::string& comment)
|
||||
int CommentValue::read(const std::string& comment)
|
||||
{
|
||||
std::string c = comment;
|
||||
CharsetId charsetId = undefined;
|
||||
if (comment.length() > 8 && comment.substr(0, 8) == "charset=") {
|
||||
std::string::size_type pos = comment.find_first_of(' ');
|
||||
std::string name = comment.substr(8, pos-8);
|
||||
// Strip quotes (so you can also to specify the charset without quotes)
|
||||
// Strip quotes (so you can also specify the charset without quotes)
|
||||
if (name[0] == '"') name = name.substr(1);
|
||||
if (name[name.length()-1] == '"') name = name.substr(0, name.length()-1);
|
||||
charsetId = CharsetInfo::charsetIdByName(name);
|
||||
if (charsetId == invalidCharsetId) throw Error(28, name);
|
||||
if (charsetId == invalidCharsetId) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << Error(28, name) << "\n";
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
c.clear();
|
||||
if (pos != std::string::npos) c = comment.substr(pos+1);
|
||||
}
|
||||
const std::string code(CharsetInfo::code(charsetId), 8);
|
||||
StringValueBase::read(code + c);
|
||||
return StringValueBase::read(code + c);
|
||||
}
|
||||
|
||||
std::ostream& CommentValue::write(std::ostream& os) const
|
||||
@ -374,43 +384,62 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void DateValue::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
int DateValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
|
||||
{
|
||||
// byteOrder not needed
|
||||
// Hard coded to read Iptc style dates
|
||||
if (len != 8) throw Error(29);
|
||||
if (len != 8) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << Error(29) << "\n";
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
int scanned = sscanf(reinterpret_cast<const char*>(buf),
|
||||
"%4d%2d%2d",
|
||||
&date_.year, &date_.month, &date_.day);
|
||||
if (scanned != 3) throw Error(29);
|
||||
if (scanned != 3) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << Error(29) << "\n";
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DateValue::read(const std::string& buf)
|
||||
int DateValue::read(const std::string& buf)
|
||||
{
|
||||
// byteOrder not needed
|
||||
// Hard coded to read Iptc style dates
|
||||
if (buf.length() < 8) throw Error(29);
|
||||
if (buf.length() < 8) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << Error(29) << "\n";
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
int scanned = sscanf(buf.data(),
|
||||
"%4d-%d-%d",
|
||||
&date_.year, &date_.month, &date_.day);
|
||||
if (scanned != 3) throw Error(29);
|
||||
if (scanned != 3) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << Error(29) << "\n";
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DateValue::setDate( const Date& src )
|
||||
void DateValue::setDate(const Date& src)
|
||||
{
|
||||
date_.year = src.year;
|
||||
date_.month = src.month;
|
||||
date_.day = src.day;
|
||||
}
|
||||
|
||||
long DateValue::copy(byte* buf, ByteOrder byteOrder) const
|
||||
long DateValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
|
||||
{
|
||||
// byteOrder not needed
|
||||
// sprintf wants to add the null terminator, so use oversized buffer
|
||||
char temp[9];
|
||||
|
||||
int wrote = sprintf( temp, "%04d%02d%02d",
|
||||
date_.year, date_.month, date_.day);
|
||||
int wrote = sprintf(temp, "%04d%02d%02d",
|
||||
date_.year, date_.month, date_.day);
|
||||
assert(wrote == 8);
|
||||
memcpy(buf, temp, 8);
|
||||
return 8;
|
||||
@ -465,40 +494,82 @@ namespace Exiv2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TimeValue::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
int TimeValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
|
||||
{
|
||||
// byteOrder not needed
|
||||
// Hard coded to read Iptc style times
|
||||
if (len != 11) throw Error(30);
|
||||
char plusMinus;
|
||||
int scanned = sscanf(reinterpret_cast<const char*>(buf),
|
||||
"%2d%2d%2d%1c%2d%2d",
|
||||
&time_.hour, &time_.minute, &time_.second,
|
||||
&plusMinus, &time_.tzHour, &time_.tzMinute );
|
||||
|
||||
if (scanned != 6) throw Error(30);
|
||||
if (plusMinus == '-') {
|
||||
time_.tzHour *= -1;
|
||||
time_.tzMinute *= -1;
|
||||
// Hard coded to read HHMMSS or Iptc style times
|
||||
int rc = 1;
|
||||
if (len == 6) {
|
||||
// Try to read (non-standard) HHMMSS format
|
||||
rc = scanTime3(reinterpret_cast<const char*>(buf),
|
||||
"%2d%2d%2d");
|
||||
}
|
||||
if (len == 11) {
|
||||
rc = scanTime6(reinterpret_cast<const char*>(buf),
|
||||
"%2d%2d%2d%1c%2d%2d");
|
||||
}
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
if (rc) {
|
||||
std::cerr << Error(30) << "\n";
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
void TimeValue::read(const std::string& buf)
|
||||
int TimeValue::read(const std::string& buf)
|
||||
{
|
||||
// byteOrder not needed
|
||||
// Hard coded to read Iptc style times
|
||||
if (buf.length() < 9) throw Error(30);
|
||||
char plusMinus;
|
||||
int scanned = sscanf(buf.data(),
|
||||
"%d:%d:%d%1c%d:%d",
|
||||
&time_.hour, &time_.minute, &time_.second,
|
||||
&plusMinus, &time_.tzHour, &time_.tzMinute );
|
||||
|
||||
if (scanned != 6) throw Error(30);
|
||||
if (plusMinus == '-') {
|
||||
time_.tzHour *= -1;
|
||||
time_.tzMinute *= -1;
|
||||
// Hard coded to read H:M:S or Iptc style times
|
||||
int rc = 1;
|
||||
if (buf.length() < 9) {
|
||||
// Try to read (non-standard) H:M:S format
|
||||
rc = scanTime3(buf.data(), "%d:%d:%d");
|
||||
}
|
||||
else {
|
||||
rc = scanTime6(buf.data(), "%d:%d:%d%1c%d:%d");
|
||||
}
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
if (rc) {
|
||||
std::cerr << Error(30) << "\n";
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TimeValue::scanTime3(const char* buf, const char* format)
|
||||
{
|
||||
int rc = 1;
|
||||
Time t;
|
||||
int scanned = sscanf(buf, format, &t.hour, &t.minute, &t.second);
|
||||
if ( scanned == 3
|
||||
&& t.hour >= 0 && t.hour < 24
|
||||
&& t.minute >= 0 && t.minute < 60
|
||||
&& t.second >= 0 && t.second < 60) {
|
||||
time_ = t;
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TimeValue::scanTime6(const char* buf, const char* format)
|
||||
{
|
||||
int rc = 1;
|
||||
Time t;
|
||||
char plusMinus;
|
||||
int scanned = sscanf(buf, format, &t.hour, &t.minute, &t.second,
|
||||
&plusMinus, &t.tzHour, &t.tzMinute);
|
||||
if ( scanned == 6
|
||||
&& t.hour >= 0 && t.hour < 24
|
||||
&& t.minute >= 0 && t.minute < 60
|
||||
&& t.second >= 0 && t.second < 60
|
||||
&& t.tzHour >= 0 && t.tzHour < 24
|
||||
&& t.tzMinute >= 0 && t.tzMinute < 60) {
|
||||
time_ = t;
|
||||
if (plusMinus == '-') {
|
||||
time_.tzHour *= -1;
|
||||
time_.tzMinute *= -1;
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void TimeValue::setTime( const Time& src )
|
||||
@ -506,9 +577,8 @@ namespace Exiv2 {
|
||||
memcpy(&time_, &src, sizeof(time_));
|
||||
}
|
||||
|
||||
long TimeValue::copy(byte* buf, ByteOrder byteOrder) const
|
||||
long TimeValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
|
||||
{
|
||||
// byteOrder not needed
|
||||
// sprintf wants to add the null terminator, so use oversized buffer
|
||||
char temp[12];
|
||||
char plusMinus = '+';
|
||||
|
||||
@ -83,8 +83,10 @@ namespace Exiv2 {
|
||||
@param buf Pointer to the data buffer to read from
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual void read(const byte* buf, long len, ByteOrder byteOrder) =0;
|
||||
virtual int read(const byte* buf, long len, ByteOrder byteOrder) =0;
|
||||
/*!
|
||||
@brief Set the value from a string buffer. The format of the string
|
||||
corresponds to that of the write() method, i.e., a string
|
||||
@ -92,8 +94,10 @@ namespace Exiv2 {
|
||||
function.
|
||||
|
||||
@param buf The string to read from.
|
||||
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual void read(const std::string& buf) =0;
|
||||
virtual int read(const std::string& buf) =0;
|
||||
/*!
|
||||
@brief Set the data area, if the value has one by copying (cloning)
|
||||
the buffer pointed to by buf.
|
||||
@ -270,12 +274,14 @@ namespace Exiv2 {
|
||||
@param buf Pointer to the data buffer to read from
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Byte order. Not needed.
|
||||
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual void read(const byte* buf,
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder =invalidByteOrder);
|
||||
//! Set the data from a string of integer values (e.g., "0 1 2 3")
|
||||
virtual void read(const std::string& buf);
|
||||
virtual int read(const std::string& buf);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
@ -344,7 +350,7 @@ namespace Exiv2 {
|
||||
//! Assignment operator.
|
||||
StringValueBase& operator=(const StringValueBase& rhs);
|
||||
//! Read the value from buf. This default implementation uses buf as it is.
|
||||
virtual void read(const std::string& buf);
|
||||
virtual int read(const std::string& buf);
|
||||
/*!
|
||||
@brief Read the value from a character buffer.
|
||||
|
||||
@ -354,8 +360,10 @@ namespace Exiv2 {
|
||||
@param buf Pointer to the data buffer to read from
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Byte order. Not needed.
|
||||
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual void read(const byte* buf,
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder =invalidByteOrder);
|
||||
//@}
|
||||
@ -472,7 +480,7 @@ namespace Exiv2 {
|
||||
to append a terminating '\\0' character if buf doesn't end
|
||||
with '\\0'.
|
||||
*/
|
||||
virtual void read(const std::string& buf);
|
||||
virtual int read(const std::string& buf);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
@ -568,9 +576,10 @@ namespace Exiv2 {
|
||||
<BR>
|
||||
The default charset is Undefined.
|
||||
|
||||
@throw Error if an invalid character set is encountered
|
||||
@return 0 if successful<BR>
|
||||
1 if an invalid character set is encountered
|
||||
*/
|
||||
void read(const std::string& comment);
|
||||
int read(const std::string& comment);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
@ -636,9 +645,10 @@ namespace Exiv2 {
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Byte order. Not needed.
|
||||
|
||||
@throw Error in case of an unsupported date format
|
||||
@return 0 if successful<BR>
|
||||
1 in case of an unsupported date format
|
||||
*/
|
||||
virtual void read(const byte* buf,
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder =invalidByteOrder);
|
||||
/*!
|
||||
@ -646,9 +656,10 @@ namespace Exiv2 {
|
||||
|
||||
@param buf String containing the date
|
||||
|
||||
@throw Error in case of an unsupported date format
|
||||
@return 0 if successful<BR>
|
||||
1 in case of an unsupported date format
|
||||
*/
|
||||
virtual void read(const std::string& buf);
|
||||
virtual int read(const std::string& buf);
|
||||
//! Set the date
|
||||
void setDate(const Date& src);
|
||||
//@}
|
||||
@ -721,6 +732,8 @@ namespace Exiv2 {
|
||||
//! Simple Time helper structure
|
||||
struct Time
|
||||
{
|
||||
Time() : hour(0), minute(0), second(0), tzHour(0), tzMinute(0) {}
|
||||
|
||||
int hour; //!< Hour
|
||||
int minute; //!< Minute
|
||||
int second; //!< Second
|
||||
@ -742,19 +755,21 @@ namespace Exiv2 {
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Byte order. Not needed.
|
||||
|
||||
@throw Error in case of an unsupported time format
|
||||
@return 0 if successful<BR>
|
||||
1 in case of an unsupported time format
|
||||
*/
|
||||
virtual void read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder =invalidByteOrder);
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder =invalidByteOrder);
|
||||
/*!
|
||||
@brief Set the value to that of the string buf.
|
||||
|
||||
@param buf String containing the time.
|
||||
|
||||
@throw Error in case of an unsupported time format
|
||||
@return 0 if successful<BR>
|
||||
1 in case of an unsupported time format
|
||||
*/
|
||||
virtual void read(const std::string& buf);
|
||||
virtual int read(const std::string& buf);
|
||||
//! Set the time
|
||||
void setTime(const Time& src);
|
||||
//@}
|
||||
@ -780,9 +795,7 @@ namespace Exiv2 {
|
||||
virtual const Time& getTime() const { return time_; }
|
||||
virtual long count() const { return size(); }
|
||||
virtual long size() const;
|
||||
/*!
|
||||
@brief Write the value to an output stream. .
|
||||
*/
|
||||
//! Write the value to an output stream. .
|
||||
virtual std::ostream& write(std::ostream& os) const;
|
||||
virtual long toLong(long n =0) const;
|
||||
virtual float toFloat(long n =0) const
|
||||
@ -792,8 +805,20 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Set time from \em buf if it conforms to \em format (3 input items)
|
||||
int scanTime3(const char* buf, const char* format);
|
||||
//! Set time from \em buf if it conforms to \em format (6 input items)
|
||||
int scanTime6(const char* buf, const char* format);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Internal virtual copy constructor.
|
||||
virtual TimeValue* clone_() const;
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
Time time_;
|
||||
|
||||
@ -845,14 +870,14 @@ namespace Exiv2 {
|
||||
//@{
|
||||
//! Assignment operator.
|
||||
ValueType<T>& operator=(const ValueType<T>& rhs);
|
||||
virtual void read(const byte* buf, long len, ByteOrder byteOrder);
|
||||
virtual int read(const byte* buf, long len, ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Set the data from a string of values of type T (e.g.,
|
||||
"0 1 2 3" or "1/2 1/3 1/4" depending on what T is).
|
||||
Generally, the accepted input format is the same as that
|
||||
produced by the write() method.
|
||||
*/
|
||||
virtual void read(const std::string& buf);
|
||||
virtual int read(const std::string& buf);
|
||||
/*!
|
||||
@brief Set the data area. This method copies (clones) the buffer
|
||||
pointed to by buf.
|
||||
@ -1092,16 +1117,17 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
int ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
|
||||
{
|
||||
value_.clear();
|
||||
for (long i = 0; i < len; i += TypeInfo::typeSize(typeId())) {
|
||||
value_.push_back(getValue<T>(buf + i, byteOrder));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ValueType<T>::read(const std::string& buf)
|
||||
int ValueType<T>::read(const std::string& buf)
|
||||
{
|
||||
std::istringstream is(buf);
|
||||
T tmp;
|
||||
@ -1109,6 +1135,7 @@ namespace Exiv2 {
|
||||
while (is >> tmp) {
|
||||
value_.push_back(tmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user