small improvements

- fixed some mostly ID3/MP3 related bugs
- added convenience methods/operators
This commit is contained in:
Martchus 2016-03-18 21:43:09 +01:00
parent 2af5ce997b
commit 899e2a97fe
15 changed files with 199 additions and 71 deletions

View File

@ -58,7 +58,7 @@ void BasicFileInfo::open(bool readOnly)
*/
void BasicFileInfo::reopen(bool readOnly)
{
close();
invalidated();
m_file.open(m_path, (m_readOnly = readOnly) ? ios_base::in | ios_base::binary : ios_base::in | ios_base::out | ios_base::binary);
m_file.seekg(0, ios_base::end);
m_size = m_file.tellg();
@ -76,6 +76,14 @@ void BasicFileInfo::close()
m_file.clear();
}
/*!
* \brief Invalidates the file info manually.
*/
void BasicFileInfo::invalidate()
{
invalidated();
}
/*!
* \brief Sets the current file.
*
@ -202,7 +210,7 @@ string BasicFileInfo::containingDirectory() const
/*!
* \brief This function is called when the BasicFileInfo gets invalidated.
* This is the case when the current file changes.
* This is the case when the current file changes or is reopened.
*
* When subclassing and overwriting this virtual method invoke the base
* implementation by calling BasicFileInfo::invalidated() before the reimplemented code.
@ -210,7 +218,6 @@ string BasicFileInfo::containingDirectory() const
void BasicFileInfo::invalidated()
{
m_size = 0;
m_path.clear();
close();
}

View File

@ -22,6 +22,7 @@ public:
bool isOpen() const;
bool isReadOnly() const;
void close();
void invalidate();
const std::string &path() const;
void setPath(const std::string &path);

View File

@ -123,7 +123,7 @@ void Id3v1Tag::make(ostream &stream)
// track
try {
if(!m_trackPos.isEmpty() && m_trackPos.type() == TagDataType::PositionInSet)
buffer[1] = m_trackPos.toPositionIntSet().position();
buffer[1] = m_trackPos.toPositionInSet().position();
} catch(ConversionException &) {
addNotification(NotificationType::Warning, "Track position field can not be set because given value can not be converted appropriately.", context);
}

View File

@ -108,6 +108,7 @@ int parseGenreIndex(const stringtype &denotation, bool isBigEndian = false)
void Id3v2Frame::parse(BinaryReader &reader, const uint32 version, const uint32 maximalSize)
{
invalidateStatus();
clear();
string context("parsing ID3v2 frame");
// parse header
@ -115,13 +116,13 @@ void Id3v2Frame::parse(BinaryReader &reader, const uint32 version, const uint32
// parse header for ID3v2.1 and ID3v2.2
// -> read ID
setId(reader.readUInt24BE());
if((id() & 0xFFFF0000u) == 0) {
if(id() & 0xFFFF0000u) {
m_padding = false;
} else {
// padding reached
m_padding = true;
addNotification(NotificationType::Debug, "Frame ID starts with null-byte -> padding reached.", context);
throw NoDataFoundException();
} else {
m_padding = false;
}
// -> update context
@ -143,13 +144,13 @@ void Id3v2Frame::parse(BinaryReader &reader, const uint32 version, const uint32
// parse header for ID3v2.3 and ID3v2.4
// -> read ID
setId(reader.readUInt32BE());
if((id() & 0xFF000000u) == 0) {
if(id() & 0xFF000000u) {
m_padding = false;
} else {
// padding reached
m_padding = true;
addNotification(NotificationType::Debug, "Frame ID starts with null-byte -> padding reached.", context);
throw NoDataFoundException();
} else {
m_padding = false;
}
// -> update context
@ -232,7 +233,7 @@ void Id3v2Frame::parse(BinaryReader &reader, const uint32 version, const uint32
position = PositionInSet(parseString(buffer.get() + 1, m_dataSize - 1, dataEncoding));
}
value().assignPosition(position);
} catch(ConversionException &) {
} catch(const ConversionException &) {
addNotification(NotificationType::Warning, "The value of track/disk position frame is not numeric and will be ignored.", context);
}
@ -246,7 +247,7 @@ void Id3v2Frame::parse(BinaryReader &reader, const uint32 version, const uint32
milliseconds = ConversionUtilities::stringToNumber<double>(parseString(buffer.get() + 1, m_dataSize - 1, dataEncoding), 10);
}
value().assignTimeSpan(TimeSpan::fromMilliseconds(milliseconds));
} catch (ConversionException &) {
} catch (const ConversionException &) {
addNotification(NotificationType::Warning, "The value of the length frame is not numeric and will be ignored.", context);
}
@ -440,7 +441,7 @@ Id3v2FrameMaker::Id3v2FrameMaker(Id3v2Frame &frame, const byte version) :
// just write the data
copy(m_frame.value().dataPointer(), m_frame.value().dataPointer() + m_decompressedSize, m_data.get());
}
} catch(ConversionException &) {
} catch(const ConversionException &) {
m_frame.addNotification(NotificationType::Critical, "Assigned value can not be converted appropriately.", context);
throw InvalidDataException();
}
@ -739,21 +740,23 @@ void Id3v2Frame::parsePicture(const char *buffer, size_t maxSize, TagValue &tagV
}
/*!
* \brief Parses the comment from the specified \a buffer.
* \brief Parses the comment/unsynchronized lyrics from the specified \a buffer.
* \param buffer Specifies the buffer holding the picture.
* \param dataSize Specifies the maximal number of bytes to read from the buffer.
* \param tagValue Specifies the tag value used to store the results.
*/
void Id3v2Frame::parseComment(const char *buffer, size_t dataSize, TagValue &tagValue)
{
static const string context("parsing comment frame");
static const string context("parsing comment/unsynchronized lyrics frame");
const char *end = buffer + dataSize;
if(dataSize < 6) {
addNotification(NotificationType::Critical, "Comment frame is incomplete.", context);
throw TruncatedDataException();
}
TagTextEncoding dataEncoding = parseTextEncodingByte(*buffer);
tagValue.setLanguage(string(++buffer, 3));
if(*(++buffer)) {
tagValue.setLanguage(string(buffer, 3));
}
auto substr = parseSubstring(buffer += 3, dataSize -= 4, dataEncoding, true);
tagValue.setDescription(string(get<0>(substr), get<1>(substr)), dataEncoding);
if(get<2>(substr) >= end) {

View File

@ -21,7 +21,6 @@ enum KnownValue : uint32 {
lEncoder = 0x54454e43,
lBpm = 0x5442504d,
lCover = 0x41504943,
//lPerformers = 0x54504532,
lWriter = 0x54455854,
lLength = 0x544c454e,
lLanguage = 0x544c414e,
@ -45,7 +44,6 @@ enum KnownValue : uint32 {
sEncoder = 0x54454e,
sBpm = 0x544250,
sCover = 0x504943,
//sPerformers = 0x545032,
sWriter = 0x545854,
sLength = 0x544c45,
sLanguage = 0x544c41,

View File

@ -204,7 +204,7 @@ inline LIB_EXPORT const char *icra() {
}
inline LIB_EXPORT const char *dateRelease() {
return "DATE_RELEASE";
return "DATE_RELEASED";
}
inline LIB_EXPORT const char *dateRecorded() {
return "DATE_RECORDED";

View File

@ -920,7 +920,7 @@ bool MediaFileInfo::removeAllId3v2Tags()
*/
Id3v2Tag *MediaFileInfo::createId3v2Tag()
{
if(!m_id3v2Tags.size()) {
if(m_id3v2Tags.empty()) {
m_id3v2Tags.emplace_back(make_unique<Id3v2Tag>());
}
return m_id3v2Tags.front().get();
@ -1048,9 +1048,7 @@ bool MediaFileInfo::areTagsSupported() const
/*!
* \brief Returns a pointer to the assigned MP4 tag or nullptr if none is assigned.
*
* \remarks The MediaFileInfo keeps the ownership over the returned
* pointer. The returned MP4 tag will be destroyed when the
* \remarks The MediaFileInfo keeps the ownership over the object which will be destroyed when the
* MediaFileInfo is invalidated.
*/
Mp4Tag *MediaFileInfo::mp4Tag() const
@ -1061,7 +1059,6 @@ Mp4Tag *MediaFileInfo::mp4Tag() const
/*!
* \brief Returns pointers to the assigned Matroska tags.
*
* \remarks The MediaFileInfo keeps the ownership over the returned
* pointers. The returned Matroska tags will be destroyed when the
* MediaFileInfo is invalidated.
@ -1077,11 +1074,20 @@ const vector<unique_ptr<MatroskaTag> > &MediaFileInfo::matroskaTags() const
}
}
/*!
* \brief Returns a pointer to the first assigned Vorbis comment or nullptr if none is assigned.
* \remarks The MediaFileInfo keeps the ownership over the object which will be destroyed when the
* MediaFileInfo is invalidated.
*/
VorbisComment *MediaFileInfo::vorbisComment() const
{
return m_containerFormat == ContainerFormat::Ogg && m_container && m_container->tagCount() > 0 ? static_cast<OggContainer *>(m_container.get())->tags().front().get() : nullptr;
}
/*!
* \brief Returns all chapters assigned to the current file.
*
* \remarks The MediaFileInfo keeps the ownership over the chapters which will be
* destroyed when the MediaFileInfo is invalidated.
* \remarks The MediaFileInfo keeps the ownership over the object which will be destroyed when the
* MediaFileInfo is invalidated.
*/
vector<AbstractChapter *> MediaFileInfo::chapters() const
{
@ -1098,9 +1104,8 @@ vector<AbstractChapter *> MediaFileInfo::chapters() const
/*!
* \brief Returns all attachments assigned to the current file.
*
* \remarks The MediaFileInfo keeps the ownership over the attachments which will be
* destroyed when the MediaFileInfo is invalidated.
* \remarks The MediaFileInfo keeps the ownership over the object which will be destroyed when the
* MediaFileInfo is invalidated.
*/
vector<AbstractAttachment *> MediaFileInfo::attachments() const
{
@ -1184,7 +1189,6 @@ NotificationType MediaFileInfo::worstNotificationTypeIncludingRelatedObjects() c
/*!
* \brief Returns the notifications of the current instance and all related
* objects (tracks, tags, container, ...).
*
* \remarks The specified list is not cleared before notifications are added.
*/
void MediaFileInfo::gatherRelatedNotifications(NotificationList &notifications) const
@ -1390,23 +1394,32 @@ void MediaFileInfo::makeMp3File()
addNotifications(*tag);
}
// determine padding, check whether rewrite is required
// check whether rewrite is required
bool rewriteRequired = isForcingRewrite() || (tagsSize > static_cast<uint32>(m_containerOffset));
uint32 padding;
uint32 padding = 0;
if(!rewriteRequired) {
// rewriting is not forced and new tag is not too big for available space
// -> calculate new padding
padding = static_cast<uint32>(m_containerOffset) - tagsSize;
// check whether padding matches specifications
// -> check whether the new padding matches specifications
if(padding < minPadding() || padding > maxPadding()) {
rewriteRequired = true;
}
}
if(rewriteRequired) {
// use preferred padding when rewriting
if(makers.empty()) {
// an ID3v2 tag shouldn't be written
// -> can't include padding
if(padding) {
// but padding would be present -> need to rewrite
padding = 0;
rewriteRequired = true;
}
} else if(rewriteRequired) {
// rewriting is forced or new ID3v2 tag is too big for available space
// -> use preferred padding when rewriting anyways
padding = preferredPadding();
updateStatus("Preparing streams for rewriting ...");
} else {
updateStatus("Preparing streams for updating ...");
}
updateStatus(rewriteRequired ? "Preparing streams for rewriting ..." : "Preparing streams for updating ...");
// setup stream(s) for writing
// -> define variables needed to handle output stream and backup stream (required when rewriting the file)
@ -1449,7 +1462,7 @@ void MediaFileInfo::makeMp3File()
// include padding into the last ID3v2 tag
makers.back().make(outputStream, padding);
} else {
// no ID3v2 tags assigned -> just write padding
// just write padding
for(; padding; --padding) {
outputStream.put(0);
}

View File

@ -26,6 +26,7 @@ class MatroskaTag;
class AbstractTrack;
class WaveAudioStream;
class MpegAudioFrameStream;
class VorbisComment;
enum class MediaType;
enum class TagType : unsigned int;
@ -117,6 +118,7 @@ public:
std::vector<Tag *> tags() const;
Mp4Tag *mp4Tag() const;
const std::vector<std::unique_ptr<MatroskaTag> > &matroskaTags() const;
VorbisComment *vorbisComment() const;
bool areTagsSupported() const;
// methods to create/remove tags

View File

@ -771,7 +771,7 @@ calculatePadding:
reset();
try {
parseTracks();
} catch(Failure &) {
} catch(const Failure &) {
addNotification(NotificationType::Critical, "Unable to reparse the header of the new file.", context);
throw;
}
@ -931,11 +931,11 @@ void Mp4Container::updateOffsets(const std::vector<int64> &oldMdatOffsets, const
addNotification(NotificationType::Warning, "traf atom stores multiple tfhd atoms but it should only contain exactly one tfhd atom.", context);
}
}
} catch(Failure &) {
} catch(const Failure &) {
addNotification(NotificationType::Critical, "Unable to parse childs of top-level atom moof.", context);
}
}
} catch(Failure &) {
} catch(const Failure &) {
addNotification(NotificationType::Critical, "Unable to parse top-level atom moof.", context);
}
// update each track
@ -946,7 +946,7 @@ void Mp4Container::updateOffsets(const std::vector<int64> &oldMdatOffsets, const
if(!track->isHeaderValid()) {
try {
track->parseHeader();
} catch(Failure &) {
} catch(const Failure &) {
addNotification(NotificationType::Warning, "The chunk offsets of track " + track->name() + " couldn't be updated because the track seems to be invalid..", context);
throw;
}
@ -954,7 +954,7 @@ void Mp4Container::updateOffsets(const std::vector<int64> &oldMdatOffsets, const
if(track->isHeaderValid()) {
try {
track->updateChunkOffsets(oldMdatOffsets, newMdatOffsets);
} catch(Failure &) {
} catch(const Failure &) {
addNotification(NotificationType::Warning, "The chunk offsets of track " + track->name() + " couldn't be updated.", context);
throw;
}

View File

@ -455,7 +455,7 @@ Mp4TagFieldMaker::Mp4TagFieldMaker(Mp4TagField &field) :
// track number and disk number are exceptions
// raw data type 0 is used, information is stored as pair of unsigned integers
case Mp4TagAtomIds::TrackPosition: case Mp4TagAtomIds::DiskPosition: {
PositionInSet pos = m_field.value().toPositionIntSet();
PositionInSet pos = m_field.value().toPositionInSet();
m_writer.writeInt32BE(pos.position());
if(pos.total() <= numeric_limits<int16>::max()) {
m_writer.writeInt16BE(static_cast<int16>(pos.total()));

View File

@ -280,12 +280,12 @@ void OggContainer::internalMakeFile()
}
// clear iterator
m_iterator = OggIterator(fileInfo().stream(), startOffset(), fileInfo().size());
} catch(OperationAbortedException &) {
} catch(const OperationAbortedException &) {
addNotification(NotificationType::Information, "Rewriting file to apply new tag information has been aborted.", context);
BackupHelper::restoreOriginalFileFromBackupFile(fileInfo().path(), backupPath, fileInfo().stream(), backupStream);
m_iterator.setStream(fileInfo().stream());
throw;
} catch(ios_base::failure &ex) {
} catch(const ios_base::failure &ex) {
addNotification(NotificationType::Critical, "IO error occured when rewriting file to apply new tag information.\n" + string(ex.what()), context);
BackupHelper::restoreOriginalFileFromBackupFile(fileInfo().path(), backupPath, fileInfo().stream(), backupStream);
m_iterator.setStream(fileInfo().stream());

View File

@ -39,10 +39,10 @@ public:
bool bytesRemaining(size_t atLeast) const;
operator bool() const;
OggIterator &operator ++();
OggIterator operator ++(int);
OggIterator &operator --();
OggIterator operator --(int);
OggIterator &operator++();
OggIterator operator++(int);
OggIterator &operator--();
OggIterator operator--(int);
private:
bool fetchNextPage();
@ -256,7 +256,7 @@ inline bool OggIterator::bytesRemaining(size_t atLeast) const
/*!
* \brief Increments the current position by one segment if the iterator is valid; otherwise nothing happens.
*/
inline OggIterator &OggIterator::operator ++()
inline OggIterator &OggIterator::operator++()
{
nextSegment();
return *this;
@ -265,7 +265,7 @@ inline OggIterator &OggIterator::operator ++()
/*!
* \brief Increments the current position by one segment if the iterator is valid; otherwise nothing happens.
*/
inline OggIterator OggIterator::operator ++(int)
inline OggIterator OggIterator::operator++(int)
{
OggIterator tmp = *this;
nextSegment();
@ -275,7 +275,7 @@ inline OggIterator OggIterator::operator ++(int)
/*!
* \brief Decrements the current position by one segment if the iterator is valid; otherwise nothing happens.
*/
inline OggIterator &OggIterator::operator --()
inline OggIterator &OggIterator::operator--()
{
previousSegment();
return *this;
@ -284,7 +284,7 @@ inline OggIterator &OggIterator::operator --()
/*!
* \brief Decrements the current position by one segment if the iterator is valid; otherwise nothing happens.
*/
inline OggIterator OggIterator::operator --(int)
inline OggIterator OggIterator::operator--(int)
{
OggIterator tmp = *this;
previousSegment();

View File

@ -26,6 +26,7 @@ public:
constexpr int32 position() const;
constexpr int32 total() const;
constexpr bool isNull() const;
constexpr bool operator==(const PositionInSet &other) const;
template <typename StringType = std::string>
StringType toString() const;
@ -91,6 +92,14 @@ constexpr inline bool PositionInSet::isNull() const
return m_position == 0 && m_total == 0;
}
/*!
* \brief Returns whether this instance equals \a other.
*/
constexpr inline bool PositionInSet::operator==(const PositionInSet &other) const
{
return m_position == other.m_position && m_total == other.m_total;
}
/*!
* \brief Returns the string representation of the current PositionInSet.
*/

View File

@ -9,6 +9,7 @@
#include <algorithm>
#include <utility>
#include <cstring>
using namespace std;
using namespace ConversionUtilities;
@ -119,7 +120,7 @@ TagValue::TagValue(const PositionInSet &value) :
TagValue::TagValue(const TagValue &other) :
m_size(other.m_size),
m_type(other.m_type),
m_dec(other.m_dec),
m_desc(other.m_desc),
m_mimeType(other.m_mimeType),
m_lng(other.m_lng),
m_labeledAsReadonly(other.m_labeledAsReadonly),
@ -140,7 +141,7 @@ TagValue &TagValue::operator=(const TagValue &other)
if(this != &other) {
m_size = other.m_size;
m_type = other.m_type;
m_dec = other.m_dec;
m_desc = other.m_desc;
m_mimeType = other.m_mimeType;
m_lng = other.m_lng;
m_labeledAsReadonly = other.m_labeledAsReadonly;
@ -156,6 +157,45 @@ TagValue &TagValue::operator=(const TagValue &other)
return *this;
}
/*!
* \brief Returns whether both instances are equal.
*
* Both instances are only considered equal, if the data type, encodings (if relevant for the type) and meta data are equal.
*/
bool TagValue::operator==(const TagValue &other) const
{
if(m_type != other.m_type || m_desc != other.m_desc || (!m_desc.empty() && m_descEncoding != other.m_descEncoding)
|| m_mimeType != other.m_mimeType || m_lng != other.m_lng || m_labeledAsReadonly != other.m_labeledAsReadonly) {
return false;
}
switch(m_type) {
case TagDataType::Text:
if(m_size != other.m_size && m_encoding != other.m_encoding) {
return false;
}
return strncmp(m_ptr.get(), other.m_ptr.get(), m_size) == 0;
case TagDataType::PositionInSet:
return toPositionInSet() == other.toPositionInSet();
case TagDataType::Integer:
return toInteger() == other.toInteger();
case TagDataType::StandardGenreIndex:
return toStandardGenreIndex() == other.toStandardGenreIndex();
case TagDataType::TimeSpan:
return toTimeSpan() == other.toTimeSpan();
case TagDataType::DateTime:
return toDateTime() == other.toDateTime();
case TagDataType::Picture:
case TagDataType::Binary:
case TagDataType::Undefined:
if(m_size != other.m_size) {
return false;
}
return strncmp(m_ptr.get(), other.m_ptr.get(), m_size) == 0;
default:
return false;
}
}
/*!
* \brief Destroys the TagValue.
*/
@ -171,7 +211,7 @@ TagValue::~TagValue()
*/
void TagValue::clearMetadata()
{
m_dec.clear();
m_desc.clear();
m_mimeType.clear();
m_lng.clear();
m_labeledAsReadonly = false;
@ -260,7 +300,7 @@ int TagValue::toStandardGenreIndex() const
* PositionInSet representation.
* \throws Throws ConversionException an failure.
*/
PositionInSet TagValue::toPositionIntSet() const
PositionInSet TagValue::toPositionInSet() const
{
if(!isEmpty()) {
switch(m_type) {
@ -293,7 +333,7 @@ TimeSpan TagValue::toTimeSpan() const
if(!isEmpty()) {
switch(m_type) {
case TagDataType::Text:
return TimeSpan::fromSeconds(ConversionUtilities::stringToNumber<int64>(string(m_ptr.get(), m_size)));
return TimeSpan::fromString(string(m_ptr.get(), m_size));
case TagDataType::Integer:
case TagDataType::TimeSpan:
switch(m_size) {
@ -366,7 +406,7 @@ void TagValue::toString(string &result) const
result = ConversionUtilities::numberToString(toInteger());
return;
case TagDataType::PositionInSet:
result = toPositionIntSet().toString();
result = toPositionInSet().toString();
return;
case TagDataType::StandardGenreIndex:
if(const char *genreName = Id3Genres::stringFromIndex(toInteger())) {
@ -386,6 +426,56 @@ void TagValue::toString(string &result) const
result.clear();
}
/*!
* \brief Converts the value of the current TagValue object to its equivalent
* std::wstring representation.
* \throws Throws ConversionException on failure.
* \remarks Use this only, if UTF-16 text is assigned.
*/
u16string TagValue::toWString() const
{
u16string res;
toWString(res);
return res;
}
/*!
* \brief Converts the value of the current TagValue object to its equivalent
* std::u16string representation.
* \throws Throws ConversionException on failure.
* \remarks Use this only, if UTF-16 text is assigned.
*/
void TagValue::toWString(u16string &result) const
{
if(!isEmpty()) {
switch(m_type) {
case TagDataType::Text:
result.assign(reinterpret_cast<typename u16string::value_type *>(m_ptr.get()), m_size / sizeof(typename u16string::value_type));
return;
case TagDataType::Integer:
result = ConversionUtilities::numberToString<int32, u16string>(toInteger());
return;
case TagDataType::PositionInSet:
result = toPositionInSet().toString<u16string>();
return;
case TagDataType::StandardGenreIndex:
if(const char *genreName = Id3Genres::stringFromIndex(toInteger())) {
// TODO: implement this
throw ConversionException("Wide default genre strings are currently not supported.");
} else {
throw ConversionException("No string representation for the assigned standard genre index available.");
}
break;
case TagDataType::TimeSpan:
// TODO: implement this
throw ConversionException("Wide time span string representations are currently not supported.");
default:
throw ConversionException("Can not convert binary data/picture to string.");
}
}
result.clear();
}
/*!
* \brief Assigns a copy of the given \a text.
* \param text Specifies the text to be assigned.
@ -438,15 +528,17 @@ void TagValue::assignStandardGenreIndex(int index)
*/
void TagValue::assignData(const char *data, size_t length, TagDataType type, TagTextEncoding encoding)
{
m_size = length;
m_type = type;
m_encoding = encoding;
if(m_size > 0) {
m_ptr.reset(new char[m_size]);
if(length > m_size) {
m_ptr = make_unique<char[]>(length);
}
if(length) {
std::copy(data, data + length, m_ptr.get());
} else {
m_ptr.reset();
}
m_size = length;
m_type = type;
m_encoding = encoding;
}
/*!

View File

@ -75,6 +75,7 @@ public:
// operators
TagValue &operator=(const TagValue &other);
TagValue &operator=(TagValue &&other) = default;
bool operator==(const TagValue &other) const;
// methods
bool isEmpty() const;
@ -84,9 +85,11 @@ public:
TagDataType type() const;
std::string toString() const;
void toString(std::string &result) const;
std::u16string toWString() const;
void toWString(std::u16string &result) const;
int32 toInteger() const;
int toStandardGenreIndex() const;
PositionInSet toPositionIntSet() const;
PositionInSet toPositionInSet() const;
ChronoUtilities::TimeSpan toTimeSpan() const;
ChronoUtilities::DateTime toDateTime() const;
size_t dataSize() const;
@ -118,7 +121,7 @@ private:
std::unique_ptr<char[]> m_ptr;
std::string::size_type m_size;
TagDataType m_type;
std::string m_dec;
std::string m_desc;
std::string m_mimeType;
std::string m_lng;
bool m_labeledAsReadonly;
@ -212,7 +215,7 @@ inline char *TagValue::dataPointer() const
*/
inline const std::string &TagValue::description() const
{
return m_dec;
return m_desc;
}
/*!
@ -225,7 +228,7 @@ inline const std::string &TagValue::description() const
*/
inline void TagValue::setDescription(const std::string &value, TagTextEncoding encoding)
{
m_dec = value;
m_desc = value;
m_descEncoding = encoding;
}