9#include <c++utilities/conversion/binaryconversion.h>
10#include <c++utilities/io/binaryreader.h>
11#include <c++utilities/io/binarywriter.h>
61string EbmlElement::parsingContext()
const
71 static const string context(
"parsing EBML element header");
83 std::uint8_t beg =
static_cast<std::uint8_t
>(
stream().peek()), mask = 0x80;
103 m_id = BE::toInt<std::uint32_t>(buf);
111 const std::uint8_t actualLevel =
level();
112 if (actualLevel > supposedLevel) {
126 if (sibling->nextSibling() ==
this) {
127 sibling->m_nextSibling.release();
135 previousSibling->m_nextSibling.reset(
this);
137 betterParent->m_firstChild.reset(
this);
146 beg =
static_cast<std::uint8_t
>(
stream().peek());
160 diag.emplace_back(
DiagLevel::Critical,
"EBML size length is not supported.", parsingContext());
180 diag.emplace_back(
DiagLevel::Critical,
"EBML header seems to be truncated.", parsingContext());
184 diag.emplace_back(
DiagLevel::Warning,
"Data of EBML element seems to be truncated; unable to parse siblings of that element.",
213 diag.emplace_back(
DiagLevel::Warning, argsToString(skipped,
" bytes have been skipped"), parsingContext());
241 char buff[maxBytesToRead] = { 0 };
242 const auto bytesToSkip = maxBytesToRead - min(
dataSize(), maxBytesToRead);
244 stream().read(buff + bytesToSkip,
static_cast<streamoff
>(
sizeof(buff) - bytesToSkip));
245 return BE::toInt<std::uint64_t>(buff);
257 return static_cast<double>(
reader().readFloat32BE());
259 return reader().readFloat64BE();
273 }
else if (
id <= 0x7FFF) {
275 }
else if (
id <= 0x3FFFFF) {
277 }
else if (
id <= 0x1FFFFFFF) {
292 }
else if (size <= 16382ul) {
294 }
else if (size <= 2097150ul) {
296 }
else if (size <= 268435454ul) {
298 }
else if (size <= 34359738366ul) {
300 }
else if (size <= 4398046511102ul) {
302 }
else if (size <= 562949953421310ul) {
304 }
else if (size <= 72057594037927934ul) {
320 *buff =
static_cast<char>(
id);
322 }
else if (
id <= 0x7FFF) {
323 BE::getBytes(
static_cast<std::uint16_t
>(
id), buff);
325 }
else if (
id <= 0x3FFFFF) {
326 BE::getBytes(
static_cast<std::uint32_t
>(
id << 0x8), buff);
328 }
else if (
id <= 0x1FFFFFFF) {
329 BE::getBytes(
static_cast<std::uint32_t
>(
id), buff);
346 *buff =
static_cast<char>(size | 0x80);
348 }
else if (size <= 16382ul) {
349 BE::getBytes(
static_cast<std::uint16_t
>(size | 0x4000), buff);
351 }
else if (size <= 2097150ul) {
352 BE::getBytes(
static_cast<std::uint32_t
>((size | 0x200000) << 0x08), buff);
354 }
else if (size <= 268435454ul) {
355 BE::getBytes(
static_cast<std::uint32_t
>(size | 0x10000000), buff);
357 }
else if (size <= 34359738366ul) {
358 BE::getBytes(
static_cast<std::uint64_t
>((size | 0x800000000) << 0x18), buff);
360 }
else if (size <= 4398046511102ul) {
361 BE::getBytes(
static_cast<std::uint64_t
>((size | 0x40000000000) << 0x10), buff);
363 }
else if (size <= 562949953421310ul) {
364 BE::getBytes(
static_cast<std::uint64_t
>((size | 0x2000000000000) << 0x08), buff);
366 }
else if (size <= 72057594037927934ul) {
367 BE::getBytes(
static_cast<std::uint64_t
>(size | 0x100000000000000), buff);
384 if (minBytes <= 1 && size < 126) {
385 *buff =
static_cast<char>(size | 0x80);
387 }
else if (minBytes <= 2 && size <= 16382ul) {
388 BE::getBytes(
static_cast<std::uint16_t
>(size | 0x4000), buff);
390 }
else if (minBytes <= 3 && size <= 2097150ul) {
391 BE::getBytes(
static_cast<std::uint32_t
>((size | 0x200000) << 0x08), buff);
393 }
else if (minBytes <= 4 && size <= 268435454ul) {
394 BE::getBytes(
static_cast<std::uint32_t
>(size | 0x10000000), buff);
396 }
else if (minBytes <= 5 && size <= 34359738366ul) {
397 BE::getBytes(
static_cast<std::uint64_t
>((size | 0x800000000) << 0x18), buff);
399 }
else if (minBytes <= 6 && size <= 4398046511102ul) {
400 BE::getBytes(
static_cast<std::uint64_t
>((size | 0x40000000000) << 0x10), buff);
402 }
else if (minBytes <= 7 && size <= 562949953421310ul) {
403 BE::getBytes(
static_cast<std::uint64_t
>((size | 0x2000000000000) << 0x08), buff);
405 }
else if (minBytes <= 8 && size <= 72057594037927934ul) {
406 BE::getBytes(
static_cast<std::uint64_t
>(size | 0x100000000000000), buff);
418 if (integer <= 0xFFul) {
420 }
else if (integer <= 0xFFFFul) {
422 }
else if (integer <= 0xFFFFFFul) {
424 }
else if (integer <= 0xFFFFFFFFul) {
426 }
else if (integer <= 0xFFFFFFFFFFul) {
428 }
else if (integer <= 0xFFFFFFFFFFFFul) {
430 }
else if (integer <= 0xFFFFFFFFFFFFFFul) {
443 if (value <= 0xFFul) {
444 *buff =
static_cast<char>(value);
446 }
else if (value <= 0xFFFFul) {
447 BE::getBytes(
static_cast<std::uint16_t
>(value), buff);
449 }
else if (value <= 0xFFFFFFul) {
450 BE::getBytes(
static_cast<std::uint32_t
>(value << 0x08), buff);
452 }
else if (value <= 0xFFFFFFFFul) {
453 BE::getBytes(
static_cast<std::uint32_t
>(value), buff);
455 }
else if (value <= 0xFFFFFFFFFFul) {
456 BE::getBytes(
static_cast<std::uint64_t
>(value << 0x18), buff);
458 }
else if (value <= 0xFFFFFFFFFFFFul) {
459 BE::getBytes(
static_cast<std::uint64_t
>(value << 0x10), buff);
461 }
else if (value <= 0xFFFFFFFFFFFFFFul) {
462 BE::getBytes(
static_cast<std::uint64_t
>(value << 0x08), buff);
465 BE::getBytes(
static_cast<std::uint64_t
>(value), buff);
481 if (minBytes <= 1 && value <= 0xFFul) {
482 *buff =
static_cast<char>(value);
484 }
else if (minBytes <= 2 && value <= 0xFFFFul) {
485 BE::getBytes(
static_cast<std::uint16_t
>(value), buff);
487 }
else if (minBytes <= 3 && value <= 0xFFFFFFul) {
488 BE::getBytes(
static_cast<std::uint32_t
>(value << 0x08), buff);
490 }
else if (minBytes <= 4 && value <= 0xFFFFFFFFul) {
491 BE::getBytes(
static_cast<std::uint32_t
>(value), buff);
493 }
else if (minBytes <= 5 && value <= 0xFFFFFFFFFFul) {
494 BE::getBytes(
static_cast<std::uint64_t
>(value << 0x18), buff);
496 }
else if (minBytes <= 6 && value <= 0xFFFFFFFFFFFFul) {
497 BE::getBytes(
static_cast<std::uint64_t
>(value << 0x10), buff);
499 }
else if (minBytes <= 7 && value <= 0xFFFFFFFFFFFFFFul) {
500 BE::getBytes(
static_cast<std::uint64_t
>(value << 0x08), buff);
503 BE::getBytes(
static_cast<std::uint64_t
>(value), buff);
523 stream.write(buff2, elementSize);
539 stream.write(content.data(),
static_cast<std::streamsize
>(content.size()));
The Diagnostics class is a container for DiagMessage.
The EbmlElement class helps to parse EBML files such as Matroska files.
std::uint64_t firstChildOffset() const
Returns the offset of the first child of the element.
static std::uint8_t makeUInteger(std::uint64_t value, char *buff)
Writes value to buff.
EbmlElement(MatroskaContainer &container, std::uint64_t startOffset)
Constructs a new top level element with the specified container at the specified startOffset.
static std::uint8_t calculateIdLength(IdentifierType id)
Returns the length of the specified id in byte.
static void makeSimpleElement(std::ostream &stream, IdentifierType id, std::uint64_t content)
Makes a simple EBML element.
static std::uint8_t calculateSizeDenotationLength(std::uint64_t size)
Returns the length of the size denotation for the specified size in byte.
static std::uint8_t makeId(IdentifierType id, char *buff)
Stores the specified id in the specified buffer which must be at least 8 bytes long.
double readFloat()
Reads the content of the element as float.
static std::uint64_t bytesToBeSkipped
Specifies the number of bytes to be skipped till a valid EBML element is found in the stream.
std::string idToString() const
Converts the specified EBML ID to a printable string.
std::string readString()
Reads the content of the element as string.
std::uint64_t readUInteger()
Reads the content of the element as unsigned integer.
static std::uint8_t makeSizeDenotation(std::uint64_t size, char *buff)
Makes the size denotation for the specified size and stores it to buff.
void internalParse(Diagnostics &diag)
Parses the EBML element.
static std::uint8_t calculateUIntegerLength(std::uint64_t integer)
Returns the length of the specified unsigned integer in byte.
The GenericFileElement class helps to parse binary files which consist of an arboreal element structu...
ImplementationType * lastChild()
Returns the last child of the element.
std::uint64_t startOffset() const
std::uint32_t headerSize() const
Returns the header size of the element in byte.
const IdentifierType & id() const
typename FileElementTraits< EbmlElement >::DataSizeType DataSizeType
std::uint8_t level() const
ImplementationType * nextSibling()
Returns the next sibling of the element.
std::unique_ptr< EbmlElement > m_nextSibling
ImplementationType * parent()
Returns the parent of the element.
std::uint64_t m_startOffset
ImplementationType * firstChild()
Returns the first child of the element.
std::uint32_t sizeLength() const
std::unique_ptr< ImplementationType > m_firstChild
static constexpr std::uint32_t maximumIdLengthSupported()
DataSizeType dataSize() const
std::uint64_t totalSize() const
typename FileElementTraits< ImplementationType >::IdentifierType IdentifierType
Specifies the type used to store identifiers.
static constexpr std::uint32_t maximumSizeLengthSupported()
std::uint64_t dataOffset() const
ContainerType & container()
CppUtilities::BinaryReader & reader()
std::uint64_t maxTotalSize() const
std::uint32_t m_sizeLength
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Implementation of GenericContainer<MediaFileInfo, MatroskaTag, MatroskaTrack, EbmlElement>.
The exception that is thrown when the data to be parsed is truncated and therefore can not be parsed ...
Contains all classes and functions of the TagInfo library.
TAG_PARSER_EXPORT MatroskaElementLevel matroskaIdLevel(std::uint32_t matroskaId)
Returns the level at which elements with the specified matroskaId are supposed to occur in a Matroska...