Use "..." to implement subelementByPath
This commit is contained in:
parent
88edd43f8c
commit
091fa1daf7
|
@ -101,8 +101,8 @@ public:
|
||||||
const ImplementationType* firstChild() const;
|
const ImplementationType* firstChild() const;
|
||||||
ImplementationType* lastChild();
|
ImplementationType* lastChild();
|
||||||
const ImplementationType* lastChild() const;
|
const ImplementationType* lastChild() const;
|
||||||
ImplementationType* subelementByPath(const std::initializer_list<IdentifierType> &path, Diagnostics &diag);
|
ImplementationType* subelementByPath(Diagnostics &diag, IdentifierType item);
|
||||||
ImplementationType* subelementByPath(std::list<IdentifierType> &path, Diagnostics &diag);
|
ImplementationType* subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...);
|
||||||
ImplementationType* childById(const IdentifierType &id, Diagnostics &diag);
|
ImplementationType* childById(const IdentifierType &id, Diagnostics &diag);
|
||||||
ImplementationType* siblingById(const IdentifierType &id, Diagnostics &diag, bool includeThis = false);
|
ImplementationType* siblingById(const IdentifierType &id, Diagnostics &diag, bool includeThis = false);
|
||||||
bool isParent() const;
|
bool isParent() const;
|
||||||
|
@ -522,7 +522,7 @@ inline const ImplementationType *GenericFileElement<ImplementationType>::lastChi
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the sub element for the specified \a path.
|
* \brief Returns the sub element for the specified path.
|
||||||
*
|
*
|
||||||
* The current element keeps ownership over the returned element.
|
* The current element keeps ownership over the returned element.
|
||||||
* If no element could be found nullptr is returned.
|
* If no element could be found nullptr is returned.
|
||||||
|
@ -531,41 +531,45 @@ inline const ImplementationType *GenericFileElement<ImplementationType>::lastChi
|
||||||
* \throws Throws std::ios_base::failure when an IO error occurs.
|
* \throws Throws std::ios_base::failure when an IO error occurs.
|
||||||
*/
|
*/
|
||||||
template <class ImplementationType>
|
template <class ImplementationType>
|
||||||
inline ImplementationType *GenericFileElement<ImplementationType>::subelementByPath(const std::initializer_list<IdentifierType> &path, Diagnostics &diag)
|
ImplementationType *GenericFileElement<ImplementationType>::subelementByPath(Diagnostics &diag, IdentifierType item)
|
||||||
{
|
{
|
||||||
std::list<GenericFileElement<ImplementationType>::IdentifierType> list(path);
|
// ensure element is parsed
|
||||||
return subelementByPath(list, diag);
|
parse(diag);
|
||||||
|
// return the element if it matches the current and last item in the path
|
||||||
|
if(item == id()) {
|
||||||
|
return static_cast<ImplementationType *>(this);
|
||||||
|
}
|
||||||
|
// check whether a sibling matches the item
|
||||||
|
if(nextSibling()) {
|
||||||
|
return nextSibling()->subelementByPath(diag, item);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the sub element for the specified \a path.
|
* \brief Returns the sub element for the specified path.
|
||||||
*
|
*
|
||||||
* The current element keeps ownership over the returned element.
|
* The current element keeps ownership over the returned element.
|
||||||
* If no element could be found nullptr is returned.
|
* If no element could be found nullptr is returned.
|
||||||
* The specified \a path will modified.
|
|
||||||
*
|
*
|
||||||
* \throws Throws a parsing exception when a parsing error occurs.
|
* \throws Throws a parsing exception when a parsing error occurs.
|
||||||
* \throws Throws std::ios_base::failure when an IO error occurs.
|
* \throws Throws std::ios_base::failure when an IO error occurs.
|
||||||
*/
|
*/
|
||||||
template <class ImplementationType>
|
template <class ImplementationType>
|
||||||
ImplementationType *GenericFileElement<ImplementationType>::subelementByPath(std::list<IdentifierType> &path, Diagnostics &diag)
|
ImplementationType *GenericFileElement<ImplementationType>::subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...)
|
||||||
{
|
{
|
||||||
parse(diag); // ensure element is parsed
|
// ensure element is parsed
|
||||||
if(path.size()) {
|
parse(diag);
|
||||||
if(path.front() == id()) {
|
// continue with next item in path if the element matches the current item
|
||||||
if(path.size() == 1) {
|
if(item == id()) {
|
||||||
return static_cast<ImplementationType *>(this);
|
if(!firstChild()) {
|
||||||
} else {
|
return nullptr;
|
||||||
if(firstChild()) {
|
|
||||||
path.pop_front();
|
|
||||||
return firstChild()->subelementByPath(path, diag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(nextSibling()) {
|
|
||||||
return nextSibling()->subelementByPath(path, diag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return firstChild()->subelementByPath(diag, remainingPath);
|
||||||
|
}
|
||||||
|
// check whether a sibling matches the current item
|
||||||
|
if(nextSibling()) {
|
||||||
|
return nextSibling()->subelementByPath(diag, item, remainingPath);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ ElementPosition Mp4Container::determineTagPosition(Diagnostics &diag) const
|
||||||
{
|
{
|
||||||
if(m_firstElement) {
|
if(m_firstElement) {
|
||||||
const Mp4Atom *mediaDataAtom = m_firstElement->siblingById(Mp4AtomIds::MediaData, diag);
|
const Mp4Atom *mediaDataAtom = m_firstElement->siblingById(Mp4AtomIds::MediaData, diag);
|
||||||
const Mp4Atom *userDataAtom = m_firstElement->subelementByPath({Mp4AtomIds::Movie, Mp4AtomIds::UserData}, diag);
|
const Mp4Atom *userDataAtom = m_firstElement->subelementByPath(diag, Mp4AtomIds::Movie, Mp4AtomIds::UserData);
|
||||||
if(mediaDataAtom && userDataAtom) {
|
if(mediaDataAtom && userDataAtom) {
|
||||||
return userDataAtom->startOffset() < mediaDataAtom->startOffset() ? ElementPosition::BeforeData : ElementPosition::AfterData;
|
return userDataAtom->startOffset() < mediaDataAtom->startOffset() ? ElementPosition::BeforeData : ElementPosition::AfterData;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ void Mp4Container::internalParseHeader(Diagnostics &diag)
|
||||||
void Mp4Container::internalParseTags(Diagnostics &diag)
|
void Mp4Container::internalParseTags(Diagnostics &diag)
|
||||||
{
|
{
|
||||||
const string context("parsing tags of MP4 container");
|
const string context("parsing tags of MP4 container");
|
||||||
if(Mp4Atom *udtaAtom = firstElement()->subelementByPath({Mp4AtomIds::Movie, Mp4AtomIds::UserData}, diag)) {
|
if(Mp4Atom *udtaAtom = firstElement()->subelementByPath(diag, Mp4AtomIds::Movie, Mp4AtomIds::UserData)) {
|
||||||
Mp4Atom *metaAtom = udtaAtom->childById(Mp4AtomIds::Meta, diag);
|
Mp4Atom *metaAtom = udtaAtom->childById(Mp4AtomIds::Meta, diag);
|
||||||
bool surplusMetaAtoms = false;
|
bool surplusMetaAtoms = false;
|
||||||
while(metaAtom) {
|
while(metaAtom) {
|
||||||
|
@ -153,7 +153,7 @@ void Mp4Container::internalParseTracks(Diagnostics &diag)
|
||||||
diag.emplace_back(DiagLevel::Critical, "mvhd atom is does not exist.", context);
|
diag.emplace_back(DiagLevel::Critical, "mvhd atom is does not exist.", context);
|
||||||
}
|
}
|
||||||
// get mvex atom which holds default values for fragmented files
|
// get mvex atom which holds default values for fragmented files
|
||||||
if(Mp4Atom *mehdAtom = moovAtom->subelementByPath({Mp4AtomIds::MovieExtends, Mp4AtomIds::MovieExtendsHeader}, diag)) {
|
if(Mp4Atom *mehdAtom = moovAtom->subelementByPath(diag, Mp4AtomIds::MovieExtends, Mp4AtomIds::MovieExtendsHeader)) {
|
||||||
m_fragmented = true;
|
m_fragmented = true;
|
||||||
if(mehdAtom->dataSize() > 0) {
|
if(mehdAtom->dataSize() > 0) {
|
||||||
stream().seekg(static_cast<iostream::off_type>(mehdAtom->dataOffset()));
|
stream().seekg(static_cast<iostream::off_type>(mehdAtom->dataOffset()));
|
||||||
|
|
Loading…
Reference in New Issue