libebml_ng
lazyload.h
Go to the documentation of this file.
1 #ifndef EBML_NG_LAZYLOADMASTERELEMENT_H
2 #define EBML_NG_LAZYLOADMASTERELEMENT_H
3 
4 #include <unordered_map>
5 #include <map>
6 #include <unordered_set>
7 #include <mutex>
8 #include <shared_mutex>
9 
10 #include "base/ebmlMasterElement.h"
12 #include "../ptrs.h"
13 #include "../seekdata.h"
14 #include "../exceptions.h"
15 #include "../ebmlDataElement.h"
16 
17 
18 namespace ebml {
19  typedef std::map<off_t, std::unique_ptr<seekData_t>> children_m;
20 
21  template<typename T>
22  class status_t {
23  protected:
24  bool result;
25  union {
26  std::string reason;
27  };
28  T _data;
29 
30  public:
31  status_t(bool);
32  status_t(bool, const T&);
33  status_t(bool, T&&);
34 
35  // template<typename... Args>
36  // status_t(bool, Args...);
37 
38  status_t(bool, const std::string&);
39  status_t(bool, std::string&&);
40  status_t(bool, const char*);
41 
42  status_t(bool, const std::string&, const T&);
43  status_t(bool, const char*, const T&);
44  status_t(bool, std::string&&, T&&);
45  status_t(bool, const char*, T&&);
46 
47  // template<typename... Args>
48  // status_t(bool, const std::string&, Args...);
49 
50  // template<typename... Args>
51  // status_t(bool, std::string&&, Args...);
52 
53  status_t(const status_t&);Can padding for AFO br
54  status_t(status_t&&);
55  ~status_t();
56 
57  status_t& operator=(const status_t&);
59 
60  operator bool() const;
61  operator const T&() const;
62  const T& data() const;
63  operator std::string() const;
64  void throw_exc(const c_ebmlElement_sp&) const;
65  };
66 
68  protected:
69  bool result;
70  union {
71  std::string reason;
72  };
73 
74  public:
75  prepared_base_t(bool);
76  prepared_base_t(bool, const std::string&);
77  prepared_base_t(bool, std::string&&);
80 
81  virtual ~prepared_base_t();
82 
85 
86  operator bool() const;
87  };
88 
89  class prepared_insert_t {
90  public:
91  off_t prevOffset;
92  off_t prevEnd;
93  off_t offset;
94  off_t endOffset;
95  off_t nextOffset;
97  children_m::iterator insertionHint;
98 
99  prepared_insert_t(off_t, off_t, off_t, off_t, off_t, const sizetree_t&, const children_m::iterator&);
100  prepared_insert_t(off_t, off_t, off_t, off_t, off_t, sizetree_t&&, children_m::iterator&&);
101  prepared_insert_t(off_t, off_t, off_t, off_t, off_t);
102  // ~prepared_insert_t();
103 
106 
109 
110  void throw_exc(const std::string&, const c_ebmlElement_sp&) const;
111  // operator ebmlInsertionError() const;
112  };
113 
114  class prepared_move_t : public prepared_base_t {
115  public:
116  off_t srcPrevEnd;
117  off_t srcOffset;
118  off_t srcNextOffset;
119 
120  off_t prevOffset;
121  off_t prevEnd;
122 
123  off_t dest_offset;
124  off_t endOffset;
125 
126  off_t nextOffset;
127  children_m::iterator sourceIter;
128  children_m::iterator insertionHint;
129 
130  prepared_move_t(bool, off_t, off_t, off_t, off_t, off_t, off_t, off_t, off_t, const children_m::iterator&, const children_m::iterator&);
131  prepared_move_t(bool, off_t, off_t, off_t, off_t, off_t, off_t, off_t, off_t, children_m::iterator&&, children_m::iterator&&);
132  prepared_move_t(bool, const std::string&, off_t, off_t, off_t, off_t, off_t, off_t, off_t, off_t);
133  prepared_move_t(bool, std::string&&, off_t, off_t, off_t, off_t, off_t, off_t, off_t, off_t);
134  // ~prepared_move_t();
135 
138 
141 
142  operator ebmlMoveError() const;
143  };
144 
145  class prepared_resize_t : public prepared_base_t {
146  public:
147  off_t offset;
148  off_t endOffset;
149  off_t lastChildOffset;
150  off_t lastChildEnd;
151  off_t nextSiblingOffset;
153 
154  prepared_resize_t(bool, off_t, off_t, off_t, off_t, off_t, seekData_t*);
155  prepared_resize_t(bool, const std::string&, off_t, off_t, off_t, off_t, off_t);
156  prepared_resize_t(bool, std::string&&, off_t, off_t, off_t, off_t, off_t);
157 
160 
163 
164  operator ebmlResizeError() const;
165  };
166 
168  private:
169  std::unique_lock<std::shared_mutex> _lock;
170 
171  public:
172  upgradedLock_t(std::shared_lock<std::shared_mutex>&);
173  ~upgradedLock_t();
174  };
175 
177  private:
178  std::shared_lock<std::shared_mutex> _glob;
179  std::shared_lock<std::shared_mutex> _loc;
180 
181  public:
182  localReadLock_t(std::shared_mutex&, std::shared_mutex&);
185  };
186 
188  private:
189  std::shared_lock<std::shared_mutex> _glob;
190  std::unique_lock<std::shared_mutex> _loc;
191 
192  public:
193  localWriteLock_t(std::shared_mutex&, std::shared_mutex&);
195  };
196 
197  typedef std::unique_lock<std::shared_mutex> globalWriteLock_t;
198 
199  class childElemHelper_t {
200  // public:
201  // childElemHelper_t();
202  // childElemHelper_t(const childElemHelper_t&);
203 
204  protected:
205  virtual void _onBeforeInsert(ebmlLazyLoad&, off_t, const ebmlElement_sp&) const;
206  virtual void _onAfterInsert(ebmlLazyLoad&, off_t, const ebmlElement_sp&, seekData_t*) const;
207  virtual void _onBeforeMove(ebmlLazyLoad&) const;
208  virtual void _onAfterMove(ebmlLazyLoad&) const;
209  virtual void _onBeforeRemove(ebmlLazyLoad&) const;
210  virtual void _onAfterRemove(ebmlLazyLoad&) const;
211  friend class ebmlLazyLoad;
212  };
213 
214  extern childElemHelper_t childHelper;
215 
216  class ebmlLazyLoadClass : public ClsMixin<ebmlLazyLoadClass, ebmlLazyLoad, ebmlMasterElementClass> {
217  protected:
219  public:
220  ebmlLazyLoadClass(const char*, const std::wstring&, const childClassSpecArg_l&);
221  ebmlLazyLoadClass(ebmlID_t, const std::wstring&, const childClassSpecArg_l&);
222  ebmlLazyLoadClass(const char*, const std::wstring&, const childClassSpecArg_l&, const seekHelper_t*);
223  ebmlLazyLoadClass(ebmlID_t, const std::wstring&, const childClassSpecArg_l&, const seekHelper_t*);
224 
225  ebmlLazyLoadClass(const char*, const std::wstring&, const childClassSpecArg_l&, const childElemHelper_t*);
226  ebmlLazyLoadClass(ebmlID_t, const std::wstring&, const childClassSpecArg_l&, const childElemHelper_t*);
227  ebmlLazyLoadClass(const char*, const std::wstring&, const childClassSpecArg_l&, const seekHelper_t*, const childElemHelper_t*);
228  ebmlLazyLoadClass(ebmlID_t, const std::wstring&, const childClassSpecArg_l&, const seekHelper_t*, const childElemHelper_t*);
229 
230  protected:
231  // Read existing element in file
233  ebmlLazyLoad_sp operator()(ioBase*, off_t) const;
234 
235  // Create new element in file
236  ebmlLazyLoad_sp operator()(ioBase*, vintWidth_t, size_t) const;
237  ebmlLazyLoad_sp operator()(ioBase*, off_t, vintWidth_t, size_t) const;
238  // ebmlLazyLoad_sp operator()(ioBase*, vintWidth_t, size_t, const ebmlElement_l&) const;
239  ebmlLazyLoad_sp operator()(ioBase*, off_t, vintWidth_t, size_t, const ebmlElement_l&) const;
240 
241  ebmlLazyLoad_sp operator()(ebmlLazyLoad*, off_t, vintWidth_t, size_t) const;
242  // ebmlLazyLoad_sp operator()(ebmlLazyLoad*, vintWidth_t, size_t, const ebmlElement_l&) const;
243  ebmlLazyLoad_sp operator()(ebmlLazyLoad*, off_t, vintWidth_t, size_t, const ebmlElement_l&) const;
244 
245  // ebmlElement* _new() const override;
246  // ebmlElement_sp _decode(const parseFile&) const override;
247  // ebmlElement_sp _cdecode(const parseFile&) const override;
248 
249  public:
250 
251  // Create new element in parent element
252  // ebmlElement_sp operator()(const ebmlElement_sp&, vintWidth_t, size_t) const;
253  // ebmlElement_sp operator()(ebmlElement_sp&&, vintWidth_t, size_t) const;
254  // ebmlElement_sp operator()(ebmlElement_sp&&, off_t, vintWidth_t, size_t) const;
255  friend class ebmlSchema;
256  friend class ebmlLazyLoad;
257  };
258 
259  class ebmlLazyLoad : public InstMixin<ebmlLazyLoadClass, ebmlLazyLoad, ebmlMasterElement> {
260  friend class ClsMixin<ebmlLazyLoadClass, ebmlLazyLoad, ebmlMasterElementClass>;
262  void _clone(const ebmlLazyLoad&);
263 
264  protected:
265  mutable std::shared_mutex _mutex;
267  ioBase* _file_raw = nullptr;
268  size_t _dataSize;
269 
271  std::unordered_map<
272  ebmlID_t,
273  std::map<off_t, seekData_t*>
275  std::unordered_map<ebmlID_t, std::unique_ptr<seekMapBase>> _children_by_key;
276 
277  protected:
280  ebmlLazyLoad(const ebmlLazyLoadClass*, ioBase&, off_t, vintWidth_t, size_t);
281  ebmlLazyLoad(const ebmlLazyLoadClass*, ioBase&, off_t, vintWidth_t, size_t, const ebmlElement_l&);
282  // ebmlLazyLoad_sp operator()(ioBase*, vintWidth_t, size_t, const ebmlElement_l&) const;
283  ebmlLazyLoad(const ebmlLazyLoadClass*, ebmlLazyLoad&, off_t, vintWidth_t, size_t);
284  ebmlLazyLoad(const ebmlLazyLoadClass*, ebmlLazyLoad&, off_t, vintWidth_t, size_t, const ebmlElement_l&);
285  // ebmlLazyLoad_sp operator()(ioBase*) const;
286  // ebmlLazyLoad_sp operator()(ioBase*, off_t) const;
287  //
288  // // Create new element in file
289  // ebmlLazyLoad_sp operator()(ioBase*, vintWidth_t, size_t) const;
290  // ebmlLazyLoad_sp operator()(ioBase*, off_t, vintWidth_t, size_t) const;
291  // // ebmlLazyLoad_sp operator()(ioBase*, vintWidth_t, size_t, const ebmlElement_l&) const;
292  // ebmlLazyLoad_sp operator()(ioBase*, off_t, vintWidth_t, size_t, const ebmlElement_l&) const;
293  //
294  // ebmlLazyLoad_sp operator()(ebmlLazyLoad*, off_t, vintWidth_t, size_t) const;
295  // // ebmlLazyLoad_sp operator()(ebmlLazyLoad*, vintWidth_t, size_t, const ebmlElement_l&) const;
296  // ebmlLazyLoad_sp operator()(ebmlLazyLoad*, off_t, vintWidth_t, size_t, const ebmlElement_l&) const;
297  size_t _initNew(ioBase&, off_t, vintWidth_t, size_t);
298  // size_t _initNew(ioBase*, off_t, vintWidth_t, size_t, const ebmlElement_l&);
299 
300  public:
301  const children_m& seeksByOffset() const;
302  const std::unordered_map<
303  ebmlID_t,
304  std::map<off_t, seekData_t*>
305  >& seeksByEBMLID() const;
306  const std::unordered_map<ebmlID_t, std::unique_ptr<seekMapBase>>& seeksByKey() const;
307  ioBase& file() const;
308  off_t endOfData() const;
309 
310  // Thread safe members
311  ebmlElement_sp get(off_t);
312 
313  template<typename T>
314  ebml::ptr<T> get(off_t);
315 
316  ebmlElement_sp get(ebmlID_t, size_t);
317 
318  template<typename T>
319  ebml::ptr<T> get(ebmlID_t, size_t);
320 
321  c_ebmlElement_sp cget(off_t) const;
322 
323  template<typename T>
324  ebml::ptr<T> cget(off_t) const;
325 
326  c_ebmlElement_sp cget(ebmlID_t, size_t) const;
327 
328  template<typename T>
329  ebml::ptr<T> cget(ebmlID_t, size_t) const;
330 
331  template<typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
332  ebmlElement_sp getByKey(ebmlID_t, const K&);
333 
334  template<typename T, typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
335  std::enable_if_t<!std::is_same<ebmlElement, T>::value && std::is_base_of<ebmlElement, T>::value, ebml::ptr<T>>
336  getByKey(ebmlID_t, const K&);
337 
338  template<typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
339  c_ebmlElement_sp cgetByKey(ebmlID_t, const K&) const;
340 
341  template<typename T, typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
342  std::enable_if_t<!std::is_same<const ebmlElement, T>::value && std::is_base_of<const ebmlElement, T>::value, ebml::ptr<T>>
343  cgetByKey(ebmlID_t, const K&) const;
344 
345  // Insertion functions
346  seekData_t* insert(off_t offset, const ebmlElement_sp& child);
347  std::vector<seekData_t*> insert(off_t offset, const ebmlElement_l& children);
348  seekData_t* insert(off_t offset, const std::string& data);
349  std::vector<seekData_t*> insert(off_t offset, const std::vector<std::string>& data);
350  seekData_t* insert(off_t offset, const char* data);
351 
352  template<typename T, typename... Args>
353  std::enable_if_t<std::is_base_of<ebmlElementClass, T>::value, std::pair<ebmlElement_sp, seekData_t*>>
354  insert(off_t offset, const T& cls, Args...);
355 
356  template<typename T>
357  std::enable_if_t<!std::is_base_of<ebmlLazyLoad, T>::value && std::is_base_of<ebmlElement, T>::value, seekData_t*>
358  insert(off_t offset, const ebml::ptr<T>& child);
359 
360  void move(off_t src_offset, off_t dest_offset);
361 
362  void resize(size_t size);
363 
364  void remove(const ebmlElement_sp& child);
365  void remove(off_t offset);
366 
367 
368  // Block boundary functions
369  off_t findBoundary(off_t offset);
370  off_t rfindBoundary(off_t offset);
371 
372  // Child navigation functions
375  seekData_t* nextChild(off_t offset);
376  seekData_t* prevChild(off_t offset);
377 
378  // Space management functions
379  off_t findFree(off_t offset, size_t size);
380  off_t rfindFree(off_t offset, size_t size);
381 
382  // Insertion and move check functions
383  status_t<prepared_insert_t> canInsert(off_t offset, size_t size);
386  status_t<prepared_insert_t> canMove(off_t src_offset, off_t dst_offset);
387 
388  // Resize check functions
390  // query_t canSetUnknownSize(bool flag);
393 
394  // Range insertion functions
395  status_t<prepared_insert_t> canInsertRange(off_t offset, size_t size);
396  status_t<prepared_insert_t> insertRange(off_t offset, size_t size);
397 
398  // Range collapse functions
399  status_t<prepared_insert_t> canCollapseRange(off_t offset, size_t size);
400  status_t<prepared_insert_t> collapseRange(off_t offset, size_t size);
401 
402  // Hole punching functions
403  status_t<prepared_insert_t> canPunchHole(off_t offset, size_t size);
404  status_t<prepared_insert_t> punchHole(off_t offset, size_t size);
405 
406  // Members from ebmlElement
407  std::wstring minirepr() const override;
408  size_t dataSize() const override;
409  bool sizeSupported(size_t size);
410 
411  // NON-thread safe functions
412  // Use only when manually acquiring lock
413 
414  // Requires local read lock (getLocalRLock())
415  ebmlElement_sp _get(off_t);
416 
417  template<typename T>
418  ebml::ptr<T> _get(off_t);
419 
420  c_ebmlElement_sp _cget(off_t) const;
421 
422  template<typename T>
423  ebml::ptr<T> _cget(off_t) const;
424 
425  ebmlElement_sp _get(ebmlID_t, size_t);
426 
427  template<typename T>
428  ebml::ptr<T> _get(ebmlID_t, size_t);
429 
430  c_ebmlElement_sp _cget(ebmlID_t, size_t) const;
431 
432  template<typename T>
433  ebml::ptr<T> _cget(ebmlID_t, size_t) const;
434 
435  template<typename T>
436  ebml::ptr<T> _cget(ebmlID_t, size_t);
437 
438  template<typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
439  ebmlElement_sp _getByKey(ebmlID_t, const K&);
440 
441  template<typename T, typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
442  std::enable_if_t<!std::is_same<ebmlElement, T>::value && std::is_base_of<ebmlElement, T>::value, ebml::ptr<T>>
443  _getByKey(ebmlID_t, const K&);
444 
445  template<typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
446  c_ebmlElement_sp _cgetByKey(ebmlID_t, const K&) const;
447 
448  template<typename T, typename K, typename H=std::hash<K>, typename E=std::equal_to<K>>
449  std::enable_if_t<!std::is_same<const ebmlElement, T>::value && std::is_base_of<const ebmlElement, T>::value, ebml::ptr<T>>
450  _cgetByKey(ebmlID_t, const K&) const;
451 
452  // Block boundary functions
453  off_t _findBoundary(off_t offset);
454  off_t _rfindBoundary(off_t offset);
455 
456  // Child navigation functions
457  seekData_t* _firstChildSeek() const;
458  seekData_t* _lastChildSeek() const;
459  seekData_t* _prevChildSeek(off_t offset, bool strict=true) const;
460  seekData_t* _nextChildSeek(off_t offset, bool strict=true) const;
461 
462  std::pair<children_m::iterator, children_m::iterator> _find(off_t offset, bool left=true);
463  children_m::iterator _findNext(off_t offset, bool strict=true);
464  children_m::iterator _findPrev(off_t offset, bool strict=true);
465  // std::pair<seekData_t*, seekData_t*> _adjacentChildSeeks(off_t, bool left=true) const;
466 
467  // Space management functions
468  off_t _findFree(off_t offset, size_t size);
469  off_t _rfindFree(off_t offset, size_t size);
470 
471  // Insertion and move check functions
472  status_t<prepared_insert_t> _canInsert(off_t offset, size_t size);
473  status_t<prepared_insert_t> _canInsert(off_t offset, const ebmlElement_sp&);
474  status_t<prepared_insert_t> _canInsert(off_t offset, const ebmlElement_l&);
475  status_t<prepared_insert_t> _canInsert(off_t offset, const std::string& data);
476  status_t<prepared_insert_t> _canInsert(off_t offset, const char* data);
477 
478  prepared_move_t _canMove(off_t src_offset, off_t dst_offset);
479 
480  // Resize check functions
481  prepared_resize_t _canResize(size_t size);
482  // query_t _canSetUnknownSize(bool flag);
483  prepared_resize_t _canResizeChild(off_t, size_t size);
485  // query_t _canResizeChild(ebmlElement* child, size_t size);
486 
487  // fallocate check functions
488  status_t<prepared_insert_t> _canInsertRange(off_t offset, size_t size);
489  status_t<prepared_insert_t> _canCollapseRange(off_t offset, size_t size);
490  status_t<prepared_insert_t> _canPunchHole(off_t offset, size_t size);
491 
492  // Requires local write lock
493 
494  // Insertion and removal functions
495  seekData_t* _insert(off_t offset, const ebmlElement_sp& child);
496  seekData_t* _insert(off_t offset, const ebmlElement_sp& child, const status_t<prepared_insert_t>&);
497  seekData_t* _insert(off_t offset, const std::string& data);
498  seekData_t* _insert(off_t offset, const std::string& data, const status_t<prepared_insert_t>&);
499  std::vector<seekData_t*> _insert(off_t offset, const std::vector<std::string>& data);
500  std::vector<seekData_t*> _insert(off_t offset, const std::vector<std::string>& data, const status_t<prepared_insert_t>&);
501 
502  // private:
503  // virtual void _preinsert_hook(off_t, const ebmlElement_sp&);
504  // virtual void _postinsert_hook(off_t, const ebmlElement_sp&, seekData_t*);
505 
506  public:
507  std::vector<seekData_t*> _insert(off_t offset, const ebmlElement_l& children);
508  std::vector<seekData_t*> _insert(off_t offset, const ebmlElement_l& children, const status_t<prepared_insert_t>&);
509 
510  seekData_t* _insert(off_t offset, const char* data);
511  seekData_t* _insert(off_t offset, const char* data, const status_t<prepared_insert_t>&);
512 
513  template<typename T, typename... Args>
514  std::enable_if_t<std::is_base_of<ebmlLazyLoadClass, T>::value, std::pair<ebmlElement_sp, seekData_t*>>
515  _insert(off_t offset, const T& cls, vintWidth_t sizeWidth, size_t dataSize, Args...);
516 
517  template<typename T, typename... Args>
518  std::enable_if_t<!std::is_base_of<ebmlLazyLoadClass, T>::value && std::is_base_of<ebmlElementClass, T>::value, std::pair<ebmlElement_sp, seekData_t*>>
519  _insert(off_t offset, const T& cls, Args... args);
520 
521  template<typename T>
522  std::enable_if_t<!std::is_base_of<ebmlLazyLoad, T>::value && std::is_base_of<ebmlElement, T>::value, seekData_t*>
523  _insert(off_t offset, const ebml::ptr<T>& child);
524 
525  void _move(off_t src_offset, off_t dest_offset);
526  void _move(off_t src_offset, off_t dest_offset, const prepared_move_t&);
527 
528  void _resize(size_t size);
529  void _resize(size_t size, const prepared_resize_t&);
530 
531  // void _remove(const ebmlElement_sp& child);
532  void _remove(off_t offset);
533  void _remove(children_m::iterator);
534 
535  private:
536  virtual void _preremove_hook(const children_m::iterator&);
537  virtual void _postremove_hook(seekData_t*);
538 
539  public:
540  // fallocate functions
541  void _insertRange(off_t offset, size_t size);
542  void _collapseRange(off_t offset, size_t size);
543  void _punchHole(off_t offset, size_t size);
544 
545  protected:
546  void _handleParseFile(const parseFile&) override;
547  virtual void _handleSeekData(std::unique_ptr<seekData_t>&&);
548  virtual void _handleSeekData(std::unique_ptr<seekData_t>&&, const children_m::iterator&);
549  void _addChild(const ebmlElement_sp&) override;
550  void _addChild(ebmlElement_sp&&) override;
551 
555  ebmlMasterElement::_const_iterator* _cend() const override;
556 
557  // ebmlElement_sp _get_existing(seekData_t* seekData);
559  ebmlElement_sp _read_elem(seekData_t* seekData) const;
560  ebmlElement_sp _read_elem(const parseFile& parsed);
561  ebmlElement_sp _read_elem(const parseFile& parsed) const;
562 
566  friend class ebmlLazyLoadClass;
567  friend class seekData_t;
568  };
569 }
570 
571 #define DECL_GETBYKEY_MEMBERS(K) \
572  extern template ebmlElement_sp ebmlLazyLoad::getByKey<K>(ebmlID_t, const K&); \
573  extern template ebmlElement_sp ebmlLazyLoad::_getByKey<K>(ebmlID_t, const K&); \
574  extern template c_ebmlElement_sp ebmlLazyLoad::cgetByKey<K>(ebmlID_t, const K&); \
575  extern template c_ebmlElement_sp ebmlLazyLoad::_cgetByKey<K>(ebmlID_t, const K&); \
576 
577 #define INST_GETBYKEY_MEMBERS(K) \
578  template ebmlElement_sp ebmlLazyLoad::getByKey<K>(ebmlID_t, const K&); \
579  template ebmlElement_sp ebmlLazyLoad::_getByKey<K>(ebmlID_t, const K&); \
580  template c_ebmlElement_sp ebmlLazyLoad::cgetByKey<K>(ebmlID_t, const K&); \
581  template c_ebmlElement_sp ebmlLazyLoad::_cgetByKey<K>(ebmlID_t, const K&); \
582 
583 #define DECL_GETBYKEY_MEMBERS2(T, K) \
584  extern template ebml::ptr<T> ebmlLazyLoad::getByKey<T, K>(ebmlID_t, const K&); \
585  extern template ebml::ptr<T> ebmlLazyLoad::_getByKey<T, K>(ebmlID_t, const K&); \
586  extern template ptr<const T> ebmlLazyLoad::cgetByKey<const T, K>(ebmlID_t, const K&) const; \
587  extern template ptr<const T> ebmlLazyLoad::_cgetByKey<const T, K>(ebmlID_t, const K&) const;
588 
589 #define INST_GETBYKEY_MEMBERS2(T, K) \
590  template ebml::ptr<T> ebmlLazyLoad::getByKey<T, K>(ebmlID_t, const K&); \
591  template ebml::ptr<T> ebmlLazyLoad::_getByKey<T, K>(ebmlID_t, const K&); \
592  template ptr<const T> ebmlLazyLoad::cgetByKey<const T, K>(ebmlID_t, const K&) const; \
593  template ptr<const T> ebmlLazyLoad::_cgetByKey<const T, K>(ebmlID_t, const K&) const;
594 
595 #define DECL_GET_MEMBERS(T) \
596  extern template ebml::ptr<T> ebmlLazyLoad::get<T>(off_t); \
597  extern template ebml::ptr<T> ebmlLazyLoad::get<T>(ebmlID_t, size_t); \
598  extern template ebml::ptr<T> ebmlLazyLoad::_get<T>(off_t); \
599  extern template ebml::ptr<T> ebmlLazyLoad::_get<T>(ebmlID_t, size_t); \
600  extern template ptr<const T> ebmlLazyLoad::cget<const T>(off_t) const; \
601  extern template ptr<const T> ebmlLazyLoad::cget<const T>(ebmlID_t, size_t) const; \
602  extern template ptr<const T> ebmlLazyLoad::_cget<const T>(off_t) const; \
603  extern template ptr<const T> ebmlLazyLoad::_cget<const T>(ebmlID_t, size_t) const; \
604  DECL_GETBYKEY_MEMBERS2(T, unsigned long long) \
605  DECL_GETBYKEY_MEMBERS2(T, long long) \
606  DECL_GETBYKEY_MEMBERS2(T, std::string) \
607  DECL_GETBYKEY_MEMBERS2(T, std::wstring) \
608  DECL_GETBYKEY_MEMBERS2(T, double)
609 
610 #define INST_GET_MEMBERS(T) \
611  template ebml::ptr<T> ebmlLazyLoad::get<T>(off_t); \
612  template ebml::ptr<T> ebmlLazyLoad::get<T>(ebmlID_t, size_t); \
613  template ebml::ptr<T> ebmlLazyLoad::_get<T>(off_t); \
614  template ebml::ptr<T> ebmlLazyLoad::_get<T>(ebmlID_t, size_t); \
615  template ptr<const T> ebmlLazyLoad::cget<const T>(off_t) const; \
616  template ptr<const T> ebmlLazyLoad::cget<const T>(ebmlID_t, size_t) const; \
617  template ptr<const T> ebmlLazyLoad::_cget<const T>(off_t) const; \
618  template ptr<const T> ebmlLazyLoad::_cget<const T>(ebmlID_t, size_t) const; \
619  INST_GETBYKEY_MEMBERS2(T, unsigned long long) \
620  INST_GETBYKEY_MEMBERS2(T, long long) \
621  INST_GETBYKEY_MEMBERS2(T, std::string) \
622  INST_GETBYKEY_MEMBERS2(T, std::wstring) \
623  INST_GETBYKEY_MEMBERS2(T, double)
624 
625 namespace ebml {
626  // DECL_GET_MEMBERS(ebmlDataElement<unsigned long long>)
627  // DECL_GET_MEMBERS(ebmlDataElement<long long>)
628  // DECL_GET_MEMBERS(ebmlDataElement<double>)
629  // DECL_GET_MEMBERS(ebmlDataElement<std::string>)
630  // DECL_GET_MEMBERS(ebmlDataElement<std::wstring>)
631 
632  extern template class ClsMixin<ebmlLazyLoadClass, ebmlLazyLoad, ebmlMasterElementClass>;
633  extern template class InstMixin<ebmlLazyLoadClass, ebmlLazyLoad, ebmlMasterElement>;
634  extern template std::pair<ebmlElement_sp, seekData_t*> ebmlLazyLoad::insert(off_t, const ebmlLazyLoadClass&, vintWidth_t, size_t);
635  extern template std::pair<ebmlElement_sp, seekData_t*> ebmlLazyLoad::_insert(off_t, const ebmlLazyLoadClass&, vintWidth_t, size_t);
636  extern template std::pair<ebmlElement_sp, seekData_t*> ebmlLazyLoad::insert(off_t, const ebmlLazyLoadClass&, vintWidth_t, size_t, const ebmlElement_l&);
637  extern template std::pair<ebmlElement_sp, seekData_t*> ebmlLazyLoad::_insert(off_t, const ebmlLazyLoadClass&, vintWidth_t, size_t, const ebmlElement_l&);
638  // extern template ptr<const ebmlLazyLoad> ebmlLazyLoad::cgetByKey<const ebmlLazyLoad, unsigned long long>(ebmlID_t, const unsigned long long&);
639  // DECL_GETBYKEY_MEMBERS2(ebmlDataElement<std::wstring>, unsigned long long)
640 }
641 #endif
off_t nextSiblingOffset
Definition: prepared.h:139
off_t srcOffset
Definition: prepared.h:84
Helper class for creating and initializing seek data.
Definition: seekdata.h:195
off_t lastChildOffset
Definition: prepared.h:137
void move(off_t, off_t)
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
status_t< prepared_insert_t > _canInsertRange(off_t offset, size_t size)
virtual void _onBeforeInsert(ebmlLazyLoad &, off_t, const ebmlElement_sp &) const
Definition: childElemHelper_t.cpp:20
off_t nextOffset
Definition: prepared.h:94
prepared_resize_t & operator=(const prepared_move_t &)
status_t< prepared_move_t > canMove(off_t, off_t, const writeLock_t &)
off_t endOfData() const
virtual void _onBeforeRemove(ebmlLazyLoad &) const
Definition: childElemHelper_t.cpp:24
off_t srcNextOffset
Definition: prepared.h:85
children_m::iterator _findNext(off_t offset, bool strict=true)
Definition: ebmlLazyLoad.cpp:465
Definition: lazyload.h:167
Definition: childElemHelper_t.h:22
Definition: exceptions.h:134
size_t size(const std::string &value)
Definition: binary.h:8
off_t nextOffset
Definition: prepared.h:23
const std::unordered_map< ebmlID_t, std::unique_ptr< seekMapBase > > & seeksByKey() const
off_t offset
Definition: lazyload.h:93
ebmlMasterElement::_const_iterator * _cbegin() const override
Definition: ebmlLazyLoad.cpp:965
seekData_t * _lastChildSeek() const
std::unique_lock< std::shared_mutex > globalWriteLock_t
Definition: lazyload.h:197
std::unordered_map< ebmlID_t, std::map< off_t, seekData_t * > > _children_by_ebmlID
Definition: ebmlLazyLoad.h:100
status_t< prepared_insert_t > canCollapseRange(off_t offset, size_t size)
Abstract base class for EBML master element instances.This class provides the functionality to manage...
Definition: ebmlMasterElement.h:19
Definition: ebmlMasterElement.h:269
off_t _findFree(off_t offset, size_t size)
Definition: prepared.h:15
virtual void _onAfterInsert(ebmlLazyLoad &, off_t, const ebmlElement_sp &, seekData_t *) const
Definition: childElemHelper_t.cpp:21
Represents parsed seek data extracted from an EBML element.
Definition: seekdata.h:39
upgradedLock_t upgradeLocal()
localReadLock_t(std::shared_mutex &, std::shared_mutex &)
status_t< prepared_insert_t > canInsertRange(off_t offset, size_t size)
prepared_resize_t()
Definition: prepared_resize_t.cpp:10
void _addChild(const ebmlElement_sp &) override
Attaches a child element (rvalue version).
Definition: ebmlLazyLoad.cpp:959
const childElemHelper_t * _childHelper
Definition: lazyload.h:218
status_t< prepared_insert_t > canPunchHole(off_t offset, size_t size)
Represents a parsed EBML file segment.
Definition: io.h:32
children_m::iterator sourceIter
Definition: prepared.h:95
const children_m & seeksByOffset() const
Definition: ebmlLazyLoad.cpp:105
Definition: prepared.h:133
ebmlLazyLoad(const ebmlLazyLoadType *)
Definition: ebmlLazyLoad.cpp:47
off_t srcPrevEnd
Definition: prepared.h:83
void _punchHole(off_t offset, size_t size)
off_t endOffset
Definition: prepared.h:136
upgradedLock_t(std::shared_lock< std::shared_mutex > &)
ioBase * _file_raw
Definition: ebmlLazyLoad.h:92
seekData_t * _nextChildSeek(off_t offset, bool strict=true) const
seekData_t * nextChild(off_t offset)
void _handleParseFile(const parseFile &) override
Handles the parsing of seek data for a child element.
Definition: ebmlLazyLoad.cpp:123
seekData_t * prevChild(off_t offset)
Definition: status.h:14
std::enable_if_t<!std::is_base_of< ebmlElement, std::decay_t< K > >::value, ebml::ptr< const ebmlElement > > cgetByKey(ebmlID_t, const K &) const
sizetree_t sizetree
Definition: lazyload.h:96
seekData_t * seekData
Definition: prepared.h:140
ebmlMasterElement::_iterator * _begin() override
Definition: ebmlLazyLoad.cpp:963
ebmlLazyLoadClass(const char *, const std::wstring &, const childClassSpecArg_l &)
Definition: exceptions.h:150
off_t prevOffset
Definition: prepared.h:87
seekData_t * insert(off_t, const ebml::ptr< ebmlElement > &)
Definition: ebmlLazyLoad.h:693
void _insertRange(off_t offset, size_t size)
status_t< prepared_insert_t > punchHole(off_t offset, size_t size)
ioBase & file() const
Definition: ebmlLazyLoad.cpp:109
ebml::ptr< ebmlElement > _read_elem(seekData_t &seekData)
Definition: ebmlLazyLoad.cpp:327
Definition: basictypes.h:40
off_t prevEnd
Definition: prepared.h:18
Definition: lazyload.h:176
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.
off_t findBoundary(off_t offset)
std::unordered_map< ebmlID_t, std::unique_ptr< seekMapBase > > _children_by_key
Definition: ebmlLazyLoad.h:101
children_m::iterator insertionHint
Definition: prepared.h:96
children_m _children_by_offset
Definition: ebmlLazyLoad.h:96
Definition: ebmlMasterElement.h:324
Definition: ebmlSchema.h:32
prepared_insert_t & operator=(const prepared_insert_t &)
virtual void _onAfterRemove(ebmlLazyLoad &) const
Definition: childElemHelper_t.cpp:25
virtual ~prepared_base_t()
localWriteLock_t(std::shared_mutex &, std::shared_mutex &)
seekData_t * firstChild()
Definition: lazyload.h:187
Definition: lazyload.h:216
Definition: lazyload.h:67
off_t _rfindFree(off_t offset, size_t size)
off_t prevOffset
Definition: prepared.h:17
Represents an EBML Master Element with on-disk, transactional child management.
Definition: ebmlLazyLoad.h:85
void throw_exc(const std::string &, const c_ebmlElement_sp &) const
Definition: prepared_insert_t.cpp:28
status_t< prepared_resize_t > canResize(size_t, const writeLock_t &)
localReadLock_t getLocalRLock() const
size_t _initNew(ioBase &, off_t, vintWidth_t, size_t)
Definition: ebmlLazyLoad.cpp:69
uint64_t ebmlID_t
Definition: ebmlID_t.h:7
virtual void _onBeforeMove(ebmlLazyLoad &) const
Definition: childElemHelper_t.cpp:22
prepared_insert_t()
Definition: prepared_insert_t.cpp:10
status_t< prepared_insert_t > _canPunchHole(off_t offset, size_t size)
off_t dest_offset
Definition: lazyload.h:123
const T & data() const
status_t< prepared_insert_t > _canCollapseRange(off_t offset, size_t size)
bool sizeSupported(size_t size, const writeLock_t &)
Definition: ebmlLazyLoad.h:818
ebmlMasterElement::_const_iterator * _cend() const override
Definition: ebmlLazyLoad.cpp:966
void throw_exc(const ptr< const ebmlElement > &) const
size_t dataSize() const override
Definition: ebmlLazyLoad.cpp:119
ptr< const ebmlElement > c_ebmlElement_sp
Definition: ptrs.h:843
Structure representing the size tree for an EBML master element.
Definition: sizetree_t.h:15
off_t prevEnd
Definition: prepared.h:88
children_m::iterator _findPrev(off_t offset, bool strict=true)
Definition: ebmlLazyLoad.cpp:473
uint8_t vintWidth_t
Definition: ebmlID_t.h:8
std::wstring minirepr() const override
Definition: ebmlLazyLoad.cpp:954
ebml::ptr< const ebmlElement > cget(off_t) const
Definition: ebmlLazyLoad.h:585
off_t endOffset
Definition: prepared.h:22
std::string reason
Definition: status.h:18
off_t lastChildEnd
Definition: prepared.h:138
virtual void _onAfterMove(ebmlLazyLoad &) const
Definition: childElemHelper_t.cpp:23
T _data
Definition: status.h:20
upgradedLock_t upgradeGlobal()
off_t rfindBoundary(off_t offset)
ebmlLazyLoad_sp operator()(ioBase *) const
std::string reason
Definition: lazyload.h:71
seekData_t * lastChild()
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
children_m::iterator insertionHint
Definition: prepared.h:25
const std::unordered_map< ebmlID_t, std::map< off_t, seekData_t * > > & seeksByEBMLID() const
prepared_base_t & operator=(const prepared_base_t &)
seekData_t * _firstChildSeek() const
status_t & operator=(const status_t &)
Abstract base class for EBML Element instances.
Definition: ebmlElement.h:79
ioBase_sp _file
Definition: ebmlLazyLoad.h:91
ebmlMasterElement::_iterator * _end() override
Definition: ebmlLazyLoad.cpp:964
writeLock_t getGlobalLock() const
Definition: ebmlLazyLoad.cpp:297
unsigned char sizeWidth() const
Definition: ebmlElement.cpp:230
std::pair< children_m::iterator, children_m::iterator > _find(off_t offset, bool left=true)
Definition: ebmlLazyLoad.cpp:445
size_t _dataSize
Definition: ebmlLazyLoad.h:93
prepared_resize_t _canResizeChild(off_t, size_t size)
localWriteLock_t getLocalWLock() const
status_t< prepared_insert_t > insertRange(off_t offset, size_t size)
void _handleSeekData(std::unique_ptr< seekData_t > &&)
Definition: ebmlLazyLoad.cpp:145
prepared_move_t & operator=(const prepared_move_t &)
Base class for file-like IO operations.
Definition: io.h:22
bool result
Definition: status.h:16
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
void _collapseRange(off_t offset, size_t size)
off_t endOffset
Definition: lazyload.h:124
bool result
Definition: lazyload.h:69
childElemHelper_t childHelper
Definition: childElemHelper_t.cpp:27
status_t< prepared_insert_t > canResizeChild(const seekData_t &, size_t size)
off_t offset
Definition: prepared.h:135
Definition: prepared.h:81
status_t< prepared_insert_t > collapseRange(off_t offset, size_t size)
upgradedLock_t upgradeGlobal()
seekData_t * _prevChildSeek(off_t offset, bool strict=true) const