1 #ifndef EBML_NG_LAZYLOAD_BASE_H 2 #define EBML_NG_LAZYLOAD_BASE_H 7 #include <shared_mutex> 9 #include "../base/ebmlMasterElementType.h" 10 #include "../base/ebmlMasterElement.h" 21 #include "../../ebmlVoid.h" 22 #include "../../repr.h" 24 #define EN_IF_INST(T, R) std::enable_if_t<!std::is_same<ebmlElement, T>::value && std::is_base_of<ebmlElement, std::decay_t<T>>::value, R> 25 #define EN_IF_CLS(T, R) std::enable_if_t<std::is_base_of<ebmlElementType, std::decay_t<T>>::value, R> 26 #define EN_IFN_INST(T, R) std::enable_if_t<!std::is_base_of<ebmlElement, std::decay_t<T>>::value, R> 27 #define EN_IFN_CLS(T, R) std::enable_if_t<!std::is_base_of<ebmlElementType, std::decay_t<T>>::value, R> 28 #define KEY_ARGS typename K, typename H = std::hash<K>, typename E = std::equal_to<K> 99 std::map<off_t, seekData_t*>
115 const std::unordered_map<
117 std::map<off_t, seekData_t*>
118 >& seeksByEBMLID()
const;
119 const std::unordered_map<ebmlID_t, std::unique_ptr<seekMapBase>>& seeksByKey()
const;
138 off_t endOfData()
const;
279 std::vector<seekData_t*> insert(off_t,
const ebmlElement_l&);
293 seekData_t* insert(off_t,
const std::string&);
316 template<
typename T,
typename... Args>
inline EN_IF_CLS(T,
elem_seek_pair) insert(off_t,
const T& cls, Args&&...);
333 template<
typename T,
typename... Args>
334 inline std::enable_if_t<std::is_base_of<ebmlLazyLoadType, T>::value, std::pair<ebmlElement_sp, seekData_t*>> _insert(off_t offset,
const T& cls,
vintWidth_t sizeWidth,
size_t dataSize, Args... args);
336 template<
typename T,
typename... Args>
337 inline std::enable_if_t<!std::is_base_of<ebmlLazyLoadType, T>::value && std::is_base_of<ebmlElementType, T>::value, std::pair<ebmlElement_sp, seekData_t*>>_insert(off_t,
const T& cls, Args...);
343 void move(off_t, off_t);
357 inline void resize(
size_t size);
363 inline bool _sizeSupported(
size_t size);
365 inline void _resize(
size_t size);
373 inline void remove(off_t offset);
374 inline void remove(off_t offset,
const readLock_t&);
375 inline void remove(off_t offset,
const writeLock_t&);
381 inline void _remove(off_t offset);
387 off_t findBoundary(off_t offset);
388 off_t findBoundary(off_t offset,
const readLock_t&);
389 off_t findBoundary(off_t offset,
const writeLock_t&);
392 off_t _findBoundary(off_t offset);
395 off_t rfindBoundary(off_t offset);
396 off_t rfindBoundary(off_t offset,
const readLock_t&);
397 off_t rfindBoundary(off_t offset,
const writeLock_t&);
400 off_t _rfindBoundary(off_t offset);
448 inline void insertRange(off_t offset,
size_t size);
449 inline void insertRange(off_t offset,
size_t size,
const readLock_t&);
450 inline void insertRange(off_t offset,
size_t size,
const writeLock_t&);
455 inline void _insertRange(off_t offset,
size_t size);
461 inline void collapseRange(off_t offset,
size_t size);
462 inline void collapseRange(off_t offset,
size_t size,
const readLock_t&);
463 inline void collapseRange(off_t offset,
size_t size,
const writeLock_t&);
468 inline void _collapseRange(off_t offset,
size_t size);
474 inline void punchHole(off_t offset,
size_t size);
475 inline void punchHole(off_t offset,
size_t size,
const readLock_t&);
481 inline void _punchHole(off_t offset,
size_t size);
487 std::wstring minirepr()
const override;
488 size_t dataSize()
const override;
493 seekData_t* _prevChildSeek(off_t offset,
bool strict=
true)
const;
494 seekData_t* _nextChildSeek(off_t offset,
bool strict=
true)
const;
496 std::pair<children_m::iterator, children_m::iterator> _find(off_t offset,
bool left=
true);
497 children_m::iterator _findNext(off_t offset,
bool strict=
true);
498 children_m::iterator _findPrev(off_t offset,
bool strict=
true);
502 off_t _findFree(off_t offset,
size_t size);
503 off_t _rfindFree(off_t offset,
size_t size);
509 void _handleParseFile(
const parseFile&)
override;
510 void _handleSeekData(std::unique_ptr<seekData_t>&&);
511 virtual void _handleSeekData(std::unique_ptr<seekData_t>&&,
const children_m::iterator&);
527 template<SEEKMAPDEFAULTS>
553 return _get<T>(offset);
558 return _get<T>(offset);
563 return _get<T>(offset);
566 template<
typename T>
inline ebml::ptr<T> ebmlLazyLoad::_get(off_t offset) {
572 return _get(
ebmlID, index);
577 return _get(
ebmlID, index);
582 return _get(
ebmlID, index);
587 return _cget(offset);
592 return _cget(offset);
597 return _cget(offset);
602 return _cget<T>(offset);
607 return _cget<T>(offset);
612 return _cget<T>(offset);
615 template<
typename T>
inline ebml::ptr<T> ebmlLazyLoad::_cget(off_t offset)
const {
621 return _cget(
ebmlID, index);
626 return _cget(
ebmlID, index);
631 return _cget(
ebmlID, index);
634 template<
typename K,
typename H,
typename E>
637 return _getByKey<K, H, E>(
ebmlID, key);
640 template<
typename K,
typename H,
typename E>
643 return _getByKey<K, H, E>(
ebmlID, key);
646 template<
typename K,
typename H,
typename E>
649 return _getByKey<K, H, E>(
ebmlID, key);
652 template<
typename K,
typename H,
typename E>
655 std::string errmsg =
"element not found with ebmlID ";
656 errmsg += std::to_string(
ebmlID);
657 errmsg +=
" and key ";
664 if (seekmap.count(key) == 0) {
665 std::string errmsg =
"element not found with ebmlID ";
666 errmsg += std::to_string(
ebmlID);
667 errmsg +=
" and key ";
672 auto seekData = seekmap.at(key);
674 return seekData->get();
677 template<
typename T,
typename K,
typename H,
typename E>
680 return _getByKey<T, K, H, E>(
ebmlID, key);
683 template<
typename T,
typename K,
typename H,
typename E>
690 return _canInsert(offset, elem_p);
695 return _insert(offset, elem_p);
700 return _insert(offset, elem_p);
705 return _insert(offset, elem_p);
710 return _insert(offset, elem_p, prepared);
714 auto prepared = _canInsert(offset, elem_p);
715 return _insert(offset, elem_p, prepared);
722 return _canInsert(offset,
data);
727 auto prepared = _canInsert(offset,
data);
728 return _insert(offset,
data, prepared);
733 auto prepared = _canInsert(offset,
data);
734 return _insert(offset,
data, prepared);
739 auto prepared = _canInsert(offset,
data);
740 return _insert(offset,
data, prepared);
745 return _insert(offset,
data, status );
749 return _insert(offset,
data.data(), status);
756 return _canInsert(offset,
data);
762 return _canInsert(offset, std::move(
sizetree));
767 auto prepared = _canInsert(offset,
data);
768 return _insert(offset,
data, prepared);
773 auto prepared = _canInsert(offset,
data);
774 return _insert(offset,
data, prepared);
779 auto prepared = _canInsert(offset,
data);
780 return _insert(offset,
data, prepared);
785 return _insert(offset,
data, status );
790 return _canRemove(offset);
810 _remove(offset, status);
813 inline void ebmlLazyLoad::_remove(off_t offset) {
814 auto status = _canRemove(offset);
815 _remove(offset, status);
820 return _sizeSupported(
size);
823 inline bool ebmlLazyLoad::_sizeSupported(
size_t size) {
841 inline void ebmlLazyLoad::_resize(
size_t size) {
842 auto status = _canResize(
size);
843 _resize(
size, status);
846 template<
typename T,
typename... Args>
849 return _insert(offset,
cls, args...);
852 template<
typename T,
typename... Args>
855 return _insert(offset,
cls, args...);
858 template<
typename T,
typename... Args>
861 return _insert(offset,
cls, args...);
864 template<
typename T,
typename... Args>
865 inline std::enable_if_t<std::is_base_of<ebmlLazyLoadType, T>::value, std::pair<ebmlElement_sp, seekData_t*>>
866 ebmlLazyLoad::_insert(off_t offset,
const T& cls,
vintWidth_t sizeWidth,
size_t dataSize, Args... args) {
868 auto query = _canInsert(offset, std::move(
sizetree));
869 auto&
data = query.data();
873 query.throw_exc(elem);
881 if (data.prev.endOffset < offset) {
889 if (
data.extent.endOffset <
data.next) {
894 auto seekData_up = std::unique_ptr<seekData_t>(seekData);
896 return {std::move(elem), seekData};
899 template<
typename T,
typename... Args>
900 inline std::enable_if_t<!std::is_base_of<ebmlLazyLoadType, T>::value && std::is_base_of<ebmlElementType, T>::value, std::pair<ebmlElement_sp, seekData_t*>>
901 ebmlLazyLoad::_insert(off_t offset,
const T& cls, Args... args) {
903 status_t<prepared_insert_t> status = _canInsert(offset, elem);
904 auto seek = _insert(offset, elem, status);
905 return {std::move(elem), seek};
Helper class for creating and initializing seek data.
Definition: seekdata.h:195
T & data(const ebmlElement_sp &elem)
std::enable_if_t<!std::is_base_of< ebmlElement, std::decay_t< K > >::value, ebml::ptr< ebmlElement > > getByKey(ebmlID_t, const K &)
Gets a child element based on a user-defined key.
Definition: ebmlLazyLoad.h:635
friend class ebmlSchema
Definition: ebmlLazyLoad.h:60
ebml_shared_ptr< T > ebml_dynamic_pointer_cast(const ebml_shared_ptr< U > &)
Definition: ptrs.h:676
std::list< childTypeSpecArg_t > childTypeSpecArg_l
Alias for a list of child type specification arguments.
Definition: childTypeSpec.h:39
Definition: childElemHelper_t.h:22
size_t size(const std::string &value)
Definition: binary.h:8
ebmlElement(const ebmlElementType *)
Protected constructor.
Definition: ebmlElement.cpp:22
#define EN_IF_INST(T, R)
Definition: ebmlLazyLoad.h:24
seekData_t * makeSeekData(ebmlElement &elem) const =0
std::unordered_map< ebmlID_t, std::map< off_t, seekData_t * > > _children_by_ebmlID
Definition: ebmlLazyLoad.h:100
Definition: ebmlMasterElement.h:269
Represents a parsed EBML string segment.
Definition: string.h:37
status_t< prepared_remove_t > canRemove(off_t, const writeLock_t &)
Definition: ebmlLazyLoad.h:788
Represents parsed seek data extracted from an EBML element.
Definition: seekdata.h:39
sizetree_t sizetree() const
Generates the size tree for the element hierarchy.
Definition: ebmlMasterElement.cpp:90
Represents a parsed EBML file segment.
Definition: io.h:32
Definition: prepared.h:133
#define DECODE_ERR_DEFAULT
Definition: exceptions.h:13
ebmlID_t ebmlID
EBML ID associated with this element type.
Definition: ebmlElementType.h:129
seekData_t * insert(off_t, const ebml::ptr< ebmlElement > &)
Definition: ebmlLazyLoad.h:693
ioBase & file() const
Definition: ebmlLazyLoad.cpp:109
Definition: basictypes.h:40
A drop-in replacement for std::shared_ptr tailored for EBML objects.
Definition: ptrs.h:27
const ebmlLazyLoadType & cls() const
Returns a reference to the associated element class.
std::unordered_map< ebmlID_t, std::unique_ptr< seekMapBase > > _children_by_key
Definition: ebmlLazyLoad.h:101
children_m _children_by_offset
Definition: ebmlLazyLoad.h:96
A template class representing a lazy-loading EBML master element.
Definition: ebmlLazyLoad.h:46
writeLock_t getWLock() const
Definition: ebmlLazyLoad.cpp:228
Definition: ebmlMasterElement.h:324
unsigned char widthAsVint(unsigned long long n)
Computes the minimal width (in bytes) required to encode an unsigned long long as a vint...
Definition: vint.h:51
const size_t UNKNOWN
Special constant representing an unknown or maximum value.
Definition: vint.cpp:15
off_t dataOffsetInFile() const
Definition: ebmlElement.cpp:182
std::wstring repr(const std::string &str)
Definition: repr.cpp:36
unsigned char writeVoid(char *, size_t) const
Definition: ebmlVoid.cpp:16
ebmlVoidType Void
Definition: ebmlVoid.cpp:127
Represents an EBML Master Element with on-disk, transactional child management.
Definition: ebmlLazyLoad.h:85
readLock_t getRLock() const
Definition: ebmlLazyLoad.cpp:161
friend class ebmlLazyLoad
Definition: ebmlLazyLoad.h:61
uint64_t ebmlID_t
Definition: ebmlID_t.h:7
bool sizeSupported(size_t size, const writeLock_t &)
Definition: ebmlLazyLoad.h:818
size_t dataSize() const override
Definition: ebmlLazyLoad.cpp:119
Structure representing the size tree for an EBML master element.
Definition: sizetree_t.h:15
uint8_t vintWidth_t
Definition: ebmlID_t.h:8
ebml::ptr< const ebmlElement > cget(off_t) const
Definition: ebmlLazyLoad.h:585
vintWidth_t _sizeWidth
Definition: ebmlElement.h:224
Definition: ebmlLazyLoad.h:528
ebml::ptr< ebmlLazyLoad > sp()
ebml_shared_ptr< T > ebml_static_pointer_cast(const ebml_shared_ptr< U > &)
Definition: ptrs.h:731
void remove(off_t offset)
Definition: ebmlLazyLoad.h:793
std::pair< ebmlElement_sp, seekData_t * > elem_seek_pair
Definition: ebmlLazyLoad.h:31
std::shared_mutex _mutex
Definition: ebmlLazyLoad.h:90
void resize(size_t size)
Definition: ebmlLazyLoad.h:831
status_t< prepared_insert_t > canInsert(off_t, sizetree_t &&, const writeLock_t &)
Definition: ebmlLazyLoad.cpp:483
Abstract base class for EBML Element instances.
Definition: ebmlElement.h:79
ioBase_sp _file
Definition: ebmlLazyLoad.h:91
size_t pack(const std::string &value, size_t size, char *dest)
Definition: binary.h:12
unsigned char sizeWidth() const
Definition: ebmlElement.cpp:230
size_t _dataSize
Definition: ebmlLazyLoad.h:93
void _handleSeekData(std::unique_ptr< seekData_t > &&)
Definition: ebmlLazyLoad.cpp:145
Templated helper class for EBML elements that search for key data within child elements.
Definition: seekdata.h:220
#define EN_IF_CLS(T, R)
Definition: ebmlLazyLoad.h:25
ebml::ptr< ebmlElement > get(off_t)
Definition: ebmlLazyLoad.h:536
Base class for file-like IO operations.
Definition: io.h:22
Definition: exceptions.h:46
#define EN_IFN_INST(T, R)
Definition: ebmlLazyLoad.h:26
std::map< off_t, std::unique_ptr< seekData_t > > children_m
Definition: children_m.h:10
std::vector< ebmlElement_sp > ebmlElement_l
Definition: c_ebmlElement_l.h:9
childElemHelper_t childHelper
Definition: childElemHelper_t.cpp:27
friend class seekData_t
Definition: ebmlLazyLoad.h:524
ebmlID_t ebmlID() const
Retrieve the EBML ID of the element.
Definition: ebmlElement.cpp:268