|
Packit |
01d647 |
// ***************************************************************** -*- C++ -*-
|
|
Packit |
01d647 |
/*
|
|
Packit |
01d647 |
* Copyright (C) 2004-2018 Exiv2 authors
|
|
Packit |
01d647 |
* This program is part of the Exiv2 distribution.
|
|
Packit |
01d647 |
*
|
|
Packit |
01d647 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
01d647 |
* modify it under the terms of the GNU General Public License
|
|
Packit |
01d647 |
* as published by the Free Software Foundation; either version 2
|
|
Packit |
01d647 |
* of the License, or (at your option) any later version.
|
|
Packit |
01d647 |
*
|
|
Packit |
01d647 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
01d647 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
01d647 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
01d647 |
* GNU General Public License for more details.
|
|
Packit |
01d647 |
*
|
|
Packit |
01d647 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
01d647 |
* along with this program; if not, write to the Free Software
|
|
Packit |
01d647 |
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
01d647 |
*/
|
|
Packit |
01d647 |
/*
|
|
Packit |
01d647 |
File: value.cpp
|
|
Packit |
01d647 |
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
|
Packit |
01d647 |
History: 26-Jan-04, ahu: created
|
|
Packit |
01d647 |
11-Feb-04, ahu: isolated as a component
|
|
Packit |
01d647 |
31-Jul-04, brad: added Time, Date and String values
|
|
Packit |
01d647 |
*/
|
|
Packit |
01d647 |
// *****************************************************************************
|
|
Packit |
01d647 |
// included header files
|
|
Packit |
01d647 |
#include "value.hpp"
|
|
Packit |
01d647 |
#include "types.hpp"
|
|
Packit |
01d647 |
#include "enforce.hpp"
|
|
Packit |
01d647 |
#include "error.hpp"
|
|
Packit |
01d647 |
#include "convert.hpp"
|
|
Packit |
01d647 |
#include "unused.h"
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// + standard includes
|
|
Packit |
01d647 |
#include <iostream>
|
|
Packit |
01d647 |
#include <iomanip>
|
|
Packit |
01d647 |
#include <sstream>
|
|
Packit |
01d647 |
#include <cassert>
|
|
Packit |
01d647 |
#include <cstring>
|
|
Packit |
01d647 |
#include <ctime>
|
|
Packit |
01d647 |
#include <cstdarg>
|
|
Packit |
01d647 |
#include <cstdio>
|
|
Packit |
01d647 |
#include <cstdlib>
|
|
Packit |
01d647 |
#include <ctype.h>
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
#if defined(_MSC_VER) && _MSC_VER < 1900
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
#define snprintf c99_snprintf
|
|
Packit |
01d647 |
#define vsnprintf c99_vsnprintf
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
int count = -1;
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
if (size != 0)
|
|
Packit |
01d647 |
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
|
|
Packit |
01d647 |
if (count == -1)
|
|
Packit |
01d647 |
count = _vscprintf(format, ap);
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
return count;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
int count;
|
|
Packit |
01d647 |
va_list ap;
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
va_start(ap, format);
|
|
Packit |
01d647 |
count = c99_vsnprintf(outBuf, size, format, ap);
|
|
Packit |
01d647 |
va_end(ap);
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
return count;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// *****************************************************************************
|
|
Packit |
01d647 |
// class member definitions
|
|
Packit |
01d647 |
namespace Exiv2 {
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Value::Value(TypeId typeId)
|
|
Packit |
01d647 |
: ok_(true), type_(typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Value::~Value()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Value& Value::operator=(const Value& rhs)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
if (this == &rhs) return *this;
|
|
Packit |
01d647 |
type_ = rhs.type_;
|
|
Packit |
01d647 |
ok_ = rhs.ok_;
|
|
Packit |
01d647 |
return *this;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Value::AutoPtr Value::create(TypeId typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
AutoPtr value;
|
|
Packit |
01d647 |
switch (typeId) {
|
|
Packit |
01d647 |
case invalidTypeId:
|
|
Packit |
01d647 |
case signedByte:
|
|
Packit |
01d647 |
case unsignedByte:
|
|
Packit |
01d647 |
value = AutoPtr(new DataValue(typeId));
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case asciiString:
|
|
Packit |
01d647 |
value = AutoPtr(new AsciiValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case unsignedShort:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<uint16_t>);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case unsignedLong:
|
|
Packit |
01d647 |
case tiffIfd:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<uint32_t>(typeId));
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case unsignedRational:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<URational>);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case undefined:
|
|
Packit |
01d647 |
value = AutoPtr(new DataValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case signedShort:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<int16_t>);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case signedLong:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<int32_t>);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case signedRational:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<Rational>);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case tiffFloat:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<float>);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case tiffDouble:
|
|
Packit |
01d647 |
value = AutoPtr(new ValueType<double>);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case string:
|
|
Packit |
01d647 |
value = AutoPtr(new StringValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case date:
|
|
Packit |
01d647 |
value = AutoPtr(new DateValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case time:
|
|
Packit |
01d647 |
value = AutoPtr(new TimeValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case comment:
|
|
Packit |
01d647 |
value = AutoPtr(new CommentValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case xmpText:
|
|
Packit |
01d647 |
value = AutoPtr(new XmpTextValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case xmpBag:
|
|
Packit |
01d647 |
case xmpSeq:
|
|
Packit |
01d647 |
case xmpAlt:
|
|
Packit |
01d647 |
value = AutoPtr(new XmpArrayValue(typeId));
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
case langAlt:
|
|
Packit |
01d647 |
value = AutoPtr(new LangAltValue);
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
default:
|
|
Packit |
01d647 |
value = AutoPtr(new DataValue(typeId));
|
|
Packit |
01d647 |
break;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return value;
|
|
Packit |
01d647 |
} // Value::create
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int Value::setDataArea(const byte* /*buf*/, long /*len*/)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return -1;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::string Value::toString() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::ostringstream os;
|
|
Packit |
01d647 |
write(os);
|
|
Packit |
01d647 |
ok_ = !os.fail();
|
|
Packit |
01d647 |
return os.str();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::string Value::toString(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return toString();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long Value::sizeDataArea() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DataBuf Value::dataArea() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return DataBuf(0, 0);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DataValue::DataValue(TypeId typeId) : Value(typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DataValue::DataValue(const byte* buf,
|
|
Packit |
01d647 |
long len, ByteOrder byteOrder,TypeId typeId)
|
|
Packit |
01d647 |
: Value(typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
read(buf, len, byteOrder);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DataValue::~DataValue()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DataValue::count() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return size();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int DataValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// byteOrder not needed
|
|
Packit |
01d647 |
value_.assign(buf, buf + len);
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int DataValue::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::istringstream is(buf);
|
|
Packit |
01d647 |
int tmp;
|
|
Packit |
01d647 |
ValueType val;
|
|
Packit |
01d647 |
while (!(is.eof())) {
|
|
Packit |
01d647 |
is >> tmp;
|
|
Packit |
01d647 |
if (is.fail()) return 1;
|
|
Packit |
01d647 |
val.push_back(static_cast<byte>(tmp));
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
value_.swap(val);
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DataValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// byteOrder not needed
|
|
Packit |
01d647 |
return static_cast<long>(
|
|
Packit |
01d647 |
std::copy(value_.begin(), value_.end(), buf) - buf
|
|
Packit |
01d647 |
);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DataValue::size() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return static_cast<long>(value_.size());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DataValue* DataValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new DataValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& DataValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::vector<byte>::size_type end = value_.size();
|
|
Packit |
01d647 |
for (std::vector<byte>::size_type i = 0; i != end; ++i) {
|
|
Packit |
01d647 |
os << static_cast<int>(value_[i]);
|
|
Packit |
01d647 |
if (i < end - 1) os << " ";
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return os;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::string DataValue::toString(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::ostringstream os;
|
|
Packit |
01d647 |
os << static_cast<int>(value_[n]);
|
|
Packit |
01d647 |
ok_ = !os.fail();
|
|
Packit |
01d647 |
return os.str();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DataValue::toLong(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return value_[n];
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
float DataValue::toFloat(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return value_[n];
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Rational DataValue::toRational(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return Rational(value_[n], 1);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValueBase::StringValueBase(TypeId typeId)
|
|
Packit |
01d647 |
: Value(typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValueBase::StringValueBase(TypeId typeId, const std::string& buf)
|
|
Packit |
01d647 |
: Value(typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
read(buf);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValueBase::StringValueBase(const StringValueBase& rhs)
|
|
Packit |
01d647 |
: Value(rhs), value_(rhs.value_)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValueBase::~StringValueBase()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValueBase& StringValueBase::operator=(const StringValueBase& rhs)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
if (this == &rhs) return *this;
|
|
Packit |
01d647 |
Value::operator=(rhs);
|
|
Packit |
01d647 |
value_ = rhs.value_;
|
|
Packit |
01d647 |
return *this;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int StringValueBase::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
value_ = buf;
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int StringValueBase::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// byteOrder not needed
|
|
Packit |
01d647 |
if (buf) value_ = std::string(reinterpret_cast<const char*>(buf), len);
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long StringValueBase::copy(byte* buf, ByteOrder /*byteOrder*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
if (value_.size() == 0) return 0;
|
|
Packit |
01d647 |
// byteOrder not needed
|
|
Packit |
01d647 |
assert(buf != 0);
|
|
Packit |
01d647 |
return static_cast<long>(
|
|
Packit |
01d647 |
value_.copy(reinterpret_cast<char*>(buf), value_.size())
|
|
Packit |
01d647 |
);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long StringValueBase::count() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return size();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long StringValueBase::size() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return static_cast<long>(value_.size());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& StringValueBase::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return os << value_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long StringValueBase::toLong(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return value_[n];
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
float StringValueBase::toFloat(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return value_[n];
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Rational StringValueBase::toRational(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return Rational(value_[n], 1);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValue::StringValue()
|
|
Packit |
01d647 |
: StringValueBase(string)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValue::StringValue(const std::string& buf)
|
|
Packit |
01d647 |
: StringValueBase(string, buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValue::~StringValue()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
StringValue* StringValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new StringValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
AsciiValue::AsciiValue()
|
|
Packit |
01d647 |
: StringValueBase(asciiString)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
AsciiValue::AsciiValue(const std::string& buf)
|
|
Packit |
01d647 |
: StringValueBase(asciiString, buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
AsciiValue::~AsciiValue()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int AsciiValue::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
value_ = buf;
|
|
Packit |
01d647 |
if (value_.size() > 0 && value_[value_.size()-1] != '\0') value_ += '\0';
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
AsciiValue* AsciiValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new AsciiValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& AsciiValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Write only up to the first '\0' (if any)
|
|
Packit |
01d647 |
std::string::size_type pos = value_.find_first_of('\0');
|
|
Packit |
01d647 |
if (pos == std::string::npos) pos = value_.size();
|
|
Packit |
01d647 |
return os << value_.substr(0, pos);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue::CharsetTable::CharsetTable(CharsetId charsetId,
|
|
Packit |
01d647 |
const char* name,
|
|
Packit |
01d647 |
const char* code)
|
|
Packit |
01d647 |
: charsetId_(charsetId), name_(name), code_(code)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
//! Lookup list of supported IFD type information
|
|
Packit |
01d647 |
const CommentValue::CharsetTable CommentValue::CharsetInfo::charsetTable_[] = {
|
|
Packit |
01d647 |
CharsetTable(ascii, "Ascii", "ASCII\0\0\0"),
|
|
Packit |
01d647 |
CharsetTable(jis, "Jis", "JIS\0\0\0\0\0"),
|
|
Packit |
01d647 |
CharsetTable(unicode, "Unicode", "UNICODE\0"),
|
|
Packit |
01d647 |
CharsetTable(undefined, "Undefined", "\0\0\0\0\0\0\0\0"),
|
|
Packit |
01d647 |
CharsetTable(invalidCharsetId, "InvalidCharsetId", "\0\0\0\0\0\0\0\0"),
|
|
Packit |
01d647 |
CharsetTable(lastCharsetId, "InvalidCharsetId", "\0\0\0\0\0\0\0\0")
|
|
Packit |
01d647 |
};
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
const char* CommentValue::CharsetInfo::name(CharsetId charsetId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return charsetTable_[ charsetId < lastCharsetId ? charsetId : undefined ].name_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
const char* CommentValue::CharsetInfo::code(CharsetId charsetId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return charsetTable_[ charsetId < lastCharsetId ? charsetId : undefined ].code_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue::CharsetId CommentValue::CharsetInfo::charsetIdByName(
|
|
Packit |
01d647 |
const std::string& name)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
int i = 0;
|
|
Packit |
01d647 |
for (; charsetTable_[i].charsetId_ != lastCharsetId
|
|
Packit |
01d647 |
&& charsetTable_[i].name_ != name; ++i) {}
|
|
Packit |
01d647 |
return charsetTable_[i].charsetId_ == lastCharsetId ?
|
|
Packit |
01d647 |
invalidCharsetId : charsetTable_[i].charsetId_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue::CharsetId CommentValue::CharsetInfo::charsetIdByCode(
|
|
Packit |
01d647 |
const std::string& code)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
int i = 0;
|
|
Packit |
01d647 |
for (; charsetTable_[i].charsetId_ != lastCharsetId
|
|
Packit |
01d647 |
&& std::string(charsetTable_[i].code_, 8) != code; ++i) {}
|
|
Packit |
01d647 |
return charsetTable_[i].charsetId_ == lastCharsetId ?
|
|
Packit |
01d647 |
invalidCharsetId : charsetTable_[i].charsetId_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue::CommentValue()
|
|
Packit |
01d647 |
: StringValueBase(Exiv2::undefined), byteOrder_(littleEndian)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue::CommentValue(const std::string& comment)
|
|
Packit |
01d647 |
: StringValueBase(Exiv2::undefined), byteOrder_(littleEndian)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
read(comment);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue::~CommentValue()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int CommentValue::read(const std::string& comment)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::string c = comment;
|
|
Packit |
01d647 |
CharsetId charsetId = undefined;
|
|
Packit |
01d647 |
if (comment.length() > 8 && comment.substr(0, 8) == "charset=") {
|
|
Packit |
01d647 |
std::string::size_type pos = comment.find_first_of(' ');
|
|
Packit |
01d647 |
std::string name = comment.substr(8, pos-8);
|
|
Packit |
01d647 |
// Strip quotes (so you can also specify the charset without quotes)
|
|
Packit |
01d647 |
if (name[0] == '"') name = name.substr(1);
|
|
Packit |
01d647 |
if (name[name.length()-1] == '"') name = name.substr(0, name.length()-1);
|
|
Packit |
01d647 |
charsetId = CharsetInfo::charsetIdByName(name);
|
|
Packit |
01d647 |
if (charsetId == invalidCharsetId) {
|
|
Packit |
01d647 |
#ifndef SUPPRESS_WARNINGS
|
|
Packit |
01d647 |
EXV_WARNING << Error(kerInvalidCharset, name) << "\n";
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
return 1;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
c.clear();
|
|
Packit |
01d647 |
if (pos != std::string::npos) c = comment.substr(pos+1);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (charsetId == unicode) {
|
|
Packit |
01d647 |
const char* to = byteOrder_ == littleEndian ? "UCS-2LE" : "UCS-2BE";
|
|
Packit |
01d647 |
convertStringCharset(c, "UTF-8", to);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
const std::string code(CharsetInfo::code(charsetId), 8);
|
|
Packit |
01d647 |
return StringValueBase::read(code + c);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int CommentValue::read(const byte* buf, long len, ByteOrder byteOrder)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
byteOrder_ = byteOrder;
|
|
Packit |
01d647 |
return StringValueBase::read(buf, len, byteOrder);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long CommentValue::copy(byte* buf, ByteOrder byteOrder) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::string c = value_;
|
|
Packit |
01d647 |
if (charsetId() == unicode) {
|
|
Packit |
01d647 |
c = value_.substr(8);
|
|
Packit |
01d647 |
const size_t sz = c.size();
|
|
Packit |
01d647 |
UNUSED(sz);
|
|
Packit |
01d647 |
if (byteOrder_ == littleEndian && byteOrder == bigEndian) {
|
|
Packit |
01d647 |
convertStringCharset(c, "UCS-2LE", "UCS-2BE");
|
|
Packit |
01d647 |
assert(c.size() == sz);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
else if (byteOrder_ == bigEndian && byteOrder == littleEndian) {
|
|
Packit |
01d647 |
convertStringCharset(c, "UCS-2BE", "UCS-2LE");
|
|
Packit |
01d647 |
assert(c.size() == sz);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
c = value_.substr(0, 8) + c;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (c.size() == 0)
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
assert(buf != 0);
|
|
Packit |
01d647 |
return static_cast<long>(c.copy(reinterpret_cast<char*>(buf), c.size()));
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& CommentValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
CharsetId csId = charsetId();
|
|
Packit |
01d647 |
if (csId != undefined) {
|
|
Packit |
01d647 |
os << "charset=\"" << CharsetInfo::name(csId) << "\" ";
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return os << comment();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::string CommentValue::comment(const char* encoding) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::string c;
|
|
Packit |
01d647 |
if (value_.length() < 8) {
|
|
Packit |
01d647 |
return c;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
c = value_.substr(8);
|
|
Packit |
01d647 |
if (charsetId() == unicode) {
|
|
Packit |
01d647 |
const char* from = encoding == 0 || *encoding == '\0' ? detectCharset(c) : encoding;
|
|
Packit |
01d647 |
convertStringCharset(c, from, "UTF-8");
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return c;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue::CharsetId CommentValue::charsetId() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
CharsetId charsetId = undefined;
|
|
Packit |
01d647 |
if (value_.length() >= 8) {
|
|
Packit |
01d647 |
const std::string code = value_.substr(0, 8);
|
|
Packit |
01d647 |
charsetId = CharsetInfo::charsetIdByCode(code);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return charsetId;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
const char* CommentValue::detectCharset(std::string& c) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Interpret a BOM if there is one
|
|
Packit |
01d647 |
if (0 == strncmp(c.data(), "\xef\xbb\xbf", 3)) {
|
|
Packit |
01d647 |
c = c.substr(3);
|
|
Packit |
01d647 |
return "UTF-8";
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (0 == strncmp(c.data(), "\xff\xfe", 2)) {
|
|
Packit |
01d647 |
c = c.substr(2);
|
|
Packit |
01d647 |
return "UCS-2LE";
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (0 == strncmp(c.data(), "\xfe\xff", 2)) {
|
|
Packit |
01d647 |
c = c.substr(2);
|
|
Packit |
01d647 |
return "UCS-2BE";
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// Todo: Add logic to guess if the comment is encoded in UTF-8
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
return byteOrder_ == littleEndian ? "UCS-2LE" : "UCS-2BE";
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
CommentValue* CommentValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new CommentValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpValue::XmpValue(TypeId typeId)
|
|
Packit |
01d647 |
: Value(typeId),
|
|
Packit |
01d647 |
xmpArrayType_(xaNone),
|
|
Packit |
01d647 |
xmpStruct_(xsNone)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpValue& XmpValue::operator=(const XmpValue& rhs)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
if (this == &rhs) return *this;
|
|
Packit |
01d647 |
xmpArrayType_ = rhs.xmpArrayType_;
|
|
Packit |
01d647 |
xmpStruct_ = rhs.xmpStruct_;
|
|
Packit |
01d647 |
return *this;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
void XmpValue::setXmpArrayType(XmpArrayType xmpArrayType)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
xmpArrayType_ = xmpArrayType;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
void XmpValue::setXmpStruct(XmpStruct xmpStruct)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
xmpStruct_ = xmpStruct;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpValue::XmpArrayType XmpValue::xmpArrayType() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return xmpArrayType_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpValue::XmpArrayType XmpValue::xmpArrayType(TypeId typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
XmpArrayType xa = xaNone;
|
|
Packit |
01d647 |
switch (typeId) {
|
|
Packit |
01d647 |
case xmpAlt: xa = xaAlt; break;
|
|
Packit |
01d647 |
case xmpBag: xa = xaBag; break;
|
|
Packit |
01d647 |
case xmpSeq: xa = xaSeq; break;
|
|
Packit |
01d647 |
default: break;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return xa;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpValue::XmpStruct XmpValue::xmpStruct() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return xmpStruct_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long XmpValue::copy(byte* buf,
|
|
Packit |
01d647 |
ByteOrder /*byteOrder*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::ostringstream os;
|
|
Packit |
01d647 |
write(os);
|
|
Packit |
01d647 |
std::string s = os.str();
|
|
Packit |
01d647 |
if (s.size() > 0) std::memcpy(buf, &s[0], s.size());
|
|
Packit |
01d647 |
return static_cast<long>(s.size());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int XmpValue::read(const byte* buf,
|
|
Packit |
01d647 |
long len,
|
|
Packit |
01d647 |
ByteOrder /*byteOrder*/)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::string s(reinterpret_cast<const char*>(buf), len);
|
|
Packit |
01d647 |
return read(s);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long XmpValue::size() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::ostringstream os;
|
|
Packit |
01d647 |
write(os);
|
|
Packit |
01d647 |
return static_cast<long>(os.str().size());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpTextValue::XmpTextValue()
|
|
Packit |
01d647 |
: XmpValue(xmpText)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpTextValue::XmpTextValue(const std::string& buf)
|
|
Packit |
01d647 |
: XmpValue(xmpText)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
read(buf);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int XmpTextValue::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// support a type=Alt,Bag,Seq,Struct indicator
|
|
Packit |
01d647 |
std::string b = buf;
|
|
Packit |
01d647 |
std::string type;
|
|
Packit |
01d647 |
if (buf.length() > 5 && buf.substr(0, 5) == "type=") {
|
|
Packit |
01d647 |
std::string::size_type pos = buf.find_first_of(' ');
|
|
Packit |
01d647 |
type = buf.substr(5, pos-5);
|
|
Packit |
01d647 |
// Strip quotes (so you can also specify the type without quotes)
|
|
Packit |
01d647 |
if (type[0] == '"') type = type.substr(1);
|
|
Packit |
01d647 |
if (type[type.length()-1] == '"') type = type.substr(0, type.length()-1);
|
|
Packit |
01d647 |
b.clear();
|
|
Packit |
01d647 |
if (pos != std::string::npos) b = buf.substr(pos+1);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (!type.empty()) {
|
|
Packit |
01d647 |
if (type == "Alt") {
|
|
Packit |
01d647 |
setXmpArrayType(XmpValue::xaAlt);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
else if (type == "Bag") {
|
|
Packit |
01d647 |
setXmpArrayType(XmpValue::xaBag);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
else if (type == "Seq") {
|
|
Packit |
01d647 |
setXmpArrayType(XmpValue::xaSeq);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
else if (type == "Struct") {
|
|
Packit |
01d647 |
setXmpStruct();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
else {
|
|
Packit |
01d647 |
throw Error(kerInvalidXmpText, type);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
value_ = b;
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpTextValue::AutoPtr XmpTextValue::clone() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return AutoPtr(clone_());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long XmpTextValue::size() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return static_cast<long>(value_.size());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long XmpTextValue::count() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return size();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& XmpTextValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
bool del = false;
|
|
Packit |
01d647 |
if (xmpArrayType() != XmpValue::xaNone) {
|
|
Packit |
01d647 |
switch (xmpArrayType()) {
|
|
Packit |
01d647 |
case XmpValue::xaAlt: os << "type=\"Alt\""; break;
|
|
Packit |
01d647 |
case XmpValue::xaBag: os << "type=\"Bag\""; break;
|
|
Packit |
01d647 |
case XmpValue::xaSeq: os << "type=\"Seq\""; break;
|
|
Packit |
01d647 |
case XmpValue::xaNone: break; // just to suppress the warning
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
del = true;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
else if (xmpStruct() != XmpValue::xsNone) {
|
|
Packit |
01d647 |
switch (xmpStruct()) {
|
|
Packit |
01d647 |
case XmpValue::xsStruct: os << "type=\"Struct\""; break;
|
|
Packit |
01d647 |
case XmpValue::xsNone: break; // just to suppress the warning
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
del = true;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (del && !value_.empty()) os << " ";
|
|
Packit |
01d647 |
return os << value_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long XmpTextValue::toLong(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return parseLong(value_, ok_);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
float XmpTextValue::toFloat(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return parseFloat(value_, ok_);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Rational XmpTextValue::toRational(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return parseRational(value_, ok_);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpTextValue* XmpTextValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new XmpTextValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpArrayValue::XmpArrayValue(TypeId typeId)
|
|
Packit |
01d647 |
: XmpValue(typeId)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
setXmpArrayType(xmpArrayType(typeId));
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int XmpArrayValue::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
if (!buf.empty()) value_.push_back(buf);
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpArrayValue::AutoPtr XmpArrayValue::clone() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return AutoPtr(clone_());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long XmpArrayValue::count() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return static_cast<long>(value_.size());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& XmpArrayValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
for (std::vector<std::string>::const_iterator i = value_.begin();
|
|
Packit |
01d647 |
i != value_.end(); ++i) {
|
|
Packit |
01d647 |
if (i != value_.begin()) os << ", ";
|
|
Packit |
01d647 |
os << *i;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return os;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::string XmpArrayValue::toString(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return value_[n];
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long XmpArrayValue::toLong(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return parseLong(value_[n], ok_);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
float XmpArrayValue::toFloat(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return parseFloat(value_[n], ok_);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Rational XmpArrayValue::toRational(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return parseRational(value_[n], ok_);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
XmpArrayValue* XmpArrayValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new XmpArrayValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
LangAltValue::LangAltValue()
|
|
Packit |
01d647 |
: XmpValue(langAlt)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
LangAltValue::LangAltValue(const std::string& buf)
|
|
Packit |
01d647 |
: XmpValue(langAlt)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
read(buf);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int LangAltValue::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::string b = buf;
|
|
Packit |
01d647 |
std::string lang = "x-default";
|
|
Packit |
01d647 |
if (buf.length() > 5 && buf.substr(0, 5) == "lang=") {
|
|
Packit |
01d647 |
std::string::size_type pos = buf.find_first_of(' ');
|
|
Packit |
01d647 |
lang = buf.substr(5, pos-5);
|
|
Packit |
01d647 |
// Strip quotes (so you can also specify the language without quotes)
|
|
Packit |
01d647 |
if (lang[0] == '"') lang = lang.substr(1);
|
|
Packit |
01d647 |
if (lang[lang.length()-1] == '"') lang = lang.substr(0, lang.length()-1);
|
|
Packit |
01d647 |
b.clear();
|
|
Packit |
01d647 |
if (pos != std::string::npos) b = buf.substr(pos+1);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
value_[lang] = b;
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
LangAltValue::AutoPtr LangAltValue::clone() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return AutoPtr(clone_());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long LangAltValue::count() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return static_cast<long>(value_.size());
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
static const std::string x_default = "x-default";
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& LangAltValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
bool first = true;
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// Write the default entry first
|
|
Packit |
01d647 |
ValueType::const_iterator i = value_.find(x_default);
|
|
Packit |
01d647 |
if (i != value_.end()) {
|
|
Packit |
01d647 |
os << "lang=\"" << i->first << "\" " << i->second;
|
|
Packit |
01d647 |
first = false;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
// Write the others
|
|
Packit |
01d647 |
for (i = value_.begin(); i != value_.end(); ++i) {
|
|
Packit |
01d647 |
if (i->first != x_default ) {
|
|
Packit |
01d647 |
if (!first) os << ", ";
|
|
Packit |
01d647 |
os << "lang=\"" << i->first << "\" " << i->second;
|
|
Packit |
01d647 |
first = false;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return os;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::string LangAltValue::toString(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return toString(x_default);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::string LangAltValue::toString(const std::string& qualifier) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ValueType::const_iterator i = value_.find(qualifier);
|
|
Packit |
01d647 |
if (i != value_.end()) {
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return i->second;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
ok_ = false;
|
|
Packit |
01d647 |
return "";
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long LangAltValue::toLong(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = false;
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
float LangAltValue::toFloat(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = false;
|
|
Packit |
01d647 |
return 0.0f;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Rational LangAltValue::toRational(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
ok_ = false;
|
|
Packit |
01d647 |
return Rational(0, 0);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
LangAltValue* LangAltValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new LangAltValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DateValue::DateValue()
|
|
Packit |
01d647 |
: Value(date)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DateValue::DateValue(int year, int month, int day)
|
|
Packit |
01d647 |
: Value(date)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
date_.year = year;
|
|
Packit |
01d647 |
date_.month = month;
|
|
Packit |
01d647 |
date_.day = day;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DateValue::~DateValue()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int DateValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Hard coded to read Iptc style dates
|
|
Packit |
01d647 |
if (len != 8) {
|
|
Packit |
01d647 |
#ifndef SUPPRESS_WARNINGS
|
|
Packit |
01d647 |
EXV_WARNING << Error(kerUnsupportedDateFormat) << "\n";
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
return 1;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
// Make the buffer a 0 terminated C-string for sscanf
|
|
Packit |
01d647 |
char b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
Packit |
01d647 |
std::memcpy(b, reinterpret_cast<const char*>(buf), 8);
|
|
Packit |
01d647 |
int scanned = sscanf(b, "%4d%2d%2d",
|
|
Packit |
01d647 |
&date_.year, &date_.month, &date_.day);
|
|
Packit |
01d647 |
if (scanned != 3) {
|
|
Packit |
01d647 |
#ifndef SUPPRESS_WARNINGS
|
|
Packit |
01d647 |
EXV_WARNING << Error(kerUnsupportedDateFormat) << "\n";
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
return 1;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int DateValue::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Hard coded to read Iptc style dates
|
|
Packit |
01d647 |
if (buf.length() < 8) {
|
|
Packit |
01d647 |
#ifndef SUPPRESS_WARNINGS
|
|
Packit |
01d647 |
EXV_WARNING << Error(kerUnsupportedDateFormat) << "\n";
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
return 1;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
int scanned = sscanf(buf.c_str(), "%4d-%d-%d",
|
|
Packit |
01d647 |
&date_.year, &date_.month, &date_.day);
|
|
Packit |
01d647 |
if (scanned != 3) {
|
|
Packit |
01d647 |
#ifndef SUPPRESS_WARNINGS
|
|
Packit |
01d647 |
EXV_WARNING << Error(kerUnsupportedDateFormat) << "\n";
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
return 1;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
void DateValue::setDate(const Date& src)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
date_.year = src.year;
|
|
Packit |
01d647 |
date_.month = src.month;
|
|
Packit |
01d647 |
date_.day = src.day;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DateValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// sprintf wants to add the null terminator, so use oversized buffer
|
|
Packit |
01d647 |
char temp[9];
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int wrote = sprintf(temp, "%04d%02d%02d", date_.year, date_.month, date_.day);
|
|
Packit |
01d647 |
assert(wrote == 8);
|
|
Packit |
01d647 |
std::memcpy(buf, temp, wrote);
|
|
Packit |
01d647 |
return wrote;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
const DateValue::Date& DateValue::getDate() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return date_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DateValue::count() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return size();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DateValue::size() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return 8;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
DateValue* DateValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new DateValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& DateValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::ios::fmtflags f( os.flags() );
|
|
Packit |
01d647 |
os << date_.year << '-' << std::right
|
|
Packit |
01d647 |
<< std::setw(2) << std::setfill('0') << date_.month << '-'
|
|
Packit |
01d647 |
<< std::setw(2) << std::setfill('0') << date_.day;
|
|
Packit |
01d647 |
os.flags(f);
|
|
Packit |
01d647 |
return os;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long DateValue::toLong(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Range of tm struct is limited to about 1970 to 2038
|
|
Packit |
01d647 |
// This will return -1 if outside that range
|
|
Packit |
01d647 |
std::tm tms;
|
|
Packit |
01d647 |
std::memset(&tms, 0, sizeof(tms));
|
|
Packit |
01d647 |
tms.tm_mday = date_.day;
|
|
Packit |
01d647 |
tms.tm_mon = date_.month - 1;
|
|
Packit |
01d647 |
tms.tm_year = date_.year - 1900;
|
|
Packit |
01d647 |
long l = static_cast<long>(std::mktime(&tms));
|
|
Packit |
01d647 |
ok_ = (l != -1);
|
|
Packit |
01d647 |
return l;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
float DateValue::toFloat(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return static_cast<float>(toLong(n));
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Rational DateValue::toRational(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return Rational(toLong(n), 1);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
TimeValue::TimeValue()
|
|
Packit |
01d647 |
: Value(time)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
TimeValue::TimeValue(int hour, int minute,
|
|
Packit |
01d647 |
int second, int tzHour,
|
|
Packit |
01d647 |
int tzMinute)
|
|
Packit |
01d647 |
: Value(date)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
time_.hour = hour;
|
|
Packit |
01d647 |
time_.minute = minute;
|
|
Packit |
01d647 |
time_.second = second;
|
|
Packit |
01d647 |
time_.tzHour = tzHour;
|
|
Packit |
01d647 |
time_.tzMinute = tzMinute;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
TimeValue::~TimeValue()
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int TimeValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Make the buffer a 0 terminated C-string for scanTime[36]
|
|
Packit |
01d647 |
char b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
Packit |
01d647 |
std::memcpy(b, reinterpret_cast<const char*>(buf), (len < 12 ? len : 11));
|
|
Packit |
01d647 |
// Hard coded to read HHMMSS or Iptc style times
|
|
Packit |
01d647 |
int rc = 1;
|
|
Packit |
01d647 |
if (len == 6) {
|
|
Packit |
01d647 |
// Try to read (non-standard) HHMMSS format
|
|
Packit |
01d647 |
rc = scanTime3(b, "%2d%2d%2d");
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (len == 11) {
|
|
Packit |
01d647 |
rc = scanTime6(b, "%2d%2d%2d%1c%2d%2d");
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (rc) {
|
|
Packit |
01d647 |
rc = 1;
|
|
Packit |
01d647 |
#ifndef SUPPRESS_WARNINGS
|
|
Packit |
01d647 |
EXV_WARNING << Error(kerUnsupportedTimeFormat) << "\n";
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return rc;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int TimeValue::read(const std::string& buf)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Hard coded to read H:M:S or Iptc style times
|
|
Packit |
01d647 |
int rc = 1;
|
|
Packit |
01d647 |
if (buf.length() < 9) {
|
|
Packit |
01d647 |
// Try to read (non-standard) H:M:S format
|
|
Packit |
01d647 |
rc = scanTime3(buf.c_str(), "%d:%d:%d");
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
else {
|
|
Packit |
01d647 |
rc = scanTime6(buf.c_str(), "%d:%d:%d%1c%d:%d");
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
if (rc) {
|
|
Packit |
01d647 |
rc = 1;
|
|
Packit |
01d647 |
#ifndef SUPPRESS_WARNINGS
|
|
Packit |
01d647 |
EXV_WARNING << Error(kerUnsupportedTimeFormat) << "\n";
|
|
Packit |
01d647 |
#endif
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return rc;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int TimeValue::scanTime3(const char* buf, const char* format)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
int rc = 1;
|
|
Packit |
01d647 |
Time t;
|
|
Packit |
01d647 |
int scanned = sscanf(buf, format, &t.hour, &t.minute, &t.second);
|
|
Packit |
01d647 |
if ( scanned == 3
|
|
Packit |
01d647 |
&& t.hour >= 0 && t.hour < 24
|
|
Packit |
01d647 |
&& t.minute >= 0 && t.minute < 60
|
|
Packit |
01d647 |
&& t.second >= 0 && t.second < 60) {
|
|
Packit |
01d647 |
time_ = t;
|
|
Packit |
01d647 |
rc = 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return rc;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
int TimeValue::scanTime6(const char* buf, const char* format)
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
int rc = 1;
|
|
Packit |
01d647 |
Time t;
|
|
Packit |
01d647 |
char plusMinus;
|
|
Packit |
01d647 |
int scanned = sscanf(buf, format, &t.hour, &t.minute, &t.second,
|
|
Packit |
01d647 |
&plusMinus, &t.tzHour, &t.tzMinute);
|
|
Packit |
01d647 |
if ( scanned == 6
|
|
Packit |
01d647 |
&& t.hour >= 0 && t.hour < 24
|
|
Packit |
01d647 |
&& t.minute >= 0 && t.minute < 60
|
|
Packit |
01d647 |
&& t.second >= 0 && t.second < 60
|
|
Packit |
01d647 |
&& t.tzHour >= 0 && t.tzHour < 24
|
|
Packit |
01d647 |
&& t.tzMinute >= 0 && t.tzMinute < 60) {
|
|
Packit |
01d647 |
time_ = t;
|
|
Packit |
01d647 |
if (plusMinus == '-') {
|
|
Packit |
01d647 |
time_.tzHour *= -1;
|
|
Packit |
01d647 |
time_.tzMinute *= -1;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
rc = 0;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
return rc;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
void TimeValue::setTime( const Time& src )
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
std::memcpy(&time_, &src, sizeof(time_));
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long TimeValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
char temp[12];
|
|
Packit |
01d647 |
char plusMinus = '+';
|
|
Packit |
01d647 |
if (time_.tzHour < 0 || time_.tzMinute < 0)
|
|
Packit |
01d647 |
plusMinus = '-';
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
const int wrote = snprintf(temp, sizeof(temp), // 11 bytes are written + \0
|
|
Packit |
01d647 |
"%02d%02d%02d%1c%02d%02d",
|
|
Packit |
01d647 |
time_.hour, time_.minute, time_.second,
|
|
Packit |
01d647 |
plusMinus, abs(time_.tzHour), abs(time_.tzMinute));
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
enforce(wrote == 11, Exiv2::kerUnsupportedTimeFormat);
|
|
Packit |
01d647 |
std::memcpy(buf, temp, wrote);
|
|
Packit |
01d647 |
return wrote;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
const TimeValue::Time& TimeValue::getTime() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return time_;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long TimeValue::count() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return size();
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long TimeValue::size() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return 11;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
TimeValue* TimeValue::clone_() const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return new TimeValue(*this);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ostream& TimeValue::write(std::ostream& os) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
char plusMinus = '+';
|
|
Packit |
01d647 |
if (time_.tzHour < 0 || time_.tzMinute < 0) plusMinus = '-';
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
std::ios::fmtflags f( os.flags() );
|
|
Packit |
01d647 |
os << std::right
|
|
Packit |
01d647 |
<< std::setw(2) << std::setfill('0') << time_.hour << ':'
|
|
Packit |
01d647 |
<< std::setw(2) << std::setfill('0') << time_.minute << ':'
|
|
Packit |
01d647 |
<< std::setw(2) << std::setfill('0') << time_.second << plusMinus
|
|
Packit |
01d647 |
<< std::setw(2) << std::setfill('0') << abs(time_.tzHour) << ':'
|
|
Packit |
01d647 |
<< std::setw(2) << std::setfill('0') << abs(time_.tzMinute);
|
|
Packit |
01d647 |
os.flags(f);
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
return os;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
long TimeValue::toLong(long /*n*/) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
// Returns number of seconds in the day in UTC.
|
|
Packit |
01d647 |
long result = (time_.hour - time_.tzHour) * 60 * 60;
|
|
Packit |
01d647 |
result += (time_.minute - time_.tzMinute) * 60;
|
|
Packit |
01d647 |
result += time_.second;
|
|
Packit |
01d647 |
if (result < 0) {
|
|
Packit |
01d647 |
result += 86400;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
ok_ = true;
|
|
Packit |
01d647 |
return result;
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
float TimeValue::toFloat(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return static_cast<float>(toLong(n));
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
Rational TimeValue::toRational(long n) const
|
|
Packit |
01d647 |
{
|
|
Packit |
01d647 |
return Rational(toLong(n), 1);
|
|
Packit |
01d647 |
}
|
|
Packit |
01d647 |
|
|
Packit |
01d647 |
} // namespace Exiv2
|