Tag Parser 12.3.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
Loading...
Searching...
No Matches
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
44template <class ImplementationType> class TAG_PARSER_EXPORT GenericFileElement {
45 friend class FileElementTraits<ImplementationType>;
46
47public:
52
57
62
63 GenericFileElement(ContainerType &container, std::uint64_t startOffset);
64 GenericFileElement(ImplementationType &parent, std::uint64_t startOffset);
65 GenericFileElement(ContainerType &container, std::uint64_t startOffset, std::uint64_t maxSize);
66 GenericFileElement(const GenericFileElement &other) = delete;
69
71 const ContainerType &container() const;
72 std::iostream &stream();
73 CppUtilities::BinaryReader &reader();
74 CppUtilities::BinaryWriter &writer();
75 std::uint64_t startOffset() const;
76 std::uint64_t relativeStartOffset() const;
77 const IdentifierType &id() const;
78 std::string idToString() const;
79 std::uint32_t idLength() const;
80 std::uint32_t headerSize() const;
82 std::uint32_t sizeLength() const;
83 std::uint64_t dataOffset() const;
84 std::uint64_t totalSize() const;
85 std::uint64_t endOffset() const;
86 std::uint64_t maxTotalSize() const;
87 std::uint8_t level() const;
88 ImplementationType *parent();
89 const ImplementationType *parent() const;
90 ImplementationType *parent(std::uint8_t n);
91 const ImplementationType *parent(std::uint8_t n) const;
92 ImplementationType *nextSibling();
93 const ImplementationType *nextSibling() const;
94 ImplementationType *firstChild();
95 const ImplementationType *firstChild() const;
96 ImplementationType *lastChild();
97 const ImplementationType *lastChild() const;
98 template <class IdType> ImplementationType *subelementByPath(Diagnostics &diag, IdType item);
99 template <class IdType, class... IdTypes> ImplementationType *subelementByPath(Diagnostics &diag, IdType item, IdTypes... remainingPath);
100 template <class IdType> const ImplementationType *subelementByPath(Diagnostics &diag, IdType item) const;
101 template <class IdType, class... IdTypes>
102 const ImplementationType *subelementByPath(Diagnostics &diag, IdType item, IdTypes... 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 template <typename TargetStream = std::ostream>
121 void copyHeader(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
122 template <typename TargetStream = std::ostream>
123 void copyWithoutChilds(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
124 template <typename TargetStream = std::ostream>
125 void copyEntirely(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
128 template <typename TargetStream = std::ostream> void copyBuffer(TargetStream &targetStream);
129 template <typename TargetStream = std::ostream>
130 void copyPreferablyFromBuffer(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
131 const std::unique_ptr<char[]> &buffer();
132 ImplementationType *denoteFirstChild(std::uint32_t offset);
133
134protected:
136 std::uint64_t m_startOffset;
137 std::uint64_t m_maxSize;
139 std::uint32_t m_idLength;
140 std::uint32_t m_sizeLength;
141 ImplementationType *m_parent;
142 std::unique_ptr<ImplementationType> m_nextSibling;
143 std::unique_ptr<ImplementationType> m_firstChild;
144 std::unique_ptr<char[]> m_buffer;
145
146private:
147 template <typename TargetStream = std::ostream>
148 void copyInternal(
149 TargetStream &targetStream, std::uint64_t startOffset, std::uint64_t bytesToCopy, Diagnostics &diag, AbortableProgressFeedback *progress);
150
151 ContainerType *m_container;
152 bool m_parsed;
153
154protected:
156};
157
162template <class ImplementationType>
164 GenericFileElement<ImplementationType>::ContainerType &container, std::uint64_t startOffset)
165 : m_id(IdentifierType())
166 , m_startOffset(startOffset)
167 , m_dataSize(0)
168 , m_idLength(0)
169 , m_sizeLength(0)
170 , m_parent(nullptr)
171 , m_container(&container)
172 , m_parsed(false)
173 , m_sizeUnknown(false)
174{
175 m_maxSize = container.fileInfo().size();
176 if (m_maxSize > startOffset) {
178 stream().seekg(static_cast<std::streamoff>(startOffset), std::ios_base::beg);
179 } else {
180 m_maxSize = 0;
181 }
182}
183
187template <class ImplementationType>
188GenericFileElement<ImplementationType>::GenericFileElement(ImplementationType &parent, std::uint64_t startOffset)
189 : m_id(IdentifierType())
190 , m_startOffset(startOffset)
191 , m_maxSize(parent.startOffset() + parent.totalSize() - startOffset)
192 , m_dataSize(0)
193 , m_idLength(0)
194 , m_sizeLength(0)
195 , m_parent(&parent)
196 , m_container(&parent.container())
197 , m_parsed(false)
198 , m_sizeUnknown(false)
199{
200}
201
205template <class ImplementationType>
207 GenericFileElement<ImplementationType>::ContainerType &container, std::uint64_t startOffset, std::uint64_t maxSize)
208 : m_id(IdentifierType())
209 , m_startOffset(startOffset)
210 , m_maxSize(maxSize)
211 , m_dataSize(0)
212 , m_idLength(0)
213 , m_sizeLength(0)
214 , m_parent(nullptr)
215 , m_container(&container)
216 , m_parsed(false)
217 , m_sizeUnknown(false)
218{
219}
220
224template <class ImplementationType>
229
233template <class ImplementationType>
238
242template <class ImplementationType> inline std::iostream &GenericFileElement<ImplementationType>::stream()
243{
244 return m_container->stream();
245}
246
250template <class ImplementationType> inline CppUtilities::BinaryReader &GenericFileElement<ImplementationType>::reader()
251{
252 return m_container->reader();
253}
254
258template <class ImplementationType> inline CppUtilities::BinaryWriter &GenericFileElement<ImplementationType>::writer()
259{
260 return m_container->writer();
261}
262
266template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::startOffset() const
267{
268 return m_startOffset;
269}
270
274template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::relativeStartOffset() const
275{
276 return parent() ? startOffset() - parent()->startOffset() : startOffset();
277}
278
282template <class ImplementationType>
287
291template <class ImplementationType> inline std::string GenericFileElement<ImplementationType>::idToString() const
292{
293 return static_cast<ImplementationType *>(this)->idToString();
294}
295
299template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::idLength() const
300{
301 return m_idLength;
302}
303
309template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::headerSize() const
310{
311 return m_idLength + m_sizeLength;
312}
313
319template <class ImplementationType>
324
328template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::sizeLength() const
329{
330 return m_sizeLength;
331}
332
338template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::dataOffset() const
339{
340 return startOffset() + headerSize();
341}
342
348template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::totalSize() const
349{
350 return headerSize() + dataSize();
351}
352
356template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::endOffset() const
357{
358 return startOffset() + totalSize();
359}
360
367template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::maxTotalSize() const
368{
369 return m_maxSize;
370}
371
376template <class ImplementationType> std::uint8_t GenericFileElement<ImplementationType>::level() const
377{
378 std::uint8_t level = 0;
379 for (const ImplementationType *parent = m_parent; parent; ++level, parent = parent->m_parent)
380 ;
381 return level;
382}
383
390template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::parent()
391{
392 return m_parent;
393}
394
401template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::parent() const
402{
403 return m_parent;
404}
405
412template <class ImplementationType> ImplementationType *GenericFileElement<ImplementationType>::parent(std::uint8_t n)
413{
414 ImplementationType *parent = static_cast<ImplementationType *>(this);
415 for (; n && parent; --n, parent = parent->m_parent)
416 ;
417 return parent;
418}
419
426template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::parent(std::uint8_t n) const
427{
428 return const_cast<GenericFileElement<ImplementationType> *>(this)->parent(n);
429}
430
439template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::nextSibling()
440{
441 return m_nextSibling.get();
442}
443
452template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::nextSibling() const
453{
454 return m_nextSibling.get();
455}
456
465template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::firstChild()
466{
467 return m_firstChild.get();
468}
469
478template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::firstChild() const
479{
480 return m_firstChild.get();
481}
482
491template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::lastChild()
492{
493 for (ImplementationType *child = firstChild(); child; child = child->nextSibling()) {
494 if (!child->m_nextSibling) {
495 return child;
496 }
497 }
498 return nullptr;
499}
500
509template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::lastChild() const
510{
511 return const_cast<GenericFileElement<ImplementationType> *>(this)->lastChild();
512}
513
523template <class ImplementationType>
524template <class IdType>
526{
527 // ensure element is parsed
528 parse(diag);
529 // return the element if it matches the current and last item in the path
530 if (item == id()) {
531 return static_cast<ImplementationType *>(this);
532 }
533 // check whether a sibling matches the item
534 if (nextSibling()) {
535 return nextSibling()->subelementByPath(diag, item);
536 }
537 return nullptr;
538}
539
549template <class ImplementationType>
550template <class IdType, class... IdTypes>
551ImplementationType *GenericFileElement<ImplementationType>::subelementByPath(Diagnostics &diag, IdType item, IdTypes... remainingPath)
552{
553 // ensure element is parsed
554 parse(diag);
555 // continue with next item in path if the element matches the current item
556 if (item == id()) {
557 if (!firstChild()) {
558 return nullptr;
559 }
560 return firstChild()->subelementByPath(diag, remainingPath...);
561 }
562 // check whether a sibling matches the current item
563 if (nextSibling()) {
564 return nextSibling()->subelementByPath(diag, item, remainingPath...);
565 }
566 return nullptr;
567}
568
578template <class ImplementationType>
579template <class IdType>
580const ImplementationType *GenericFileElement<ImplementationType>::subelementByPath(Diagnostics &diag, IdType item) const
581{
582 return const_cast<GenericFileElement<ImplementationType> *>(this)->subelementByPath(diag, item);
583}
584
594template <class ImplementationType>
595template <class IdType, class... IdTypes>
596const ImplementationType *GenericFileElement<ImplementationType>::subelementByPath(Diagnostics &diag, IdType item, IdTypes... remainingPath) const
597{
598 return const_cast<GenericFileElement<ImplementationType> *>(this)->subelementByPath(diag, item, remainingPath...);
599}
600
610template <class ImplementationType> ImplementationType *GenericFileElement<ImplementationType>::childById(const IdentifierType &id, Diagnostics &diag)
611{
612 parse(diag); // ensure element is parsed
613 for (ImplementationType *child = firstChild(); child; child = child->nextSibling()) {
614 child->parse(diag);
615 if (child->id() == id) {
616 return child;
617 }
618 }
619 return nullptr;
620}
621
631template <class ImplementationType>
632const ImplementationType *GenericFileElement<ImplementationType>::childById(const IdentifierType &id, Diagnostics &diag) const
633{
634 return const_cast<GenericFileElement<ImplementationType> *>(this)->childById(id, diag);
635}
636
647template <class ImplementationType>
649{
650 parse(diag); // ensure element is parsed
651 for (ImplementationType *sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
652 sibling->parse(diag);
653 if (sibling->id() == id) {
654 return sibling;
655 }
656 }
657 return nullptr;
658}
659
670template <class ImplementationType>
672{
673 return const_cast<GenericFileElement<ImplementationType> *>(this)->siblingById(id, diag);
674}
675
686template <class ImplementationType>
688{
689 parse(diag); // ensure element is parsed
690 for (ImplementationType *sibling = static_cast<ImplementationType *>(this); sibling; sibling = sibling->nextSibling()) {
691 sibling->parse(diag);
692 if (sibling->id() == id) {
693 return sibling;
694 }
695 }
696 return nullptr;
697}
698
709template <class ImplementationType>
711{
712 return const_cast<GenericFileElement<ImplementationType> *>(this)->siblingByIdIncludingThis(id, diag);
713}
714
718template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isParent() const
719{
720 return static_cast<const ImplementationType *>(this)->isParent();
721}
722
726template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isPadding() const
727{
728 return static_cast<const ImplementationType *>(this)->isPadding();
729}
730
734template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::firstChildOffset() const
735{
736 return static_cast<const ImplementationType *>(this)->firstChildOffset();
737}
738
742template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isParsed() const
743{
744 return m_parsed;
745}
746
753template <class ImplementationType> void GenericFileElement<ImplementationType>::clear()
754{
755 m_id = IdentifierType();
756 //m_startOffset = 0;
757 m_idLength = 0;
758 m_dataSize = 0;
759 m_sizeLength = 0;
760 m_nextSibling = nullptr;
761 m_firstChild = nullptr;
762 m_parsed = false;
763}
764
779template <class ImplementationType> void GenericFileElement<ImplementationType>::parse(Diagnostics &diag)
780{
781 if (!m_parsed) {
782 static_cast<ImplementationType *>(this)->internalParse(diag);
783 m_parsed = true;
784 }
785}
786
803template <class ImplementationType> void GenericFileElement<ImplementationType>::reparse(Diagnostics &diag)
804{
805 clear();
806 static_cast<ImplementationType *>(this)->parse(diag);
807 m_parsed = true;
808}
809
822template <class ImplementationType>
824 Diagnostics &diag, std::uint64_t *paddingSize, AbortableProgressFeedback *progress)
825{
826 if (progress) {
827 progress->stopIfAborted();
828 }
829 // validate element itself by just parsing it
830 parse(diag);
831 // validate children
832 if (firstChild()) {
833 try {
834 firstChild()->validateSubsequentElementStructure(diag, paddingSize, progress);
835 } catch (const Failure &) {
836 // ignore critical errors in child structure to continue validating siblings
837 // (critical notifications about the errors should have already been added to diag, so nothing to do)
838 }
839 } else if (paddingSize && isPadding()) { // element is padding
840 *paddingSize += totalSize();
841 }
842 // validate siblings
843 if (nextSibling()) {
844 nextSibling()->validateSubsequentElementStructure(diag, paddingSize, progress);
845 }
846}
847
851template <class ImplementationType>
852template <typename TargetStream>
854{
855 copyInternal(targetStream, startOffset(), headerSize(), diag, progress);
856}
857
861template <class ImplementationType>
862template <typename TargetStream>
864{
865 if (std::uint32_t firstChildOffset = this->firstChildOffset()) {
866 copyInternal(targetStream, startOffset(), firstChildOffset, diag, progress);
867 } else {
868 copyInternal(targetStream, startOffset(), totalSize(), diag, progress);
869 }
870}
871
875template <class ImplementationType>
876template <typename TargetStream>
878{
879 copyInternal(targetStream, startOffset(), totalSize(), diag, progress);
880}
881
886template <class ImplementationType> void GenericFileElement<ImplementationType>::makeBuffer()
887{
888 m_buffer = std::make_unique<char[]>(totalSize());
889 container().stream().seekg(static_cast<std::streamoff>(startOffset()));
890 container().stream().read(m_buffer.get(), static_cast<std::streamsize>(totalSize()));
891}
892
896template <class ImplementationType> inline void GenericFileElement<ImplementationType>::discardBuffer()
897{
898 m_buffer.reset();
899}
900
905template <class ImplementationType>
906template <typename TargetStream>
907inline void GenericFileElement<ImplementationType>::copyBuffer(TargetStream &targetStream)
908{
909 targetStream.write(m_buffer.get(), static_cast<std::streamsize>(totalSize()));
910}
911
916template <class ImplementationType>
917template <typename TargetStream>
919 TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
920{
921 m_buffer ? copyBuffer(targetStream) : copyEntirely(targetStream, diag, progress);
922}
923
928template <class ImplementationType> inline const std::unique_ptr<char[]> &GenericFileElement<ImplementationType>::buffer()
929{
930 return m_buffer;
931}
932
940template <class ImplementationType>
941template <typename TargetStream>
943 TargetStream &targetStream, std::uint64_t startOffset, std::uint64_t bytesToCopy, Diagnostics &diag, AbortableProgressFeedback *progress)
944{
945 // ensure the header has been parsed correctly
946 try {
947 parse(diag);
948 } catch (const Failure &) {
949 throw InvalidDataException();
950 }
951 auto &stream = container().stream();
952 stream.seekg(static_cast<std::streamoff>(startOffset), std::ios_base::beg);
953 CppUtilities::CopyHelper<0x10000> copyHelper;
954 if (progress) {
955 copyHelper.callbackCopy(stream, targetStream, bytesToCopy, std::bind(&AbortableProgressFeedback::isAborted, std::ref(progress)),
956 std::bind(&AbortableProgressFeedback::updateStepPercentageFromFraction, std::ref(progress), std::placeholders::_1));
957 } else {
958 copyHelper.copy(stream, targetStream, bytesToCopy);
959 }
960}
961
966template <class ImplementationType>
967ImplementationType *GenericFileElement<ImplementationType>::denoteFirstChild(std::uint32_t relativeFirstChildOffset)
968{
969 if (relativeFirstChildOffset + minimumElementSize() <= totalSize()) {
970 m_firstChild.reset(new ImplementationType(static_cast<ImplementationType &>(*this), startOffset() + relativeFirstChildOffset));
971 } else {
972 m_firstChild.reset();
973 }
974 return m_firstChild.get();
975}
976
980template <class ImplementationType> constexpr std::uint32_t GenericFileElement<ImplementationType>::maximumIdLengthSupported()
981{
982 return sizeof(IdentifierType);
983}
984
988template <class ImplementationType> constexpr std::uint32_t GenericFileElement<ImplementationType>::maximumSizeLengthSupported()
989{
990 return sizeof(DataSizeType);
991}
992
996template <class ImplementationType> constexpr std::uint8_t GenericFileElement<ImplementationType>::minimumElementSize()
997{
999}
1000
1015} // namespace TagParser
1016
1017#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.
The Diagnostics class is a container for DiagMessage.
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
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.
void copyEntirely(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Writes the entire element including all children to the specified targetStream.
void copyBuffer(TargetStream &targetStream)
Copies buffered data to targetStream.
const ContainerType & container() const
Returns the related container.
std::uint64_t startOffset() const
Returns the start offset in the related stream.
void copyHeader(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Writes the header information of the element to the specified targetStream.
std::string idToString() const
Returns a printable string representation of the element ID.
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.
const ImplementationType * subelementByPath(Diagnostics &diag, IdType item) const
Returns the sub element for the specified path.
const std::unique_ptr< char[]> & buffer()
Returns buffered data.
const ImplementationType * firstChild() const
Returns the first child of the element.
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.
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.
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
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...
void copyWithoutChilds(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Writes the element without its children to the specified targetStream.
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, IdType 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.
ImplementationType * subelementByPath(Diagnostics &diag, IdType item, IdTypes... remainingPath)
Returns the sub element for the specified path.
const ImplementationType * parent() const
Returns the parent of the element.
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.
void copyPreferablyFromBuffer(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Copies buffered data to targetStream if data has been buffered; copies from input stream otherwise.
const ImplementationType * subelementByPath(Diagnostics &diag, IdType item, IdTypes... remainingPath) const
Returns the sub element for the specified path.
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
Definition global.h:14
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10