Don't clear field before parsing by default

This commit is contained in:
Martchus 2018-03-11 22:27:12 +01:00
parent 8d91886b14
commit 59024a66a0
12 changed files with 26 additions and 40 deletions

View File

@ -221,7 +221,7 @@ template <class ImplementationType> inline void TagField<ImplementationType>::se
} }
/*! /*!
* \brief Clears id, value, type info and sets default flag to false. * \brief Clears id, value, type info, sets default flag to false and resets further implementation specific values.
*/ */
template <class ImplementationType> void TagField<ImplementationType>::clear() template <class ImplementationType> void TagField<ImplementationType>::clear()
{ {
@ -230,7 +230,7 @@ template <class ImplementationType> void TagField<ImplementationType>::clear()
m_typeInfo = TypeInfoType(); m_typeInfo = TypeInfoType();
m_typeInfoAssigned = false; m_typeInfoAssigned = false;
m_default = true; m_default = true;
static_cast<ImplementationType *>(this)->cleared(); static_cast<ImplementationType *>(this)->reset();
} }
/*! /*!

View File

@ -111,7 +111,6 @@ template <class stringtype> int parseGenreIndex(const stringtype &denotation)
*/ */
void Id3v2Frame::parse(BinaryReader &reader, uint32 version, uint32 maximalSize, Diagnostics &diag) void Id3v2Frame::parse(BinaryReader &reader, uint32 version, uint32 maximalSize, Diagnostics &diag)
{ {
clear();
static const string defaultContext("parsing ID3v2 frame"); static const string defaultContext("parsing ID3v2 frame");
string context; string context;
@ -335,9 +334,9 @@ void Id3v2Frame::make(BinaryWriter &writer, byte version, Diagnostics &diag)
} }
/*! /*!
* \brief Ensures the field is cleared. * \brief Resets ID3v2-specific values. Called via clear().
*/ */
void Id3v2Frame::clear() void Id3v2Frame::reset()
{ {
m_flag = 0; m_flag = 0;
m_group = 0; m_group = 0;

View File

@ -138,10 +138,8 @@ public:
static IdentifierType fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); static IdentifierType fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos);
static std::string fieldIdToString(IdentifierType id); static std::string fieldIdToString(IdentifierType id);
protected:
void clear();
private: private:
void reset();
uint32 m_parsedVersion; uint32 m_parsedVersion;
uint32 m_dataSize; uint32 m_dataSize;
uint32 m_totalSize; uint32 m_totalSize;

View File

