Use "..." to implement subelementByPath
This commit is contained in:
parent
88edd43f8c
commit
091fa1daf7
|
@ -101,8 +101,8 @@ public:
|
|||
const ImplementationType* firstChild() const;
|
||||
ImplementationType* lastChild();
|
||||
const ImplementationType* lastChild() const;
|
||||
ImplementationType* subelementByPath(const std::initializer_list<IdentifierType> &path, Diagnostics &diag);
|
||||
ImplementationType* subelementByPath(std::list<IdentifierType> &path, Diagnostics &diag);
|
||||
ImplementationType* subelementByPath(Diagnostics &diag, IdentifierType item);
|
||||
ImplementationType* subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...);
|
||||
ImplementationType* childById(const IdentifierType &id, Diagnostics &diag);
|
||||
ImplementationType* siblingById(const IdentifierType &id, Diagnostics &diag, bool includeThis = false);
|
||||
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.
|
||||
* 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.
|
||||
*/
|
||||
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);
|
||||
return subelementByPath(list, diag);
|
||||
// ensure element is parsed
|
||||
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.
|
||||
* 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 std::ios_base::failure when an IO error occurs.
|
||||
*/
|
||||
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
|
||||
if(path.size()) {
|
||||
if(path.front() == id()) {
|
||||
if(path.size() == 1) {
|
||||
return static_cast<ImplementationType *>(this);
|
||||
} else {
|
||||
if(firstChild()) {
|
||||
path.pop_front();
|
||||
return firstChild()->subelementByPath(path, diag);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(nextSibling()) {
|
||||
return nextSibling()->subelementByPath(path, diag);
|
||||
}
|
||||
// ensure element is parsed
|
||||
parse(diag);
|
||||
// continue with next item in path if the element matches the current item
|
||||
if(item == id()) {
|
||||
if(!firstChild()) {
|
||||
return nullptr;
|
||||
}
|
||||
return firstChild()->subelementByPath(diag, remainingPath);
|
||||
}
|
||||
// check whether a sibling matches the current item
|
||||
if(nextSibling()) {
|
||||
return nextSibling()->subelementByPath(diag, item, remainingPath);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ ElementPosition Mp4Container::determineTagPosition(Diagnostics &diag) const
|
|||
{
|
||||
if(m_firstElement) {
|
||||
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) {
|
||||
return userDataAtom->startOffset() < mediaDataAtom->startOffset() ? ElementPosition::BeforeData : ElementPosition::AfterData;
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ void Mp4Container::internalParseHeader(Diagnostics &diag)
|
|||
void Mp4Container::internalParseTags(Diagnostics &diag)
|
||||
{
|
||||
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);
|
||||
bool surplusMetaAtoms = false;
|
||||
while(metaAtom) {
|
||||
|
@ -153,7 +153,7 @@ void Mp4Container::internalParseTracks(Diagnostics &diag)
|
|||
diag.emplace_back(DiagLevel::Critical, "mvhd atom is does not exist.", context);
|
||||
}
|
||||
// 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;
|
||||
if(mehdAtom->dataSize() > 0) {
|
||||
stream().seekg(static_cast<iostream::off_type>(mehdAtom->dataOffset()));
|
||||
|
|
Loading…
Reference in New Issue