Tag Parser 10.3.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
genericfileelement.h
Go to the documentation of this file.
1#ifndef TAG_PARSER_GENERICFILEELEMENT_H
2#define TAG_PARSER_GENERICFILEELEMENT_H
3
4#include "./exceptions.h"
6
7#include <c++utilities/io/copy.h>
8
9#include <cstdint>
10#include <initializer_list>
11#include <iostream>
12#include <list>
13#include <memory>
14#include <string>
15
16namespace CppUtilities {
17class BinaryReader;
18class BinaryWriter;
19} // namespace CppUtilities
20
21namespace TagParser {
22
23class Diagnostics;
24
34template <typename ImplementationType> class FileElementTraits {
35};
36
45template <class ImplementationType> class TAG_PARSER_EXPORT GenericFileElement {
46 friend class FileElementTraits<ImplementationType>;
47
48public:
53
58
63
64 GenericFileElement(ContainerType &container, std::uint64_t startOffset);
65 GenericFileElement(ImplementationType &parent, std::uint64_t startOffset);
66 GenericFileElement(ContainerType &container, std::uint64_t startOffset, std::uint64_t maxSize);
67 GenericFileElement(const GenericFileElement &other) = delete;
70
72 const ContainerType &container() const;
73 std::iostream &stream();
74 CppUtilities::BinaryReader &reader();
75 CppUtilities::BinaryWriter &writer();
76 std::uint64_t startOffset() const;
77 std::uint64_t relativeStartOffset() const;
78 const IdentifierType &id() const;
79 std::string idToString() const;
80 std::uint32_t idLength() const;
81 std::uint32_t headerSize() const;
83 std::uint32_t sizeLength() const;
84 std::uint64_t dataOffset() const;
85 std::uint64_t totalSize() const;
86 std::uint64_t endOffset() const;
87 std::uint64_t maxTotalSize() const;
88 std::uint8_t level() const;
89 ImplementationType *parent();
90 const ImplementationType *parent() const;
91 ImplementationType *parent(std::uint8_t n);
92 const ImplementationType *parent(std::uint8_t n) const;
93 ImplementationType *nextSibling();
94 const ImplementationType *nextSibling() const;
95 ImplementationType *firstChild();
96 const ImplementationType *firstChild() const;
97 ImplementationType *lastChild();
98 const ImplementationType *lastChild() const;
99 ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item);
100 ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...);
101 const ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item) const;
102 const ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...) const;
103 ImplementationType *childById(const IdentifierType &id, Diagnostics &diag);
104 const ImplementationType *childById(const IdentifierType &id, Diagnostics &diag) const;
105 ImplementationType *siblingById(const IdentifierType &id, Diagnostics &diag);
106 const ImplementationType *siblingById(const IdentifierType &id, Diagnostics &diag) const;
107 ImplementationType *siblingByIdIncludingThis(const IdentifierType &id, Diagnostics &diag);
108 const ImplementationType *siblingByIdIncludingThis(const IdentifierType &id, Diagnostics &diag) const;
109 bool isParent() const;
110 bool isPadding() const;
111 std::uint64_t firstChildOffset() const;
112 bool isParsed() const;
113 void clear();
114 void parse(Diagnostics &diag);
115 void reparse(Diagnostics &diag);
116 void validateSubsequentElementStructure(Diagnostics &diag, std::uint64_t *paddingSize = nullptr, AbortableProgressFeedback *progress = nullptr);
117 static constexpr std::uint32_t maximumIdLengthSupported();
118 static constexpr std::uint32_t maximumSizeLengthSupported();
119 static constexpr std::uint8_t minimumElementSize();
120 void copyHeader(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
121 void copyWithoutChilds(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
122 void copyEntirely(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
125 void copyBuffer(std::ostream &targetStream);
126 void copyPreferablyFromBuffer(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
127 const std::unique_ptr<char[]> &buffer();
128 ImplementationType *denoteFirstChild(std::uint32_t offset);
129
130protected:
132 std::uint64_t m_startOffset;
133 std::uint64_t m_maxSize;
135 std::uint32_t m_idLength;
136 std::uint32_t m_sizeLength;
137 ImplementationType *m_parent;
138 std::unique_ptr<ImplementationType> m_nextSibling;
139 std::unique_ptr<ImplementationType> m_firstChild;
140 std::unique_ptr<char[]> m_buffer;
141
142private:
143 void copyInternal(
144 std::ostream &targetStream, std::uint64_t startOffset, std::uint64_t bytesToCopy, Diagnostics &diag, AbortableProgressFeedback *progress);
145
146 ContainerType *m_container;
147 bool m_parsed;
148
149protected:
151};
152
157template <class ImplementationType>
159 GenericFileElement<ImplementationType>::ContainerType &container, std::uint64_t startOffset)
160 : m_id(IdentifierType())
161 , m_startOffset(startOffset)
162 , m_dataSize(0)
163 , m_idLength(0)
164 , m_sizeLength(0)
165 , m_parent(nullptr)
166 , m_container(&container)
167 , m_parsed(false)
168 , m_sizeUnknown(false)
169{
170 m_maxSize = container.fileInfo().size();
171 if (m_maxSize > startOffset) {
173 stream().seekg(static_cast<std::streamoff>(startOffset), std::ios_base::beg);
174 } else {
175 m_maxSize = 0;
176 }
177}
178
182template <class ImplementationType>
183GenericFileElement<ImplementationType>::GenericFileElement(ImplementationType &parent, std::uint64_t startOffset)
184 : m_id(IdentifierType())
185 , m_startOffset(startOffset)
186 , m_maxSize(parent.startOffset() + parent.totalSize() - startOffset)
187 , m_dataSize(0)
188 , m_idLength(0)
189 , m_sizeLength(0)
190 , m_parent(&parent)
191 , m_container(&parent.container())
192 , m_parsed(false)
193 , m_sizeUnknown(false)
194{
195}
196
200template <class ImplementationType>
202 GenericFileElement<ImplementationType>::ContainerType &container, std::uint64_t startOffset, std::uint64_t maxSize)
203 : m_id(IdentifierType())
204 , m_startOffset(startOffset)
205 , m_maxSize(maxSize)
206 , m_dataSize(0)
207 , m_idLength(0)
208 , m_sizeLength(0)
209 , m_parent(nullptr)
210 , m_container(&container)
211 , m_parsed(false)
212 , m_sizeUnknown(false)
213{
214}
215
219template <class ImplementationType>
221{
222 return *m_container;
223}
224
228template <class ImplementationType>
230{
231 return *m_container;
232}
233
237template <class ImplementationType> inline std::iostream &GenericFileElement<ImplementationType>::stream()
238{
239 return m_container->stream();
240}
241
245template <class ImplementationType> inline CppUtilities::BinaryReader &GenericFileElement<ImplementationType>::reader()
246{
247 return m_container->reader();
248}
249
253template <class ImplementationType> inline CppUtilities::BinaryWriter &GenericFileElement<ImplementationType>::writer()
254{
255 return m_container->writer();
256}
257
261template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::startOffset() const
262{
263 return m_startOffset;
264}
265
269template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::relativeStartOffset() const
270{
271 return parent() ? startOffset() - parent()->startOffset() : startOffset();
272}
273
277template <class ImplementationType>
279{
280 return m_id;
281}
282
286template <class ImplementationType> inline std::string GenericFileElement<ImplementationType>::idToString() const
287{
288 return static_cast<ImplementationType *>(this)->idToString();
289}
290
294template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::idLength() const
295{
296 return m_idLength;
297}
298
304template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::headerSize() const
305{
306 return m_idLength + m_sizeLength;
307}
308
314template <class ImplementationType>
316{
317 return m_dataSize;
318}
319
323template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::sizeLength() const
324{
325 return m_sizeLength;
326}
327
333template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::dataOffset() const
334{
335 return startOffset() + headerSize();
336}
337
343template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::totalSize() const
344{
345 return headerSize() + dataSize();
346}
347
351template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::endOffset() const
352{
353 return startOffset() + totalSize();
354}
355
362template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::maxTotalSize() const
363{
364 return m_maxSize;
365}
366
371template <class ImplementationType> std::uint8_t GenericFileElement<ImplementationType>::level() const
372{
373 std::uint8_t level = 0;
374 for (const ImplementationType *parent = m_parent; parent; ++level, parent = parent->m_parent)
375 ;
376 return level;
377}
378
385template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::parent()
386{
387 return m_parent;
388}
389
396template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::parent() const
397{
398 return m_parent;
399}
400
407template <class ImplementationType> ImplementationType *GenericFileElement<ImplementationType>::parent(std::uint8_t n)
408{
409 ImplementationType *parent = static_cast<ImplementationType *>(this);
410 for (; n && parent; --n, parent = parent->m_parent)
411 ;
412 return parent;
413}
414
421template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::parent(std::uint8_t n) const
422{
423 return const_cast<GenericFileElement<ImplementationType> *>(this)->parent(n);
424}
425
434template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::nextSibling()
435{
436 return m_nextSibling.get();
437}
438
447template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::nextSibling() const
448{
449 return m_nextSibling.get();
450}
451
460template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::firstChild()
461{
462 return m_firstChild.get();
463}
464
473template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::firstChild() const
474{
475 return m_firstChild.get();
476}
477
486template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::lastChild()
487{
488 for (ImplementationType *child = firstChild(); child; child = child->nextSibling()) {
489 if (!child->m_nextSibling) {
490 return child;
491 }
492 }
493 return nullptr;
494}
495
504template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::lastChild() const
505{
506 return const_cast<GenericFileElement<ImplementationType> *>(this)->lastChild();
507}
508
518template <class ImplementationType>
520{
521 // ensure element is parsed
522 parse(diag);
523 // return the element if it matches the current and last item in the path
524 if (item == id()) {
525 return static_cast<ImplementationType *>(this);
526 }
527 // check whether a sibling matches the item
528 if (nextSibling()) {
529 return nextSibling()->subelementByPath(diag, item);
530 }
531 return nullptr;
532}
533
543template <class ImplementationType>
545{
546 // ensure element is parsed
547 parse(diag);
548 // continue with next item in path if the element matches the current item
549 if (item == id()) {
550 if (!firstChild()) {
551 return nullptr;
552 }
553 return firstChild()->subelementByPath(diag, remainingPath);
554 }
555 // check whether a sibling matches the current item
556 if (nextSibling()) {
557 return nextSibling()->subelementByPath(diag, item, remainingPath);
558 }
559 return nullptr;
560}
561
571template <class ImplementationType>
573{
574 return const_cast<GenericFileElement<ImplementationType> *>(this)->subelementByPath(diag, item);
575}
576
586template <class ImplementationType>
588 Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...) const
589{
590 return const_cast<GenericFileElement<ImplementationType> *>(this)->subelementByPath(diag, item, remainingPath);
591}
592
602template <class ImplementationType> ImplementationType *GenericFileElement<ImplementationType>::childById(const IdentifierType &id, Diagnostics &diag)
603{
604 parse(diag); // ensure element is parsed
605 for (ImplementationType *child = firstChild(); child; child = child->nextSibling()) {
606 child->parse(diag);
607 if (child->id() == id) {
608 return child;
609 }
610 }
611 return nullptr;
612}
613
623template <class ImplementationType>
624const ImplementationType *GenericFileElement<ImplementationType>::childById(const IdentifierType &id, Diagnostics &diag) const
625{
626 return const_cast<GenericFileElement<ImplementationType> *>(this)->childById(id, diag);
627}
628
639template <class ImplementationType>
641{
642 parse(diag); // ensure element is parsed
643 for (ImplementationType *sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
644 sibling->parse(diag);
645 if (sibling->id() == id) {
646 return sibling;
647 }
648 }
649 return nullptr;
650}
651
662template <class ImplementationType>
664{
665 return const_cast<GenericFileElement<ImplementationType> *>(this)->siblingById(id, diag);
666}
667
678template <class ImplementationType>
680{
681 parse(diag); // ensure element is parsed
682 for (ImplementationType *sibling = static_cast<ImplementationType *>(this); sibling; sibling = sibling->nextSibling()) {
683 sibling->parse(diag);
684 if (sibling->id() == id) {
685 return sibling;
686 }
687 }
688 return nullptr;
689}
690
701template <class ImplementationType>
703{
704 return const_cast<GenericFileElement<ImplementationType> *>(this)->siblingByIdIncludingThis(id, diag);
705}
706
710template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isParent() const
711{
712 return static_cast<const ImplementationType *>(this)->isParent();
713}
714
718template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isPadding() const
719{
720 return static_cast<const ImplementationType *>(this)->isPadding();
721}
722
726template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::firstChildOffset() const
727{
728 return static_cast<const ImplementationType *>(this)->firstChildOffset();
729}
730
734template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isParsed() const
735{
736 return m_parsed;
737}
738
745template <class ImplementationType> void GenericFileElement<ImplementationType>::clear()
746{
747 m_id = IdentifierType();
748 //m_startOffset = 0;
749 m_idLength = 0;
750 m_dataSize = 0;
751 m_sizeLength = 0;
752 m_nextSibling = nullptr;
753 m_firstChild = nullptr;
754 m_parsed = false;
755}
756
771template <class ImplementationType> void GenericFileElement<ImplementationType>::parse(Diagnostics &diag)
772{
773 if (!m_parsed) {
774 static_cast<ImplementationType *>(this)->internalParse(diag);
775 m_parsed = true;
776 }
777}
778
795template <class ImplementationType> void GenericFileElement<ImplementationType>::reparse(Diagnostics &diag)
796{
797 clear();
798 static_cast<ImplementationType *>(this)->parse(diag);
799 m_parsed = true;
800}
801
814template <class ImplementationType>
816 Diagnostics &diag, std::uint64_t *paddingSize, AbortableProgressFeedback *progress)
817{
818 if (progress) {
819 progress->stopIfAborted();
820 }
821 // validate element itself by just parsing it
822 parse(diag);
823 // validate children
824 if (firstChild()) {
825 try {
826 firstChild()->validateSubsequentElementStructure(diag, paddingSize, progress);
827 } catch (const Failure &) {
828 // ignore critical errors in child structure to continue validating siblings
829 // (critical notifications about the errors should have already been added to diag, so nothing to do)
830 }
831 } else if (paddingSize && isPadding()) { // element is padding
832 *paddingSize += totalSize();
833 }
834 // validate siblings
835 if (nextSibling()) {
836 nextSibling()->validateSubsequentElementStructure(diag, paddingSize, progress);
837 }
838}
839
843template <class ImplementationType>
845{
846 copyInternal(targetStream, startOffset(), headerSize(), diag, progress);
847}
848
852template <class ImplementationType>
854{
855 if (std::uint32_t firstChildOffset = this->firstChildOffset()) {
856 copyInternal(targetStream, startOffset(), firstChildOffset, diag, progress);
857 } else {
858 copyInternal(targetStream, startOffset(), totalSize(), diag, progress);
859 }
860}
861
865template <class ImplementationType>
867{
868 copyInternal(targetStream, startOffset(), totalSize(), diag, progress);
869}
870
875template <class ImplementationType> void GenericFileElement<ImplementationType>::makeBuffer()
876{
877 m_buffer = std::make_unique<char[]>(totalSize());
878 container().stream().seekg(static_cast<std::streamoff>(startOffset()));
879 container().stream().read(m_buffer.get(), static_cast<std::streamsize>(totalSize()));
880}
881
885template <class ImplementationType> inline void GenericFileElement<ImplementationType>::discardBuffer()
886{
887 m_buffer.reset();
888}
889
894template <class ImplementationType> inline void GenericFileElement<ImplementationType>::copyBuffer(std::ostream &targetStream)
895{
896 targetStream.write(m_buffer.get(), static_cast<std::streamsize>(totalSize()));
897}
898
903template <class ImplementationType>
905 std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
906{
907 m_buffer ? copyBuffer(targetStream) : copyEntirely(targetStream, diag, progress);
908}
909
914template <class ImplementationType> inline const std::unique_ptr<char[]> &GenericFileElement<ImplementationType>::buffer()
915{
916 return m_buffer;
917}
918
926template <class ImplementationType>
928 std::ostream &targetStream, std::uint64_t startOffset, std::uint64_t bytesToCopy, Diagnostics &diag, AbortableProgressFeedback *progress)
929{
930 // ensure the header has been parsed correctly
931 try {
932 parse(diag);
933 } catch (const Failure &) {
934 throw InvalidDataException();
935 }
936 auto &stream = container().stream();
937 stream.seekg(static_cast<std::streamoff>(startOffset), std::ios_base::beg);
939 if (progress) {
940 copyHelper.callbackCopy(stream, targetStream, bytesToCopy, std::bind(&AbortableProgressFeedback::isAborted, std::ref(progress)),
941 std::bind(&AbortableProgressFeedback::updateStepPercentageFromFraction, std::ref(progress), std::placeholders::_1));
942 } else {
943 copyHelper.copy(stream, targetStream, bytesToCopy);
944 }
945}
946
951template <class ImplementationType>
952ImplementationType *GenericFileElement<ImplementationType>::denoteFirstChild(std::uint32_t relativeFirstChildOffset)
953{
954 if (relativeFirstChildOffset + minimumElementSize() <= totalSize()) {
955 m_firstChild.reset(new ImplementationType(static_cast<ImplementationType &>(*this), startOffset() + relativeFirstChildOffset));
956 } else {
957 m_firstChild.reset();
958 }
959 return m_firstChild.get();
960}
961
965template <class ImplementationType> constexpr std::uint32_t GenericFileElement<ImplementationType>::maximumIdLengthSupported()
966{
967 return sizeof(IdentifierType);
968}
969
973template <class ImplementationType> constexpr std::uint32_t GenericFileElement<ImplementationType>::maximumSizeLengthSupported()
974{
975 return sizeof(DataSizeType);
976}
977
981template <class ImplementationType> constexpr std::uint8_t GenericFileElement<ImplementationType>::minimumElementSize()
982{
984}
985
1000} // namespace TagParser
1001
1002#endif // TAG_PARSER_GENERICFILEELEMENT_H
The AbortableProgressFeedback class provides feedback about an ongoing operation via callbacks.
bool isAborted() const
Returns whether the operation has been aborted via tryToAbort().
void stopIfAborted() const
Throws an OperationAbortedException if aborted.
void updateStepPercentageFromFraction(double stepPercentage)
Updates the current step percentage and invokes the second callback specified on construction (or the...
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
Definition: exceptions.h:11
Defines traits for the specified ImplementationType.
The GenericFileElement class helps to parse binary files which consist of an arboreal element structu...
GenericFileElement(ContainerType &container, std::uint64_t startOffset)
const ImplementationType * parent(std::uint8_t n) const
Returns the n-th parent of the element.
ImplementationType * lastChild()
Returns the last child of the element.
const ContainerType & container() const
Returns the related container.
std::uint64_t startOffset() const
Returns the start offset in the related stream.
std::string idToString() const
Returns a printable string representation of the element ID.
void copyPreferablyFromBuffer(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Copies buffered data to targetStream if data has been buffered; copies from input stream otherwise.
const ImplementationType * nextSibling() const
Returns the next sibling of the element.
void discardBuffer()
Discards buffered data.
GenericFileElement(ContainerType &container, std::uint64_t startOffset, std::uint64_t maxSize)
ImplementationType * siblingByIdIncludingThis(const IdentifierType &id, Diagnostics &diag)
Returns the first sibling with the specified id or the current instance if its ID equals id.
void copyEntirely(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Writes the entire element including all children to the specified targetStream.
const std::unique_ptr< char[]> & buffer()
Returns buffered data.
const ImplementationType * firstChild() const
Returns the first child of the element.
void copyWithoutChilds(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Writes the element without its children to the specified targetStream.
std::uint32_t headerSize() const
Returns the header size of the element in byte.
const ImplementationType * childById(const IdentifierType &id, Diagnostics &diag) const
Returns the first child with the specified id.
bool isParent() const
Returns an indication whether this instance is a parent element.
std::uint64_t endOffset() const
Returns the offset of the first byte which doesn't belong to this element anymore.
bool isPadding() const
Returns an indication whether this instance is a padding element.
const IdentifierType & id() const
Returns the element ID.
CppUtilities::BinaryWriter & writer()
Returns the related BinaryWriter.
void copyHeader(std::ostream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Writes the header information of the element to the specified targetStream.
typename FileElementTraits< ImplementationType >::DataSizeType DataSizeType
Specifies the type used to store data sizes.
std::uint8_t level() const
Returns how deep the element is nested (0 for top-level elements, 1 for children of top-level element...
typename FileElementTraits< ImplementationType >::ContainerType ContainerType
Specifies the type of the corresponding container.
ImplementationType * subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...)
Returns the sub element for the specified path.
std::iostream & stream()
Returns the related stream.
const ImplementationType * siblingById(const IdentifierType &id, Diagnostics &diag) const
Returns the first sibling with the specified id.
GenericFileElement & operator=(const GenericFileElement &other)=delete
const ImplementationType * subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...) const
Returns the sub element for the specified path.
void copyBuffer(std::ostream &targetStream)
Copies buffered data to targetStream.
ImplementationType * childById(const IdentifierType &id, Diagnostics &diag)
Returns the first child with the specified id.
std::uint64_t firstChildOffset() const
Returns the offset of the first child (relative to the start offset of this element).
bool isParsed() const
Returns an indication whether this instance has been parsed yet.
ImplementationType * nextSibling()
Returns the next sibling of the element.
std::unique_ptr< ImplementationType > m_nextSibling
GenericFileElement(GenericFileElement &other)=delete
ImplementationType * parent()
Returns the parent of the element.
static constexpr std::uint8_t minimumElementSize()
Returns the minimum element size.
ImplementationType * denoteFirstChild(std::uint32_t offset)
Denotes the first child to start at the specified offset (relative to the start offset of this descri...
ImplementationType * firstChild()
Returns the first child of the element.
std::uint32_t sizeLength() const
Returns the length of the size denotation of the element in byte.
std::unique_ptr< ImplementationType > m_firstChild
const ImplementationType * siblingByIdIncludingThis(const IdentifierType &id, Diagnostics &diag) const
Returns the first sibling with the specified id or the current instance if its ID equals id.
const ImplementationType * lastChild() const
Returns the last child of the element.
ImplementationType * subelementByPath(Diagnostics &diag, IdentifierType item)
Returns the sub element for the specified path.
static constexpr std::uint32_t maximumIdLengthSupported()
Returns the maximum id length supported by the class in byte.
DataSizeType dataSize() const
Returns the data size of the element in byte.
std::uint64_t totalSize() const
Returns the total size of the element.
const ImplementationType * parent() const
Returns the parent of the element.
const ImplementationType * subelementByPath(Diagnostics &diag, IdentifierType item) const
Returns the sub element for the specified path.
void parse(Diagnostics &diag)
Parses the header information of the element which is read from the related stream at the start offse...
std::uint64_t relativeStartOffset() const
Returns the offset of the element in its parent or - if it is a top-level element - in the related st...
void validateSubsequentElementStructure(Diagnostics &diag, std::uint64_t *paddingSize=nullptr, AbortableProgressFeedback *progress=nullptr)
Parses (see parse()) this and all subsequent elements.
typename FileElementTraits< ImplementationType >::IdentifierType IdentifierType
Specifies the type used to store identifiers.
static constexpr std::uint32_t maximumSizeLengthSupported()
Returns the maximum size length supported by the class in byte.
std::uint64_t dataOffset() const
Returns the data offset of the element in the related stream.
GenericFileElement(const GenericFileElement &other)=delete
GenericFileElement(ImplementationType &parent, std::uint64_t startOffset)
Constructs a new sub level file element with the specified parent at the specified startOffset.
ContainerType & container()
Returns the related container.
ImplementationType * parent(std::uint8_t n)
Returns the n-th parent of the element.
void clear()
Clears the status of the element.
std::uint32_t idLength() const
Returns the length of the id denotation in byte.
std::unique_ptr< char[]> m_buffer
CppUtilities::BinaryReader & reader()
Returns the related BinaryReader.
std::uint64_t maxTotalSize() const
Returns maximum total size.
void makeBuffer()
Buffers the element (header and data).
void reparse(Diagnostics &diag)
Parses the header information of the element which is read from the related stream at the start offse...
ImplementationType * siblingById(const IdentifierType &id, Diagnostics &diag)
Returns the first sibling with the specified id.
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10