1 #ifndef GENERICFILEELEMENT_H 2 #define GENERICFILEELEMENT_H 8 #include <c++utilities/conversion/types.h> 9 #include <c++utilities/io/copy.h> 10 #include <c++utilities/misc/memory.h> 13 #include <initializer_list> 27 template <
class ImplementationType>
34 template<
typename ImplementationType>
40 ImplementationType *operator *();
41 const ImplementationType *operator *()
const;
42 operator bool()
const;
46 ImplementationType *m_current;
52 template<
typename ImplementationType>
60 template<
typename ImplementationType>
69 template<
typename ImplementationType>
78 template<
typename ImplementationType>
82 m_current = m_current->nextSibling();
89 template<
typename ImplementationType>
92 return m_current !=
nullptr;
104 template<
typename ImplementationType>
115 template <
class ImplementationType>
141 GenericFileElement(containerType &container, uint64 startOffset);
142 GenericFileElement(implementationType &parent, uint64 startOffset);
143 GenericFileElement(containerType &container, uint64 startOffset, uint64 maxSize);
144 GenericFileElement(
const GenericFileElement& other) =
delete;
145 GenericFileElement(GenericFileElement& other) =
delete;
146 GenericFileElement& operator =(
const GenericFileElement& other) =
delete;
148 containerType& container();
149 const containerType& container()
const;
150 std::iostream &stream();
151 IoUtilities::BinaryReader &reader();
152 IoUtilities::BinaryWriter &writer();
153 uint64 startOffset()
const;
154 uint64 relativeStartOffset()
const;
155 const identifierType &id()
const;
156 std::string idToString()
const;
157 uint32 idLength()
const;
158 uint32 headerSize()
const;
159 dataSizeType dataSize()
const;
160 uint32 sizeLength()
const;
161 uint64 dataOffset()
const;
162 uint64 totalSize()
const;
163 uint64 endOffset()
const;
164 uint64 maxTotalSize()
const;
165 implementationType* parent();
166 const implementationType* parent()
const;
167 implementationType* nextSibling();
168 const implementationType* nextSibling()
const;
169 implementationType* firstChild();
170 const implementationType* firstChild()
const;
171 implementationType* subelementByPath(
const std::initializer_list<identifierType> &path);
172 implementationType* subelementByPath(std::list<identifierType> &path);
173 implementationType* childById(
const identifierType &
id);
174 implementationType* siblingById(
const identifierType &
id,
bool includeThis =
false);
179 bool isParent()
const;
180 bool isPadding()
const;
181 uint64 firstChildOffset()
const;
182 bool isParsed()
const;
186 void validateSubsequentElementStructure(
NotificationList &gatheredNotifications, uint64 *paddingSize =
nullptr);
187 static constexpr uint32 maximumIdLengthSupported();
188 static constexpr uint32 maximumSizeLengthSupported();
189 static constexpr byte minimumElementSize();
190 void copyHeader(std::ostream &targetStream);
191 void copyWithoutChilds(std::ostream &targetStream);
192 void copyEntirely(std::ostream &targetStream);
194 void discardBuffer();
195 void copyBuffer(std::ostream &targetStream);
196 const std::unique_ptr<char[]> &buffer();
197 implementationType *denoteFirstChild(uint32 offset);
212 void copyInternal(std::ostream &targetStream, uint64 startOffset, uint64 bytesToCopy);
214 containerType* m_container;
222 template <
class ImplementationType>
225 m_startOffset(startOffset),
230 m_container(&container),
233 stream().seekg(0, std::ios_base::end);
234 m_maxSize =
static_cast<uint64
>(stream().tellg());
235 if(m_maxSize > startOffset) {
236 m_maxSize -= startOffset;
237 stream().seekg(startOffset, std::ios_base::beg);
246 template <
class ImplementationType>
249 m_startOffset(startOffset),
250 m_maxSize(parent.startOffset() + parent.totalSize() - startOffset),
255 m_container(&parent.container()),
262 template <
class ImplementationType>
265 m_startOffset(startOffset),
271 m_container(&container),
278 template <
class ImplementationType>
287 template <
class ImplementationType>
296 template <
class ImplementationType>
299 return m_container->
stream();
305 template <
class ImplementationType>
308 return m_container->
reader();
314 template <
class ImplementationType>
317 return m_container->
writer();
323 template <
class ImplementationType>
326 return m_startOffset;
332 template <
class ImplementationType>
335 return parent() ? startOffset() - parent()->
startOffset() : startOffset();
341 template <
class ImplementationType>
350 template <
class ImplementationType>
353 return static_cast<ImplementationType *
>(
this)->idToString();
359 template <
class ImplementationType>
370 template <
class ImplementationType>
373 return m_idLength + m_sizeLength;
381 template <
class ImplementationType>
390 template <
class ImplementationType>
401 template <
class ImplementationType>
404 return startOffset() + headerSize();
412 template <
class ImplementationType>
415 return headerSize() + dataSize();
421 template <
class ImplementationType>
424 return startOffset() + totalSize();
433 template <
class ImplementationType>
445 template <
class ImplementationType>
457 template <
class ImplementationType>
471 template <
class ImplementationType>
474 return m_nextSibling.get();
485 template <
class ImplementationType>
488 return m_nextSibling.get();
499 template <
class ImplementationType>
502 return m_firstChild.get();
513 template <
class ImplementationType>
516 return m_firstChild.get();
528 template <
class ImplementationType>
531 std::list<GenericFileElement<ImplementationType>::identifierType> list(path);
532 return subelementByPath(list);
545 template <
class ImplementationType>
550 if(path.front() == id()) {
551 if(path.size() == 1) {
556 return firstChild()->subelementByPath(path);
561 return nextSibling()->subelementByPath(path);
577 template <
class ImplementationType>
583 if(child->id() == id) {
604 template <
class ImplementationType>
608 for(
implementationType *sibling = includeThis ? static_cast<implementationType*>(
this) : nextSibling(); sibling; sibling = sibling->nextSibling()) {
610 if(sibling->id() == id) {
620 template <
class ImplementationType>
629 template <
class ImplementationType>
638 template <
class ImplementationType>
647 template <
class ImplementationType>
656 template <
class ImplementationType>
659 return static_cast<const ImplementationType *
>(
this)->isParent();
665 template <
class ImplementationType>
668 return static_cast<const ImplementationType *
>(
this)->isPadding();
674 template <
class ImplementationType>
677 return static_cast<const ImplementationType *
>(
this)->firstChildOffset();
683 template <
class ImplementationType>
695 template <
class ImplementationType>
703 m_nextSibling =
nullptr;
704 m_firstChild =
nullptr;
722 template <
class ImplementationType>
726 static_cast<ImplementationType *
>(
this)->internalParse();
747 template <
class ImplementationType>
751 static_cast<ImplementationType *
>(
this)->parse();
767 template <
class ImplementationType>
772 gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end());
774 firstChild()->validateSubsequentElementStructure(gatheredNotifications, paddingSize);
775 }
else if(paddingSize && isPadding()) {
776 *paddingSize += totalSize();
779 nextSibling()->validateSubsequentElementStructure(gatheredNotifications, paddingSize);
782 gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end());
790 template <
class ImplementationType>
793 copyInternal(targetStream, startOffset(), headerSize());
799 template <
class ImplementationType>
802 if(uint32 firstChildOffset = this->firstChildOffset()) {
803 copyInternal(targetStream, startOffset(), firstChildOffset);
805 copyInternal(targetStream, startOffset(), totalSize());
812 template <
class ImplementationType>
815 copyInternal(targetStream, startOffset(), totalSize());
822 template <
class ImplementationType>
825 m_buffer = std::make_unique<char[]>(totalSize());
826 container().
stream().seekg(startOffset());
827 container().
stream().read(m_buffer.get(), totalSize());
833 template <
class ImplementationType>
843 template <
class ImplementationType>
846 targetStream.write(m_buffer.get(), totalSize());
853 template <
class ImplementationType>
866 template <
class ImplementationType>
876 auto &stream = container().
stream();
877 stream.seekg(startOffset);
889 template <
class ImplementationType>
892 if(relativeFirstChildOffset + minimumElementSize() <= totalSize()) {
893 m_firstChild.reset(
new implementationType(static_cast<implementationType &>(*
this), startOffset() + relativeFirstChildOffset));
895 m_firstChild.reset();
897 return m_firstChild.get();
903 template <
class ImplementationType>
912 template <
class ImplementationType>
921 template <
class ImplementationType>
943 #endif // GENERICFILEELEMENT_H
Contains utility classes helping to read and write streams.
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.