1 #ifndef GENERICFILEELEMENT_H 2 #define GENERICFILEELEMENT_H 8 #include <c++utilities/conversion/types.h> 9 #include <c++utilities/io/copy.h> 12 #include <initializer_list> 26 template <
class ImplementationType>
33 template<
typename ImplementationType>
41 operator bool()
const;
45 ImplementationType *m_current;
51 template<
typename ImplementationType>
59 template<
typename ImplementationType>
68 template<
typename ImplementationType>
77 template<
typename ImplementationType>
81 m_current = m_current->nextSibling();
88 template<
typename ImplementationType>
91 return m_current !=
nullptr;
103 template<
typename ImplementationType>
114 template <
class ImplementationType>
147 containerType& container();
148 const containerType& container()
const;
149 std::iostream &stream();
150 IoUtilities::BinaryReader &reader();
151 IoUtilities::BinaryWriter &writer();
152 uint64 startOffset()
const;
153 uint64 relativeStartOffset()
const;
155 std::string idToString()
const;
156 uint32 idLength()
const;
157 uint32 headerSize()
const;
159 uint32 sizeLength()
const;
160 uint64 dataOffset()
const;
161 uint64 totalSize()
const;
162 uint64 endOffset()
const;
163 uint64 maxTotalSize()
const;
170 implementationType* subelementByPath(
const std::initializer_list<identifierType> &path);
178 bool isParent()
const;
179 bool isPadding()
const;
180 uint64 firstChildOffset()
const;
181 bool isParsed()
const;
185 void validateSubsequentElementStructure(
NotificationList &gatheredNotifications, uint64 *paddingSize =
nullptr);
186 static constexpr uint32 maximumIdLengthSupported();
187 static constexpr uint32 maximumSizeLengthSupported();
188 static constexpr byte minimumElementSize();
189 void copyHeader(std::ostream &targetStream);
190 void copyWithoutChilds(std::ostream &targetStream);
191 void copyEntirely(std::ostream &targetStream);
193 void discardBuffer();
194 void copyBuffer(std::ostream &targetStream);
195 void copyPreferablyFromBuffer(std::ostream &targetStream);
196 const std::unique_ptr<char[]> &buffer();
212 void copyInternal(std::ostream &targetStream, uint64 startOffset, uint64 bytesToCopy);
214 containerType* m_container;
222 template <
class ImplementationType>
224 m_id(identifierType()),
225 m_startOffset(startOffset),
230 m_container(&container),
233 m_maxSize = container.fileInfo().size();
234 if(m_maxSize > startOffset) {
235 m_maxSize -= startOffset;
236 stream().seekg(startOffset, std::ios_base::beg);
245 template <
class ImplementationType>
246 GenericFileElement<ImplementationType>::GenericFileElement(GenericFileElement<ImplementationType>::implementationType &parent, uint64 startOffset) :
247 m_id(identifierType()),
248 m_startOffset(startOffset),
249 m_maxSize(parent.startOffset() + parent.totalSize() - startOffset),
254 m_container(&parent.container()),
261 template <
class ImplementationType>
262 GenericFileElement<ImplementationType>::GenericFileElement(GenericFileElement<ImplementationType>::containerType &container, uint64 startOffset, uint64 maxSize) :
263 m_id(identifierType()),
264 m_startOffset(startOffset),
270 m_container(&container),
277 template <
class ImplementationType>
286 template <
class ImplementationType>
295 template <
class ImplementationType>
298 return m_container->
stream();
304 template <
class ImplementationType>
307 return m_container->
reader();
313 template <
class ImplementationType>
316 return m_container->
writer();
322 template <
class ImplementationType>
325 return m_startOffset;
331 template <
class ImplementationType>
334 return parent() ? startOffset() - parent()->
startOffset() : startOffset();
340 template <
class ImplementationType>
349 template <
class ImplementationType>
352 return static_cast<ImplementationType *
>(
this)->idToString();
358 template <
class ImplementationType>
369 template <
class ImplementationType>
372 return m_idLength + m_sizeLength;
380 template <
class ImplementationType>
389 template <
class ImplementationType>
400 template <
class ImplementationType>
403 return startOffset() + headerSize();
411 template <
class ImplementationType>
414 return headerSize() + dataSize();
420 template <
class ImplementationType>
423 return startOffset() + totalSize();
432 template <
class ImplementationType>
444 template <
class ImplementationType>
456 template <
class ImplementationType>
470 template <
class ImplementationType>
473 return m_nextSibling.get();
484 template <
class ImplementationType>
487 return m_nextSibling.get();
498 template <
class ImplementationType>
501 return m_firstChild.get();
512 template <
class ImplementationType>
515 return m_firstChild.get();
527 template <
class ImplementationType>
530 std::list<GenericFileElement<ImplementationType>::identifierType> list(path);
531 return subelementByPath(list);
544 template <
class ImplementationType>
549 if(path.front() == id()) {
550 if(path.size() == 1) {
551 return static_cast<implementationType*
>(
this);
555 return firstChild()->subelementByPath(path);
560 return nextSibling()->subelementByPath(path);
576 template <
class ImplementationType>
582 if(child->id() == id) {
603 template <
class ImplementationType>
607 for(
implementationType *sibling = includeThis ? static_cast<implementationType*>(
this) : nextSibling(); sibling; sibling = sibling->nextSibling()) {
609 if(sibling->id() == id) {
619 template <
class ImplementationType>
628 template <
class ImplementationType>
637 template <
class ImplementationType>
646 template <
class ImplementationType>
655 template <
class ImplementationType>
658 return static_cast<const ImplementationType *
>(
this)->isParent();
664 template <
class ImplementationType>
667 return static_cast<const ImplementationType *
>(
this)->isPadding();
673 template <
class ImplementationType>
676 return static_cast<const ImplementationType *
>(
this)->firstChildOffset();
682 template <
class ImplementationType>
694 template <
class ImplementationType>
702 m_nextSibling =
nullptr;
703 m_firstChild =
nullptr;
721 template <
class ImplementationType>
725 static_cast<ImplementationType *
>(
this)->internalParse();
746 template <
class ImplementationType>
750 static_cast<ImplementationType *
>(
this)->parse();
766 template <
class ImplementationType>
772 gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end());
776 firstChild()->validateSubsequentElementStructure(gatheredNotifications, paddingSize);
782 }
else if(paddingSize && isPadding()) {
783 *paddingSize += totalSize();
787 nextSibling()->validateSubsequentElementStructure(gatheredNotifications, paddingSize);
790 gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end());
798 template <
class ImplementationType>
801 copyInternal(targetStream, startOffset(), headerSize());
807 template <
class ImplementationType>
810 if(uint32 firstChildOffset = this->firstChildOffset()) {
811 copyInternal(targetStream, startOffset(), firstChildOffset);
813 copyInternal(targetStream, startOffset(), totalSize());
820 template <
class ImplementationType>
823 copyInternal(targetStream, startOffset(), totalSize());
830 template <
class ImplementationType>
833 m_buffer = std::make_unique<char[]>(totalSize());
834 container().
stream().seekg(startOffset());
835 container().
stream().read(m_buffer.get(), totalSize());
841 template <
class ImplementationType>
851 template <
class ImplementationType>
854 targetStream.write(m_buffer.get(), totalSize());
861 template <
class ImplementationType>
864 m_buffer ? copyBuffer(targetStream) : copyEntirely(targetStream);
871 template <
class ImplementationType>
884 template <
class ImplementationType>
892 throw InvalidDataException();
894 auto &stream = container().
stream();
895 stream.seekg(startOffset);
897 copyHelper.callbackCopy(stream, targetStream, bytesToCopy, std::bind(&GenericFileElement<ImplementationType>::isAborted,
this), std::bind(&GenericFileElement<ImplementationType>::updatePercentage,
this, std::placeholders::_1));
899 throw OperationAbortedException();
907 template <
class ImplementationType>
910 if(relativeFirstChildOffset + minimumElementSize() <= totalSize()) {
911 m_firstChild.reset(
new implementationType(static_cast<implementationType &>(*
this), startOffset() + relativeFirstChildOffset));
913 m_firstChild.reset();
915 return m_firstChild.get();
921 template <
class ImplementationType>
930 template <
class ImplementationType>
939 template <
class ImplementationType>
961 #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.