libebml_ng
ebmlElement.h
Go to the documentation of this file.
1 
11 #ifndef EBML_NG_ELEMENT_H
12 #define EBML_NG_ELEMENT_H
13 
14 #include "ptrs.h"
15 #include "parsing/string.h"
16 #include "parsing/io.h"
17 #include "flexptr.h"
18 
19 namespace ebml {
20  extern template class flexible_ptr<ebmlElement>;
22 
23  extern template class flexible_ptr<ebmlMasterElement>;
25 
79  class ebmlElement {
80  friend class ebmlDocument;
81  friend class ebmlElementType;
82  friend class ebmlMasterElement;
83  friend class ebmlLazyLoad;
84  // friend class ebmlSchema;
85 
86  template<typename T>
87  friend class ebmlDataElementClass;
88 
89  // Constructor/Destructor
90  protected:
98  void _validate();
99 
100  public:
101  virtual ~ebmlElement();
102 
103  protected:
108 
109  public:
119  virtual const ebmlElementType& cls() const;
120 
125  ebmlID_t ebmlID() const;
126 
133  template<typename T=ebmlElement>
134  inline T& as();
135 
142  template<typename T=ebmlElement>
143  inline T& as() const;
144 
150 
155  ebml::ptr<const ebmlElement> sp() const;
156 
157  template<typename T>
158  inline ebml::ptr<T> sp();
159 
160  template<typename T>
161  inline ebml::ptr<T> sp() const;
162 
165 
166  template<typename T>
167  inline ebml::wptr<T> wp();
168 
169  template<typename T>
170  inline ebml::wptr<T> wp() const;
171 
172  // Hierarchy members.
173  public:
178  bool parent_is_const() const;
179 
185  ebml::ptr<ebmlMasterElement> parent() const; // Returns pointer to non-const parent. Throws ebmlException if parent_is_const() returns true.
186 
191  ebml::ptr<const ebmlMasterElement> c_parent() const; // Returns pointer to const parent.
192 
193  private:
195 
196  protected:
197  void _setParent(const ebml::ptr<ebmlMasterElement>& parent, bool weak = true);
198  void _setParent(const ebml::ptr<const ebmlMasterElement>& parent, bool weak = true);
199  void _setParent(ebml::ptr<ebmlMasterElement>&& parent, bool weak = true);
200  void _setParent(ebml::ptr<const ebmlMasterElement>&& parent, bool weak = true);
201 
202  void _setParent(ebmlMasterElement& parent, bool weak = true);
203  void _setParent(const ebmlMasterElement& parent, bool weak = true);
204 
205 
206  void _detach();
207 
208  public:
209  ebmlElement_sp root() const;
210  c_ebmlElement_sp c_root() const;
211 
212  protected:
214 
215  public:
216  ebmlDocument_sp document() const;
217 
218  public:
219  bool hasParent() const;
220 
221  // Size functions.
222 
223  protected:
224  vintWidth_t _sizeWidth = 0;
225 
226  public:
227  unsigned char headSize() const;
228  unsigned char headSize(size_t) const; // May be deprecated
229  unsigned char sizeWidth() const;
230  unsigned char sizeWidth(size_t) const; // May be deprecated
231  size_t outerSize() const;
232  size_t outerSize(size_t) const; // May be deprecated
233  virtual size_t dataSize() const = 0;
234 
235  // Location attributes and methods.
236  off_t offsetInParent() const;
237  off_t offsetInFile() const;
238  off_t dataOffsetInParent() const;
239  off_t dataOffsetInFile() const;
240 
241  protected:
242  off_t _offsetInParent = -1; // value of -1 indicates undefined.
243 
244  // Encode functions.
245  protected:
246  size_t _encode_head(char*, size_t) const;
247  virtual size_t _encode(char*) const = 0;
248 
249  public:
261  inline std::string encode() const;
262  inline size_t encode(char*) const;
263  inline size_t encode(ioBase&) const;
264  inline size_t encode(ioBase&, off_t) const;
265 
277  size_t encode(char*, size_t) const;
278 
283  // Cloning functions:
284  protected:
285  // virtual void _clonedata(const ebmlElement*) = 0;
286  virtual ebmlElement* _clone() const = 0;
287 
288  public:
289  // virtual ebmlElement_sp clone() const;
290  ebml::ptr<ebmlElement> clone() const;
291 
292  // Repr function:
293  virtual std::wstring minirepr() const = 0;
294  virtual std::wstring repr() const;
295 
296  seekData_t* makeSeekData();
297  seekData_t* makeSeekData() const;
298  };
299 
319  template<typename ebmltype_t, typename ebmlinst_t, typename instbase_t=ebmlElement>
320  class ebmlElementCRTP : public instbase_t {
321  protected:
322  ebmlElement* _clone() const;
323 
324  public:
325  using ebmltype = ebmltype_t;
326 
327  template<typename... Args>
328  ebmlElementCRTP(const ebmltype_t* cls, Args&&... args) : instbase_t(cls, std::forward<Args>(args)...) {}
329  const ebmltype_t& cls() const;
330 
331  using ebmlElement::sp;
333  ebml::ptr<const ebmlinst_t> sp() const;
334 
335  using ebmlElement::wp;
337  ebml::wptr<const ebmlinst_t> wp() const;
338 
339  ebml::ptr<ebmlinst_t> clone() const;
340  };
341 
342  template<typename ebmlinst_t, typename parse_t>
343  concept has_init = requires(ebmlinst_t& instance, const parse_t& parsed) {
344  { instance._init(parsed) };
345  };
346 
347  template<typename ebmlinst_t, typename parse_t>
348  concept has_cinit = requires(ebmlinst_t& instance, const parse_t& parsed) {
349  { instance._cinit(parsed) };
350  };
351 
352  template<typename ebmlinst_t, typename... Args>
353  concept has_constructor = requires(Args&&... args) {
354  { new ebmlinst_t(std::forward<Args>(args)...) };
355  };
356 
357  template<typename ebmlinst_t>
358  concept has_clone_method = requires(ebmlinst_t& instance, ebmlinst_t& orig) {
359  { instance._clone(orig) };
360  };
361 
362  template<typename T>
363  inline T& ebmlElement::as() {
364  if (auto recast = dynamic_cast<T*>(this)) {
365  return *recast;
366  }
367 
368  throw std::bad_cast();
369  }
370 
371  template<typename T>
372  inline T& ebmlElement::as() const {
373  if (auto recast = dynamic_cast<T*>(this)) {
374  return *recast;
375  }
376 
377  throw std::bad_cast();
378  }
379 
380  template<typename T>
382  return ebml_dynamic_pointer_cast<T>(this->_self);
383  }
384 
385  template<typename T>
387  auto ptr = ebml_static_pointer_cast<const ebmlElement>(this->_self);
388  return ebml_dynamic_pointer_cast<T>(std::move(ptr));
389  }
390 
391  inline off_t ebmlElement::offsetInParent() const {
392  return _offsetInParent;
393  }
394 
395  inline void ebmlElement::_validate() {
396  auto lock = std::unique_lock(_self.mutex);
397 
398  if (_self.ctl == nullptr) {
399  _self.ctl = new control_block;
400  _self.ctl->weakcount = 1;
401  _self.ptr = this;
402  }
403 
404  _self.ctl->valid = true;
405  }
406 
407  inline size_t ebmlElement::encode(char* dest) const {
408  size_t dataSize = this->dataSize();
409  return ebmlElement::encode(dest, dataSize);
410  }
411 
412  inline std::string ebmlElement::encode() const {
413  std::string result;
414  size_t dataSize = this->dataSize();
415  result.resize(dataSize+16);
416  size_t outerSize = this->encode(&result[0], dataSize);
417  result.resize(outerSize);
418  return result;
419  }
420 
421  inline size_t ebmlElement::encode(ioBase& dest) const {
422  size_t _dataSize = dataSize();
423  auto buffer = std::make_unique<char[]>(_dataSize + 16);
424  auto outerSize = encode(buffer.get(), _dataSize);
425  return dest.write(buffer.get(), outerSize);
426  }
427 
428  inline size_t ebmlElement::encode(ioBase& dest, off_t offset) const {
429  size_t _dataSize = dataSize();
430  auto buffer = std::make_unique<char[]>(_dataSize + 16);
431  auto outerSize = encode(buffer.get(), _dataSize);
432  return dest.write(buffer.get(), offset, outerSize);
433  }
434 }
435 
436 #endif
concept has_constructor
Definition: ebmlElement.h:353
friend class ebmlDocument
Definition: ebmlElement.h:80
Abstract base class for EBML Element Type objects.
Definition: ebmlElementType.h:106
virtual size_t dataSize() const =0
Definition: ebmlElement.cpp:226
Definition: ptrs.h:19
ebml_shared_ptr< T > ebml_dynamic_pointer_cast(const ebml_shared_ptr< U > &)
Definition: ptrs.h:676
void _validate()
Definition: ebmlElement.h:395
friend class ebmlDataElementClass
Definition: ebmlElement.h:87
friend class ebmlMasterElement
Definition: ebmlElement.h:82
Abstract base class for EBML master element instances.This class provides the functionality to manage...
Definition: ebmlMasterElement.h:19
concept has_clone_method
Definition: ebmlElement.h:358
Represents parsed seek data extracted from an EBML element.
Definition: seekdata.h:39
ebml::wptr< ebmlElement > wp()
Definition: ebmlElement.cpp:356
friend class ebmlElementType
Definition: ebmlElement.h:81
std::weak_ptr< ebmlDocument > ebmlDocument_wp
Definition: ptrs.h:915
concept has_init
Definition: ebmlElement.h:343
A drop-in replacement for std::weak_ptr tailored for EBML objects.
Definition: ptrs.h:30
ebmlElementCRTP(const ebmltype_t *cls, Args &&... args)
Definition: ebmlElement.h:328
Definition: basictypes.h:40
A drop-in replacement for std::shared_ptr tailored for EBML objects.
Definition: ptrs.h:27
size_t outerSize() const
Definition: ebmlElement.cpp:255
const ebmlElementType * _cls
Pointer to the companion element type (an ebmlElementClass subclass).
Definition: ebmlElement.h:105
flexible_ptr< ebmlElement > ebmlElement_fp
Definition: ebmlElement.h:21
std::wstring repr(const std::string &str)
Definition: repr.cpp:36
friend class ebmlLazyLoad
Definition: ebmlElement.h:83
uint64_t ebmlID_t
Definition: ebmlID_t.h:7
std::shared_ptr< ebmlDocument > ebmlDocument_sp
Definition: ptrs.h:909
uint8_t vintWidth_t
Definition: ebmlID_t.h:8
ebml_shared_ptr< T > ebml_static_pointer_cast(const ebml_shared_ptr< U > &)
Definition: ptrs.h:731
wptr< ebmlElement > _self
Custom weak pointer to self (used for shared-from-this semantics).
Definition: ebmlElement.h:107
off_t _offsetInParent
Definition: ebmlElement.h:242
off_t offsetInParent() const
Definition: ebmlElement.h:391
Abstract base class for EBML Element instances.
Definition: ebmlElement.h:79
std::string encode() const
Encodes the element and returns it as a std::string.
Definition: ebmlElement.h:412
CRTP template for EBML Element instances.
Definition: ebmlElement.h:320
Template class for EBML data types.
Definition: ebmlDataElement.h:42
ebmlDocument_wp _document
Definition: ebmlElement.h:213
Base class for file-like IO operations.
Definition: io.h:22
ebml::ptr< ebmlElement > sp()
Returns a shared pointer to the element instance.
Definition: ebmlElement.cpp:348
flexible_ptr< ebmlMasterElement > ebmlMasterElement_fp
Definition: ebmlElement.h:24
T & as()
Dynamically cast the element to the requested type.
Definition: ebmlElement.h:363
size_t write(const char *, size_t)
Definition: io.cpp:23
concept has_cinit
Definition: ebmlElement.h:348