This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,17 @@
#include "ebml/CIdentifier.h"
namespace EBML {
const CIdentifier& CIdentifier::operator=(const CIdentifier& id)
{
m_id = id.m_id;
return *this;
}
bool operator==(const CIdentifier& id1, const CIdentifier& id2) { return id1.m_id == id2.m_id; }
bool operator!=(const CIdentifier& id1, const CIdentifier& id2) { return id1.m_id != id2.m_id; }
bool operator<=(const CIdentifier& id1, const CIdentifier& id2) { return id1.m_id <= id2.m_id; }
bool operator>=(const CIdentifier& id1, const CIdentifier& id2) { return id1.m_id >= id2.m_id; }
bool operator<(const CIdentifier& id1, const CIdentifier& id2) { return id1.m_id < id2.m_id; }
bool operator>(const CIdentifier& id1, const CIdentifier& id2) { return id1.m_id > id2.m_id; }
} // namespace EBML
@@ -0,0 +1,14 @@
#include "ebml/CReader.h"
namespace EBML {
CReader::CReader(IReaderCallback& callback) { m_impl = createReader(callback); }
CReader::~CReader() { m_impl->release(); }
bool CReader::processData(const void* buffer, const size_t size) { return m_impl->processData(buffer, size); }
CIdentifier CReader::getCurrentNodeID() const { return m_impl->getCurrentNodeID(); }
size_t CReader::getCurrentNodeSize() const { return m_impl->getCurrentNodeSize(); }
void CReader::release() {}
} // namespace EBML
@@ -0,0 +1,15 @@
#include "ebml/CReaderHelper.h"
namespace EBML {
CReaderHelper::CReaderHelper() { m_impl = createReaderHelper(); }
CReaderHelper::~CReaderHelper() { m_impl->release(); }
uint64_t CReaderHelper::getUInt(const void* buffer, const size_t size) { return m_impl->getUInt(buffer, size); }
int64_t CReaderHelper::getInt(const void* buffer, const size_t size) { return m_impl->getInt(buffer, size); }
double CReaderHelper::getDouble(const void* buffer, const size_t size) { return m_impl->getDouble(buffer, size); }
const char* CReaderHelper::getStr(const void* buffer, const size_t size) { return m_impl->getStr(buffer, size); }
void CReaderHelper::release() {}
} // namespace EBML
@@ -0,0 +1,14 @@
#include "ebml/CWriter.h"
namespace EBML {
CWriter::CWriter(IWriterCallback& callback) { m_impl = createWriter(callback); }
CWriter::~CWriter() { m_impl->release(); }
bool CWriter::openChild(const CIdentifier& identifier) { return m_impl->openChild(identifier); }
bool CWriter::setChildData(const void* buffer, const size_t size) { return m_impl->setChildData(buffer, size); }
bool CWriter::closeChild() { return m_impl->closeChild(); }
void CWriter::release() {}
} // namespace EBML
@@ -0,0 +1,21 @@
#include "ebml/CWriterHelper.h"
namespace EBML {
CWriterHelper::CWriterHelper() { m_impl = createWriterHelper(); }
CWriterHelper::~CWriterHelper() { m_impl->release(); }
bool CWriterHelper::connect(IWriter* writer) { return m_impl->connect(writer); }
bool CWriterHelper::disconnect() { return m_impl->disconnect(); }
bool CWriterHelper::openChild(const CIdentifier& identifier) { return m_impl->openChild(identifier); }
bool CWriterHelper::closeChild() { return m_impl->closeChild(); }
bool CWriterHelper::setInt(const int64_t value) { return m_impl->setInt(value); }
bool CWriterHelper::setUInt(const uint64_t value) { return m_impl->setUInt(value); }
bool CWriterHelper::setFloat(const float value) { return m_impl->setFloat(value); }
bool CWriterHelper::setDouble(const double value) { return m_impl->setDouble(value); }
bool CWriterHelper::setBinary(const void* buffer, const size_t size) { return m_impl->setBinary(buffer, size); }
bool CWriterHelper::setStr(const char* value) { return m_impl->setStr(value); }
} // namespace EBML
@@ -0,0 +1,357 @@
#include "ebml/IReader.h"
#include <cstring>
#include <cstdio>
#include <cstring>
#include <iostream>
#if 0
#define _Debug_ _is_in_debug_mode_(m_totalBytes)
static bool _is_in_debug_mode_(uint64_t value)
{
static int i=0;
// bool result=i++>5500000;
bool result=value>29605500;
if (result) std::cout << "Arround " << value << std::endl;
return result;
}
#else
#define _Debug_ false
#endif
// ________________________________________________________________________________________________________________
//
inline bool needsTwoBytesToGetCodedSizeLength(const unsigned char* buffer) { return buffer[0] == 0; }
inline size_t getCodedSizeLength(const unsigned char* buffer)
{
if (buffer[0] >> 7) { return 1; }
if (buffer[0] >> 6) { return 2; }
if (buffer[0] >> 5) { return 3; }
if (buffer[0] >> 4) { return 4; }
if (buffer[0] >> 3) { return 5; }
if (buffer[0] >> 2) { return 6; }
if (buffer[0] >> 1) { return 7; }
if (buffer[0]) { return 8; }
if (buffer[1] >> 7) { return 9; }
return 10;
}
inline uint64_t getValue(unsigned char* buffer)
{
uint64_t result = 0;
const size_t length = getCodedSizeLength(buffer);
size_t ithBit = length;
for (size_t i = 0; i < length; ++i)
{
result = (result << 8) + (buffer[i]);
result &= ~(ithBit > 0 && ithBit <= 8 ? (1 << (8 - ithBit)) : 0);
ithBit -= 8;
}
return result;
}
// ________________________________________________________________________________________________________________
//
namespace EBML {
namespace {
class CReaderNode
{
public:
CReaderNode(const CIdentifier& identifier, CReaderNode* parentNode) : m_ParentNode(parentNode), m_Id(identifier) { }
private:
CReaderNode() = delete;
public:
CReaderNode* m_ParentNode = nullptr;
CIdentifier m_Id;
size_t m_ContentSize = 0;
size_t m_ReadContentSize = 0;
unsigned char* m_Buffer = nullptr;
};
} // namespace
} // namespace EBML
// ________________________________________________________________________________________________________________
//
namespace EBML {
namespace {
class CReader final : public IReader
{
public:
explicit CReader(IReaderCallback& callback) : m_readerCB(callback) { }
~CReader() override;
bool processData(const void* buffer, const size_t size) override;
CIdentifier getCurrentNodeID() const override;
size_t getCurrentNodeSize() const override;
void release() override;
protected:
enum EStatus
{
FillingIdentifier,
FillingContentSize,
FillingContent,
};
IReaderCallback& m_readerCB;
CReaderNode* m_currentNode = nullptr;
size_t m_pendingSize = 0;
size_t m_nPending = 0;
unsigned char* m_pending = nullptr;
EStatus m_status = FillingIdentifier;
EStatus m_lastStatus = FillingIdentifier;
CIdentifier m_currentID = 0;
size_t m_currentContentSize = 0;
size_t m_totalBytes = 0;
};
} // namespace
// ________________________________________________________________________________________________________________
//
CReader::~CReader()
{
delete [] m_pending;
while (m_currentNode)
{
CReaderNode* parentNode = m_currentNode->m_ParentNode;
delete m_currentNode;
m_currentNode = parentNode;
}
}
bool CReader::processData(const void* buffer, const size_t size)
{
m_totalBytes += size;
if (_Debug_)
{
std::cout << "Received " << size << " byte(s) new buffer :";
for (int i = 0; i < int(size) /* && i<4*/; ++i) { printf("[%02X]", ((unsigned char*)buffer)[i]); }
std::cout << "...\n";
}
if (!buffer || !size) { return true; }
unsigned char* tmpBuffer = (unsigned char*)buffer;
size_t currentSize = size;
bool finished = false;
while (!finished)
{
size_t processedPendingBytes = 0;
size_t processedBytes = 0;
m_lastStatus = m_status;
if (_Debug_ && m_nPending)
{
std::cout << m_nPending << " byte(s) pending : ";
for (int i = 0; i < int(m_nPending); ++i) { printf("[%02X]", m_pending[i]); }
std::cout << "\n";
}
// Processes data
switch (m_status)
{
case FillingIdentifier:
case FillingContentSize:
{
if (needsTwoBytesToGetCodedSizeLength(m_nPending ? m_pending : tmpBuffer))
{
if (m_nPending + currentSize < 2)
{
finished = true;
break;
}
if (m_nPending == 1)
{
// assumes (currentSize != 0) because (m_nPending + currentSize >= 2) and (m_nPending == 1)
m_pending[1] = tmpBuffer[0];
tmpBuffer++;
m_nPending++;
currentSize--;
}
}
const size_t length = getCodedSizeLength(m_nPending ? m_pending : tmpBuffer);
if (length > currentSize + m_nPending) { finished = true; }
else
{
unsigned char* encodedBuffer = new unsigned char[length];
const size_t pendingBytesToCopy = (length > m_nPending ? m_nPending : length);
memcpy(encodedBuffer, m_pending, size_t(pendingBytesToCopy));
memcpy(encodedBuffer + pendingBytesToCopy, tmpBuffer, size_t(length - pendingBytesToCopy));
const uint64_t value = getValue(encodedBuffer);
delete [] encodedBuffer;
processedPendingBytes = pendingBytesToCopy;
processedBytes = length;
switch (m_status)
{
case FillingIdentifier:
{
m_currentID = value;
m_status = FillingContentSize;
if (_Debug_)
{
printf("Found identifier 0x%llX - Changing status to FillingContentSize...\n", static_cast<unsigned long long>(m_currentID));
}
}
break;
case FillingContentSize:
{
m_currentContentSize = value;
if (m_readerCB.isMasterChild(m_currentID))
{
m_status = FillingIdentifier;
if (_Debug_)
{
std::cout << "Found content size " << m_currentContentSize << " of master node - Changing status to FillingIdentifier...\n";
}
}
else
{
m_status = FillingContent;
if (_Debug_)
{
std::cout << "Found content size " << m_currentContentSize <<
" of *non* master node - Changing status to FillingContent...\n";
}
}
}
break;
case FillingContent:
// Should never happen - avoids the warning
break;
}
}
}
break;
case FillingContent:
{
if (m_currentNode->m_ContentSize == 0)
{
m_status = FillingIdentifier;
if (_Debug_)
{
std::cout << "Finished with " << m_currentNode->m_ContentSize << " byte(s) content - Changing status to FillingIdentifier...\n";
}
m_readerCB.processChildData(nullptr, 0);
}
else
{
if (m_currentNode->m_ReadContentSize == 0 && m_currentNode->m_ContentSize <= currentSize)
{
m_status = FillingIdentifier;
processedBytes = m_currentNode->m_ContentSize;
if (_Debug_)
{
std::cout << "Optimized processing of " << m_currentNode->m_ContentSize <<
" byte(s) content - Changing status to FillingIdentifier...\n";
}
m_readerCB.processChildData(tmpBuffer, m_currentNode->m_ContentSize);
}
else
{
if (m_currentNode->m_ContentSize - m_currentNode->m_ReadContentSize > currentSize)
{
memcpy(m_currentNode->m_Buffer + m_currentNode->m_ReadContentSize, tmpBuffer, size_t(currentSize));
processedBytes = currentSize;
finished = true;
}
else
{
memcpy(m_currentNode->m_Buffer + m_currentNode->m_ReadContentSize, tmpBuffer,
size_t(m_currentNode->m_ContentSize - m_currentNode->m_ReadContentSize));
processedBytes = m_currentNode->m_ContentSize - m_currentNode->m_ReadContentSize;
m_status = FillingIdentifier;
if (_Debug_)
{
std::cout << "Finished with " << m_currentNode->m_ContentSize << " byte(s) content - Changing status to FillingIdentifier...\n";
}
m_readerCB.processChildData(m_currentNode->m_Buffer, m_currentNode->m_ContentSize);
}
}
}
}
break;
}
// Updates buffer pointer and size
const size_t processedBytesInBuffer = processedBytes - processedPendingBytes;
tmpBuffer += processedBytesInBuffer;
currentSize -= processedBytesInBuffer;
m_nPending -= processedPendingBytes;
// Updates read size
CReaderNode* node = m_currentNode;
while (node)
{
node->m_ReadContentSize += processedBytes;
node = node->m_ParentNode;
}
// Creates new node when needed
if (m_status != FillingContentSize && m_lastStatus == FillingContentSize)
{
m_currentNode = new CReaderNode(m_currentID, m_currentNode);
m_currentNode->m_ContentSize = m_currentContentSize;
m_currentNode->m_Buffer = new unsigned char[m_currentContentSize];
m_readerCB.openChild(m_currentNode->m_Id);
}
else
{
// Closes finished nodes
while (m_currentNode && (m_currentNode->m_ContentSize == m_currentNode->m_ReadContentSize || m_currentNode->m_ContentSize == 0))
{
m_readerCB.closeChild();
CReaderNode* parent = m_currentNode->m_ParentNode;
delete [] m_currentNode->m_Buffer;
delete m_currentNode;
m_currentNode = parent;
}
}
}
// Updates pending data
if (m_nPending + currentSize > m_pendingSize)
{
unsigned char* pending = new unsigned char[m_nPending + currentSize + 1
]; // Ugly hack, reserve 1 more byte on pending data so we are sure we can insert this additional pending byte when only one byte is pending and two bytes are needed for decoding identifier and/or buffer size
memcpy(pending, m_pending, m_nPending);
delete [] m_pending;
m_pending = pending;
m_pendingSize = m_nPending + currentSize;
}
memcpy(m_pending + m_nPending, tmpBuffer, currentSize);
m_nPending += currentSize;
if (_Debug_) { std::cout << "\n"; }
return true;
}
CIdentifier CReader::getCurrentNodeID() const { return m_currentNode ? m_currentNode->m_Id : CIdentifier(); }
size_t CReader::getCurrentNodeSize() const { return m_currentNode ? m_currentNode->m_ContentSize : 0; }
void CReader::release() { delete this; }
// ________________________________________________________________________________________________________________
//
EBML_API IReader* createReader(IReaderCallback& callback) { return new CReader(callback); }
} // namespace EBML
@@ -0,0 +1,85 @@
#include "ebml/IReaderHelper.h"
#include <string>
#include <cstring>
namespace EBML {
namespace {
class CReaderHelper final : public IReaderHelper
{
public:
CReaderHelper() { }
uint64_t getUInt(const void* buffer, const size_t size) override;
int64_t getInt(const void* buffer, const size_t size) override;
double getDouble(const void* buffer, const size_t size) override;
const char* getStr(const void* buffer, const size_t size) override;
void release() override;
std::string m_Str;
};
} // namespace
uint64_t CReaderHelper::getUInt(const void* buffer, const size_t size)
{
uint64_t result = 0;
for (size_t i = 0; i < size; ++i)
{
result <<= 8;
result |= reinterpret_cast<const unsigned char*>(buffer)[i];
}
return result;
}
int64_t CReaderHelper::getInt(const void* buffer, const size_t size)
{
int64_t result = 0;
if (size != 0 && reinterpret_cast<const unsigned char*>(buffer)[0] & 0x80) { result = -1; }
for (size_t i = 0; i < size; ++i)
{
result <<= 8;
result |= reinterpret_cast<const unsigned char*>(buffer)[i];
}
return result;
}
double CReaderHelper::getDouble(const void* buffer, const size_t size)
{
switch (size)
{
case 4:
{
float res;
uint32_t data;
data = uint32_t(getUInt(buffer, size));
memcpy(&res, &data, sizeof(res));
return double(res);
}
case 8:
{
double res;
uint64_t data;
data = getUInt(buffer, size);
memcpy(&res, &data, sizeof(res));
return res;
}
case 0:
case 10:
default: return 0.0;
}
}
const char* CReaderHelper::getStr(const void* buffer, const size_t size)
{
if (size) { m_Str.assign(reinterpret_cast<const char*>(buffer), size_t(size)); }
else { m_Str = ""; }
return m_Str.c_str();
}
void CReaderHelper::release() { delete this; }
EBML_API IReaderHelper* createReaderHelper() { return new CReaderHelper(); }
} // namespace EBML
@@ -0,0 +1,214 @@
#include "ebml/IWriter.h"
#include <vector>
#include <cstring>
inline size_t getCodedSizeLength(const uint64_t value)
{
if (value < 0x000000000000007fLL) { return 1; }
if (value < 0x0000000000003fffLL) { return 2; }
if (value < 0x00000000001fffffLL) { return 3; }
if (value < 0x000000000fffffffLL) { return 4; }
if (value < 0x00000007ffffffffLL) { return 5; }
if (value < 0x000003ffffffffffLL) { return 6; }
if (value < 0x0001ffffffffffffLL) { return 7; }
if (value < 0x00ffffffffffffffLL) { return 8; }
if (value < 0x7fffffffffffffffLL) { return 9; }
return 10;
}
inline bool getCodedBuffer(const uint64_t value, unsigned char* buffer, size_t* size)
{
const size_t length = getCodedSizeLength(value);
if (length > *size) { return false; }
size_t bit = length;
for (size_t i = 0; i < length; ++i)
{
const size_t byteShift = length - i - 1;
size_t byte = (byteShift >= 8 ? 0 : static_cast<unsigned char>((value >> (byteShift * 8)) & 0xff));
byte |= (bit > 0 && bit <= 8 ? (1 << (8 - bit)) : 0);
bit -= 8;
buffer[i] = static_cast<unsigned char>(byte);
}
*size = length;
return true;
}
// ________________________________________________________________________________________________________________
//
namespace EBML {
namespace {
class CWriterNode final
{
public:
CWriterNode(const CIdentifier& identifier, CWriterNode* parentNode) : m_ID(identifier), m_ParentNode(parentNode) {}
~CWriterNode();
void process(IWriterCallback& callback);
protected:
size_t getTotalContentSize(bool identifierAndSize);
private:
CWriterNode() = delete;
public:
CIdentifier m_ID;
CWriterNode* m_ParentNode = nullptr;
size_t m_BufferLength = 0;
unsigned char* m_Buffer = nullptr;
bool m_Buffered = false;
std::vector<CWriterNode*> m_Childrens;
};
} // namespace
// ________________________________________________________________________________________________________________
//
CWriterNode::~CWriterNode()
{
for (auto i = m_Childrens.begin(); i != m_Childrens.end(); ++i) { delete (*i); }
if (m_Buffer)
{
delete [] m_Buffer;
m_Buffer = nullptr;
}
}
void CWriterNode::process(IWriterCallback& callback)
{
unsigned char id[10];
unsigned char pContentSize[10];
size_t contentSizeLength = sizeof(pContentSize);
size_t identifierLength = sizeof(id);
const size_t contentSize = getTotalContentSize(false);
if (!getCodedBuffer(contentSize, pContentSize, &contentSizeLength)) { } // SHOULD NEVER HAPPEN
if (!getCodedBuffer(m_ID, id, &identifierLength)) { } // SHOULD NEVER HAPPEN
callback.write(id, identifierLength);
callback.write(pContentSize, contentSizeLength);
if (m_Childrens.empty()) { callback.write(m_Buffer, m_BufferLength); }
else { for (auto i = m_Childrens.begin(); i != m_Childrens.end(); ++i) { (*i)->process(callback); } }
}
size_t CWriterNode::getTotalContentSize(const bool identifierAndSize)
{
size_t contentSize = 0;
if (m_Childrens.empty()) { contentSize = m_BufferLength; }
else { for (auto i = m_Childrens.begin(); i != m_Childrens.end(); ++i) { contentSize += (*i)->getTotalContentSize(true); } }
size_t res = contentSize;
if (identifierAndSize)
{
res += getCodedSizeLength(m_ID);
res += getCodedSizeLength(contentSize);
}
return res;
}
// ________________________________________________________________________________________________________________
//
namespace {
class CWriter final : public IWriter
{
public:
explicit CWriter(IWriterCallback& callback) : m_callback(callback) {}
bool openChild(const CIdentifier& identifier) override;
bool setChildData(const void* buffer, const size_t size) override;
bool closeChild() override;
void release() override;
protected:
CWriterNode* m_node = nullptr;
IWriterCallback& m_callback;
private:
CWriter() = delete;
};
} // namespace
// ________________________________________________________________________________________________________________
//
bool CWriter::openChild(const CIdentifier& identifier)
{
if (m_node) { if (m_node->m_Buffered) { return false; } }
CWriterNode* pResult = new CWriterNode(identifier, m_node);
if (m_node) { m_node->m_Childrens.push_back(pResult); }
m_node = pResult;
return true;
}
bool CWriter::setChildData(const void* buffer, const size_t size)
{
if (!m_node) { return false; }
if (!m_node->m_Childrens.empty()) { return false; }
unsigned char* bufferCopy = nullptr;
if (size)
{
if (!buffer) { return false; }
bufferCopy = new unsigned char[size];
if (!bufferCopy) { return false; }
memcpy(bufferCopy, buffer, size);
}
delete [] m_node->m_Buffer;
m_node->m_BufferLength = size;
m_node->m_Buffer = bufferCopy;
m_node->m_Buffered = true;
return true;
}
bool CWriter::closeChild()
{
if (!m_node) { return false; }
if ((!m_node->m_Buffered) && (m_node->m_Childrens.empty()))
{
m_node->m_BufferLength = 0;
m_node->m_Buffer = nullptr;
m_node->m_Buffered = true;
}
CWriterNode* parent = m_node->m_ParentNode;
if (!parent)
{
m_node->process(m_callback);
delete m_node;
}
m_node = parent;
return true;
}
void CWriter::release()
{
while (m_node) { closeChild(); }
delete this;
}
// ________________________________________________________________________________________________________________
//
EBML_API IWriter* createWriter(IWriterCallback& callback) { return new CWriter(callback); }
} // namespace EBML
@@ -0,0 +1,129 @@
#include "ebml/IWriterHelper.h"
#include "ebml/IWriter.h"
#include <cstdlib>
#include <cstring>
namespace EBML {
namespace {
class CWriterHelper final : public IWriterHelper
{
public:
CWriterHelper() { }
bool connect(IWriter* writer) override;
bool disconnect() override;
bool openChild(const CIdentifier& identifier) override;
bool closeChild() override;
bool setInt(const int64_t value) override;
bool setUInt(const uint64_t value) override;
bool setFloat(const float value) override;
bool setDouble(const double value) override;
bool setBinary(const void* buffer, const size_t size) override;
bool setStr(const char* value) override;
void release() override;
protected:
IWriter* m_writer = nullptr;
};
} // namespace
bool CWriterHelper::connect(IWriter* writer)
{
m_writer = writer;
return m_writer ? true : false;
}
bool CWriterHelper::disconnect()
{
if (!m_writer) { return false; }
m_writer = nullptr;
return true;
}
// ________________________________________________________________________________________________________________
//
bool CWriterHelper::openChild(const CIdentifier& identifier) { return m_writer ? m_writer->openChild(identifier) : false; }
bool CWriterHelper::closeChild() { return m_writer ? m_writer->closeChild() : false; }
// ________________________________________________________________________________________________________________
//
bool CWriterHelper::setInt(const int64_t value)
{
unsigned char buffer[8];
size_t size = 8;
if (value == 0x00000000000000LL) { size = 0; }
else if (value >= -0x00000000000080LL && value <= 0x0000000000007fLL) { size = 1; }
else if (value >= -0x00000000008000LL && value <= 0x00000000007fffLL) { size = 2; }
else if (value >= -0x00000000800000LL && value <= 0x000000007fffffLL) { size = 3; }
else if (value >= -0x00000080000000LL && value <= 0x0000007fffffffLL) { size = 4; }
else if (value >= -0x00008000000000LL && value <= 0x00007fffffffffLL) { size = 5; }
else if (value >= -0x00800000000000LL && value <= 0x007fffffffffffLL) { size = 6; }
else if (value >= -0x80000000000000LL && value <= 0x7fffffffffffffLL) { size = 7; }
//else { size = 8; }
for (size_t i = 0; i < size; ++i) { buffer[size - i - 1] = static_cast<unsigned char>((value >> (i * 8)) & 0xff); }
return m_writer->setChildData(buffer, size);
}
bool CWriterHelper::setUInt(const uint64_t value)
{
size_t size = 8;
unsigned char buffer[8];
if (value == 0x000000000000000LL) { size = 0; }
else if (value < 0x000000000000100LL) { size = 1; }
else if (value < 0x000000000010000LL) { size = 2; }
else if (value < 0x000000001000000LL) { size = 3; }
else if (value < 0x000000100000000LL) { size = 4; }
else if (value < 0x000010000000000LL) { size = 5; }
else if (value < 0x001000000000000LL) { size = 6; }
else if (value < 0x100000000000000LL) { size = 7; }
for (size_t i = 0; i < size; ++i) { buffer[size - i - 1] = static_cast<unsigned char>((value >> (i * 8)) & 0xff); }
return m_writer->setChildData(buffer, size);
}
bool CWriterHelper::setFloat(const float value)
{
uint32_t res;
unsigned char buffer[8];
memcpy(&res, &value, sizeof(value));
const size_t size = (value != 0 ? 4 : 0);
for (size_t i = 0; i < size; ++i) { buffer[size - i - 1] = static_cast<unsigned char>((res >> (i * 8)) & 0xff); }
return m_writer->setChildData(buffer, size);
}
bool CWriterHelper::setDouble(const double value)
{
uint64_t res;
unsigned char buffer[8];
memcpy(&res, &value, sizeof(value));
const size_t size = (value != 0 ? 8 : 0);
for (size_t i = 0; i < size; ++i) { buffer[size - i - 1] = static_cast<unsigned char>((res >> (i * 8)) & 0xff); }
return m_writer->setChildData(buffer, size);
}
bool CWriterHelper::setBinary(const void* buffer, const size_t size) { return m_writer->setChildData(buffer, size); }
bool CWriterHelper::setStr(const char* value) { return m_writer->setChildData(value, strlen(value)); }
// ________________________________________________________________________________________________________________
//
void CWriterHelper::release() { delete this; }
// ________________________________________________________________________________________________________________
//
EBML_API IWriterHelper* createWriterHelper() { return new CWriterHelper(); }
} // namespace EBML