Tag Parser 12.1.0
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 ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item);
99 ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...);
100 const ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item) const;
101 const ImplementationType *subelementByPath(Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...) const;
102 ImplementationType *childById(const IdentifierType &id, Diagnostics &diag);
103 const ImplementationType *childById(const IdentifierType &id, Diagnostics &diag) const;
104 ImplementationType *siblingById(const IdentifierType &id, Diagnostics &diag);
105 const ImplementationType *siblingById(const IdentifierType &id, Diagnostics &diag) const;
106 ImplementationType *siblingByIdIncludingThis(const IdentifierType &id, Diagnostics &diag);
107 const ImplementationType *siblingByIdIncludingThis(const IdentifierType &id, Diagnostics &diag) const;
108 bool isParent() const;
109 bool isPadding() const;
110 std::uint64_t firstChildOffset() const;
111 bool isParsed() const;
112 void clear();
113 void parse(Diagnostics &diag);
114 void reparse(Diagnostics &diag);
115 void validateSubsequentElementStructure(Diagnostics &diag, std::uint64_t *paddingSize = nullptr, AbortableProgressFeedback *progress = nullptr);
116 static constexpr std::uint32_t maximumIdLengthSupported();
117 static constexpr std::uint32_t maximumSizeLengthSupported();
118 static constexpr std::uint8_t minimumElementSize();
119 template <typename TargetStream = std::ostream>
120 void copyHeader(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
121 template <typename TargetStream = std::ostream>
122 void copyWithoutChilds(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
123 template <typename TargetStream = std::ostream>
124 void copyEntirely(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
127 template <typename TargetStream = std::ostream> void copyBuffer(TargetStream &targetStream);
128 template <typename TargetStream = std::ostream>
129 void copyPreferablyFromBuffer(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress);
130 const std::unique_ptr<char[]> &buffer();
131 ImplementationType *denoteFirstChild(std::uint32_t offset);
132
133protected:
135 std::uint64_t m_startOffset;
136 std::uint64_t m_maxSize;
138 std::uint32_t m_idLength;
139 std::uint32_t m_sizeLength;
140 ImplementationType *m_parent;
141 std::unique_ptr<ImplementationType> m_nextSibling;
142 std::unique_ptr<ImplementationType> m_firstChild;
143 std::unique_ptr<char[]> m_buffer;
144
145private:
146 template <typename TargetStream = std::ostream>
147 void copyInternal(
148 TargetStream &targetStream, std::uint64_t startOffset, std::uint64_t bytesToCopy, Diagnostics &diag, AbortableProgressFeedback *progress);
149
150 ContainerType *m_container;
151 bool m_parsed;
152
153protected:
155};
156
161template <class ImplementationType>
163 GenericFileElement<ImplementationType>::ContainerType &container, std::uint64_t startOffset)
164 : m_id(IdentifierType())
165 , m_startOffset(startOffset)
166 , m_dataSize(0)
167 , m_idLength(0)
168 , m_sizeLength(0)
169 , m_parent(nullptr)
170 , m_container(&container)
171 , m_parsed(false)
172 , m_sizeUnknown(false)
173{
174 m_maxSize = container.fileInfo().size();
175 if (m_maxSize > startOffset) {
177 stream().seekg(static_cast<std::streamoff>(startOffset), std::ios_base::beg);
178 } else {
179 m_maxSize = 0;
180 }
181}
182
186template <class ImplementationType>
187GenericFileElement<ImplementationType>::GenericFileElement(ImplementationType &parent, std::uint64_t startOffset)
188 : m_id(IdentifierType())
189 , m_startOffset(startOffset)
190 , m_maxSize(parent.startOffset() + parent.totalSize() - startOffset)
191 , m_dataSize(0)
192 , m_idLength(0)
193 , m_sizeLength(0)
194 , m_parent(&parent)
195 , m_container(&parent.container())
196 , m_parsed(false)
197 , m_sizeUnknown(false)
198{
199}
200
204template <class ImplementationType>
206 GenericFileElement<ImplementationType>::ContainerType &container, std::uint64_t startOffset, std::uint64_t maxSize)
207 : m_id(IdentifierType())
208 , m_startOffset(startOffset)
209 , m_maxSize(maxSize)
210 , m_dataSize(0)
211 , m_idLength(0)
212 , m_sizeLength(0)
213 , m_parent(nullptr)
214 , m_container(&container)
215 , m_parsed(false)
216 , m_sizeUnknown(false)
217{
218}
219
223template <class ImplementationType>
228
232template <class ImplementationType>
237
241template <class ImplementationType> inline std::iostream &GenericFileElement<ImplementationType>::stream()
242{
243 return m_container->stream();
244}
245
249template <class ImplementationType> inline CppUtilities::BinaryReader &GenericFileElement<ImplementationType>::reader()
250{
251 return m_container->reader();
252}
253
257template <class ImplementationType> inline CppUtilities::BinaryWriter &GenericFileElement<ImplementationType>::writer()
258{
259 return m_container->writer();
260}
261
265template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::startOffset() const
266{
267 return m_startOffset;
268}
269
273template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::relativeStartOffset() const
274{
275 return parent() ? startOffset() - parent()->startOffset() : startOffset();
276}
277
281template <class ImplementationType>
286
290template <class ImplementationType> inline std::string GenericFileElement<ImplementationType>::idToString() const
291{
292 return static_cast<ImplementationType *>(this)->idToString();
293}
294
298template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::idLength() const
299{
300 return m_idLength;
301}
302
308template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::headerSize() const
309{
310 return m_idLength + m_sizeLength;
311}
312
318template <class ImplementationType>
323
327template <class ImplementationType> inline std::uint32_t GenericFileElement<ImplementationType>::sizeLength() const
328{
329 return m_sizeLength;
330}
331
337template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::dataOffset() const
338{
339 return startOffset() + headerSize();
340}
341
347template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::totalSize() const
348{
349 return headerSize() + dataSize();
350}
351
355template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::endOffset() const
356{
357 return startOffset() + totalSize();
358}
359
366template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::maxTotalSize() const
367{
368 return m_maxSize;
369}
370
375template <class ImplementationType> std::uint8_t GenericFileElement<ImplementationType>::level() const
376{
377 std::uint8_t level = 0;
378 for (const ImplementationType *parent = m_parent; parent; ++level, parent = parent->m_parent)
379 ;
380 return level;
381}
382
389template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::parent()
390{
391 return m_parent;
392}
393
400template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::parent() const
401{
402 return m_parent;
403}
404
411template <class ImplementationType> ImplementationType *GenericFileElement<ImplementationType>::parent(std::uint8_t n)
412{
413 ImplementationType *parent = static_cast<ImplementationType *>(this);
414 for (; n && parent; --n, parent = parent->m_parent)
415 ;
416 return parent;
417}
418
425template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::parent(std::uint8_t n) const
426{
427 return const_cast<GenericFileElement<ImplementationType> *>(this)->parent(n);
428}
429
438template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::nextSibling()
439{
440 return m_nextSibling.get();
441}
442
451template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::nextSibling() const
452{
453 return m_nextSibling.get();
454}
455
464template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::firstChild()
465{
466 return m_firstChild.get();
467}
468
477template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::firstChild() const
478{
479 return m_firstChild.get();
480}
481
490template <class ImplementationType> inline ImplementationType *GenericFileElement<ImplementationType>::lastChild()
491{
492 for (ImplementationType *child = firstChild(); child; child = child->nextSibling()) {
493 if (!child->m_nextSibling) {
494 return child;
495 }
496 }
497 return nullptr;
498}
499
508template <class ImplementationType> inline const ImplementationType *GenericFileElement<ImplementationType>::lastChild() const
509{
510 return const_cast<GenericFileElement<ImplementationType> *>(this)->lastChild();
511}
512
522template <class ImplementationType>
524{
525 // ensure element is parsed
526 parse(diag);
527 // return the element if it matches the current and last item in the path
528 if (item == id()) {
529 return static_cast<ImplementationType *>(this);
530 }
531 // check whether a sibling matches the item
532 if (nextSibling()) {
533 return nextSibling()->subelementByPath(diag, item);
534 }
535 return nullptr;
536}
537
547template <class ImplementationType>
549{
550 // ensure element is parsed
551 parse(diag);
552 // continue with next item in path if the element matches the current item
553 if (item == id()) {
554 if (!firstChild()) {
555 return nullptr;
556 }
557 return firstChild()->subelementByPath(diag, remainingPath);
558 }
559 // check whether a sibling matches the current item
560 if (nextSibling()) {
561 return nextSibling()->subelementByPath(diag, item, remainingPath);
562 }
563 return nullptr;
564}
565
575template <class ImplementationType>
577{
578 return const_cast<GenericFileElement<ImplementationType> *>(this)->subelementByPath(diag, item);
579}
580
590template <class ImplementationType>
592 Diagnostics &diag, IdentifierType item, IdentifierType remainingPath...) const
593{
594 return const_cast<GenericFileElement<ImplementationType> *>(this)->subelementByPath(diag, item, remainingPath);
595}
596
606template <class ImplementationType> ImplementationType *GenericFileElement<ImplementationType>::childById(const IdentifierType &id, Diagnostics &diag)
607{
608 parse(diag); // ensure element is parsed
609 for (ImplementationType *child = firstChild(); child; child = child->nextSibling()) {
610 child->parse(diag);
611 if (child->id() == id) {
612 return child;
613 }
614 }
615 return nullptr;
616}
617
627template <class ImplementationType>
628const ImplementationType *GenericFileElement<ImplementationType>::childById(const IdentifierType &id, Diagnostics &diag) const
629{
630 return const_cast<GenericFileElement<ImplementationType> *>(this)->childById(id, diag);
631}
632
643template <class ImplementationType>
645{
646 parse(diag); // ensure element is parsed
647 for (ImplementationType *sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
648 sibling->parse(diag);
649 if (sibling->id() == id) {
650 return sibling;
651 }
652 }
653 return nullptr;
654}
655
666template <class ImplementationType>
668{
669 return const_cast<GenericFileElement<ImplementationType> *>(this)->siblingById(id, diag);
670}
671
682template <class ImplementationType>
684{
685 parse(diag); // ensure element is parsed
686 for (ImplementationType *sibling = static_cast<ImplementationType *>(this); sibling; sibling = sibling->nextSibling()) {
687 sibling->parse(diag);
688 if (sibling->id() == id) {
689 return sibling;
690 }
691 }
692 return nullptr;
693}
694
705template <class ImplementationType>
707{
708 return const_cast<GenericFileElement<ImplementationType> *>(this)->siblingByIdIncludingThis(id, diag);
709}
710
714template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isParent() const
715{
716 return static_cast<const ImplementationType *>(this)->isParent();
717}
718
722template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isPadding() const
723{
724 return static_cast<const ImplementationType *>(this)->isPadding();
725}
726
730template <class ImplementationType> inline std::uint64_t GenericFileElement<ImplementationType>::firstChildOffset() const
731{
732 return static_cast<const ImplementationType *>(this)->firstChildOffset();
733}
734
738template <class ImplementationType> inline bool GenericFileElement<ImplementationType>::isParsed() const
739{
740 return m_parsed;
741}
742
749template <class ImplementationType> void GenericFileElement<ImplementationType>::clear()
750{
751 m_id = IdentifierType();
752 //m_startOffset = 0;
753 m_idLength = 0;
754 m_dataSize = 0;
755 m_sizeLength = 0;
756 m_nextSibling = nullptr;
757 m_firstChild = nullptr;
758 m_parsed = false;
759}
760
775template <class ImplementationType> void GenericFileElement<ImplementationType>::parse(Diagnostics &diag)
776{
777 if (!m_parsed) {
778 static_cast<ImplementationType *>(this)->internalParse(diag);
779 m_parsed = true;
780 }
781}
782
799template <class ImplementationType> void GenericFileElement<ImplementationType>::reparse(Diagnostics &diag)
800{
801 clear();
802 static_cast<ImplementationType *>(this)->parse(diag);
803 m_parsed = true;
804}
805
818template <class ImplementationType>
820 Diagnostics &diag, std::uint64_t *paddingSize, AbortableProgressFeedback *progress)
821{
822 if (progress) {
823 progress->stopIfAborted();
824 }
825 // validate element itself by just parsing it
826 parse(diag);
827 // validate children
828 if (firstChild()) {
829 try {
830 firstChild()->validateSubsequentElementStructure(diag, paddingSize, progress);
831 } catch (const Failure &) {
832 // ignore critical errors in child structure to continue validating siblings
833 // (critical notifications about the errors should have already been added to diag, so nothing to do)
834 }
835 } else if (paddingSize && isPadding()) { // element is padding
836 *paddingSize += totalSize();
837 }
838 // validate siblings
839 if (nextSibling()) {
840 nextSibling()->validateSubsequentElementStructure(diag, paddingSize, progress);
841 }
842}
843
847template <class ImplementationType>
848template <typename TargetStream>
850{
851 copyInternal(targetStream, startOffset(), headerSize(), diag, progress);
852}
853
857template <class ImplementationType>
858template <typename TargetStream>
860{
861 if (std::uint32_t firstChildOffset = this->firstChildOffset()) {
862 copyInternal(targetStream, startOffset(), firstChildOffset, diag, progress);
863 } else {
864 copyInternal(targetStream, startOffset(), totalSize(), diag, progress);
865 }
866}
867
871template <class ImplementationType>
872template <typename TargetStream>
874{
875 copyInternal(targetStream, startOffset(), totalSize(), diag, progress);
876}
877
882template <class ImplementationType> void GenericFileElement<ImplementationType>::makeBuffer()
883{
884 m_buffer = std::make_unique<char[]>(totalSize());
885 container().stream().seekg(static_cast<std::streamoff>(startOffset()));
886 container().stream().read(m_buffer.get(), static_cast<std::streamsize>(totalSize()));
887}
888
892template <class ImplementationType> inline void GenericFileElement<ImplementationType>::discardBuffer()
893{
894 m_buffer.reset();
895}
896
901template <class ImplementationType>
902template <typename TargetStream>
903inline void GenericFileElement<ImplementationType>::copyBuffer(TargetStream &targetStream)
904{
905 targetStream.write(m_buffer.get(), static_cast<std::streamsize>(totalSize()));
906}
907
912template <class ImplementationType>
913template <typename TargetStream>
915 TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
916{
917 m_buffer ? copyBuffer(targetStream) : copyEntirely(targetStream, diag, progress);
918}
919
924template <class ImplementationType> inline const std::unique_ptr<char[]> &GenericFileElement<ImplementationType>::buffer()
925{
926 return m_buffer;
927}
928
936template <class ImplementationType>
937template <typename TargetStream>
939 TargetStream &targetStream, std::uint64_t startOffset, std::uint64_t bytesToCopy, Diagnostics &diag, AbortableProgressFeedback *progress)
940{
941 // ensure the header has been parsed correctly
942 try {
943 parse(diag);
944 } catch (const Failure &) {
945 throw InvalidDataException();
946 }
947 auto &stream = container().stream();
948 stream.seekg(static_cast<std::streamoff>(startOffset), std::ios_base::beg);
949 CppUtilities::CopyHelper<0x10000> copyHelper;
950 if (progress) {
951 copyHelper.callbackCopy(stream, targetStream, bytesToCopy, std::bind(&AbortableProgressFeedback::isAborted, std::ref(progress)),
952 std::bind(&AbortableProgressFeedback::updateStepPercentageFromFraction, std::ref(progress), std::placeholders::_1));
953 } else {
954 copyHelper.copy(stream, targetStream, bytesToCopy);
955 }
956}
957
962template <class ImplementationType>
963ImplementationType *GenericFileElement<ImplementationType>::denoteFirstChild(std::uint32_t relativeFirstChildOffset)
964{
965 if (relativeFirstChildOffset + minimumElementSize() <= totalSize()) {
966 m_firstChild.reset(new ImplementationType(static_cast<ImplementationType &>(*this), startOffset() + relativeFirstChildOffset));
967 } else {
968 m_firstChild.reset();
969 }
970 return m_firstChild.get();
971}
972
976template <class ImplementationType> constexpr std::uint32_t GenericFileElement<ImplementationType>::maximumIdLengthSupported()
977{
978 return sizeof(IdentifierType);
979}
980
984template <class ImplementationType> constexpr std::uint32_t GenericFileElement<ImplementationType>::maximumSizeLengthSupported()
985{
986 return sizeof(DataSizeType);
987}
988
992template <class ImplementationType> constexpr std::uint8_t GenericFileElement<ImplementationType>::minimumElementSize()
993{
995}
996
1011} // namespace TagParser
1012
1013#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.
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.
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 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.
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.
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, 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.
void copyPreferablyFromBuffer(TargetStream &targetStream, Diagnostics &diag, AbortableProgressFeedback *progress)
Copies buffered data to targetStream if data has been buffered; copies from input stream otherwise.
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
Definition global.h:13
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10