120 lines
No EOL
2.4 KiB
C++
120 lines
No EOL
2.4 KiB
C++
#include "ebmlelement.hpp"
|
|
#include "imkvreader.hpp"
|
|
#include "ebmlreadhelpers.hpp"
|
|
|
|
#include <assert.h>
|
|
|
|
namespace mkvparser
|
|
{
|
|
|
|
// read helpers
|
|
namespace
|
|
{
|
|
|
|
long ReadUInt(IMkvReader* _reader,
|
|
long long& _pos, /* in-out */
|
|
long& _len, /* in-out */
|
|
const long long _avail, /* in */
|
|
const long long _end, /* in */
|
|
long long& _outVal /* out*/
|
|
)
|
|
{
|
|
if ((_pos + 1) > _avail)
|
|
{
|
|
_len = 1;
|
|
return E_BUFFER_NOT_FULL;
|
|
}
|
|
|
|
long long result = GetUIntLength(_reader, _pos, _len);
|
|
|
|
if (result < 0) //error
|
|
return static_cast<long>(result);
|
|
|
|
if (result > 0) //weird
|
|
return E_BUFFER_NOT_FULL;
|
|
|
|
if ((_end >= 0) && ((_pos + _len) > _end))
|
|
return E_FILE_FORMAT_INVALID;
|
|
|
|
if ((_pos + _len) > _avail)
|
|
return E_BUFFER_NOT_FULL;
|
|
|
|
_outVal = ReadUInt(_reader, _pos, _len);
|
|
|
|
if (_outVal < 0) //error (or underflow)
|
|
return static_cast<long>(_outVal);
|
|
|
|
_pos += _len; // consume
|
|
|
|
return 0;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
|
EBMLElement::EBMLElement()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
long long EBMLElement::Parse(IMkvReader* _reader, long long _pos)
|
|
{
|
|
assert(_reader);
|
|
assert(_pos >= 0);
|
|
|
|
Reset();
|
|
|
|
long long total, available;
|
|
const long status = _reader->Length(&total, &available);
|
|
|
|
if (status < 0) //error
|
|
return status;
|
|
|
|
if (available < 0)
|
|
return -1;
|
|
|
|
if ((total >= 0) && (available > total))
|
|
return -1;
|
|
|
|
if ((total >= 0) && (_pos >= total))
|
|
return E_FILE_FORMAT_INVALID;
|
|
|
|
//Read ID
|
|
long len;
|
|
long long pos = _pos;
|
|
const long long idpos = pos;
|
|
long long id = 0;
|
|
long long result = ReadUInt(_reader, pos, len, available, total, id); // position is updated inside
|
|
if (result != 0)
|
|
return result;
|
|
|
|
if (id < 0) //error
|
|
return id;
|
|
|
|
//Read Size
|
|
long long size = 0;
|
|
result = ReadUInt(_reader, pos, len, available, total, size); // position is updated inside
|
|
if (result != 0)
|
|
return result;
|
|
|
|
if (size < 0) //error
|
|
return size;
|
|
|
|
// no errors, set the values
|
|
m_id = id;
|
|
m_pos = idpos;
|
|
m_payloadPos = pos;
|
|
m_payloadSize = size;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void EBMLElement::Reset()
|
|
{
|
|
m_id = -1; // invalid ID
|
|
m_pos = -1; // invalid pos
|
|
m_payloadPos = -1;
|
|
m_payloadSize = -1; // invalid size
|
|
}
|
|
|
|
} // namespace mkvparser
|