@ -300,20 +300,17 @@ void Id3v2Tag::parse(istream &stream, const uint64 maximalSize, Diagnostics &dia
// read frames // read frames
auto pos = stream.tellg(); auto pos = stream.tellg();
Id3v2Frame frame;
while (bytesRemaining) { while (bytesRemaining) {
// seek to next frame // seek to next frame
stream.seekg(pos); stream.seekg(pos);
// parse frame // parse frame
Id3v2Frame frame;
try { try {
frame.parse(reader, majorVersion, bytesRemaining, diag); frame.parse(reader, majorVersion, bytesRemaining, diag);
if (frame.id()) { if (Id3v2FrameIds::isTextFrame(frame.id()) && fields().count(frame.id()) == 1) {
// add frame if parsing was successfull diag.emplace_back(DiagLevel::Warning, "The text frame " % frame.frameIdString() + " exists more than once.", context);
if (Id3v2FrameIds::isTextFrame(frame.id()) && fields().count(frame.id()) == 1) {
diag.emplace_back(DiagLevel::Warning, "The text frame " % frame.frameIdString() + " exists more than once.", context);
}
fields().insert(make_pair(frame.id(), frame));
} }
fields().emplace(frame.id(), move(frame));
} catch (const NoDataFoundException &) { } catch (const NoDataFoundException &) {
if (frame.hasPaddingReached()) { if (frame.hasPaddingReached()) {
m_paddingSize = startOffset + m_size - pos; m_paddingSize = startOffset + m_size - pos;

View File

@ -115,18 +115,17 @@ void MatroskaTag::parse(EbmlElement &tagElement, Diagnostics &diag)
static const string context("parsing Matroska tag"); static const string context("parsing Matroska tag");
tagElement.parse(diag); tagElement.parse(diag);
m_size = tagElement.totalSize(); m_size = tagElement.totalSize();
MatroskaTagField field;
for (EbmlElement *child = tagElement.firstChild(); child; child = child->nextSibling()) { for (EbmlElement *child = tagElement.firstChild(); child; child = child->nextSibling()) {
child->parse(diag); child->parse(diag);
switch (child->id()) { switch (child->id()) {
case MatroskaIds::SimpleTag: { case MatroskaIds::SimpleTag:
try { try {
MatroskaTagField field;
field.reparse(*child, diag, true); field.reparse(*child, diag, true);
fields().insert(make_pair(field.id(), field)); fields().emplace(field.id(), move(field));
} catch (const Failure &) { } catch (const Failure &) {
} }
break; break;
}
case MatroskaIds::Targets: case MatroskaIds::Targets:
parseTargets(*child, diag); parseTargets(*child, diag);
break; break;

View File

@ -47,7 +47,6 @@ MatroskaTagField::MatroskaTagField(const string &id, const TagValue &value)
void MatroskaTagField::reparse(EbmlElement &simpleTagElement, Diagnostics &diag, bool parseNestedFields) void MatroskaTagField::reparse(EbmlElement &simpleTagElement, Diagnostics &diag, bool parseNestedFields)
{ {
string context("parsing Matroska tag field"); string context("parsing Matroska tag field");
clear();
simpleTagElement.parse(diag); simpleTagElement.parse(diag);
bool tagDefaultFound = false; bool tagDefaultFound = false;
for (EbmlElement *child = simpleTagElement.firstChild(); child; child = child->nextSibling()) { for (EbmlElement *child = simpleTagElement.firstChild(); child; child = child->nextSibling()) {

View File

@ -78,8 +78,8 @@ public:
static typename std::string fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); static typename std::string fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos);
static std::string fieldIdToString(const std::string &id); static std::string fieldIdToString(const std::string &id);
protected: private:
void cleared(); void reset();
}; };
/*! /*!
@ -117,9 +117,9 @@ inline std::string MatroskaTagField::fieldIdToString(const std::string &id)
} }
/*! /*!
* \brief Ensures the field is cleared. * \brief Resets Matroska-specific values. Called via clear().
*/ */
inline void MatroskaTagField::cleared() inline void MatroskaTagField::reset()
{ {
} }

View File

@ -352,12 +352,12 @@ void Mp4Tag::parse(Mp4Atom &metaAtom, Diagnostics &diag)
diag.emplace_back(DiagLevel::Critical, "Unable to parse child atoms of meta atom (stores hdlr and ilst atoms).", context); diag.emplace_back(DiagLevel::Critical, "Unable to parse child atoms of meta atom (stores hdlr and ilst atoms).", context);
} }
if (subAtom) { if (subAtom) {
Mp4TagField tagField;
for (auto *child = subAtom->firstChild(); child; child = child->nextSibling()) { for (auto *child = subAtom->firstChild(); child; child = child->nextSibling()) {
Mp4TagField tagField;
try { try {
child->parse(diag); child->parse(diag);
tagField.reparse(*child, diag); tagField.reparse(*child, diag);
fields().emplace(child->id(), tagField); fields().emplace(child->id(), move(tagField));
} catch (const Failure &) { } catch (const Failure &) {
} }
} }

View File

@ -77,7 +77,6 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
using namespace Mp4AtomIds; using namespace Mp4AtomIds;
using namespace Mp4TagAtomIds; using namespace Mp4TagAtomIds;
string context("parsing MP4 tag field"); string context("parsing MP4 tag field");
clear(); // clear old values
ilstChild.parse(diag); // ensure child has been parsed ilstChild.parse(diag); // ensure child has been parsed
setId(ilstChild.id()); setId(ilstChild.id());
context = "parsing MP4 tag field " + ilstChild.idToString(); context = "parsing MP4 tag field " + ilstChild.idToString();
@ -425,9 +424,9 @@ uint32 Mp4TagField::appropriateRawDataType() const
} }
/*! /*!
* \brief Ensures the field is cleared. * \brief Resets MP4-specific values. Called via clear().
*/ */
void Mp4TagField::cleared() void Mp4TagField::reset()
{ {
m_name.clear(); m_name.clear();
m_mean.clear(); m_mean.clear();

View File

@ -121,10 +121,8 @@ public:
static IdentifierType fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); static IdentifierType fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos);
static std::string fieldIdToString(IdentifierType id); static std::string fieldIdToString(IdentifierType id);
protected:
void cleared();
private: private:
void reset();
std::string m_name; std::string m_name;
std::string m_mean; std::string m_mean;
uint32 m_parsedRawDataType; uint32 m_parsedRawDataType;

View File

@ -144,13 +144,12 @@ template <class StreamType> void VorbisComment::internalParse(StreamType &stream
CHECK_MAX_SIZE(4); CHECK_MAX_SIZE(4);
stream.read(sig, 4); stream.read(sig, 4);
uint32 fieldCount = LE::toUInt32(sig); uint32 fieldCount = LE::toUInt32(sig);
VorbisCommentField field;
const string &fieldId = field.id();
for (uint32 i = 0; i < fieldCount; ++i) { for (uint32 i = 0; i < fieldCount; ++i) {
// read fields // read fields
VorbisCommentField field;
try { try {
field.parse(stream, maxSize, diag); field.parse(stream, maxSize, diag);
fields().emplace(fieldId, field); fields().emplace(field.id(), move(field));
} catch (const TruncatedDataException &) { } catch (const TruncatedDataException &) {
throw; throw;
} catch (const Failure &) { } catch (const Failure &) {

View File

@ -61,10 +61,8 @@ public:
static typename std::string fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); static typename std::string fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos);
static std::string fieldIdToString(const std::string &id); static std::string fieldIdToString(const std::string &id);
protected:
void cleared();
private: private:
void reset();
template <class StreamType> void internalParse(StreamType &stream, uint64 &maxSize, Diagnostics &diag); template <class StreamType> void internalParse(StreamType &stream, uint64 &maxSize, Diagnostics &diag);
}; };
@ -103,9 +101,9 @@ inline std::string VorbisCommentField::fieldIdToString(const std::string &id)
} }
/*! /*!
* \brief Ensures the field is cleared. * \brief Resets Vorbis Comment-specific values. Called via clear().
*/ */
inline void VorbisCommentField::cleared() inline void VorbisCommentField::reset()
{ {
} }