// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

#include "mkvparser.hpp"
#include <cassert>
#include <cstring>
#include <new>
#include <climits>

#ifdef _MSC_VER
// Disable MSVC warnings that suggest making code non-portable.
#pragma warning(disable : 4996)
#endif

mkvparser::IMkvReader::~IMkvReader() {}

void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision) {
  major = 1;
  minor = 0;
  build = 0;
  revision = 28;
}

long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len) {
  assert(pReader);
  assert(pos >= 0);

  int status;

  //#ifdef _DEBUG
  //    long long total, available;
  //    status = pReader->Length(&total, &available);
  //    assert(status >= 0);
  //    assert((total < 0) || (available <= total));
  //    assert(pos < available);
  //    assert((available - pos) >= 1);  //assume here max u-int len is 8
  //#endif

  len = 1;

  unsigned char b;

  status = pReader->Read(pos, 1, &b);

  if (status < 0)  // error or underflow
    return status;

  if (status > 0)  // interpreted as "underflow"
    return E_BUFFER_NOT_FULL;

  if (b == 0)  // we can't handle u-int values larger than 8 bytes
    return E_FILE_FORMAT_INVALID;

  unsigned char m = 0x80;

  while (!(b & m)) {
    m >>= 1;
    ++len;
  }

  //#ifdef _DEBUG
  //    assert((available - pos) >= len);
  //#endif

  long long result = b & (~m);
  ++pos;

  for (int i = 1; i < len; ++i) {
    status = pReader->Read(pos, 1, &b);

    if (status < 0) {
      len = 1;
      return status;
    }

    if (status > 0) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result <<= 8;
    result |= b;

    ++pos;
  }

  return result;
}

long long mkvparser::GetUIntLength(IMkvReader* pReader, long long pos,
                                   long& len) {
  assert(pReader);
  assert(pos >= 0);

  long long total, available;

  int status = pReader->Length(&total, &available);
  assert(status >= 0);
  assert((total < 0) || (available <= total));

  len = 1;

  if (pos >= available)
    return pos;  // too few bytes available

  unsigned char b;

  status = pReader->Read(pos, 1, &b);

  if (status < 0)
    return status;

  assert(status == 0);

  if (b == 0)  // we can't handle u-int values larger than 8 bytes
    return E_FILE_FORMAT_INVALID;

  unsigned char m = 0x80;

  while (!(b & m)) {
    m >>= 1;
    ++len;
  }

  return 0;  // success
}

// TODO(vigneshv): This function assumes that unsigned values never have their
// high bit set.
long long mkvparser::UnserializeUInt(IMkvReader* pReader, long long pos,
                                     long long size) {
  assert(pReader);
  assert(pos >= 0);

  if ((size <= 0) || (size > 8))
    return E_FILE_FORMAT_INVALID;

  long long result = 0;

  for (long long i = 0; i < size; ++i) {
    unsigned char b;

    const long status = pReader->Read(pos, 1, &b);

    if (status < 0)
      return status;

    result <<= 8;
    result |= b;

    ++pos;
  }

  return result;
}

long mkvparser::UnserializeFloat(IMkvReader* pReader, long long pos,
                                 long long size_, double& result) {
  assert(pReader);
  assert(pos >= 0);

  if ((size_ != 4) && (size_ != 8))
    return E_FILE_FORMAT_INVALID;

  const long size = static_cast<long>(size_);

  unsigned char buf[8];

  const int status = pReader->Read(pos, size, buf);

  if (status < 0)  // error
    return status;

  if (size == 4) {
    union {
      float f;
      unsigned long ff;
    };

    ff = 0;

    for (int i = 0;;) {
      ff |= buf[i];

      if (++i >= 4)
        break;

      ff <<= 8;
    }

    result = f;
  } else {
    assert(size == 8);

    union {
      double d;
      unsigned long long dd;
    };

    dd = 0;

    for (int i = 0;;) {
      dd |= buf[i];

      if (++i >= 8)
        break;

      dd <<= 8;
    }

    result = d;
  }

  return 0;
}

long mkvparser::UnserializeInt(IMkvReader* pReader, long long pos, long size,
                               long long& result) {
  assert(pReader);
  assert(pos >= 0);
  assert(size > 0);
  assert(size <= 8);

  {
    signed char b;

    const long status = pReader->Read(pos, 1, (unsigned char*)&b);

    if (status < 0)
      return status;

    result = b;

    ++pos;
  }

  for (long i = 1; i < size; ++i) {
    unsigned char b;

    const long status = pReader->Read(pos, 1, &b);

    if (status < 0)
      return status;

    result <<= 8;
    result |= b;

    ++pos;
  }

  return 0;  // success
}

long mkvparser::UnserializeString(IMkvReader* pReader, long long pos,
                                  long long size_, char*& str) {
  delete[] str;
  str = NULL;

  if (size_ >= LONG_MAX)  // we need (size+1) chars
    return E_FILE_FORMAT_INVALID;

  const long size = static_cast<long>(size_);

  str = new (std::nothrow) char[size + 1];

  if (str == NULL)
    return -1;

  unsigned char* const buf = reinterpret_cast<unsigned char*>(str);

  const long status = pReader->Read(pos, size, buf);

  if (status) {
    delete[] str;
    str = NULL;

    return status;
  }

  str[size] = '\0';

  return 0;  // success
}

long mkvparser::ParseElementHeader(IMkvReader* pReader, long long& pos,
                                   long long stop, long long& id,
                                   long long& size) {
  if ((stop >= 0) && (pos >= stop))
    return E_FILE_FORMAT_INVALID;

  long len;

  id = ReadUInt(pReader, pos, len);

  if (id < 0)
    return E_FILE_FORMAT_INVALID;

  pos += len;  // consume id

  if ((stop >= 0) && (pos >= stop))
    return E_FILE_FORMAT_INVALID;

  size = ReadUInt(pReader, pos, len);

  if (size < 0)
    return E_FILE_FORMAT_INVALID;

  pos += len;  // consume length of size

  // pos now designates payload

  if ((stop >= 0) && ((pos + size) > stop))
    return E_FILE_FORMAT_INVALID;

  return 0;  // success
}

bool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_,
                      long long& val) {
  assert(pReader);
  assert(pos >= 0);

  long long total, available;

  const long status = pReader->Length(&total, &available);
  assert(status >= 0);
  assert((total < 0) || (available <= total));
  if (status < 0)
    return false;

  long len;

  const long long id = ReadUInt(pReader, pos, len);
  assert(id >= 0);
  assert(len > 0);
  assert(len <= 8);
  assert((pos + len) <= available);

  if ((unsigned long)id != id_)
    return false;

  pos += len;  // consume id

  const long long size = ReadUInt(pReader, pos, len);
  assert(size >= 0);
  assert(size <= 8);
  assert(len > 0);
  assert(len <= 8);
  assert((pos + len) <= available);

  pos += len;  // consume length of size of payload

  val = UnserializeUInt(pReader, pos, size);
  assert(val >= 0);

  pos += size;  // consume size of payload

  return true;
}

bool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_,
                      unsigned char*& buf, size_t& buflen) {
  assert(pReader);
  assert(pos >= 0);

  long long total, available;

  long status = pReader->Length(&total, &available);
  assert(status >= 0);
  assert((total < 0) || (available <= total));
  if (status < 0)
    return false;

  long len;
  const long long id = ReadUInt(pReader, pos, len);
  assert(id >= 0);
  assert(len > 0);
  assert(len <= 8);
  assert((pos + len) <= available);

  if ((unsigned long)id != id_)
    return false;

  pos += len;  // consume id

  const long long size_ = ReadUInt(pReader, pos, len);
  assert(size_ >= 0);
  assert(len > 0);
  assert(len <= 8);
  assert((pos + len) <= available);

  pos += len;  // consume length of size of payload
  assert((pos + size_) <= available);

  const long buflen_ = static_cast<long>(size_);

  buf = new (std::nothrow) unsigned char[buflen_];
  assert(buf);  // TODO

  status = pReader->Read(pos, buflen_, buf);
  assert(status == 0);  // TODO

  buflen = buflen_;

  pos += size_;  // consume size of payload
  return true;
}

namespace mkvparser {

EBMLHeader::EBMLHeader() : m_docType(NULL) { Init(); }

EBMLHeader::~EBMLHeader() { delete[] m_docType; }

void EBMLHeader::Init() {
  m_version = 1;
  m_readVersion = 1;
  m_maxIdLength = 4;
  m_maxSizeLength = 8;

  if (m_docType) {
    delete[] m_docType;
    m_docType = NULL;
  }

  m_docTypeVersion = 1;
  m_docTypeReadVersion = 1;
}

long long EBMLHeader::Parse(IMkvReader* pReader, long long& pos) {
  assert(pReader);

  long long total, available;

  long status = pReader->Length(&total, &available);

  if (status < 0)  // error
    return status;

  pos = 0;
  long long end = (available >= 1024) ? 1024 : available;

  for (;;) {
    unsigned char b = 0;

    while (pos < end) {
      status = pReader->Read(pos, 1, &b);

      if (status < 0)  // error
        return status;

      if (b == 0x1A)
        break;

      ++pos;
    }

    if (b != 0x1A) {
      if (pos >= 1024)
        return E_FILE_FORMAT_INVALID;  // don't bother looking anymore

      if ((total >= 0) && ((total - available) < 5))
        return E_FILE_FORMAT_INVALID;

      return available + 5;  // 5 = 4-byte ID + 1st byte of size
    }

    if ((total >= 0) && ((total - pos) < 5))
      return E_FILE_FORMAT_INVALID;

    if ((available - pos) < 5)
      return pos + 5;  // try again later

    long len;

    const long long result = ReadUInt(pReader, pos, len);

    if (result < 0)  // error
      return result;

    if (result == 0x0A45DFA3) {  // EBML Header ID
      pos += len;  // consume ID
      break;
    }

    ++pos;  // throw away just the 0x1A byte, and try again
  }

  // pos designates start of size field

  // get length of size field

  long len;
  long long result = GetUIntLength(pReader, pos, len);

  if (result < 0)  // error
    return result;

  if (result > 0)  // need more data
    return result;

  assert(len > 0);
  assert(len <= 8);

  if ((total >= 0) && ((total - pos) < len))
    return E_FILE_FORMAT_INVALID;

  if ((available - pos) < len)
    return pos + len;  // try again later

  // get the EBML header size

  result = ReadUInt(pReader, pos, len);

  if (result < 0)  // error
    return result;

  pos += len;  // consume size field

  // pos now designates start of payload

  if ((total >= 0) && ((total - pos) < result))
    return E_FILE_FORMAT_INVALID;

  if ((available - pos) < result)
    return pos + result;

  end = pos + result;

  Init();

  while (pos < end) {
    long long id, size;

    status = ParseElementHeader(pReader, pos, end, id, size);

    if (status < 0)  // error
      return status;

    if (size == 0)  // weird
      return E_FILE_FORMAT_INVALID;

    if (id == 0x0286) {  // version
      m_version = UnserializeUInt(pReader, pos, size);

      if (m_version <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x02F7) {  // read version
      m_readVersion = UnserializeUInt(pReader, pos, size);

      if (m_readVersion <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x02F2) {  // max id length
      m_maxIdLength = UnserializeUInt(pReader, pos, size);

      if (m_maxIdLength <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x02F3) {  // max size length
      m_maxSizeLength = UnserializeUInt(pReader, pos, size);

      if (m_maxSizeLength <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x0282) {  // doctype
      if (m_docType)
        return E_FILE_FORMAT_INVALID;

      status = UnserializeString(pReader, pos, size, m_docType);

      if (status)  // error
        return status;
    } else if (id == 0x0287) {  // doctype version
      m_docTypeVersion = UnserializeUInt(pReader, pos, size);

      if (m_docTypeVersion <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x0285) {  // doctype read version
      m_docTypeReadVersion = UnserializeUInt(pReader, pos, size);

      if (m_docTypeReadVersion <= 0)
        return E_FILE_FORMAT_INVALID;
    }

    pos += size;
  }

  assert(pos == end);
  return 0;
}

Segment::Segment(IMkvReader* pReader, long long elem_start,
                 // long long elem_size,
                 long long start, long long size)
    : m_pReader(pReader),
      m_element_start(elem_start),
      // m_element_size(elem_size),
      m_start(start),
      m_size(size),
      m_pos(start),
      m_pUnknownSize(0),
      m_pSeekHead(NULL),
      m_pInfo(NULL),
      m_pTracks(NULL),
      m_pCues(NULL),
      m_pChapters(NULL),
      m_clusters(NULL),
      m_clusterCount(0),
      m_clusterPreloadCount(0),
      m_clusterSize(0) {}

Segment::~Segment() {
  const long count = m_clusterCount + m_clusterPreloadCount;

  Cluster** i = m_clusters;
  Cluster** j = m_clusters + count;

  while (i != j) {
    Cluster* const p = *i++;
    assert(p);

    delete p;
  }

  delete[] m_clusters;

  delete m_pTracks;
  delete m_pInfo;
  delete m_pCues;
  delete m_pChapters;
  delete m_pSeekHead;
}

long long Segment::CreateInstance(IMkvReader* pReader, long long pos,
                                  Segment*& pSegment) {
  assert(pReader);
  assert(pos >= 0);

  pSegment = NULL;

  long long total, available;

  const long status = pReader->Length(&total, &available);

  if (status < 0)  // error
    return status;

  if (available < 0)
    return -1;

  if ((total >= 0) && (available > total))
    return -1;

  // I would assume that in practice this loop would execute
  // exactly once, but we allow for other elements (e.g. Void)
  // to immediately follow the EBML header.  This is fine for
  // the source filter case (since the entire file is available),
  // but in the splitter case over a network we should probably
  // just give up early.  We could for example decide only to
  // execute this loop a maximum of, say, 10 times.
  // TODO:
  // There is an implied "give up early" by only parsing up
  // to the available limit.  We do do that, but only if the
  // total file size is unknown.  We could decide to always
  // use what's available as our limit (irrespective of whether
  // we happen to know the total file length).  This would have
  // as its sense "parse this much of the file before giving up",
  // which a slightly different sense from "try to parse up to
  // 10 EMBL elements before giving up".

  for (;;) {
    if ((total >= 0) && (pos >= total))
      return E_FILE_FORMAT_INVALID;

    // Read ID
    long len;
    long long result = GetUIntLength(pReader, pos, len);

    if (result)  // error, or too few available bytes
      return result;

    if ((total >= 0) && ((pos + len) > total))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > available)
      return pos + len;

    const long long idpos = pos;
    const long long id = ReadUInt(pReader, pos, len);

    if (id < 0)  // error
      return id;

    pos += len;  // consume ID

    // Read Size

    result = GetUIntLength(pReader, pos, len);

    if (result)  // error, or too few available bytes
      return result;

    if ((total >= 0) && ((pos + len) > total))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > available)
      return pos + len;

    long long size = ReadUInt(pReader, pos, len);

    if (size < 0)  // error
      return size;

    pos += len;  // consume length of size of element

    // Pos now points to start of payload

    // Handle "unknown size" for live streaming of webm files.
    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (id == 0x08538067) {  // Segment ID
      if (size == unknown_size)
        size = -1;

      else if (total < 0)
        size = -1;

      else if ((pos + size) > total)
        size = -1;

      pSegment = new (std::nothrow) Segment(pReader, idpos,
                                            // elem_size
                                            pos, size);

      if (pSegment == 0)
        return -1;  // generic error

      return 0;  // success
    }

    if (size == unknown_size)
      return E_FILE_FORMAT_INVALID;

    if ((total >= 0) && ((pos + size) > total))
      return E_FILE_FORMAT_INVALID;

    if ((pos + size) > available)
      return pos + size;

    pos += size;  // consume payload
  }
}

long long Segment::ParseHeaders() {
  // Outermost (level 0) segment object has been constructed,
  // and pos designates start of payload.  We need to find the
  // inner (level 1) elements.
  long long total, available;

  const int status = m_pReader->Length(&total, &available);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (available <= total));

  const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
  assert((segment_stop < 0) || (total < 0) || (segment_stop <= total));
  assert((segment_stop < 0) || (m_pos <= segment_stop));

  for (;;) {
    if ((total >= 0) && (m_pos >= total))
      break;

    if ((segment_stop >= 0) && (m_pos >= segment_stop))
      break;

    long long pos = m_pos;
    const long long element_start = pos;

    if ((pos + 1) > available)
      return (pos + 1);

    long len;
    long long result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return result;

    if (result > 0)  // underflow (weird)
      return (pos + 1);

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > available)
      return pos + len;

    const long long idpos = pos;
    const long long id = ReadUInt(m_pReader, idpos, len);

    if (id < 0)  // error
      return id;

    if (id == 0x0F43B675)  // Cluster ID
      break;

    pos += len;  // consume ID

    if ((pos + 1) > available)
      return (pos + 1);

    // Read Size
    result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return result;

    if (result > 0)  // underflow (weird)
      return (pos + 1);

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > available)
      return pos + len;

    const long long size = ReadUInt(m_pReader, pos, len);

    if (size < 0)  // error
      return size;

    pos += len;  // consume length of size of element

    const long long element_size = size + pos - element_start;

    // Pos now points to start of payload

    if ((segment_stop >= 0) && ((pos + size) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    // We read EBML elements either in total or nothing at all.

    if ((pos + size) > available)
      return pos + size;

    if (id == 0x0549A966) {  // Segment Info ID
      if (m_pInfo)
        return E_FILE_FORMAT_INVALID;

      m_pInfo = new (std::nothrow)
          SegmentInfo(this, pos, size, element_start, element_size);

      if (m_pInfo == NULL)
        return -1;

      const long status = m_pInfo->Parse();

      if (status)
        return status;
    } else if (id == 0x0654AE6B) {  // Tracks ID
      if (m_pTracks)
        return E_FILE_FORMAT_INVALID;

      m_pTracks = new (std::nothrow)
          Tracks(this, pos, size, element_start, element_size);

      if (m_pTracks == NULL)
        return -1;

      const long status = m_pTracks->Parse();

      if (status)
        return status;
    } else if (id == 0x0C53BB6B) {  // Cues ID
      if (m_pCues == NULL) {
        m_pCues = new (std::nothrow)
            Cues(this, pos, size, element_start, element_size);

        if (m_pCues == NULL)
          return -1;
      }
    } else if (id == 0x014D9B74) {  // SeekHead ID
      if (m_pSeekHead == NULL) {
        m_pSeekHead = new (std::nothrow)
            SeekHead(this, pos, size, element_start, element_size);

        if (m_pSeekHead == NULL)
          return -1;

        const long status = m_pSeekHead->Parse();

        if (status)
          return status;
      }
    } else if (id == 0x0043A770) {  // Chapters ID
      if (m_pChapters == NULL) {
        m_pChapters = new (std::nothrow)
            Chapters(this, pos, size, element_start, element_size);

        if (m_pChapters == NULL)
          return -1;

        const long status = m_pChapters->Parse();

        if (status)
          return status;
      }
    }

    m_pos = pos + size;  // consume payload
  }

  assert((segment_stop < 0) || (m_pos <= segment_stop));

  if (m_pInfo == NULL)  // TODO: liberalize this behavior
    return E_FILE_FORMAT_INVALID;

  if (m_pTracks == NULL)
    return E_FILE_FORMAT_INVALID;

  return 0;  // success
}

long Segment::LoadCluster(long long& pos, long& len) {
  for (;;) {
    const long result = DoLoadCluster(pos, len);

    if (result <= 1)
      return result;
  }
}

long Segment::DoLoadCluster(long long& pos, long& len) {
  if (m_pos < 0)
    return DoLoadClusterUnknownSize(pos, len);

  long long total, avail;

  long status = m_pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;

  long long cluster_off = -1;  // offset relative to start of segment
  long long cluster_size = -1;  // size of cluster payload

  for (;;) {
    if ((total >= 0) && (m_pos >= total))
      return 1;  // no more clusters

    if ((segment_stop >= 0) && (m_pos >= segment_stop))
      return 1;  // no more clusters

    pos = m_pos;

    // Read ID

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long idpos = pos;
    const long long id = ReadUInt(m_pReader, idpos, len);

    if (id < 0)  // error (or underflow)
      return static_cast<long>(id);

    pos += len;  // consume ID

    // Read Size

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(m_pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    pos += len;  // consume length of size of element

    // pos now points to start of payload

    if (size == 0) {  // weird
      m_pos = pos;
      continue;
    }

    const long long unknown_size = (1LL << (7 * len)) - 1;

#if 0  // we must handle this to support live webm
        if (size == unknown_size)
            return E_FILE_FORMAT_INVALID;  //TODO: allow this
#endif

    if ((segment_stop >= 0) && (size != unknown_size) &&
        ((pos + size) > segment_stop)) {
      return E_FILE_FORMAT_INVALID;
    }

#if 0  // commented-out, to support incremental cluster parsing
        len = static_cast<long>(size);

        if ((pos + size) > avail)
            return E_BUFFER_NOT_FULL;
#endif

    if (id == 0x0C53BB6B) {  // Cues ID
      if (size == unknown_size)
        return E_FILE_FORMAT_INVALID;  // TODO: liberalize

      if (m_pCues == NULL) {
        const long long element_size = (pos - idpos) + size;

        m_pCues = new Cues(this, pos, size, idpos, element_size);
        assert(m_pCues);  // TODO
      }

      m_pos = pos + size;  // consume payload
      continue;
    }

    if (id != 0x0F43B675) {  // Cluster ID
      if (size == unknown_size)
        return E_FILE_FORMAT_INVALID;  // TODO: liberalize

      m_pos = pos + size;  // consume payload
      continue;
    }

    // We have a cluster.

    cluster_off = idpos - m_start;  // relative pos

    if (size != unknown_size)
      cluster_size = size;

    break;
  }

  assert(cluster_off >= 0);  // have cluster

  long long pos_;
  long len_;

  status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_);

  if (status < 0) {  // error, or underflow
    pos = pos_;
    len = len_;

    return status;
  }

  // status == 0 means "no block entries found"
  // status > 0 means "found at least one block entry"

  // TODO:
  // The issue here is that the segment increments its own
  // pos ptr past the most recent cluster parsed, and then
  // starts from there to parse the next cluster.  If we
  // don't know the size of the current cluster, then we
  // must either parse its payload (as we do below), looking
  // for the cluster (or cues) ID to terminate the parse.
  // This isn't really what we want: rather, we really need
  // a way to create the curr cluster object immediately.
  // The pity is that cluster::parse can determine its own
  // boundary, and we largely duplicate that same logic here.
  //
  // Maybe we need to get rid of our look-ahead preloading
  // in source::parse???
  //
  // As we're parsing the blocks in the curr cluster
  //(in cluster::parse), we should have some way to signal
  // to the segment that we have determined the boundary,
  // so it can adjust its own segment::m_pos member.
  //
  // The problem is that we're asserting in asyncreadinit,
  // because we adjust the pos down to the curr seek pos,
  // and the resulting adjusted len is > 2GB.  I'm suspicious
  // that this is even correct, but even if it is, we can't
  // be loading that much data in the cache anyway.

  const long idx = m_clusterCount;

  if (m_clusterPreloadCount > 0) {
    assert(idx < m_clusterSize);

    Cluster* const pCluster = m_clusters[idx];
    assert(pCluster);
    assert(pCluster->m_index < 0);

    const long long off = pCluster->GetPosition();
    assert(off >= 0);

    if (off == cluster_off) {  // preloaded already
      if (status == 0)  // no entries found
        return E_FILE_FORMAT_INVALID;

      if (cluster_size >= 0)
        pos += cluster_size;
      else {
        const long long element_size = pCluster->GetElementSize();

        if (element_size <= 0)
          return E_FILE_FORMAT_INVALID;  // TODO: handle this case

        pos = pCluster->m_element_start + element_size;
      }

      pCluster->m_index = idx;  // move from preloaded to loaded
      ++m_clusterCount;
      --m_clusterPreloadCount;

      m_pos = pos;  // consume payload
      assert((segment_stop < 0) || (m_pos <= segment_stop));

      return 0;  // success
    }
  }

  if (status == 0) {  // no entries found
    if (cluster_size < 0)
      return E_FILE_FORMAT_INVALID;  // TODO: handle this

    pos += cluster_size;

    if ((total >= 0) && (pos >= total)) {
      m_pos = total;
      return 1;  // no more clusters
    }

    if ((segment_stop >= 0) && (pos >= segment_stop)) {
      m_pos = segment_stop;
      return 1;  // no more clusters
    }

    m_pos = pos;
    return 2;  // try again
  }

  // status > 0 means we have an entry

  Cluster* const pCluster = Cluster::Create(this, idx, cluster_off);
  // element_size);
  assert(pCluster);

  AppendCluster(pCluster);
  assert(m_clusters);
  assert(idx < m_clusterSize);
  assert(m_clusters[idx] == pCluster);

  if (cluster_size >= 0) {
    pos += cluster_size;

    m_pos = pos;
    assert((segment_stop < 0) || (m_pos <= segment_stop));

    return 0;
  }

  m_pUnknownSize = pCluster;
  m_pos = -pos;

  return 0;  // partial success, since we have a new cluster

// status == 0 means "no block entries found"

// pos designates start of payload
// m_pos has NOT been adjusted yet (in case we need to come back here)

#if 0

    if (cluster_size < 0) {  //unknown size
        const long long payload_pos = pos;  //absolute pos of cluster payload

        for (;;) {  //determine cluster size
            if ((total >= 0) && (pos >= total))
                break;

            if ((segment_stop >= 0) && (pos >= segment_stop))
                break;  //no more clusters

            //Read ID

            if ((pos + 1) > avail)
            {
                len = 1;
                return E_BUFFER_NOT_FULL;
            }

            long long result = GetUIntLength(m_pReader, pos, len);

            if (result < 0)  //error
                return static_cast<long>(result);

            if (result > 0)  //weird
                return E_BUFFER_NOT_FULL;

            if ((segment_stop >= 0) && ((pos + len) > segment_stop))
                return E_FILE_FORMAT_INVALID;

            if ((pos + len) > avail)
                return E_BUFFER_NOT_FULL;

            const long long idpos = pos;
            const long long id = ReadUInt(m_pReader, idpos, len);

            if (id < 0)  //error (or underflow)
                return static_cast<long>(id);

            //This is the distinguished set of ID's we use to determine
            //that we have exhausted the sub-element's inside the cluster
            //whose ID we parsed earlier.

            if (id == 0x0F43B675)  //Cluster ID
                break;

            if (id == 0x0C53BB6B)  //Cues ID
                break;

            switch (id)
            {
                case 0x20:  //BlockGroup
                case 0x23:  //Simple Block
                case 0x67:  //TimeCode
                case 0x2B:  //PrevSize
                    break;

                default:
                    assert(false);
                    break;
            }

            pos += len;  //consume ID (of sub-element)

            //Read Size

            if ((pos + 1) > avail)
            {
                len = 1;
                return E_BUFFER_NOT_FULL;
            }

            result = GetUIntLength(m_pReader, pos, len);

            if (result < 0)  //error
                return static_cast<long>(result);

            if (result > 0)  //weird
                return E_BUFFER_NOT_FULL;

            if ((segment_stop >= 0) && ((pos + len) > segment_stop))
                return E_FILE_FORMAT_INVALID;

            if ((pos + len) > avail)
                return E_BUFFER_NOT_FULL;

            const long long size = ReadUInt(m_pReader, pos, len);

            if (size < 0)  //error
                return static_cast<long>(size);

            pos += len;  //consume size field of element

            //pos now points to start of sub-element's payload

            if (size == 0)  //weird
                continue;

            const long long unknown_size = (1LL << (7 * len)) - 1;

            if (size == unknown_size)
                return E_FILE_FORMAT_INVALID;  //not allowed for sub-elements

            if ((segment_stop >= 0) && ((pos + size) > segment_stop))  //weird
                return E_FILE_FORMAT_INVALID;

            pos += size;  //consume payload of sub-element
            assert((segment_stop < 0) || (pos <= segment_stop));
        }  //determine cluster size

        cluster_size = pos - payload_pos;
        assert(cluster_size >= 0);

        pos = payload_pos;  //reset and re-parse original cluster
    }

    if (m_clusterPreloadCount > 0)
    {
        assert(idx < m_clusterSize);

        Cluster* const pCluster = m_clusters[idx];
        assert(pCluster);
        assert(pCluster->m_index < 0);

        const long long off = pCluster->GetPosition();
        assert(off >= 0);

        if (off == cluster_off)  //preloaded already
            return E_FILE_FORMAT_INVALID;  //subtle
    }

    m_pos = pos + cluster_size;  //consume payload
    assert((segment_stop < 0) || (m_pos <= segment_stop));

    return 2;     //try to find another cluster

#endif
}

long Segment::DoLoadClusterUnknownSize(long long& pos, long& len) {
  assert(m_pos < 0);
  assert(m_pUnknownSize);

#if 0
    assert(m_pUnknownSize->GetElementSize() < 0);  //TODO: verify this

    const long long element_start = m_pUnknownSize->m_element_start;

    pos = -m_pos;
    assert(pos > element_start);

    //We have already consumed the (cluster) ID and size fields.
    //We just need to consume the blocks and other sub-elements
    //of this cluster, until we discover the boundary.

    long long total, avail;

    long status = m_pReader->Length(&total, &avail);

    if (status < 0)  //error
        return status;

    assert((total < 0) || (avail <= total));

    const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;

    long long element_size = -1;

    for (;;) {  //determine cluster size
        if ((total >= 0) && (pos >= total))
        {
            element_size = total - element_start;
            assert(element_size > 0);

            break;
        }

        if ((segment_stop >= 0) && (pos >= segment_stop))
        {
            element_size = segment_stop - element_start;
            assert(element_size > 0);

            break;
        }

        //Read ID

        if ((pos + 1) > avail)
        {
            len = 1;
            return E_BUFFER_NOT_FULL;
        }

        long long result = GetUIntLength(m_pReader, pos, len);

        if (result < 0)  //error
            return static_cast<long>(result);

        if (result > 0)  //weird
            return E_BUFFER_NOT_FULL;

        if ((segment_stop >= 0) && ((pos + len) > segment_stop))
            return E_FILE_FORMAT_INVALID;

        if ((pos + len) > avail)
            return E_BUFFER_NOT_FULL;

        const long long idpos = pos;
        const long long id = ReadUInt(m_pReader, idpos, len);

        if (id < 0)  //error (or underflow)
            return static_cast<long>(id);

        //This is the distinguished set of ID's we use to determine
        //that we have exhausted the sub-element's inside the cluster
        //whose ID we parsed earlier.

        if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) {  //Cluster ID or Cues ID
            element_size = pos - element_start;
            assert(element_size > 0);

            break;
        }

#ifdef _DEBUG
        switch (id)
        {
            case 0x20:  //BlockGroup
            case 0x23:  //Simple Block
            case 0x67:  //TimeCode
            case 0x2B:  //PrevSize
                break;

            default:
                assert(false);
                break;
        }
#endif

        pos += len;  //consume ID (of sub-element)

        //Read Size

        if ((pos + 1) > avail)
        {
            len = 1;
            return E_BUFFER_NOT_FULL;
        }

        result = GetUIntLength(m_pReader, pos, len);

        if (result < 0)  //error
            return static_cast<long>(result);

        if (result > 0)  //weird
            return E_BUFFER_NOT_FULL;

        if ((segment_stop >= 0) && ((pos + len) > segment_stop))
            return E_FILE_FORMAT_INVALID;

        if ((pos + len) > avail)
            return E_BUFFER_NOT_FULL;

        const long long size = ReadUInt(m_pReader, pos, len);

        if (size < 0)  //error
            return static_cast<long>(size);

        pos += len;  //consume size field of element

        //pos now points to start of sub-element's payload

        if (size == 0)  //weird
            continue;

        const long long unknown_size = (1LL << (7 * len)) - 1;

        if (size == unknown_size)
            return E_FILE_FORMAT_INVALID;  //not allowed for sub-elements

        if ((segment_stop >= 0) && ((pos + size) > segment_stop))  //weird
            return E_FILE_FORMAT_INVALID;

        pos += size;  //consume payload of sub-element
        assert((segment_stop < 0) || (pos <= segment_stop));
    }  //determine cluster size

    assert(element_size >= 0);

    m_pos = element_start + element_size;
    m_pUnknownSize = 0;

    return 2;  //continue parsing
#else
  const long status = m_pUnknownSize->Parse(pos, len);

  if (status < 0)  // error or underflow
    return status;

  if (status == 0)  // parsed a block
    return 2;  // continue parsing

  assert(status > 0);  // nothing left to parse of this cluster

  const long long start = m_pUnknownSize->m_element_start;

  const long long size = m_pUnknownSize->GetElementSize();
  assert(size >= 0);

  pos = start + size;
  m_pos = pos;

  m_pUnknownSize = 0;

  return 2;  // continue parsing
#endif
}

void Segment::AppendCluster(Cluster* pCluster) {
  assert(pCluster);
  assert(pCluster->m_index >= 0);

  const long count = m_clusterCount + m_clusterPreloadCount;

  long& size = m_clusterSize;
  assert(size >= count);

  const long idx = pCluster->m_index;
  assert(idx == m_clusterCount);

  if (count >= size) {
    const long n = (size <= 0) ? 2048 : 2 * size;

    Cluster** const qq = new Cluster* [n];
    Cluster** q = qq;

    Cluster** p = m_clusters;
    Cluster** const pp = p + count;

    while (p != pp)
      *q++ = *p++;

    delete[] m_clusters;

    m_clusters = qq;
    size = n;
  }

  if (m_clusterPreloadCount > 0) {
    assert(m_clusters);

    Cluster** const p = m_clusters + m_clusterCount;
    assert(*p);
    assert((*p)->m_index < 0);

    Cluster** q = p + m_clusterPreloadCount;
    assert(q < (m_clusters + size));

    for (;;) {
      Cluster** const qq = q - 1;
      assert((*qq)->m_index < 0);

      *q = *qq;
      q = qq;

      if (q == p)
        break;
    }
  }

  m_clusters[idx] = pCluster;
  ++m_clusterCount;
}

void Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) {
  assert(pCluster);
  assert(pCluster->m_index < 0);
  assert(idx >= m_clusterCount);

  const long count = m_clusterCount + m_clusterPreloadCount;

  long& size = m_clusterSize;
  assert(size >= count);

  if (count >= size) {
    const long n = (size <= 0) ? 2048 : 2 * size;

    Cluster** const qq = new Cluster* [n];
    Cluster** q = qq;

    Cluster** p = m_clusters;
    Cluster** const pp = p + count;

    while (p != pp)
      *q++ = *p++;

    delete[] m_clusters;

    m_clusters = qq;
    size = n;
  }

  assert(m_clusters);

  Cluster** const p = m_clusters + idx;

  Cluster** q = m_clusters + count;
  assert(q >= p);
  assert(q < (m_clusters + size));

  while (q > p) {
    Cluster** const qq = q - 1;
    assert((*qq)->m_index < 0);

    *q = *qq;
    q = qq;
  }

  m_clusters[idx] = pCluster;
  ++m_clusterPreloadCount;
}

long Segment::Load() {
  assert(m_clusters == NULL);
  assert(m_clusterSize == 0);
  assert(m_clusterCount == 0);
  // assert(m_size >= 0);

  // Outermost (level 0) segment object has been constructed,
  // and pos designates start of payload.  We need to find the
  // inner (level 1) elements.

  const long long header_status = ParseHeaders();

  if (header_status < 0)  // error
    return static_cast<long>(header_status);

  if (header_status > 0)  // underflow
    return E_BUFFER_NOT_FULL;

  assert(m_pInfo);
  assert(m_pTracks);

  for (;;) {
    const int status = LoadCluster();

    if (status < 0)  // error
      return status;

    if (status >= 1)  // no more clusters
      return 0;
  }
}

SeekHead::SeekHead(Segment* pSegment, long long start, long long size_,
                   long long element_start, long long element_size)
    : m_pSegment(pSegment),
      m_start(start),
      m_size(size_),
      m_element_start(element_start),
      m_element_size(element_size),
      m_entries(0),
      m_entry_count(0),
      m_void_elements(0),
      m_void_element_count(0) {}

SeekHead::~SeekHead() {
  delete[] m_entries;
  delete[] m_void_elements;
}

long SeekHead::Parse() {
  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long pos = m_start;
  const long long stop = m_start + m_size;

  // first count the seek head entries

  int entry_count = 0;
  int void_element_count = 0;

  while (pos < stop) {
    long long id, size;

    const long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (id == 0x0DBB)  // SeekEntry ID
      ++entry_count;
    else if (id == 0x6C)  // Void ID
      ++void_element_count;

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);

  m_entries = new (std::nothrow) Entry[entry_count];

  if (m_entries == NULL)
    return -1;

  m_void_elements = new (std::nothrow) VoidElement[void_element_count];

  if (m_void_elements == NULL)
    return -1;

  // now parse the entries and void elements

  Entry* pEntry = m_entries;
  VoidElement* pVoidElement = m_void_elements;

  pos = m_start;

  while (pos < stop) {
    const long long idpos = pos;

    long long id, size;

    const long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (id == 0x0DBB) {  // SeekEntry ID
      if (ParseEntry(pReader, pos, size, pEntry)) {
        Entry& e = *pEntry++;

        e.element_start = idpos;
        e.element_size = (pos + size) - idpos;
      }
    } else if (id == 0x6C) {  // Void ID
      VoidElement& e = *pVoidElement++;

      e.element_start = idpos;
      e.element_size = (pos + size) - idpos;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);

  ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries);
  assert(count_ >= 0);
  assert(count_ <= entry_count);

  m_entry_count = static_cast<int>(count_);

  count_ = ptrdiff_t(pVoidElement - m_void_elements);
  assert(count_ >= 0);
  assert(count_ <= void_element_count);

  m_void_element_count = static_cast<int>(count_);

  return 0;
}

int SeekHead::GetCount() const { return m_entry_count; }

const SeekHead::Entry* SeekHead::GetEntry(int idx) const {
  if (idx < 0)
    return 0;

  if (idx >= m_entry_count)
    return 0;

  return m_entries + idx;
}

int SeekHead::GetVoidElementCount() const { return m_void_element_count; }

const SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const {
  if (idx < 0)
    return 0;

  if (idx >= m_void_element_count)
    return 0;

  return m_void_elements + idx;
}

#if 0
void Segment::ParseCues(long long off)
{
    if (m_pCues)
        return;

    //odbgstream os;
    //os << "Segment::ParseCues (begin)" << endl;

    long long pos = m_start + off;
    const long long element_start = pos;
    const long long stop = m_start + m_size;

    long len;

    long long result = GetUIntLength(m_pReader, pos, len);
    assert(result == 0);
    assert((pos + len) <= stop);

    const long long idpos = pos;

    const long long id = ReadUInt(m_pReader, idpos, len);
    assert(id == 0x0C53BB6B);  //Cues ID

    pos += len;  //consume ID
    assert(pos < stop);

    //Read Size

    result = GetUIntLength(m_pReader, pos, len);
    assert(result == 0);
    assert((pos + len) <= stop);

    const long long size = ReadUInt(m_pReader, pos, len);
    assert(size >= 0);

    pos += len;  //consume length of size of element
    assert((pos + size) <= stop);

    const long long element_size = size + pos - element_start;

    //Pos now points to start of payload

    m_pCues = new Cues(this, pos, size, element_start, element_size);
    assert(m_pCues);  //TODO

    //os << "Segment::ParseCues (end)" << endl;
}
#else
long Segment::ParseCues(long long off, long long& pos, long& len) {
  if (m_pCues)
    return 0;  // success

  if (off < 0)
    return -1;

  long long total, avail;

  const int status = m_pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  pos = m_start + off;

  if ((total < 0) || (pos >= total))
    return 1;  // don't bother parsing cues

  const long long element_start = pos;
  const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;

  if ((pos + 1) > avail) {
    len = 1;
    return E_BUFFER_NOT_FULL;
  }

  long long result = GetUIntLength(m_pReader, pos, len);

  if (result < 0)  // error
    return static_cast<long>(result);

  if (result > 0)  // underflow (weird)
  {
    len = 1;
    return E_BUFFER_NOT_FULL;
  }

  if ((segment_stop >= 0) && ((pos + len) > segment_stop))
    return E_FILE_FORMAT_INVALID;

  if ((pos + len) > avail)
    return E_BUFFER_NOT_FULL;

  const long long idpos = pos;

  const long long id = ReadUInt(m_pReader, idpos, len);

  if (id != 0x0C53BB6B)  // Cues ID
    return E_FILE_FORMAT_INVALID;

  pos += len;  // consume ID
  assert((segment_stop < 0) || (pos <= segment_stop));

  // Read Size

  if ((pos + 1) > avail) {
    len = 1;
    return E_BUFFER_NOT_FULL;
  }

  result = GetUIntLength(m_pReader, pos, len);

  if (result < 0)  // error
    return static_cast<long>(result);

  if (result > 0)  // underflow (weird)
  {
    len = 1;
    return E_BUFFER_NOT_FULL;
  }

  if ((segment_stop >= 0) && ((pos + len) > segment_stop))
    return E_FILE_FORMAT_INVALID;

  if ((pos + len) > avail)
    return E_BUFFER_NOT_FULL;

  const long long size = ReadUInt(m_pReader, pos, len);

  if (size < 0)  // error
    return static_cast<long>(size);

  if (size == 0)  // weird, although technically not illegal
    return 1;  // done

  pos += len;  // consume length of size of element
  assert((segment_stop < 0) || (pos <= segment_stop));

  // Pos now points to start of payload

  const long long element_stop = pos + size;

  if ((segment_stop >= 0) && (element_stop > segment_stop))
    return E_FILE_FORMAT_INVALID;

  if ((total >= 0) && (element_stop > total))
    return 1;  // don't bother parsing anymore

  len = static_cast<long>(size);

  if (element_stop > avail)
    return E_BUFFER_NOT_FULL;

  const long long element_size = element_stop - element_start;

  m_pCues =
      new (std::nothrow) Cues(this, pos, size, element_start, element_size);
  assert(m_pCues);  // TODO

  return 0;  // success
}
#endif

#if 0
void Segment::ParseSeekEntry(
    long long start,
    long long size_)
{
    long long pos = start;

    const long long stop = start + size_;

    long len;

    const long long seekIdId = ReadUInt(m_pReader, pos, len);
    //seekIdId;
    assert(seekIdId == 0x13AB);  //SeekID ID
    assert((pos + len) <= stop);

    pos += len;  //consume id

    const long long seekIdSize = ReadUInt(m_pReader, pos, len);
    assert(seekIdSize >= 0);
    assert((pos + len) <= stop);

    pos += len;  //consume size

    const long long seekId = ReadUInt(m_pReader, pos, len);  //payload
    assert(seekId >= 0);
    assert(len == seekIdSize);
    assert((pos + len) <= stop);

    pos += seekIdSize;  //consume payload

    const long long seekPosId = ReadUInt(m_pReader, pos, len);
    //seekPosId;
    assert(seekPosId == 0x13AC);  //SeekPos ID
    assert((pos + len) <= stop);

    pos += len;  //consume id

    const long long seekPosSize = ReadUInt(m_pReader, pos, len);
    assert(seekPosSize >= 0);
    assert((pos + len) <= stop);

    pos += len;  //consume size
    assert((pos + seekPosSize) <= stop);

    const long long seekOff = UnserializeUInt(m_pReader, pos, seekPosSize);
    assert(seekOff >= 0);
    assert(seekOff < m_size);

    pos += seekPosSize;  //consume payload
    assert(pos == stop);

    const long long seekPos = m_start + seekOff;
    assert(seekPos < (m_start + m_size));

    if (seekId == 0x0C53BB6B)  //Cues ID
        ParseCues(seekOff);
}
#else
bool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_,
                          Entry* pEntry) {
  if (size_ <= 0)
    return false;

  long long pos = start;
  const long long stop = start + size_;

  long len;

  // parse the container for the level-1 element ID

  const long long seekIdId = ReadUInt(pReader, pos, len);
  // seekIdId;

  if (seekIdId != 0x13AB)  // SeekID ID
    return false;

  if ((pos + len) > stop)
    return false;

  pos += len;  // consume SeekID id

  const long long seekIdSize = ReadUInt(pReader, pos, len);

  if (seekIdSize <= 0)
    return false;

  if ((pos + len) > stop)
    return false;

  pos += len;  // consume size of field

  if ((pos + seekIdSize) > stop)
    return false;

  // Note that the SeekId payload really is serialized
  // as a "Matroska integer", not as a plain binary value.
  // In fact, Matroska requires that ID values in the
  // stream exactly match the binary representation as listed
  // in the Matroska specification.
  //
  // This parser is more liberal, and permits IDs to have
  // any width.  (This could make the representation in the stream
  // different from what's in the spec, but it doesn't matter here,
  // since we always normalize "Matroska integer" values.)

  pEntry->id = ReadUInt(pReader, pos, len);  // payload

  if (pEntry->id <= 0)
    return false;

  if (len != seekIdSize)
    return false;

  pos += seekIdSize;  // consume SeekID payload

  const long long seekPosId = ReadUInt(pReader, pos, len);

  if (seekPosId != 0x13AC)  // SeekPos ID
    return false;

  if ((pos + len) > stop)
    return false;

  pos += len;  // consume id

  const long long seekPosSize = ReadUInt(pReader, pos, len);

  if (seekPosSize <= 0)
    return false;

  if ((pos + len) > stop)
    return false;

  pos += len;  // consume size

  if ((pos + seekPosSize) > stop)
    return false;

  pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize);

  if (pEntry->pos < 0)
    return false;

  pos += seekPosSize;  // consume payload

  if (pos != stop)
    return false;

  return true;
}
#endif

Cues::Cues(Segment* pSegment, long long start_, long long size_,
           long long element_start, long long element_size)
    : m_pSegment(pSegment),
      m_start(start_),
      m_size(size_),
      m_element_start(element_start),
      m_element_size(element_size),
      m_cue_points(NULL),
      m_count(0),
      m_preload_count(0),
      m_pos(start_) {}

Cues::~Cues() {
  const long n = m_count + m_preload_count;

  CuePoint** p = m_cue_points;
  CuePoint** const q = p + n;

  while (p != q) {
    CuePoint* const pCP = *p++;
    assert(pCP);

    delete pCP;
  }

  delete[] m_cue_points;
}

long Cues::GetCount() const {
  if (m_cue_points == NULL)
    return -1;

  return m_count;  // TODO: really ignore preload count?
}

bool Cues::DoneParsing() const {
  const long long stop = m_start + m_size;
  return (m_pos >= stop);
}

void Cues::Init() const {
  if (m_cue_points)
    return;

  assert(m_count == 0);
  assert(m_preload_count == 0);

  IMkvReader* const pReader = m_pSegment->m_pReader;

  const long long stop = m_start + m_size;
  long long pos = m_start;

  long cue_points_size = 0;

  while (pos < stop) {
    const long long idpos = pos;

    long len;

    const long long id = ReadUInt(pReader, pos, len);
    assert(id >= 0);  // TODO
    assert((pos + len) <= stop);

    pos += len;  // consume ID

    const long long size = ReadUInt(pReader, pos, len);
    assert(size >= 0);
    assert((pos + len) <= stop);

    pos += len;  // consume Size field
    assert((pos + size) <= stop);

    if (id == 0x3B)  // CuePoint ID
      PreloadCuePoint(cue_points_size, idpos);

    pos += size;  // consume payload
    assert(pos <= stop);
  }
}

void Cues::PreloadCuePoint(long& cue_points_size, long long pos) const {
  assert(m_count == 0);

  if (m_preload_count >= cue_points_size) {
    const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size;

    CuePoint** const qq = new CuePoint* [n];
    CuePoint** q = qq;  // beginning of target

    CuePoint** p = m_cue_points;  // beginning of source
    CuePoint** const pp = p + m_preload_count;  // end of source

    while (p != pp)
      *q++ = *p++;

    delete[] m_cue_points;

    m_cue_points = qq;
    cue_points_size = n;
  }

  CuePoint* const pCP = new CuePoint(m_preload_count, pos);
  m_cue_points[m_preload_count++] = pCP;
}

bool Cues::LoadCuePoint() const {
  // odbgstream os;
  // os << "Cues::LoadCuePoint" << endl;

  const long long stop = m_start + m_size;

  if (m_pos >= stop)
    return false;  // nothing else to do

  Init();

  IMkvReader* const pReader = m_pSegment->m_pReader;

  while (m_pos < stop) {
    const long long idpos = m_pos;

    long len;

    const long long id = ReadUInt(pReader, m_pos, len);
    assert(id >= 0);  // TODO
    assert((m_pos + len) <= stop);

    m_pos += len;  // consume ID

    const long long size = ReadUInt(pReader, m_pos, len);
    assert(size >= 0);
    assert((m_pos + len) <= stop);

    m_pos += len;  // consume Size field
    assert((m_pos + size) <= stop);

    if (id != 0x3B) {  // CuePoint ID
      m_pos += size;  // consume payload
      assert(m_pos <= stop);

      continue;
    }

    assert(m_preload_count > 0);

    CuePoint* const pCP = m_cue_points[m_count];
    assert(pCP);
    assert((pCP->GetTimeCode() >= 0) || (-pCP->GetTimeCode() == idpos));
    if (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos))
      return false;

    pCP->Load(pReader);
    ++m_count;
    --m_preload_count;

    m_pos += size;  // consume payload
    assert(m_pos <= stop);

    return true;  // yes, we loaded a cue point
  }

  // return (m_pos < stop);
  return false;  // no, we did not load a cue point
}

bool Cues::Find(long long time_ns, const Track* pTrack, const CuePoint*& pCP,
                const CuePoint::TrackPosition*& pTP) const {
  assert(time_ns >= 0);
  assert(pTrack);

#if 0
    LoadCuePoint();  //establish invariant

    assert(m_cue_points);
    assert(m_count > 0);

    CuePoint** const ii = m_cue_points;
    CuePoint** i = ii;

    CuePoint** const jj = ii + m_count + m_preload_count;
    CuePoint** j = jj;

    pCP = *i;
    assert(pCP);

    if (time_ns <= pCP->GetTime(m_pSegment))
    {
        pTP = pCP->Find(pTrack);
        return (pTP != NULL);
    }

    IMkvReader* const pReader = m_pSegment->m_pReader;

    while (i < j)
    {
        //INVARIANT:
        //[ii, i) <= time_ns
        //[i, j)  ?
        //[j, jj) > time_ns

        CuePoint** const k = i + (j - i) / 2;
        assert(k < jj);

        CuePoint* const pCP = *k;
        assert(pCP);

        pCP->Load(pReader);

        const long long t = pCP->GetTime(m_pSegment);

        if (t <= time_ns)
            i = k + 1;
        else
            j = k;

        assert(i <= j);
    }

    assert(i == j);
    assert(i <= jj);
    assert(i > ii);

    pCP = *--i;
    assert(pCP);
    assert(pCP->GetTime(m_pSegment) <= time_ns);
#else
  if (m_cue_points == NULL)
    return false;

  if (m_count == 0)
    return false;

  CuePoint** const ii = m_cue_points;
  CuePoint** i = ii;

  CuePoint** const jj = ii + m_count;
  CuePoint** j = jj;

  pCP = *i;
  assert(pCP);

  if (time_ns <= pCP->GetTime(m_pSegment)) {
    pTP = pCP->Find(pTrack);
    return (pTP != NULL);
  }

  while (i < j) {
    // INVARIANT:
    //[ii, i) <= time_ns
    //[i, j)  ?
    //[j, jj) > time_ns

    CuePoint** const k = i + (j - i) / 2;
    assert(k < jj);

    CuePoint* const pCP = *k;
    assert(pCP);

    const long long t = pCP->GetTime(m_pSegment);

    if (t <= time_ns)
      i = k + 1;
    else
      j = k;

    assert(i <= j);
  }

  assert(i == j);
  assert(i <= jj);
  assert(i > ii);

  pCP = *--i;
  assert(pCP);
  assert(pCP->GetTime(m_pSegment) <= time_ns);
#endif

  // TODO: here and elsewhere, it's probably not correct to search
  // for the cue point with this time, and then search for a matching
  // track.  In principle, the matching track could be on some earlier
  // cue point, and with our current algorithm, we'd miss it.  To make
  // this bullet-proof, we'd need to create a secondary structure,
  // with a list of cue points that apply to a track, and then search
  // that track-based structure for a matching cue point.

  pTP = pCP->Find(pTrack);
  return (pTP != NULL);
}

#if 0
bool Cues::FindNext(
    long long time_ns,
    const Track* pTrack,
    const CuePoint*& pCP,
    const CuePoint::TrackPosition*& pTP) const
{
    pCP = 0;
    pTP = 0;

    if (m_count == 0)
        return false;

    assert(m_cue_points);

    const CuePoint* const* const ii = m_cue_points;
    const CuePoint* const* i = ii;

    const CuePoint* const* const jj = ii + m_count;
    const CuePoint* const* j = jj;

    while (i < j)
    {
        //INVARIANT:
        //[ii, i) <= time_ns
        //[i, j)  ?
        //[j, jj) > time_ns

        const CuePoint* const* const k = i + (j - i) / 2;
        assert(k < jj);

        pCP = *k;
        assert(pCP);

        const long long t = pCP->GetTime(m_pSegment);

        if (t <= time_ns)
            i = k + 1;
        else
            j = k;

        assert(i <= j);
    }

    assert(i == j);
    assert(i <= jj);

    if (i >= jj)  //time_ns is greater than max cue point
        return false;

    pCP = *i;
    assert(pCP);
    assert(pCP->GetTime(m_pSegment) > time_ns);

    pTP = pCP->Find(pTrack);
    return (pTP != NULL);
}
#endif

const CuePoint* Cues::GetFirst() const {
  if (m_cue_points == NULL)
    return NULL;

  if (m_count == 0)
    return NULL;

#if 0
    LoadCuePoint();  //init cues

    const size_t count = m_count + m_preload_count;

    if (count == 0)  //weird
        return NULL;
#endif

  CuePoint* const* const pp = m_cue_points;
  assert(pp);

  CuePoint* const pCP = pp[0];
  assert(pCP);
  assert(pCP->GetTimeCode() >= 0);

  return pCP;
}

const CuePoint* Cues::GetLast() const {
  if (m_cue_points == NULL)
    return NULL;

  if (m_count <= 0)
    return NULL;

#if 0
    LoadCuePoint();  //init cues

    const size_t count = m_count + m_preload_count;

    if (count == 0)  //weird
        return NULL;

    const size_t index = count - 1;

    CuePoint* const* const pp = m_cue_points;
    assert(pp);

    CuePoint* const pCP = pp[index];
    assert(pCP);

    pCP->Load(m_pSegment->m_pReader);
    assert(pCP->GetTimeCode() >= 0);
#else
  const long index = m_count - 1;

  CuePoint* const* const pp = m_cue_points;
  assert(pp);

  CuePoint* const pCP = pp[index];
  assert(pCP);
  assert(pCP->GetTimeCode() >= 0);
#endif

  return pCP;
}

const CuePoint* Cues::GetNext(const CuePoint* pCurr) const {
  if (pCurr == NULL)
    return NULL;

  assert(pCurr->GetTimeCode() >= 0);
  assert(m_cue_points);
  assert(m_count >= 1);

#if 0
    const size_t count = m_count + m_preload_count;

    size_t index = pCurr->m_index;
    assert(index < count);

    CuePoint* const* const pp = m_cue_points;
    assert(pp);
    assert(pp[index] == pCurr);

    ++index;

    if (index >= count)
        return NULL;

    CuePoint* const pNext = pp[index];
    assert(pNext);

    pNext->Load(m_pSegment->m_pReader);
#else
  long index = pCurr->m_index;
  assert(index < m_count);

  CuePoint* const* const pp = m_cue_points;
  assert(pp);
  assert(pp[index] == pCurr);

  ++index;

  if (index >= m_count)
    return NULL;

  CuePoint* const pNext = pp[index];
  assert(pNext);
  assert(pNext->GetTimeCode() >= 0);
#endif

  return pNext;
}

const BlockEntry* Cues::GetBlock(const CuePoint* pCP,
                                 const CuePoint::TrackPosition* pTP) const {
  if (pCP == NULL)
    return NULL;

  if (pTP == NULL)
    return NULL;

  return m_pSegment->GetBlock(*pCP, *pTP);
}

const BlockEntry* Segment::GetBlock(const CuePoint& cp,
                                    const CuePoint::TrackPosition& tp) {
  Cluster** const ii = m_clusters;
  Cluster** i = ii;

  const long count = m_clusterCount + m_clusterPreloadCount;

  Cluster** const jj = ii + count;
  Cluster** j = jj;

  while (i < j) {
    // INVARIANT:
    //[ii, i) < pTP->m_pos
    //[i, j) ?
    //[j, jj)  > pTP->m_pos

    Cluster** const k = i + (j - i) / 2;
    assert(k < jj);

    Cluster* const pCluster = *k;
    assert(pCluster);

    // const long long pos_ = pCluster->m_pos;
    // assert(pos_);
    // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1);

    const long long pos = pCluster->GetPosition();
    assert(pos >= 0);

    if (pos < tp.m_pos)
      i = k + 1;
    else if (pos > tp.m_pos)
      j = k;
    else
      return pCluster->GetEntry(cp, tp);
  }

  assert(i == j);
  // assert(Cluster::HasBlockEntries(this, tp.m_pos));

  Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos);  //, -1);
  assert(pCluster);

  const ptrdiff_t idx = i - m_clusters;

  PreloadCluster(pCluster, idx);
  assert(m_clusters);
  assert(m_clusterPreloadCount > 0);
  assert(m_clusters[idx] == pCluster);

  return pCluster->GetEntry(cp, tp);
}

const Cluster* Segment::FindOrPreloadCluster(long long requested_pos) {
  if (requested_pos < 0)
    return 0;

  Cluster** const ii = m_clusters;
  Cluster** i = ii;

  const long count = m_clusterCount + m_clusterPreloadCount;

  Cluster** const jj = ii + count;
  Cluster** j = jj;

  while (i < j) {
    // INVARIANT:
    //[ii, i) < pTP->m_pos
    //[i, j) ?
    //[j, jj)  > pTP->m_pos

    Cluster** const k = i + (j - i) / 2;
    assert(k < jj);

    Cluster* const pCluster = *k;
    assert(pCluster);

    // const long long pos_ = pCluster->m_pos;
    // assert(pos_);
    // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1);

    const long long pos = pCluster->GetPosition();
    assert(pos >= 0);

    if (pos < requested_pos)
      i = k + 1;
    else if (pos > requested_pos)
      j = k;
    else
      return pCluster;
  }

  assert(i == j);
  // assert(Cluster::HasBlockEntries(this, tp.m_pos));

  Cluster* const pCluster = Cluster::Create(this, -1, requested_pos);
  //-1);
  assert(pCluster);

  const ptrdiff_t idx = i - m_clusters;

  PreloadCluster(pCluster, idx);
  assert(m_clusters);
  assert(m_clusterPreloadCount > 0);
  assert(m_clusters[idx] == pCluster);

  return pCluster;
}

CuePoint::CuePoint(long idx, long long pos)
    : m_element_start(0),
      m_element_size(0),
      m_index(idx),
      m_timecode(-1 * pos),
      m_track_positions(NULL),
      m_track_positions_count(0) {
  assert(pos > 0);
}

CuePoint::~CuePoint() { delete[] m_track_positions; }

void CuePoint::Load(IMkvReader* pReader) {
  // odbgstream os;
  // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl;

  if (m_timecode >= 0)  // already loaded
    return;

  assert(m_track_positions == NULL);
  assert(m_track_positions_count == 0);

  long long pos_ = -m_timecode;
  const long long element_start = pos_;

  long long stop;

  {
    long len;

    const long long id = ReadUInt(pReader, pos_, len);
    assert(id == 0x3B);  // CuePoint ID
    if (id != 0x3B)
      return;

    pos_ += len;  // consume ID

    const long long size = ReadUInt(pReader, pos_, len);
    assert(size >= 0);

    pos_ += len;  // consume Size field
    // pos_ now points to start of payload

    stop = pos_ + size;
  }

  const long long element_size = stop - element_start;

  long long pos = pos_;

  // First count number of track positions

  while (pos < stop) {
    long len;

    const long long id = ReadUInt(pReader, pos, len);
    assert(id >= 0);  // TODO
    assert((pos + len) <= stop);

    pos += len;  // consume ID

    const long long size = ReadUInt(pReader, pos, len);
    assert(size >= 0);
    assert((pos + len) <= stop);

    pos += len;  // consume Size field
    assert((pos + size) <= stop);

    if (id == 0x33)  // CueTime ID
      m_timecode = UnserializeUInt(pReader, pos, size);

    else if (id == 0x37)  // CueTrackPosition(s) ID
      ++m_track_positions_count;

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(m_timecode >= 0);
  assert(m_track_positions_count > 0);

  // os << "CuePoint::Load(cont'd): idpos=" << idpos
  //   << " timecode=" << m_timecode
  //   << endl;

  m_track_positions = new TrackPosition[m_track_positions_count];

  // Now parse track positions

  TrackPosition* p = m_track_positions;
  pos = pos_;

  while (pos < stop) {
    long len;

    const long long id = ReadUInt(pReader, pos, len);
    assert(id >= 0);  // TODO
    assert((pos + len) <= stop);

    pos += len;  // consume ID

    const long long size = ReadUInt(pReader, pos, len);
    assert(size >= 0);
    assert((pos + len) <= stop);

    pos += len;  // consume Size field
    assert((pos + size) <= stop);

    if (id == 0x37) {  // CueTrackPosition(s) ID
      TrackPosition& tp = *p++;
      tp.Parse(pReader, pos, size);
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(size_t(p - m_track_positions) == m_track_positions_count);

  m_element_start = element_start;
  m_element_size = element_size;
}

void CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_,
                                    long long size_) {
  const long long stop = start_ + size_;
  long long pos = start_;

  m_track = -1;
  m_pos = -1;
  m_block = 1;  // default

  while (pos < stop) {
    long len;

    const long long id = ReadUInt(pReader, pos, len);
    assert(id >= 0);  // TODO
    assert((pos + len) <= stop);

    pos += len;  // consume ID

    const long long size = ReadUInt(pReader, pos, len);
    assert(size >= 0);
    assert((pos + len) <= stop);

    pos += len;  // consume Size field
    assert((pos + size) <= stop);

    if (id == 0x77)  // CueTrack ID
      m_track = UnserializeUInt(pReader, pos, size);

    else if (id == 0x71)  // CueClusterPos ID
      m_pos = UnserializeUInt(pReader, pos, size);

    else if (id == 0x1378)  // CueBlockNumber
      m_block = UnserializeUInt(pReader, pos, size);

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(m_pos >= 0);
  assert(m_track > 0);
  // assert(m_block > 0);
}

const CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const {
  assert(pTrack);

  const long long n = pTrack->GetNumber();

  const TrackPosition* i = m_track_positions;
  const TrackPosition* const j = i + m_track_positions_count;

  while (i != j) {
    const TrackPosition& p = *i++;

    if (p.m_track == n)
      return &p;
  }

  return NULL;  // no matching track number found
}

long long CuePoint::GetTimeCode() const { return m_timecode; }

long long CuePoint::GetTime(const Segment* pSegment) const {
  assert(pSegment);
  assert(m_timecode >= 0);

  const SegmentInfo* const pInfo = pSegment->GetInfo();
  assert(pInfo);

  const long long scale = pInfo->GetTimeCodeScale();
  assert(scale >= 1);

  const long long time = scale * m_timecode;

  return time;
}

#if 0
long long Segment::Unparsed() const
{
    if (m_size < 0)
        return LLONG_MAX;

    const long long stop = m_start + m_size;

    const long long result = stop - m_pos;
    assert(result >= 0);

    return result;
}
#else
bool Segment::DoneParsing() const {
  if (m_size < 0) {
    long long total, avail;

    const int status = m_pReader->Length(&total, &avail);

    if (status < 0)  // error
      return true;  // must assume done

    if (total < 0)
      return false;  // assume live stream

    return (m_pos >= total);
  }

  const long long stop = m_start + m_size;

  return (m_pos >= stop);
}
#endif

const Cluster* Segment::GetFirst() const {
  if ((m_clusters == NULL) || (m_clusterCount <= 0))
    return &m_eos;

  Cluster* const pCluster = m_clusters[0];
  assert(pCluster);

  return pCluster;
}

const Cluster* Segment::GetLast() const {
  if ((m_clusters == NULL) || (m_clusterCount <= 0))
    return &m_eos;

  const long idx = m_clusterCount - 1;

  Cluster* const pCluster = m_clusters[idx];
  assert(pCluster);

  return pCluster;
}

unsigned long Segment::GetCount() const { return m_clusterCount; }

const Cluster* Segment::GetNext(const Cluster* pCurr) {
  assert(pCurr);
  assert(pCurr != &m_eos);
  assert(m_clusters);

  long idx = pCurr->m_index;

  if (idx >= 0) {
    assert(m_clusterCount > 0);
    assert(idx < m_clusterCount);
    assert(pCurr == m_clusters[idx]);

    ++idx;

    if (idx >= m_clusterCount)
      return &m_eos;  // caller will LoadCluster as desired

    Cluster* const pNext = m_clusters[idx];
    assert(pNext);
    assert(pNext->m_index >= 0);
    assert(pNext->m_index == idx);

    return pNext;
  }

  assert(m_clusterPreloadCount > 0);

  long long pos = pCurr->m_element_start;

  assert(m_size >= 0);  // TODO
  const long long stop = m_start + m_size;  // end of segment

  {
    long len;

    long long result = GetUIntLength(m_pReader, pos, len);
    assert(result == 0);
    assert((pos + len) <= stop);  // TODO
    if (result != 0)
      return NULL;

    const long long id = ReadUInt(m_pReader, pos, len);
    assert(id == 0x0F43B675);  // Cluster ID
    if (id != 0x0F43B675)
      return NULL;

    pos += len;  // consume ID

    // Read Size
    result = GetUIntLength(m_pReader, pos, len);
    assert(result == 0);  // TODO
    assert((pos + len) <= stop);  // TODO

    const long long size = ReadUInt(m_pReader, pos, len);
    assert(size > 0);  // TODO
    // assert((pCurr->m_size <= 0) || (pCurr->m_size == size));

    pos += len;  // consume length of size of element
    assert((pos + size) <= stop);  // TODO

    // Pos now points to start of payload

    pos += size;  // consume payload
  }

  long long off_next = 0;

  while (pos < stop) {
    long len;

    long long result = GetUIntLength(m_pReader, pos, len);
    assert(result == 0);
    assert((pos + len) <= stop);  // TODO
    if (result != 0)
      return NULL;

    const long long idpos = pos;  // pos of next (potential) cluster

    const long long id = ReadUInt(m_pReader, idpos, len);
    assert(id > 0);  // TODO

    pos += len;  // consume ID

    // Read Size
    result = GetUIntLength(m_pReader, pos, len);
    assert(result == 0);  // TODO
    assert((pos + len) <= stop);  // TODO

    const long long size = ReadUInt(m_pReader, pos, len);
    assert(size >= 0);  // TODO

    pos += len;  // consume length of size of element
    assert((pos + size) <= stop);  // TODO

    // Pos now points to start of payload

    if (size == 0)  // weird
      continue;

    if (id == 0x0F43B675) {  // Cluster ID
      const long long off_next_ = idpos - m_start;

      long long pos_;
      long len_;

      const long status = Cluster::HasBlockEntries(this, off_next_, pos_, len_);

      assert(status >= 0);

      if (status > 0) {
        off_next = off_next_;
        break;
      }
    }

    pos += size;  // consume payload
  }

  if (off_next <= 0)
    return 0;

  Cluster** const ii = m_clusters + m_clusterCount;
  Cluster** i = ii;

  Cluster** const jj = ii + m_clusterPreloadCount;
  Cluster** j = jj;

  while (i < j) {
    // INVARIANT:
    //[0, i) < pos_next
    //[i, j) ?
    //[j, jj)  > pos_next

    Cluster** const k = i + (j - i) / 2;
    assert(k < jj);

    Cluster* const pNext = *k;
    assert(pNext);
    assert(pNext->m_index < 0);

    // const long long pos_ = pNext->m_pos;
    // assert(pos_);
    // pos = pos_ * ((pos_ < 0) ? -1 : 1);

    pos = pNext->GetPosition();

    if (pos < off_next)
      i = k + 1;
    else if (pos > off_next)
      j = k;
    else
      return pNext;
  }

  assert(i == j);

  Cluster* const pNext = Cluster::Create(this, -1, off_next);
  assert(pNext);

  const ptrdiff_t idx_next = i - m_clusters;  // insertion position

  PreloadCluster(pNext, idx_next);
  assert(m_clusters);
  assert(idx_next < m_clusterSize);
  assert(m_clusters[idx_next] == pNext);

  return pNext;
}

long Segment::ParseNext(const Cluster* pCurr, const Cluster*& pResult,
                        long long& pos, long& len) {
  assert(pCurr);
  assert(!pCurr->EOS());
  assert(m_clusters);

  pResult = 0;

  if (pCurr->m_index >= 0) {  // loaded (not merely preloaded)
    assert(m_clusters[pCurr->m_index] == pCurr);

    const long next_idx = pCurr->m_index + 1;

    if (next_idx < m_clusterCount) {
      pResult = m_clusters[next_idx];
      return 0;  // success
    }

    // curr cluster is last among loaded

    const long result = LoadCluster(pos, len);

    if (result < 0)  // error or underflow
      return result;

    if (result > 0)  // no more clusters
    {
      // pResult = &m_eos;
      return 1;
    }

    pResult = GetLast();
    return 0;  // success
  }

  assert(m_pos > 0);

  long long total, avail;

  long status = m_pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;

  // interrogate curr cluster

  pos = pCurr->m_element_start;

  if (pCurr->m_element_size >= 0)
    pos += pCurr->m_element_size;
  else {
    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long id = ReadUInt(m_pReader, pos, len);

    if (id != 0x0F43B675)  // weird: not Cluster ID
      return -1;

    pos += len;  // consume ID

    // Read Size

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(m_pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    pos += len;  // consume size field

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (size == unknown_size)  // TODO: should never happen
      return E_FILE_FORMAT_INVALID;  // TODO: resolve this

    // assert((pCurr->m_size <= 0) || (pCurr->m_size == size));

    if ((segment_stop >= 0) && ((pos + size) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    // Pos now points to start of payload

    pos += size;  // consume payload (that is, the current cluster)
    assert((segment_stop < 0) || (pos <= segment_stop));

    // By consuming the payload, we are assuming that the curr
    // cluster isn't interesting.  That is, we don't bother checking
    // whether the payload of the curr cluster is less than what
    // happens to be available (obtained via IMkvReader::Length).
    // Presumably the caller has already dispensed with the current
    // cluster, and really does want the next cluster.
  }

  // pos now points to just beyond the last fully-loaded cluster

  for (;;) {
    const long status = DoParseNext(pResult, pos, len);

    if (status <= 1)
      return status;
  }
}

long Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) {
  long long total, avail;

  long status = m_pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;

  // Parse next cluster.  This is strictly a parsing activity.
  // Creation of a new cluster object happens later, after the
  // parsing is done.

  long long off_next = 0;
  long long cluster_size = -1;

  for (;;) {
    if ((total >= 0) && (pos >= total))
      return 1;  // EOF

    if ((segment_stop >= 0) && (pos >= segment_stop))
      return 1;  // EOF

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long idpos = pos;  // absolute
    const long long idoff = pos - m_start;  // relative

    const long long id = ReadUInt(m_pReader, idpos, len);  // absolute

    if (id < 0)  // error
      return static_cast<long>(id);

    if (id == 0)  // weird
      return -1;  // generic error

    pos += len;  // consume ID

    // Read Size

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(m_pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(m_pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    pos += len;  // consume length of size of element

    // Pos now points to start of payload

    if (size == 0)  // weird
      continue;

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if ((segment_stop >= 0) && (size != unknown_size) &&
        ((pos + size) > segment_stop)) {
      return E_FILE_FORMAT_INVALID;
    }

    if (id == 0x0C53BB6B) {  // Cues ID
      if (size == unknown_size)
        return E_FILE_FORMAT_INVALID;

      const long long element_stop = pos + size;

      if ((segment_stop >= 0) && (element_stop > segment_stop))
        return E_FILE_FORMAT_INVALID;

      const long long element_start = idpos;
      const long long element_size = element_stop - element_start;

      if (m_pCues == NULL) {
        m_pCues = new Cues(this, pos, size, element_start, element_size);
        assert(m_pCues);  // TODO
      }

      pos += size;  // consume payload
      assert((segment_stop < 0) || (pos <= segment_stop));

      continue;
    }

    if (id != 0x0F43B675) {  // not a Cluster ID
      if (size == unknown_size)
        return E_FILE_FORMAT_INVALID;

      pos += size;  // consume payload
      assert((segment_stop < 0) || (pos <= segment_stop));

      continue;
    }

#if 0  // this is commented-out to support incremental cluster parsing
        len = static_cast<long>(size);

        if (element_stop > avail)
            return E_BUFFER_NOT_FULL;
#endif

    // We have a cluster.

    off_next = idoff;

    if (size != unknown_size)
      cluster_size = size;

    break;
  }

  assert(off_next > 0);  // have cluster

  // We have parsed the next cluster.
  // We have not created a cluster object yet.  What we need
  // to do now is determine whether it has already be preloaded
  //(in which case, an object for this cluster has already been
  // created), and if not, create a new cluster object.

  Cluster** const ii = m_clusters + m_clusterCount;
  Cluster** i = ii;

  Cluster** const jj = ii + m_clusterPreloadCount;
  Cluster** j = jj;

  while (i < j) {
    // INVARIANT:
    //[0, i) < pos_next
    //[i, j) ?
    //[j, jj)  > pos_next

    Cluster** const k = i + (j - i) / 2;
    assert(k < jj);

    const Cluster* const pNext = *k;
    assert(pNext);
    assert(pNext->m_index < 0);

    pos = pNext->GetPosition();
    assert(pos >= 0);

    if (pos < off_next)
      i = k + 1;
    else if (pos > off_next)
      j = k;
    else {
      pResult = pNext;
      return 0;  // success
    }
  }

  assert(i == j);

  long long pos_;
  long len_;

  status = Cluster::HasBlockEntries(this, off_next, pos_, len_);

  if (status < 0) {  // error or underflow
    pos = pos_;
    len = len_;

    return status;
  }

  if (status > 0) {  // means "found at least one block entry"
    Cluster* const pNext = Cluster::Create(this,
                                           -1,  // preloaded
                                           off_next);
    // element_size);
    assert(pNext);

    const ptrdiff_t idx_next = i - m_clusters;  // insertion position

    PreloadCluster(pNext, idx_next);
    assert(m_clusters);
    assert(idx_next < m_clusterSize);
    assert(m_clusters[idx_next] == pNext);

    pResult = pNext;
    return 0;  // success
  }

  // status == 0 means "no block entries found"

  if (cluster_size < 0) {  // unknown size
    const long long payload_pos = pos;  // absolute pos of cluster payload

    for (;;) {  // determine cluster size
      if ((total >= 0) && (pos >= total))
        break;

      if ((segment_stop >= 0) && (pos >= segment_stop))
        break;  // no more clusters

      // Read ID

      if ((pos + 1) > avail) {
        len = 1;
        return E_BUFFER_NOT_FULL;
      }

      long long result = GetUIntLength(m_pReader, pos, len);

      if (result < 0)  // error
        return static_cast<long>(result);

      if (result > 0)  // weird
        return E_BUFFER_NOT_FULL;

      if ((segment_stop >= 0) && ((pos + len) > segment_stop))
        return E_FILE_FORMAT_INVALID;

      if ((pos + len) > avail)
        return E_BUFFER_NOT_FULL;

      const long long idpos = pos;
      const long long id = ReadUInt(m_pReader, idpos, len);

      if (id < 0)  // error (or underflow)
        return static_cast<long>(id);

      // This is the distinguished set of ID's we use to determine
      // that we have exhausted the sub-element's inside the cluster
      // whose ID we parsed earlier.

      if (id == 0x0F43B675)  // Cluster ID
        break;

      if (id == 0x0C53BB6B)  // Cues ID
        break;

      pos += len;  // consume ID (of sub-element)

      // Read Size

      if ((pos + 1) > avail) {
        len = 1;
        return E_BUFFER_NOT_FULL;
      }

      result = GetUIntLength(m_pReader, pos, len);

      if (result < 0)  // error
        return static_cast<long>(result);

      if (result > 0)  // weird
        return E_BUFFER_NOT_FULL;

      if ((segment_stop >= 0) && ((pos + len) > segment_stop))
        return E_FILE_FORMAT_INVALID;

      if ((pos + len) > avail)
        return E_BUFFER_NOT_FULL;

      const long long size = ReadUInt(m_pReader, pos, len);

      if (size < 0)  // error
        return static_cast<long>(size);

      pos += len;  // consume size field of element

      // pos now points to start of sub-element's payload

      if (size == 0)  // weird
        continue;

      const long long unknown_size = (1LL << (7 * len)) - 1;

      if (size == unknown_size)
        return E_FILE_FORMAT_INVALID;  // not allowed for sub-elements

      if ((segment_stop >= 0) && ((pos + size) > segment_stop))  // weird
        return E_FILE_FORMAT_INVALID;

      pos += size;  // consume payload of sub-element
      assert((segment_stop < 0) || (pos <= segment_stop));
    }  // determine cluster size

    cluster_size = pos - payload_pos;
    assert(cluster_size >= 0);  // TODO: handle cluster_size = 0

    pos = payload_pos;  // reset and re-parse original cluster
  }

  pos += cluster_size;  // consume payload
  assert((segment_stop < 0) || (pos <= segment_stop));

  return 2;  // try to find a cluster that follows next
}

const Cluster* Segment::FindCluster(long long time_ns) const {
  if ((m_clusters == NULL) || (m_clusterCount <= 0))
    return &m_eos;

  {
    Cluster* const pCluster = m_clusters[0];
    assert(pCluster);
    assert(pCluster->m_index == 0);

    if (time_ns <= pCluster->GetTime())
      return pCluster;
  }

  // Binary search of cluster array

  long i = 0;
  long j = m_clusterCount;

  while (i < j) {
    // INVARIANT:
    //[0, i) <= time_ns
    //[i, j) ?
    //[j, m_clusterCount)  > time_ns

    const long k = i + (j - i) / 2;
    assert(k < m_clusterCount);

    Cluster* const pCluster = m_clusters[k];
    assert(pCluster);
    assert(pCluster->m_index == k);

    const long long t = pCluster->GetTime();

    if (t <= time_ns)
      i = k + 1;
    else
      j = k;

    assert(i <= j);
  }

  assert(i == j);
  assert(i > 0);
  assert(i <= m_clusterCount);

  const long k = i - 1;

  Cluster* const pCluster = m_clusters[k];
  assert(pCluster);
  assert(pCluster->m_index == k);
  assert(pCluster->GetTime() <= time_ns);

  return pCluster;
}

#if 0
const BlockEntry* Segment::Seek(
    long long time_ns,
    const Track* pTrack) const
{
    assert(pTrack);

    if ((m_clusters == NULL) || (m_clusterCount <= 0))
        return pTrack->GetEOS();

    Cluster** const i = m_clusters;
    assert(i);

    {
        Cluster* const pCluster = *i;
        assert(pCluster);
        assert(pCluster->m_index == 0);  //m_clusterCount > 0
        assert(pCluster->m_pSegment == this);

        if (time_ns <= pCluster->GetTime())
            return pCluster->GetEntry(pTrack);
    }

    Cluster** const j = i + m_clusterCount;

    if (pTrack->GetType() == 2) {  //audio
        //TODO: we could decide to use cues for this, as we do for video.
        //But we only use it for video because looking around for a keyframe
        //can get expensive.  Audio doesn't require anything special so a
        //straight cluster search is good enough (we assume).

        Cluster** lo = i;
        Cluster** hi = j;

        while (lo < hi)
        {
            //INVARIANT:
            //[i, lo) <= time_ns
            //[lo, hi) ?
            //[hi, j)  > time_ns

            Cluster** const mid = lo + (hi - lo) / 2;
            assert(mid < hi);

            Cluster* const pCluster = *mid;
            assert(pCluster);
            assert(pCluster->m_index == long(mid - m_clusters));
            assert(pCluster->m_pSegment == this);

            const long long t = pCluster->GetTime();

            if (t <= time_ns)
                lo = mid + 1;
            else
                hi = mid;

            assert(lo <= hi);
        }

        assert(lo == hi);
        assert(lo > i);
        assert(lo <= j);

        while (lo > i)
        {
            Cluster* const pCluster = *--lo;
            assert(pCluster);
            assert(pCluster->GetTime() <= time_ns);

            const BlockEntry* const pBE = pCluster->GetEntry(pTrack);

            if ((pBE != 0) && !pBE->EOS())
                return pBE;

            //landed on empty cluster (no entries)
        }

        return pTrack->GetEOS();  //weird
    }

    assert(pTrack->GetType() == 1);  //video

    Cluster** lo = i;
    Cluster** hi = j;

    while (lo < hi)
    {
        //INVARIANT:
        //[i, lo) <= time_ns
        //[lo, hi) ?
        //[hi, j)  > time_ns

        Cluster** const mid = lo + (hi - lo) / 2;
        assert(mid < hi);

        Cluster* const pCluster = *mid;
        assert(pCluster);

        const long long t = pCluster->GetTime();

        if (t <= time_ns)
            lo = mid + 1;
        else
            hi = mid;

        assert(lo <= hi);
    }

    assert(lo == hi);
    assert(lo > i);
    assert(lo <= j);

    Cluster* pCluster = *--lo;
    assert(pCluster);
    assert(pCluster->GetTime() <= time_ns);

    {
        const BlockEntry* const pBE = pCluster->GetEntry(pTrack, time_ns);

        if ((pBE != 0) && !pBE->EOS())  //found a keyframe
            return pBE;
    }

    const VideoTrack* const pVideo = static_cast<const VideoTrack*>(pTrack);

    while (lo != i)
    {
        pCluster = *--lo;
        assert(pCluster);
        assert(pCluster->GetTime() <= time_ns);

        const BlockEntry* const pBlockEntry = pCluster->GetMaxKey(pVideo);

        if ((pBlockEntry != 0) && !pBlockEntry->EOS())
            return pBlockEntry;
    }

    //weird: we're on the first cluster, but no keyframe found
    //should never happen but we must return something anyway

    return pTrack->GetEOS();
}
#endif

#if 0
bool Segment::SearchCues(
    long long time_ns,
    Track* pTrack,
    Cluster*& pCluster,
    const BlockEntry*& pBlockEntry,
    const CuePoint*& pCP,
    const CuePoint::TrackPosition*& pTP)
{
    if (pTrack->GetType() != 1)  //not video
        return false;  //TODO: for now, just handle video stream

    if (m_pCues == NULL)
        return false;

    if (!m_pCues->Find(time_ns, pTrack, pCP, pTP))
        return false;  //weird

    assert(pCP);
    assert(pTP);
    assert(pTP->m_track == pTrack->GetNumber());

    //We have the cue point and track position we want,
    //so we now need to search for the cluster having
    //the indicated position.

    return GetCluster(pCP, pTP, pCluster, pBlockEntry);
}
#endif

const Tracks* Segment::GetTracks() const { return m_pTracks; }

const SegmentInfo* Segment::GetInfo() const { return m_pInfo; }

const Cues* Segment::GetCues() const { return m_pCues; }

const Chapters* Segment::GetChapters() const { return m_pChapters; }

const SeekHead* Segment::GetSeekHead() const { return m_pSeekHead; }

long long Segment::GetDuration() const {
  assert(m_pInfo);
  return m_pInfo->GetDuration();
}

Chapters::Chapters(Segment* pSegment, long long payload_start,
                   long long payload_size, long long element_start,
                   long long element_size)
    : m_pSegment(pSegment),
      m_start(payload_start),
      m_size(payload_size),
      m_element_start(element_start),
      m_element_size(element_size),
      m_editions(NULL),
      m_editions_size(0),
      m_editions_count(0) {}

Chapters::~Chapters() {
  while (m_editions_count > 0) {
    Edition& e = m_editions[--m_editions_count];
    e.Clear();
  }
}

long Chapters::Parse() {
  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long pos = m_start;  // payload start
  const long long stop = pos + m_size;  // payload stop

  while (pos < stop) {
    long long id, size;

    long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (size == 0)  // weird
      continue;

    if (id == 0x05B9) {  // EditionEntry ID
      status = ParseEdition(pos, size);

      if (status < 0)  // error
        return status;
    }

    pos += size;
    assert(pos <= stop);
  }

  assert(pos == stop);
  return 0;
}

int Chapters::GetEditionCount() const { return m_editions_count; }

const Chapters::Edition* Chapters::GetEdition(int idx) const {
  if (idx < 0)
    return NULL;

  if (idx >= m_editions_count)
    return NULL;

  return m_editions + idx;
}

bool Chapters::ExpandEditionsArray() {
  if (m_editions_size > m_editions_count)
    return true;  // nothing else to do

  const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size;

  Edition* const editions = new (std::nothrow) Edition[size];

  if (editions == NULL)
    return false;

  for (int idx = 0; idx < m_editions_count; ++idx) {
    m_editions[idx].ShallowCopy(editions[idx]);
  }

  delete[] m_editions;
  m_editions = editions;

  m_editions_size = size;
  return true;
}

long Chapters::ParseEdition(long long pos, long long size) {
  if (!ExpandEditionsArray())
    return -1;

  Edition& e = m_editions[m_editions_count++];
  e.Init();

  return e.Parse(m_pSegment->m_pReader, pos, size);
}

Chapters::Edition::Edition() {}

Chapters::Edition::~Edition() {}

int Chapters::Edition::GetAtomCount() const { return m_atoms_count; }

const Chapters::Atom* Chapters::Edition::GetAtom(int index) const {
  if (index < 0)
    return NULL;

  if (index >= m_atoms_count)
    return NULL;

  return m_atoms + index;
}

void Chapters::Edition::Init() {
  m_atoms = NULL;
  m_atoms_size = 0;
  m_atoms_count = 0;
}

void Chapters::Edition::ShallowCopy(Edition& rhs) const {
  rhs.m_atoms = m_atoms;
  rhs.m_atoms_size = m_atoms_size;
  rhs.m_atoms_count = m_atoms_count;
}

void Chapters::Edition::Clear() {
  while (m_atoms_count > 0) {
    Atom& a = m_atoms[--m_atoms_count];
    a.Clear();
  }

  delete[] m_atoms;
  m_atoms = NULL;

  m_atoms_size = 0;
}

long Chapters::Edition::Parse(IMkvReader* pReader, long long pos,
                              long long size) {
  const long long stop = pos + size;

  while (pos < stop) {
    long long id, size;

    long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (size == 0)  // weird
      continue;

    if (id == 0x36) {  // Atom ID
      status = ParseAtom(pReader, pos, size);

      if (status < 0)  // error
        return status;
    }

    pos += size;
    assert(pos <= stop);
  }

  assert(pos == stop);
  return 0;
}

long Chapters::Edition::ParseAtom(IMkvReader* pReader, long long pos,
                                  long long size) {
  if (!ExpandAtomsArray())
    return -1;

  Atom& a = m_atoms[m_atoms_count++];
  a.Init();

  return a.Parse(pReader, pos, size);
}

bool Chapters::Edition::ExpandAtomsArray() {
  if (m_atoms_size > m_atoms_count)
    return true;  // nothing else to do

  const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size;

  Atom* const atoms = new (std::nothrow) Atom[size];

  if (atoms == NULL)
    return false;

  for (int idx = 0; idx < m_atoms_count; ++idx) {
    m_atoms[idx].ShallowCopy(atoms[idx]);
  }

  delete[] m_atoms;
  m_atoms = atoms;

  m_atoms_size = size;
  return true;
}

Chapters::Atom::Atom() {}

Chapters::Atom::~Atom() {}

unsigned long long Chapters::Atom::GetUID() const { return m_uid; }

const char* Chapters::Atom::GetStringUID() const { return m_string_uid; }

long long Chapters::Atom::GetStartTimecode() const { return m_start_timecode; }

long long Chapters::Atom::GetStopTimecode() const { return m_stop_timecode; }

long long Chapters::Atom::GetStartTime(const Chapters* pChapters) const {
  return GetTime(pChapters, m_start_timecode);
}

long long Chapters::Atom::GetStopTime(const Chapters* pChapters) const {
  return GetTime(pChapters, m_stop_timecode);
}

int Chapters::Atom::GetDisplayCount() const { return m_displays_count; }

const Chapters::Display* Chapters::Atom::GetDisplay(int index) const {
  if (index < 0)
    return NULL;

  if (index >= m_displays_count)
    return NULL;

  return m_displays + index;
}

void Chapters::Atom::Init() {
  m_string_uid = NULL;
  m_uid = 0;
  m_start_timecode = -1;
  m_stop_timecode = -1;

  m_displays = NULL;
  m_displays_size = 0;
  m_displays_count = 0;
}

void Chapters::Atom::ShallowCopy(Atom& rhs) const {
  rhs.m_string_uid = m_string_uid;
  rhs.m_uid = m_uid;
  rhs.m_start_timecode = m_start_timecode;
  rhs.m_stop_timecode = m_stop_timecode;

  rhs.m_displays = m_displays;
  rhs.m_displays_size = m_displays_size;
  rhs.m_displays_count = m_displays_count;
}

void Chapters::Atom::Clear() {
  delete[] m_string_uid;
  m_string_uid = NULL;

  while (m_displays_count > 0) {
    Display& d = m_displays[--m_displays_count];
    d.Clear();
  }

  delete[] m_displays;
  m_displays = NULL;

  m_displays_size = 0;
}

long Chapters::Atom::Parse(IMkvReader* pReader, long long pos, long long size) {
  const long long stop = pos + size;

  while (pos < stop) {
    long long id, size;

    long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (size == 0)  // weird
      continue;

    if (id == 0x00) {  // Display ID
      status = ParseDisplay(pReader, pos, size);

      if (status < 0)  // error
        return status;
    } else if (id == 0x1654) {  // StringUID ID
      status = UnserializeString(pReader, pos, size, m_string_uid);

      if (status < 0)  // error
        return status;
    } else if (id == 0x33C4) {  // UID ID
      long long val;
      status = UnserializeInt(pReader, pos, size, val);

      if (val < 0)  // error
        return status;

      m_uid = static_cast<unsigned long long>(val);
    } else if (id == 0x11) {  // TimeStart ID
      const long long val = UnserializeUInt(pReader, pos, size);

      if (val < 0)  // error
        return static_cast<long>(val);

      m_start_timecode = val;
    } else if (id == 0x12) {  // TimeEnd ID
      const long long val = UnserializeUInt(pReader, pos, size);

      if (val < 0)  // error
        return static_cast<long>(val);

      m_stop_timecode = val;
    }

    pos += size;
    assert(pos <= stop);
  }

  assert(pos == stop);
  return 0;
}

long long Chapters::Atom::GetTime(const Chapters* pChapters,
                                  long long timecode) {
  if (pChapters == NULL)
    return -1;

  Segment* const pSegment = pChapters->m_pSegment;

  if (pSegment == NULL)  // weird
    return -1;

  const SegmentInfo* const pInfo = pSegment->GetInfo();

  if (pInfo == NULL)
    return -1;

  const long long timecode_scale = pInfo->GetTimeCodeScale();

  if (timecode_scale < 1)  // weird
    return -1;

  if (timecode < 0)
    return -1;

  const long long result = timecode_scale * timecode;

  return result;
}

long Chapters::Atom::ParseDisplay(IMkvReader* pReader, long long pos,
                                  long long size) {
  if (!ExpandDisplaysArray())
    return -1;

  Display& d = m_displays[m_displays_count++];
  d.Init();

  return d.Parse(pReader, pos, size);
}

bool Chapters::Atom::ExpandDisplaysArray() {
  if (m_displays_size > m_displays_count)
    return true;  // nothing else to do

  const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size;

  Display* const displays = new (std::nothrow) Display[size];

  if (displays == NULL)
    return false;

  for (int idx = 0; idx < m_displays_count; ++idx) {
    m_displays[idx].ShallowCopy(displays[idx]);
  }

  delete[] m_displays;
  m_displays = displays;

  m_displays_size = size;
  return true;
}

Chapters::Display::Display() {}

Chapters::Display::~Display() {}

const char* Chapters::Display::GetString() const { return m_string; }

const char* Chapters::Display::GetLanguage() const { return m_language; }

const char* Chapters::Display::GetCountry() const { return m_country; }

void Chapters::Display::Init() {
  m_string = NULL;
  m_language = NULL;
  m_country = NULL;
}

void Chapters::Display::ShallowCopy(Display& rhs) const {
  rhs.m_string = m_string;
  rhs.m_language = m_language;
  rhs.m_country = m_country;
}

void Chapters::Display::Clear() {
  delete[] m_string;
  m_string = NULL;

  delete[] m_language;
  m_language = NULL;

  delete[] m_country;
  m_country = NULL;
}

long Chapters::Display::Parse(IMkvReader* pReader, long long pos,
                              long long size) {
  const long long stop = pos + size;

  while (pos < stop) {
    long long id, size;

    long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (size == 0)  // weird
      continue;

    if (id == 0x05) {  // ChapterString ID
      status = UnserializeString(pReader, pos, size, m_string);

      if (status)
        return status;
    } else if (id == 0x037C) {  // ChapterLanguage ID
      status = UnserializeString(pReader, pos, size, m_language);

      if (status)
        return status;
    } else if (id == 0x037E) {  // ChapterCountry ID
      status = UnserializeString(pReader, pos, size, m_country);

      if (status)
        return status;
    }

    pos += size;
    assert(pos <= stop);
  }

  assert(pos == stop);
  return 0;
}

SegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_,
                         long long element_start, long long element_size)
    : m_pSegment(pSegment),
      m_start(start),
      m_size(size_),
      m_element_start(element_start),
      m_element_size(element_size),
      m_pMuxingAppAsUTF8(NULL),
      m_pWritingAppAsUTF8(NULL),
      m_pTitleAsUTF8(NULL) {}

SegmentInfo::~SegmentInfo() {
  delete[] m_pMuxingAppAsUTF8;
  m_pMuxingAppAsUTF8 = NULL;

  delete[] m_pWritingAppAsUTF8;
  m_pWritingAppAsUTF8 = NULL;

  delete[] m_pTitleAsUTF8;
  m_pTitleAsUTF8 = NULL;
}

long SegmentInfo::Parse() {
  assert(m_pMuxingAppAsUTF8 == NULL);
  assert(m_pWritingAppAsUTF8 == NULL);
  assert(m_pTitleAsUTF8 == NULL);

  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long pos = m_start;
  const long long stop = m_start + m_size;

  m_timecodeScale = 1000000;
  m_duration = -1;

  while (pos < stop) {
    long long id, size;

    const long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (id == 0x0AD7B1) {  // Timecode Scale
      m_timecodeScale = UnserializeUInt(pReader, pos, size);

      if (m_timecodeScale <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x0489) {  // Segment duration
      const long status = UnserializeFloat(pReader, pos, size, m_duration);

      if (status < 0)
        return status;

      if (m_duration < 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x0D80) {  // MuxingApp
      const long status =
          UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8);

      if (status)
        return status;
    } else if (id == 0x1741) {  // WritingApp
      const long status =
          UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8);

      if (status)
        return status;
    } else if (id == 0x3BA9) {  // Title
      const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8);

      if (status)
        return status;
    }

    pos += size;
    assert(pos <= stop);
  }

  assert(pos == stop);

  return 0;
}

long long SegmentInfo::GetTimeCodeScale() const { return m_timecodeScale; }

long long SegmentInfo::GetDuration() const {
  if (m_duration < 0)
    return -1;

  assert(m_timecodeScale >= 1);

  const double dd = double(m_duration) * double(m_timecodeScale);
  const long long d = static_cast<long long>(dd);

  return d;
}

const char* SegmentInfo::GetMuxingAppAsUTF8() const {
  return m_pMuxingAppAsUTF8;
}

const char* SegmentInfo::GetWritingAppAsUTF8() const {
  return m_pWritingAppAsUTF8;
}

const char* SegmentInfo::GetTitleAsUTF8() const { return m_pTitleAsUTF8; }

///////////////////////////////////////////////////////////////
// ContentEncoding element
ContentEncoding::ContentCompression::ContentCompression()
    : algo(0), settings(NULL), settings_len(0) {}

ContentEncoding::ContentCompression::~ContentCompression() {
  delete[] settings;
}

ContentEncoding::ContentEncryption::ContentEncryption()
    : algo(0),
      key_id(NULL),
      key_id_len(0),
      signature(NULL),
      signature_len(0),
      sig_key_id(NULL),
      sig_key_id_len(0),
      sig_algo(0),
      sig_hash_algo(0) {}

ContentEncoding::ContentEncryption::~ContentEncryption() {
  delete[] key_id;
  delete[] signature;
  delete[] sig_key_id;
}

ContentEncoding::ContentEncoding()
    : compression_entries_(NULL),
      compression_entries_end_(NULL),
      encryption_entries_(NULL),
      encryption_entries_end_(NULL),
      encoding_order_(0),
      encoding_scope_(1),
      encoding_type_(0) {}

ContentEncoding::~ContentEncoding() {
  ContentCompression** comp_i = compression_entries_;
  ContentCompression** const comp_j = compression_entries_end_;

  while (comp_i != comp_j) {
    ContentCompression* const comp = *comp_i++;
    delete comp;
  }

  delete[] compression_entries_;

  ContentEncryption** enc_i = encryption_entries_;
  ContentEncryption** const enc_j = encryption_entries_end_;

  while (enc_i != enc_j) {
    ContentEncryption* const enc = *enc_i++;
    delete enc;
  }

  delete[] encryption_entries_;
}

const ContentEncoding::ContentCompression*
ContentEncoding::GetCompressionByIndex(unsigned long idx) const {
  const ptrdiff_t count = compression_entries_end_ - compression_entries_;
  assert(count >= 0);

  if (idx >= static_cast<unsigned long>(count))
    return NULL;

  return compression_entries_[idx];
}

unsigned long ContentEncoding::GetCompressionCount() const {
  const ptrdiff_t count = compression_entries_end_ - compression_entries_;
  assert(count >= 0);

  return static_cast<unsigned long>(count);
}

const ContentEncoding::ContentEncryption* ContentEncoding::GetEncryptionByIndex(
    unsigned long idx) const {
  const ptrdiff_t count = encryption_entries_end_ - encryption_entries_;
  assert(count >= 0);

  if (idx >= static_cast<unsigned long>(count))
    return NULL;

  return encryption_entries_[idx];
}

unsigned long ContentEncoding::GetEncryptionCount() const {
  const ptrdiff_t count = encryption_entries_end_ - encryption_entries_;
  assert(count >= 0);

  return static_cast<unsigned long>(count);
}

long ContentEncoding::ParseContentEncAESSettingsEntry(
    long long start, long long size, IMkvReader* pReader,
    ContentEncAESSettings* aes) {
  assert(pReader);
  assert(aes);

  long long pos = start;
  const long long stop = start + size;

  while (pos < stop) {
    long long id, size;
    const long status = ParseElementHeader(pReader, pos, stop, id, size);
    if (status < 0)  // error
      return status;

    if (id == 0x7E8) {
      // AESSettingsCipherMode
      aes->cipher_mode = UnserializeUInt(pReader, pos, size);
      if (aes->cipher_mode != 1)
        return E_FILE_FORMAT_INVALID;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  return 0;
}

long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
                                                IMkvReader* pReader) {
  assert(pReader);

  long long pos = start;
  const long long stop = start + size;

  // Count ContentCompression and ContentEncryption elements.
  int compression_count = 0;
  int encryption_count = 0;

  while (pos < stop) {
    long long id, size;
    const long status = ParseElementHeader(pReader, pos, stop, id, size);
    if (status < 0)  // error
      return status;

    if (id == 0x1034)  // ContentCompression ID
      ++compression_count;

    if (id == 0x1035)  // ContentEncryption ID
      ++encryption_count;

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  if (compression_count <= 0 && encryption_count <= 0)
    return -1;

  if (compression_count > 0) {
    compression_entries_ =
        new (std::nothrow) ContentCompression* [compression_count];
    if (!compression_entries_)
      return -1;
    compression_entries_end_ = compression_entries_;
  }

  if (encryption_count > 0) {
    encryption_entries_ =
        new (std::nothrow) ContentEncryption* [encryption_count];
    if (!encryption_entries_) {
      delete[] compression_entries_;
      return -1;
    }
    encryption_entries_end_ = encryption_entries_;
  }

  pos = start;
  while (pos < stop) {
    long long id, size;
    long status = ParseElementHeader(pReader, pos, stop, id, size);
    if (status < 0)  // error
      return status;

    if (id == 0x1031) {
      // ContentEncodingOrder
      encoding_order_ = UnserializeUInt(pReader, pos, size);
    } else if (id == 0x1032) {
      // ContentEncodingScope
      encoding_scope_ = UnserializeUInt(pReader, pos, size);
      if (encoding_scope_ < 1)
        return -1;
    } else if (id == 0x1033) {
      // ContentEncodingType
      encoding_type_ = UnserializeUInt(pReader, pos, size);
    } else if (id == 0x1034) {
      // ContentCompression ID
      ContentCompression* const compression =
          new (std::nothrow) ContentCompression();
      if (!compression)
        return -1;

      status = ParseCompressionEntry(pos, size, pReader, compression);
      if (status) {
        delete compression;
        return status;
      }
      *compression_entries_end_++ = compression;
    } else if (id == 0x1035) {
      // ContentEncryption ID
      ContentEncryption* const encryption =
          new (std::nothrow) ContentEncryption();
      if (!encryption)
        return -1;

      status = ParseEncryptionEntry(pos, size, pReader, encryption);
      if (status) {
        delete encryption;
        return status;
      }
      *encryption_entries_end_++ = encryption;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);
  return 0;
}

long ContentEncoding::ParseCompressionEntry(long long start, long long size,
                                            IMkvReader* pReader,
                                            ContentCompression* compression) {
  assert(pReader);
  assert(compression);

  long long pos = start;
  const long long stop = start + size;

  bool valid = false;

  while (pos < stop) {
    long long id, size;
    const long status = ParseElementHeader(pReader, pos, stop, id, size);
    if (status < 0)  // error
      return status;

    if (id == 0x254) {
      // ContentCompAlgo
      long long algo = UnserializeUInt(pReader, pos, size);
      if (algo < 0)
        return E_FILE_FORMAT_INVALID;
      compression->algo = algo;
      valid = true;
    } else if (id == 0x255) {
      // ContentCompSettings
      if (size <= 0)
        return E_FILE_FORMAT_INVALID;

      const size_t buflen = static_cast<size_t>(size);
      typedef unsigned char* buf_t;
      const buf_t buf = new (std::nothrow) unsigned char[buflen];
      if (buf == NULL)
        return -1;

      const int read_status =
          pReader->Read(pos, static_cast<long>(buflen), buf);
      if (read_status) {
        delete[] buf;
        return status;
      }

      compression->settings = buf;
      compression->settings_len = buflen;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  // ContentCompAlgo is mandatory
  if (!valid)
    return E_FILE_FORMAT_INVALID;

  return 0;
}

long ContentEncoding::ParseEncryptionEntry(long long start, long long size,
                                           IMkvReader* pReader,
                                           ContentEncryption* encryption) {
  assert(pReader);
  assert(encryption);

  long long pos = start;
  const long long stop = start + size;

  while (pos < stop) {
    long long id, size;
    const long status = ParseElementHeader(pReader, pos, stop, id, size);
    if (status < 0)  // error
      return status;

    if (id == 0x7E1) {
      // ContentEncAlgo
      encryption->algo = UnserializeUInt(pReader, pos, size);
      if (encryption->algo != 5)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x7E2) {
      // ContentEncKeyID
      delete[] encryption -> key_id;
      encryption->key_id = NULL;
      encryption->key_id_len = 0;

      if (size <= 0)
        return E_FILE_FORMAT_INVALID;

      const size_t buflen = static_cast<size_t>(size);
      typedef unsigned char* buf_t;
      const buf_t buf = new (std::nothrow) unsigned char[buflen];
      if (buf == NULL)
        return -1;

      const int read_status =
          pReader->Read(pos, static_cast<long>(buflen), buf);
      if (read_status) {
        delete[] buf;
        return status;
      }

      encryption->key_id = buf;
      encryption->key_id_len = buflen;
    } else if (id == 0x7E3) {
      // ContentSignature
      delete[] encryption -> signature;
      encryption->signature = NULL;
      encryption->signature_len = 0;

      if (size <= 0)
        return E_FILE_FORMAT_INVALID;

      const size_t buflen = static_cast<size_t>(size);
      typedef unsigned char* buf_t;
      const buf_t buf = new (std::nothrow) unsigned char[buflen];
      if (buf == NULL)
        return -1;

      const int read_status =
          pReader->Read(pos, static_cast<long>(buflen), buf);
      if (read_status) {
        delete[] buf;
        return status;
      }

      encryption->signature = buf;
      encryption->signature_len = buflen;
    } else if (id == 0x7E4) {
      // ContentSigKeyID
      delete[] encryption -> sig_key_id;
      encryption->sig_key_id = NULL;
      encryption->sig_key_id_len = 0;

      if (size <= 0)
        return E_FILE_FORMAT_INVALID;

      const size_t buflen = static_cast<size_t>(size);
      typedef unsigned char* buf_t;
      const buf_t buf = new (std::nothrow) unsigned char[buflen];
      if (buf == NULL)
        return -1;

      const int read_status =
          pReader->Read(pos, static_cast<long>(buflen), buf);
      if (read_status) {
        delete[] buf;
        return status;
      }

      encryption->sig_key_id = buf;
      encryption->sig_key_id_len = buflen;
    } else if (id == 0x7E5) {
      // ContentSigAlgo
      encryption->sig_algo = UnserializeUInt(pReader, pos, size);
    } else if (id == 0x7E6) {
      // ContentSigHashAlgo
      encryption->sig_hash_algo = UnserializeUInt(pReader, pos, size);
    } else if (id == 0x7E7) {
      // ContentEncAESSettings
      const long status = ParseContentEncAESSettingsEntry(
          pos, size, pReader, &encryption->aes_settings);
      if (status)
        return status;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  return 0;
}

Track::Track(Segment* pSegment, long long element_start, long long element_size)
    : m_pSegment(pSegment),
      m_element_start(element_start),
      m_element_size(element_size),
      content_encoding_entries_(NULL),
      content_encoding_entries_end_(NULL) {}

Track::~Track() {
  Info& info = const_cast<Info&>(m_info);
  info.Clear();

  ContentEncoding** i = content_encoding_entries_;
  ContentEncoding** const j = content_encoding_entries_end_;

  while (i != j) {
    ContentEncoding* const encoding = *i++;
    delete encoding;
  }

  delete[] content_encoding_entries_;
}

long Track::Create(Segment* pSegment, const Info& info, long long element_start,
                   long long element_size, Track*& pResult) {
  if (pResult)
    return -1;

  Track* const pTrack =
      new (std::nothrow) Track(pSegment, element_start, element_size);

  if (pTrack == NULL)
    return -1;  // generic error

  const int status = info.Copy(pTrack->m_info);

  if (status) {  // error
    delete pTrack;
    return status;
  }

  pResult = pTrack;
  return 0;  // success
}

Track::Info::Info()
    : uid(0),
      defaultDuration(0),
      codecDelay(0),
      seekPreRoll(0),
      nameAsUTF8(NULL),
      language(NULL),
      codecId(NULL),
      codecNameAsUTF8(NULL),
      codecPrivate(NULL),
      codecPrivateSize(0),
      lacing(false) {}

Track::Info::~Info() { Clear(); }

void Track::Info::Clear() {
  delete[] nameAsUTF8;
  nameAsUTF8 = NULL;

  delete[] language;
  language = NULL;

  delete[] codecId;
  codecId = NULL;

  delete[] codecPrivate;
  codecPrivate = NULL;
  codecPrivateSize = 0;

  delete[] codecNameAsUTF8;
  codecNameAsUTF8 = NULL;
}

int Track::Info::CopyStr(char* Info::*str, Info& dst_) const {
  if (str == static_cast<char * Info::*>(NULL))
    return -1;

  char*& dst = dst_.*str;

  if (dst)  // should be NULL already
    return -1;

  const char* const src = this->*str;

  if (src == NULL)
    return 0;

  const size_t len = strlen(src);

  dst = new (std::nothrow) char[len + 1];

  if (dst == NULL)
    return -1;

  strcpy(dst, src);

  return 0;
}

int Track::Info::Copy(Info& dst) const {
  if (&dst == this)
    return 0;

  dst.type = type;
  dst.number = number;
  dst.defaultDuration = defaultDuration;
  dst.codecDelay = codecDelay;
  dst.seekPreRoll = seekPreRoll;
  dst.uid = uid;
  dst.lacing = lacing;
  dst.settings = settings;

  // We now copy the string member variables from src to dst.
  // This involves memory allocation so in principle the operation
  // can fail (indeed, that's why we have Info::Copy), so we must
  // report this to the caller.  An error return from this function
  // therefore implies that the copy was only partially successful.

  if (int status = CopyStr(&Info::nameAsUTF8, dst))
    return status;

  if (int status = CopyStr(&Info::language, dst))
    return status;

  if (int status = CopyStr(&Info::codecId, dst))
    return status;

  if (int status = CopyStr(&Info::codecNameAsUTF8, dst))
    return status;

  if (codecPrivateSize > 0) {
    if (codecPrivate == NULL)
      return -1;

    if (dst.codecPrivate)
      return -1;

    if (dst.codecPrivateSize != 0)
      return -1;

    dst.codecPrivate = new (std::nothrow) unsigned char[codecPrivateSize];

    if (dst.codecPrivate == NULL)
      return -1;

    memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize);
    dst.codecPrivateSize = codecPrivateSize;
  }

  return 0;
}

const BlockEntry* Track::GetEOS() const { return &m_eos; }

long Track::GetType() const { return m_info.type; }

long Track::GetNumber() const { return m_info.number; }

unsigned long long Track::GetUid() const { return m_info.uid; }

const char* Track::GetNameAsUTF8() const { return m_info.nameAsUTF8; }

const char* Track::GetLanguage() const { return m_info.language; }

const char* Track::GetCodecNameAsUTF8() const { return m_info.codecNameAsUTF8; }

const char* Track::GetCodecId() const { return m_info.codecId; }

const unsigned char* Track::GetCodecPrivate(size_t& size) const {
  size = m_info.codecPrivateSize;
  return m_info.codecPrivate;
}

bool Track::GetLacing() const { return m_info.lacing; }

unsigned long long Track::GetDefaultDuration() const {
  return m_info.defaultDuration;
}

unsigned long long Track::GetCodecDelay() const { return m_info.codecDelay; }

unsigned long long Track::GetSeekPreRoll() const { return m_info.seekPreRoll; }

long Track::GetFirst(const BlockEntry*& pBlockEntry) const {
  const Cluster* pCluster = m_pSegment->GetFirst();

  for (int i = 0;;) {
    if (pCluster == NULL) {
      pBlockEntry = GetEOS();
      return 1;
    }

    if (pCluster->EOS()) {
#if 0
            if (m_pSegment->Unparsed() <= 0) {  //all clusters have been loaded
                pBlockEntry = GetEOS();
                return 1;
            }
#else
      if (m_pSegment->DoneParsing()) {
        pBlockEntry = GetEOS();
        return 1;
      }
#endif

      pBlockEntry = 0;
      return E_BUFFER_NOT_FULL;
    }

    long status = pCluster->GetFirst(pBlockEntry);

    if (status < 0)  // error
      return status;

    if (pBlockEntry == 0) {  // empty cluster
      pCluster = m_pSegment->GetNext(pCluster);
      continue;
    }

    for (;;) {
      const Block* const pBlock = pBlockEntry->GetBlock();
      assert(pBlock);

      const long long tn = pBlock->GetTrackNumber();

      if ((tn == m_info.number) && VetEntry(pBlockEntry))
        return 0;

      const BlockEntry* pNextEntry;

      status = pCluster->GetNext(pBlockEntry, pNextEntry);

      if (status < 0)  // error
        return status;

      if (pNextEntry == 0)
        break;

      pBlockEntry = pNextEntry;
    }

    ++i;

    if (i >= 100)
      break;

    pCluster = m_pSegment->GetNext(pCluster);
  }

  // NOTE: if we get here, it means that we didn't find a block with
  // a matching track number.  We interpret that as an error (which
  // might be too conservative).

  pBlockEntry = GetEOS();  // so we can return a non-NULL value
  return 1;
}

long Track::GetNext(const BlockEntry* pCurrEntry,
                    const BlockEntry*& pNextEntry) const {
  assert(pCurrEntry);
  assert(!pCurrEntry->EOS());  //?

  const Block* const pCurrBlock = pCurrEntry->GetBlock();
  assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number);
  if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number)
    return -1;

  const Cluster* pCluster = pCurrEntry->GetCluster();
  assert(pCluster);
  assert(!pCluster->EOS());

  long status = pCluster->GetNext(pCurrEntry, pNextEntry);

  if (status < 0)  // error
    return status;

  for (int i = 0;;) {
    while (pNextEntry) {
      const Block* const pNextBlock = pNextEntry->GetBlock();
      assert(pNextBlock);

      if (pNextBlock->GetTrackNumber() == m_info.number)
        return 0;

      pCurrEntry = pNextEntry;

      status = pCluster->GetNext(pCurrEntry, pNextEntry);

      if (status < 0)  // error
        return status;
    }

    pCluster = m_pSegment->GetNext(pCluster);

    if (pCluster == NULL) {
      pNextEntry = GetEOS();
      return 1;
    }

    if (pCluster->EOS()) {
#if 0
            if (m_pSegment->Unparsed() <= 0)   //all clusters have been loaded
            {
                pNextEntry = GetEOS();
                return 1;
            }
#else
      if (m_pSegment->DoneParsing()) {
        pNextEntry = GetEOS();
        return 1;
      }
#endif

      // TODO: there is a potential O(n^2) problem here: we tell the
      // caller to (pre)load another cluster, which he does, but then he
      // calls GetNext again, which repeats the same search.  This is
      // a pathological case, since the only way it can happen is if
      // there exists a long sequence of clusters none of which contain a
      // block from this track.  One way around this problem is for the
      // caller to be smarter when he loads another cluster: don't call
      // us back until you have a cluster that contains a block from this
      // track. (Of course, that's not cheap either, since our caller
      // would have to scan the each cluster as it's loaded, so that
      // would just push back the problem.)

      pNextEntry = NULL;
      return E_BUFFER_NOT_FULL;
    }

    status = pCluster->GetFirst(pNextEntry);

    if (status < 0)  // error
      return status;

    if (pNextEntry == NULL)  // empty cluster
      continue;

    ++i;

    if (i >= 100)
      break;
  }

  // NOTE: if we get here, it means that we didn't find a block with
  // a matching track number after lots of searching, so we give
  // up trying.

  pNextEntry = GetEOS();  // so we can return a non-NULL value
  return 1;
}

bool Track::VetEntry(const BlockEntry* pBlockEntry) const {
  assert(pBlockEntry);
  const Block* const pBlock = pBlockEntry->GetBlock();
  assert(pBlock);
  assert(pBlock->GetTrackNumber() == m_info.number);
  if (!pBlock || pBlock->GetTrackNumber() != m_info.number)
    return false;

  // This function is used during a seek to determine whether the
  // frame is a valid seek target.  This default function simply
  // returns true, which means all frames are valid seek targets.
  // It gets overridden by the VideoTrack class, because only video
  // keyframes can be used as seek target.

  return true;
}

long Track::Seek(long long time_ns, const BlockEntry*& pResult) const {
  const long status = GetFirst(pResult);

  if (status < 0)  // buffer underflow, etc
    return status;

  assert(pResult);

  if (pResult->EOS())
    return 0;

  const Cluster* pCluster = pResult->GetCluster();
  assert(pCluster);
  assert(pCluster->GetIndex() >= 0);

  if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
    return 0;

  Cluster** const clusters = m_pSegment->m_clusters;
  assert(clusters);

  const long count = m_pSegment->GetCount();  // loaded only, not preloaded
  assert(count > 0);

  Cluster** const i = clusters + pCluster->GetIndex();
  assert(i);
  assert(*i == pCluster);
  assert(pCluster->GetTime() <= time_ns);

  Cluster** const j = clusters + count;

  Cluster** lo = i;
  Cluster** hi = j;

  while (lo < hi) {
    // INVARIANT:
    //[i, lo) <= time_ns
    //[lo, hi) ?
    //[hi, j)  > time_ns

    Cluster** const mid = lo + (hi - lo) / 2;
    assert(mid < hi);

    pCluster = *mid;
    assert(pCluster);
    assert(pCluster->GetIndex() >= 0);
    assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters));

    const long long t = pCluster->GetTime();

    if (t <= time_ns)
      lo = mid + 1;
    else
      hi = mid;

    assert(lo <= hi);
  }

  assert(lo == hi);
  assert(lo > i);
  assert(lo <= j);

  while (lo > i) {
    pCluster = *--lo;
    assert(pCluster);
    assert(pCluster->GetTime() <= time_ns);

    pResult = pCluster->GetEntry(this);

    if ((pResult != 0) && !pResult->EOS())
      return 0;

    // landed on empty cluster (no entries)
  }

  pResult = GetEOS();  // weird
  return 0;
}

const ContentEncoding* Track::GetContentEncodingByIndex(
    unsigned long idx) const {
  const ptrdiff_t count =
      content_encoding_entries_end_ - content_encoding_entries_;
  assert(count >= 0);

  if (idx >= static_cast<unsigned long>(count))
    return NULL;

  return content_encoding_entries_[idx];
}

unsigned long Track::GetContentEncodingCount() const {
  const ptrdiff_t count =
      content_encoding_entries_end_ - content_encoding_entries_;
  assert(count >= 0);

  return static_cast<unsigned long>(count);
}

long Track::ParseContentEncodingsEntry(long long start, long long size) {
  IMkvReader* const pReader = m_pSegment->m_pReader;
  assert(pReader);

  long long pos = start;
  const long long stop = start + size;

  // Count ContentEncoding elements.
  int count = 0;
  while (pos < stop) {
    long long id, size;
    const long status = ParseElementHeader(pReader, pos, stop, id, size);
    if (status < 0)  // error
      return status;

    // pos now designates start of element
    if (id == 0x2240)  // ContentEncoding ID
      ++count;

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  if (count <= 0)
    return -1;

  content_encoding_entries_ = new (std::nothrow) ContentEncoding* [count];
  if (!content_encoding_entries_)
    return -1;

  content_encoding_entries_end_ = content_encoding_entries_;

  pos = start;
  while (pos < stop) {
    long long id, size;
    long status = ParseElementHeader(pReader, pos, stop, id, size);
    if (status < 0)  // error
      return status;

    // pos now designates start of element
    if (id == 0x2240) {  // ContentEncoding ID
      ContentEncoding* const content_encoding =
          new (std::nothrow) ContentEncoding();
      if (!content_encoding)
        return -1;

      status = content_encoding->ParseContentEncodingEntry(pos, size, pReader);
      if (status) {
        delete content_encoding;
        return status;
      }

      *content_encoding_entries_end_++ = content_encoding;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);

  return 0;
}

Track::EOSBlock::EOSBlock() : BlockEntry(NULL, LONG_MIN) {}

BlockEntry::Kind Track::EOSBlock::GetKind() const { return kBlockEOS; }

const Block* Track::EOSBlock::GetBlock() const { return NULL; }

VideoTrack::VideoTrack(Segment* pSegment, long long element_start,
                       long long element_size)
    : Track(pSegment, element_start, element_size) {}

long VideoTrack::Parse(Segment* pSegment, const Info& info,
                       long long element_start, long long element_size,
                       VideoTrack*& pResult) {
  if (pResult)
    return -1;

  if (info.type != Track::kVideo)
    return -1;

  long long width = 0;
  long long height = 0;
  double rate = 0.0;

  IMkvReader* const pReader = pSegment->m_pReader;

  const Settings& s = info.settings;
  assert(s.start >= 0);
  assert(s.size >= 0);

  long long pos = s.start;
  assert(pos >= 0);

  const long long stop = pos + s.size;

  while (pos < stop) {
    long long id, size;

    const long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (id == 0x30) {  // pixel width
      width = UnserializeUInt(pReader, pos, size);

      if (width <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x3A) {  // pixel height
      height = UnserializeUInt(pReader, pos, size);

      if (height <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x0383E3) {  // frame rate
      const long status = UnserializeFloat(pReader, pos, size, rate);

      if (status < 0)
        return status;

      if (rate <= 0)
        return E_FILE_FORMAT_INVALID;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);

  VideoTrack* const pTrack =
      new (std::nothrow) VideoTrack(pSegment, element_start, element_size);

  if (pTrack == NULL)
    return -1;  // generic error

  const int status = info.Copy(pTrack->m_info);

  if (status) {  // error
    delete pTrack;
    return status;
  }

  pTrack->m_width = width;
  pTrack->m_height = height;
  pTrack->m_rate = rate;

  pResult = pTrack;
  return 0;  // success
}

bool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const {
  return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey();
}

long VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const {
  const long status = GetFirst(pResult);

  if (status < 0)  // buffer underflow, etc
    return status;

  assert(pResult);

  if (pResult->EOS())
    return 0;

  const Cluster* pCluster = pResult->GetCluster();
  assert(pCluster);
  assert(pCluster->GetIndex() >= 0);

  if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
    return 0;

  Cluster** const clusters = m_pSegment->m_clusters;
  assert(clusters);

  const long count = m_pSegment->GetCount();  // loaded only, not pre-loaded
  assert(count > 0);

  Cluster** const i = clusters + pCluster->GetIndex();
  assert(i);
  assert(*i == pCluster);
  assert(pCluster->GetTime() <= time_ns);

  Cluster** const j = clusters + count;

  Cluster** lo = i;
  Cluster** hi = j;

  while (lo < hi) {
    // INVARIANT:
    //[i, lo) <= time_ns
    //[lo, hi) ?
    //[hi, j)  > time_ns

    Cluster** const mid = lo + (hi - lo) / 2;
    assert(mid < hi);

    pCluster = *mid;
    assert(pCluster);
    assert(pCluster->GetIndex() >= 0);
    assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters));

    const long long t = pCluster->GetTime();

    if (t <= time_ns)
      lo = mid + 1;
    else
      hi = mid;

    assert(lo <= hi);
  }

  assert(lo == hi);
  assert(lo > i);
  assert(lo <= j);

  pCluster = *--lo;
  assert(pCluster);
  assert(pCluster->GetTime() <= time_ns);

  pResult = pCluster->GetEntry(this, time_ns);

  if ((pResult != 0) && !pResult->EOS())  // found a keyframe
    return 0;

  while (lo != i) {
    pCluster = *--lo;
    assert(pCluster);
    assert(pCluster->GetTime() <= time_ns);

#if 0
        //TODO:
        //We need to handle the case when a cluster
        //contains multiple keyframes.  Simply returning
        //the largest keyframe on the cluster isn't
        //good enough.
        pResult = pCluster->GetMaxKey(this);
#else
    pResult = pCluster->GetEntry(this, time_ns);
#endif

    if ((pResult != 0) && !pResult->EOS())
      return 0;
  }

  // weird: we're on the first cluster, but no keyframe found
  // should never happen but we must return something anyway

  pResult = GetEOS();
  return 0;
}

long long VideoTrack::GetWidth() const { return m_width; }

long long VideoTrack::GetHeight() const { return m_height; }

double VideoTrack::GetFrameRate() const { return m_rate; }

AudioTrack::AudioTrack(Segment* pSegment, long long element_start,
                       long long element_size)
    : Track(pSegment, element_start, element_size) {}

long AudioTrack::Parse(Segment* pSegment, const Info& info,
                       long long element_start, long long element_size,
                       AudioTrack*& pResult) {
  if (pResult)
    return -1;

  if (info.type != Track::kAudio)
    return -1;

  IMkvReader* const pReader = pSegment->m_pReader;

  const Settings& s = info.settings;
  assert(s.start >= 0);
  assert(s.size >= 0);

  long long pos = s.start;
  assert(pos >= 0);

  const long long stop = pos + s.size;

  double rate = 8000.0;  // MKV default
  long long channels = 1;
  long long bit_depth = 0;

  while (pos < stop) {
    long long id, size;

    long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (id == 0x35) {  // Sample Rate
      status = UnserializeFloat(pReader, pos, size, rate);

      if (status < 0)
        return status;

      if (rate <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x1F) {  // Channel Count
      channels = UnserializeUInt(pReader, pos, size);

      if (channels <= 0)
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x2264) {  // Bit Depth
      bit_depth = UnserializeUInt(pReader, pos, size);

      if (bit_depth <= 0)
        return E_FILE_FORMAT_INVALID;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);

  AudioTrack* const pTrack =
      new (std::nothrow) AudioTrack(pSegment, element_start, element_size);

  if (pTrack == NULL)
    return -1;  // generic error

  const int status = info.Copy(pTrack->m_info);

  if (status) {
    delete pTrack;
    return status;
  }

  pTrack->m_rate = rate;
  pTrack->m_channels = channels;
  pTrack->m_bitDepth = bit_depth;

  pResult = pTrack;
  return 0;  // success
}

double AudioTrack::GetSamplingRate() const { return m_rate; }

long long AudioTrack::GetChannels() const { return m_channels; }

long long AudioTrack::GetBitDepth() const { return m_bitDepth; }

Tracks::Tracks(Segment* pSegment, long long start, long long size_,
               long long element_start, long long element_size)
    : m_pSegment(pSegment),
      m_start(start),
      m_size(size_),
      m_element_start(element_start),
      m_element_size(element_size),
      m_trackEntries(NULL),
      m_trackEntriesEnd(NULL) {}

long Tracks::Parse() {
  assert(m_trackEntries == NULL);
  assert(m_trackEntriesEnd == NULL);

  const long long stop = m_start + m_size;
  IMkvReader* const pReader = m_pSegment->m_pReader;

  int count = 0;
  long long pos = m_start;

  while (pos < stop) {
    long long id, size;

    const long status = ParseElementHeader(pReader, pos, stop, id, size);

    if (status < 0)  // error
      return status;

    if (size == 0)  // weird
      continue;

    if (id == 0x2E)  // TrackEntry ID
      ++count;

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);

  if (count <= 0)
    return 0;  // success

  m_trackEntries = new (std::nothrow) Track* [count];

  if (m_trackEntries == NULL)
    return -1;

  m_trackEntriesEnd = m_trackEntries;

  pos = m_start;

  while (pos < stop) {
    const long long element_start = pos;

    long long id, payload_size;

    const long status =
        ParseElementHeader(pReader, pos, stop, id, payload_size);

    if (status < 0)  // error
      return status;

    if (payload_size == 0)  // weird
      continue;

    const long long payload_stop = pos + payload_size;
    assert(payload_stop <= stop);  // checked in ParseElement

    const long long element_size = payload_stop - element_start;

    if (id == 0x2E) {  // TrackEntry ID
      Track*& pTrack = *m_trackEntriesEnd;
      pTrack = NULL;

      const long status = ParseTrackEntry(pos, payload_size, element_start,
                                          element_size, pTrack);

      if (status)
        return status;

      if (pTrack)
        ++m_trackEntriesEnd;
    }

    pos = payload_stop;
    assert(pos <= stop);
  }

  assert(pos == stop);

  return 0;  // success
}

unsigned long Tracks::GetTracksCount() const {
  const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries;
  assert(result >= 0);

  return static_cast<unsigned long>(result);
}

long Tracks::ParseTrackEntry(long long track_start, long long track_size,
                             long long element_start, long long element_size,
                             Track*& pResult) const {
  if (pResult)
    return -1;

  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long pos = track_start;
  const long long track_stop = track_start + track_size;

  Track::Info info;

  info.type = 0;
  info.number = 0;
  info.uid = 0;
  info.defaultDuration = 0;

  Track::Settings v;
  v.start = -1;
  v.size = -1;

  Track::Settings a;
  a.start = -1;
  a.size = -1;

  Track::Settings e;  // content_encodings_settings;
  e.start = -1;
  e.size = -1;

  long long lacing = 1;  // default is true

  while (pos < track_stop) {
    long long id, size;

    const long status = ParseElementHeader(pReader, pos, track_stop, id, size);

    if (status < 0)  // error
      return status;

    if (size < 0)
      return E_FILE_FORMAT_INVALID;

    const long long start = pos;

    if (id == 0x60) {  // VideoSettings ID
      v.start = start;
      v.size = size;
    } else if (id == 0x61) {  // AudioSettings ID
      a.start = start;
      a.size = size;
    } else if (id == 0x2D80) {  // ContentEncodings ID
      e.start = start;
      e.size = size;
    } else if (id == 0x33C5) {  // Track UID
      if (size > 8)
        return E_FILE_FORMAT_INVALID;

      info.uid = 0;

      long long pos_ = start;
      const long long pos_end = start + size;

      while (pos_ != pos_end) {
        unsigned char b;

        const int status = pReader->Read(pos_, 1, &b);

        if (status)
          return status;

        info.uid <<= 8;
        info.uid |= b;

        ++pos_;
      }
    } else if (id == 0x57) {  // Track Number
      const long long num = UnserializeUInt(pReader, pos, size);

      if ((num <= 0) || (num > 127))
        return E_FILE_FORMAT_INVALID;

      info.number = static_cast<long>(num);
    } else if (id == 0x03) {  // Track Type
      const long long type = UnserializeUInt(pReader, pos, size);

      if ((type <= 0) || (type > 254))
        return E_FILE_FORMAT_INVALID;

      info.type = static_cast<long>(type);
    } else if (id == 0x136E) {  // Track Name
      const long status =
          UnserializeString(pReader, pos, size, info.nameAsUTF8);

      if (status)
        return status;
    } else if (id == 0x02B59C) {  // Track Language
      const long status = UnserializeString(pReader, pos, size, info.language);

      if (status)
        return status;
    } else if (id == 0x03E383) {  // Default Duration
      const long long duration = UnserializeUInt(pReader, pos, size);

      if (duration < 0)
        return E_FILE_FORMAT_INVALID;

      info.defaultDuration = static_cast<unsigned long long>(duration);
    } else if (id == 0x06) {  // CodecID
      const long status = UnserializeString(pReader, pos, size, info.codecId);

      if (status)
        return status;
    } else if (id == 0x1C) {  // lacing
      lacing = UnserializeUInt(pReader, pos, size);

      if ((lacing < 0) || (lacing > 1))
        return E_FILE_FORMAT_INVALID;
    } else if (id == 0x23A2) {  // Codec Private
      delete[] info.codecPrivate;
      info.codecPrivate = NULL;
      info.codecPrivateSize = 0;

      const size_t buflen = static_cast<size_t>(size);

      if (buflen) {
        typedef unsigned char* buf_t;

        const buf_t buf = new (std::nothrow) unsigned char[buflen];

        if (buf == NULL)
          return -1;

        const int status = pReader->Read(pos, static_cast<long>(buflen), buf);

        if (status) {
          delete[] buf;
          return status;
        }

        info.codecPrivate = buf;
        info.codecPrivateSize = buflen;
      }
    } else if (id == 0x058688) {  // Codec Name
      const long status =
          UnserializeString(pReader, pos, size, info.codecNameAsUTF8);

      if (status)
        return status;
    } else if (id == 0x16AA) {  // Codec Delay
      info.codecDelay = UnserializeUInt(pReader, pos, size);
    } else if (id == 0x16BB) {  // Seek Pre Roll
      info.seekPreRoll = UnserializeUInt(pReader, pos, size);
    }

    pos += size;  // consume payload
    assert(pos <= track_stop);
  }

  assert(pos == track_stop);

  if (info.number <= 0)  // not specified
    return E_FILE_FORMAT_INVALID;

  if (GetTrackByNumber(info.number))
    return E_FILE_FORMAT_INVALID;

  if (info.type <= 0)  // not specified
    return E_FILE_FORMAT_INVALID;

  info.lacing = (lacing > 0) ? true : false;

  if (info.type == Track::kVideo) {
    if (v.start < 0)
      return E_FILE_FORMAT_INVALID;

    if (a.start >= 0)
      return E_FILE_FORMAT_INVALID;

    info.settings = v;

    VideoTrack* pTrack = NULL;

    const long status = VideoTrack::Parse(m_pSegment, info, element_start,
                                          element_size, pTrack);

    if (status)
      return status;

    pResult = pTrack;
    assert(pResult);

    if (e.start >= 0)
      pResult->ParseContentEncodingsEntry(e.start, e.size);
  } else if (info.type == Track::kAudio) {
    if (a.start < 0)
      return E_FILE_FORMAT_INVALID;

    if (v.start >= 0)
      return E_FILE_FORMAT_INVALID;

    info.settings = a;

    AudioTrack* pTrack = NULL;

    const long status = AudioTrack::Parse(m_pSegment, info, element_start,
                                          element_size, pTrack);

    if (status)
      return status;

    pResult = pTrack;
    assert(pResult);

    if (e.start >= 0)
      pResult->ParseContentEncodingsEntry(e.start, e.size);
  } else {
    // neither video nor audio - probably metadata or subtitles

    if (a.start >= 0)
      return E_FILE_FORMAT_INVALID;

    if (v.start >= 0)
      return E_FILE_FORMAT_INVALID;

    if (info.type == Track::kMetadata && e.start >= 0)
      return E_FILE_FORMAT_INVALID;

    info.settings.start = -1;
    info.settings.size = 0;

    Track* pTrack = NULL;

    const long status =
        Track::Create(m_pSegment, info, element_start, element_size, pTrack);

    if (status)
      return status;

    pResult = pTrack;
    assert(pResult);
  }

  return 0;  // success
}

Tracks::~Tracks() {
  Track** i = m_trackEntries;
  Track** const j = m_trackEntriesEnd;

  while (i != j) {
    Track* const pTrack = *i++;
    delete pTrack;
  }

  delete[] m_trackEntries;
}

const Track* Tracks::GetTrackByNumber(long tn) const {
  if (tn < 0)
    return NULL;

  Track** i = m_trackEntries;
  Track** const j = m_trackEntriesEnd;

  while (i != j) {
    Track* const pTrack = *i++;

    if (pTrack == NULL)
      continue;

    if (tn == pTrack->GetNumber())
      return pTrack;
  }

  return NULL;  // not found
}

const Track* Tracks::GetTrackByIndex(unsigned long idx) const {
  const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries;

  if (idx >= static_cast<unsigned long>(count))
    return NULL;

  return m_trackEntries[idx];
}

#if 0
long long Cluster::Unparsed() const
{
    if (m_timecode < 0)  //not even partially loaded
        return LLONG_MAX;

    assert(m_pos >= m_element_start);
    //assert(m_element_size > m_size);

    const long long element_stop = m_element_start + m_element_size;
    assert(m_pos <= element_stop);

    const long long result = element_stop - m_pos;
    assert(result >= 0);

    return result;
}
#endif

long Cluster::Load(long long& pos, long& len) const {
  assert(m_pSegment);
  assert(m_pos >= m_element_start);

  if (m_timecode >= 0)  // at least partially loaded
    return 0;

  assert(m_pos == m_element_start);
  assert(m_element_size < 0);

  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long total, avail;

  const int status = pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));
  assert((total < 0) || (m_pos <= total));  // TODO: verify this

  pos = m_pos;

  long long cluster_size = -1;

  {
    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error or underflow
      return static_cast<long>(result);

    if (result > 0)  // underflow (weird)
      return E_BUFFER_NOT_FULL;

    // if ((pos + len) > segment_stop)
    //    return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long id_ = ReadUInt(pReader, pos, len);

    if (id_ < 0)  // error
      return static_cast<long>(id_);

    if (id_ != 0x0F43B675)  // Cluster ID
      return E_FILE_FORMAT_INVALID;

    pos += len;  // consume id

    // read cluster size

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    // if ((pos + len) > segment_stop)
    //    return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(cluster_size);

    if (size == 0)
      return E_FILE_FORMAT_INVALID;  // TODO: verify this

    pos += len;  // consume length of size of element

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (size != unknown_size)
      cluster_size = size;
  }

// pos points to start of payload

#if 0
    len = static_cast<long>(size_);

    if (cluster_stop > avail)
        return E_BUFFER_NOT_FULL;
#endif

  long long timecode = -1;
  long long new_pos = -1;
  bool bBlock = false;

  long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size;

  for (;;) {
    if ((cluster_stop >= 0) && (pos >= cluster_stop))
      break;

    // Parse ID

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long id = ReadUInt(pReader, pos, len);

    if (id < 0)  // error
      return static_cast<long>(id);

    if (id == 0)
      return E_FILE_FORMAT_INVALID;

    // This is the distinguished set of ID's we use to determine
    // that we have exhausted the sub-element's inside the cluster
    // whose ID we parsed earlier.

    if (id == 0x0F43B675)  // Cluster ID
      break;

    if (id == 0x0C53BB6B)  // Cues ID
      break;

    pos += len;  // consume ID field

    // Parse Size

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (size == unknown_size)
      return E_FILE_FORMAT_INVALID;

    pos += len;  // consume size field

    if ((cluster_stop >= 0) && (pos > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    // pos now points to start of payload

    if (size == 0)  // weird
      continue;

    if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if (id == 0x67) {  // TimeCode ID
      len = static_cast<long>(size);

      if ((pos + size) > avail)
        return E_BUFFER_NOT_FULL;

      timecode = UnserializeUInt(pReader, pos, size);

      if (timecode < 0)  // error (or underflow)
        return static_cast<long>(timecode);

      new_pos = pos + size;

      if (bBlock)
        break;
    } else if (id == 0x20) {  // BlockGroup ID
      bBlock = true;
      break;
    } else if (id == 0x23) {  // SimpleBlock ID
      bBlock = true;
      break;
    }

    pos += size;  // consume payload
    assert((cluster_stop < 0) || (pos <= cluster_stop));
  }

  assert((cluster_stop < 0) || (pos <= cluster_stop));

  if (timecode < 0)  // no timecode found
    return E_FILE_FORMAT_INVALID;

  if (!bBlock)
    return E_FILE_FORMAT_INVALID;

  m_pos = new_pos;  // designates position just beyond timecode payload
  m_timecode = timecode;  // m_timecode >= 0 means we're partially loaded

  if (cluster_size >= 0)
    m_element_size = cluster_stop - m_element_start;

  return 0;
}

long Cluster::Parse(long long& pos, long& len) const {
  long status = Load(pos, len);

  if (status < 0)
    return status;

  assert(m_pos >= m_element_start);
  assert(m_timecode >= 0);
  // assert(m_size > 0);
  // assert(m_element_size > m_size);

  const long long cluster_stop =
      (m_element_size < 0) ? -1 : m_element_start + m_element_size;

  if ((cluster_stop >= 0) && (m_pos >= cluster_stop))
    return 1;  // nothing else to do

  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long total, avail;

  status = pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  pos = m_pos;

  for (;;) {
    if ((cluster_stop >= 0) && (pos >= cluster_stop))
      break;

    if ((total >= 0) && (pos >= total)) {
      if (m_element_size < 0)
        m_element_size = pos - m_element_start;

      break;
    }

    // Parse ID

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long id = ReadUInt(pReader, pos, len);

    if (id < 0)  // error
      return static_cast<long>(id);

    if (id == 0)  // weird
      return E_FILE_FORMAT_INVALID;

    // This is the distinguished set of ID's we use to determine
    // that we have exhausted the sub-element's inside the cluster
    // whose ID we parsed earlier.

    if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) {  // Cluster or Cues ID
      if (m_element_size < 0)
        m_element_size = pos - m_element_start;

      break;
    }

    pos += len;  // consume ID field

    // Parse Size

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (size == unknown_size)
      return E_FILE_FORMAT_INVALID;

    pos += len;  // consume size field

    if ((cluster_stop >= 0) && (pos > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    // pos now points to start of payload

    if (size == 0)  // weird
      continue;

    // const long long block_start = pos;
    const long long block_stop = pos + size;

    if (cluster_stop >= 0) {
      if (block_stop > cluster_stop) {
        if ((id == 0x20) || (id == 0x23))
          return E_FILE_FORMAT_INVALID;

        pos = cluster_stop;
        break;
      }
    } else if ((total >= 0) && (block_stop > total)) {
      m_element_size = total - m_element_start;
      pos = total;
      break;
    } else if (block_stop > avail) {
      len = static_cast<long>(size);
      return E_BUFFER_NOT_FULL;
    }

    Cluster* const this_ = const_cast<Cluster*>(this);

    if (id == 0x20)  // BlockGroup
      return this_->ParseBlockGroup(size, pos, len);

    if (id == 0x23)  // SimpleBlock
      return this_->ParseSimpleBlock(size, pos, len);

    pos += size;  // consume payload
    assert((cluster_stop < 0) || (pos <= cluster_stop));
  }

  assert(m_element_size > 0);

  m_pos = pos;
  assert((cluster_stop < 0) || (m_pos <= cluster_stop));

  if (m_entries_count > 0) {
    const long idx = m_entries_count - 1;

    const BlockEntry* const pLast = m_entries[idx];
    assert(pLast);

    const Block* const pBlock = pLast->GetBlock();
    assert(pBlock);

    const long long start = pBlock->m_start;

    if ((total >= 0) && (start > total))
      return -1;  // defend against trucated stream

    const long long size = pBlock->m_size;

    const long long stop = start + size;
    assert((cluster_stop < 0) || (stop <= cluster_stop));

    if ((total >= 0) && (stop > total))
      return -1;  // defend against trucated stream
  }

  return 1;  // no more entries
}

long Cluster::ParseSimpleBlock(long long block_size, long long& pos,
                               long& len) {
  const long long block_start = pos;
  const long long block_stop = pos + block_size;

  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long total, avail;

  long status = pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  // parse track number

  if ((pos + 1) > avail) {
    len = 1;
    return E_BUFFER_NOT_FULL;
  }

  long long result = GetUIntLength(pReader, pos, len);

  if (result < 0)  // error
    return static_cast<long>(result);

  if (result > 0)  // weird
    return E_BUFFER_NOT_FULL;

  if ((pos + len) > block_stop)
    return E_FILE_FORMAT_INVALID;

  if ((pos + len) > avail)
    return E_BUFFER_NOT_FULL;

  const long long track = ReadUInt(pReader, pos, len);

  if (track < 0)  // error
    return static_cast<long>(track);

  if (track == 0)
    return E_FILE_FORMAT_INVALID;

#if 0
    //TODO(matthewjheaney)
    //This turned out to be too conservative.  The problem is that
    //if we see a track header in the tracks element with an unsupported
    //track type, we throw that track header away, so it is not present
    //in the track map.  But even though we don't understand the track
    //header, there are still blocks in the cluster with that track
    //number.  It was our decision to ignore that track header, so it's
    //up to us to deal with blocks associated with that track -- we
    //cannot simply report an error since technically there's nothing
    //wrong with the file.
    //
    //For now we go ahead and finish the parse, creating a block entry
    //for this block.  This is somewhat wasteful, because without a
    //track header there's nothing you can do with the block. What
    //we really need here is a special return value that indicates to
    //the caller that he should ignore this particular block, and
    //continue parsing.

    const Tracks* const pTracks = m_pSegment->GetTracks();
    assert(pTracks);

    const long tn = static_cast<long>(track);

    const Track* const pTrack = pTracks->GetTrackByNumber(tn);

    if (pTrack == NULL)
        return E_FILE_FORMAT_INVALID;
#endif

  pos += len;  // consume track number

  if ((pos + 2) > block_stop)
    return E_FILE_FORMAT_INVALID;

  if ((pos + 2) > avail) {
    len = 2;
    return E_BUFFER_NOT_FULL;
  }

  pos += 2;  // consume timecode

  if ((pos + 1) > block_stop)
    return E_FILE_FORMAT_INVALID;

  if ((pos + 1) > avail) {
    len = 1;
    return E_BUFFER_NOT_FULL;
  }

  unsigned char flags;

  status = pReader->Read(pos, 1, &flags);

  if (status < 0) {  // error or underflow
    len = 1;
    return status;
  }

  ++pos;  // consume flags byte
  assert(pos <= avail);

  if (pos >= block_stop)
    return E_FILE_FORMAT_INVALID;

  const int lacing = int(flags & 0x06) >> 1;

  if ((lacing != 0) && (block_stop > avail)) {
    len = static_cast<long>(block_stop - pos);
    return E_BUFFER_NOT_FULL;
  }

  status = CreateBlock(0x23,  // simple block id
                       block_start, block_size,
                       0);  // DiscardPadding

  if (status != 0)
    return status;

  m_pos = block_stop;

  return 0;  // success
}

long Cluster::ParseBlockGroup(long long payload_size, long long& pos,
                              long& len) {
  const long long payload_start = pos;
  const long long payload_stop = pos + payload_size;

  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long total, avail;

  long status = pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  if ((total >= 0) && (payload_stop > total))
    return E_FILE_FORMAT_INVALID;

  if (payload_stop > avail) {
    len = static_cast<long>(payload_size);
    return E_BUFFER_NOT_FULL;
  }

  long long discard_padding = 0;

  while (pos < payload_stop) {
    // parse sub-block element ID

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((pos + len) > payload_stop)
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long id = ReadUInt(pReader, pos, len);

    if (id < 0)  // error
      return static_cast<long>(id);

    if (id == 0)  // not a value ID
      return E_FILE_FORMAT_INVALID;

    pos += len;  // consume ID field

    // Parse Size

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((pos + len) > payload_stop)
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    pos += len;  // consume size field

    // pos now points to start of sub-block group payload

    if (pos > payload_stop)
      return E_FILE_FORMAT_INVALID;

    if (size == 0)  // weird
      continue;

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (size == unknown_size)
      return E_FILE_FORMAT_INVALID;

    if (id == 0x35A2) {  // DiscardPadding
      status = UnserializeInt(pReader, pos, size, discard_padding);

      if (status < 0)  // error
        return status;
    }

    if (id != 0x21) {  // sub-part of BlockGroup is not a Block
      pos += size;  // consume sub-part of block group

      if (pos > payload_stop)
        return E_FILE_FORMAT_INVALID;

      continue;
    }

    const long long block_stop = pos + size;

    if (block_stop > payload_stop)
      return E_FILE_FORMAT_INVALID;

    // parse track number

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((pos + len) > block_stop)
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long track = ReadUInt(pReader, pos, len);

    if (track < 0)  // error
      return static_cast<long>(track);

    if (track == 0)
      return E_FILE_FORMAT_INVALID;

#if 0
        //TODO(matthewjheaney)
        //This turned out to be too conservative.  The problem is that
        //if we see a track header in the tracks element with an unsupported
        //track type, we throw that track header away, so it is not present
        //in the track map.  But even though we don't understand the track
        //header, there are still blocks in the cluster with that track
        //number.  It was our decision to ignore that track header, so it's
        //up to us to deal with blocks associated with that track -- we
        //cannot simply report an error since technically there's nothing
        //wrong with the file.
        //
        //For now we go ahead and finish the parse, creating a block entry
        //for this block.  This is somewhat wasteful, because without a
        //track header there's nothing you can do with the block. What
        //we really need here is a special return value that indicates to
        //the caller that he should ignore this particular block, and
        //continue parsing.

        const Tracks* const pTracks = m_pSegment->GetTracks();
        assert(pTracks);

        const long tn = static_cast<long>(track);

        const Track* const pTrack = pTracks->GetTrackByNumber(tn);

        if (pTrack == NULL)
            return E_FILE_FORMAT_INVALID;
#endif

    pos += len;  // consume track number

    if ((pos + 2) > block_stop)
      return E_FILE_FORMAT_INVALID;

    if ((pos + 2) > avail) {
      len = 2;
      return E_BUFFER_NOT_FULL;
    }

    pos += 2;  // consume timecode

    if ((pos + 1) > block_stop)
      return E_FILE_FORMAT_INVALID;

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    unsigned char flags;

    status = pReader->Read(pos, 1, &flags);

    if (status < 0) {  // error or underflow
      len = 1;
      return status;
    }

    ++pos;  // consume flags byte
    assert(pos <= avail);

    if (pos >= block_stop)
      return E_FILE_FORMAT_INVALID;

    const int lacing = int(flags & 0x06) >> 1;

    if ((lacing != 0) && (block_stop > avail)) {
      len = static_cast<long>(block_stop - pos);
      return E_BUFFER_NOT_FULL;
    }

    pos = block_stop;  // consume block-part of block group
    assert(pos <= payload_stop);
  }

  assert(pos == payload_stop);

  status = CreateBlock(0x20,  // BlockGroup ID
                       payload_start, payload_size, discard_padding);
  if (status != 0)
    return status;

  m_pos = payload_stop;

  return 0;  // success
}

long Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const {
  assert(m_pos >= m_element_start);

  pEntry = NULL;

  if (index < 0)
    return -1;  // generic error

  if (m_entries_count < 0)
    return E_BUFFER_NOT_FULL;

  assert(m_entries);
  assert(m_entries_size > 0);
  assert(m_entries_count <= m_entries_size);

  if (index < m_entries_count) {
    pEntry = m_entries[index];
    assert(pEntry);

    return 1;  // found entry
  }

  if (m_element_size < 0)  // we don't know cluster end yet
    return E_BUFFER_NOT_FULL;  // underflow

  const long long element_stop = m_element_start + m_element_size;

  if (m_pos >= element_stop)
    return 0;  // nothing left to parse

  return E_BUFFER_NOT_FULL;  // underflow, since more remains to be parsed
}

Cluster* Cluster::Create(Segment* pSegment, long idx, long long off)
// long long element_size)
{
  assert(pSegment);
  assert(off >= 0);

  const long long element_start = pSegment->m_start + off;

  Cluster* const pCluster = new Cluster(pSegment, idx, element_start);
  // element_size);
  assert(pCluster);

  return pCluster;
}

Cluster::Cluster()
    : m_pSegment(NULL),
      m_element_start(0),
      m_index(0),
      m_pos(0),
      m_element_size(0),
      m_timecode(0),
      m_entries(NULL),
      m_entries_size(0),
      m_entries_count(0)  // means "no entries"
{}

Cluster::Cluster(Segment* pSegment, long idx, long long element_start
                 /* long long element_size */)
    : m_pSegment(pSegment),
      m_element_start(element_start),
      m_index(idx),
      m_pos(element_start),
      m_element_size(-1 /* element_size */),
      m_timecode(-1),
      m_entries(NULL),
      m_entries_size(0),
      m_entries_count(-1)  // means "has not been parsed yet"
{}

Cluster::~Cluster() {
  if (m_entries_count <= 0)
    return;

  BlockEntry** i = m_entries;
  BlockEntry** const j = m_entries + m_entries_count;

  while (i != j) {
    BlockEntry* p = *i++;
    assert(p);

    delete p;
  }

  delete[] m_entries;
}

bool Cluster::EOS() const { return (m_pSegment == NULL); }

long Cluster::GetIndex() const { return m_index; }

long long Cluster::GetPosition() const {
  const long long pos = m_element_start - m_pSegment->m_start;
  assert(pos >= 0);

  return pos;
}

long long Cluster::GetElementSize() const { return m_element_size; }

#if 0
bool Cluster::HasBlockEntries(
    const Segment* pSegment,
    long long off) {
    assert(pSegment);
    assert(off >= 0);  //relative to start of segment payload

    IMkvReader* const pReader = pSegment->m_pReader;

    long long pos = pSegment->m_start + off;  //absolute
    long long size;

    {
        long len;

        const long long id = ReadUInt(pReader, pos, len);
        (void)id;
        assert(id >= 0);
        assert(id == 0x0F43B675);  //Cluster ID

        pos += len;  //consume id

        size = ReadUInt(pReader, pos, len);
        assert(size > 0);

        pos += len;  //consume size

        //pos now points to start of payload
    }

    const long long stop = pos + size;

    while (pos < stop)
    {
        long len;

        const long long id = ReadUInt(pReader, pos, len);
        assert(id >= 0);  //TODO
        assert((pos + len) <= stop);

        pos += len;  //consume id

        const long long size = ReadUInt(pReader, pos, len);
        assert(size >= 0);  //TODO
        assert((pos + len) <= stop);

        pos += len;  //consume size

        if (id == 0x20)  //BlockGroup ID
            return true;

        if (id == 0x23)  //SimpleBlock ID
            return true;

        pos += size;  //consume payload
        assert(pos <= stop);
    }

    return false;
}
#endif

long Cluster::HasBlockEntries(
    const Segment* pSegment,
    long long off,  // relative to start of segment payload
    long long& pos, long& len) {
  assert(pSegment);
  assert(off >= 0);  // relative to segment

  IMkvReader* const pReader = pSegment->m_pReader;

  long long total, avail;

  long status = pReader->Length(&total, &avail);

  if (status < 0)  // error
    return status;

  assert((total < 0) || (avail <= total));

  pos = pSegment->m_start + off;  // absolute

  if ((total >= 0) && (pos >= total))
    return 0;  // we don't even have a complete cluster

  const long long segment_stop =
      (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size;

  long long cluster_stop = -1;  // interpreted later to mean "unknown size"

  {
    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // need more data
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((total >= 0) && ((pos + len) > total))
      return 0;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long id = ReadUInt(pReader, pos, len);

    if (id < 0)  // error
      return static_cast<long>(id);

    if (id != 0x0F43B675)  // weird: not cluster ID
      return -1;  // generic error

    pos += len;  // consume Cluster ID field

    // read size field

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // weird
      return E_BUFFER_NOT_FULL;

    if ((segment_stop >= 0) && ((pos + len) > segment_stop))
      return E_FILE_FORMAT_INVALID;

    if ((total >= 0) && ((pos + len) > total))
      return 0;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    if (size == 0)
      return 0;  // cluster does not have entries

    pos += len;  // consume size field

    // pos now points to start of payload

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (size != unknown_size) {
      cluster_stop = pos + size;
      assert(cluster_stop >= 0);

      if ((segment_stop >= 0) && (cluster_stop > segment_stop))
        return E_FILE_FORMAT_INVALID;

      if ((total >= 0) && (cluster_stop > total))
        // return E_FILE_FORMAT_INVALID;  //too conservative
        return 0;  // cluster does not have any entries
    }
  }

  for (;;) {
    if ((cluster_stop >= 0) && (pos >= cluster_stop))
      return 0;  // no entries detected

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    long long result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // need more data
      return E_BUFFER_NOT_FULL;

    if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long id = ReadUInt(pReader, pos, len);

    if (id < 0)  // error
      return static_cast<long>(id);

    // This is the distinguished set of ID's we use to determine
    // that we have exhausted the sub-element's inside the cluster
    // whose ID we parsed earlier.

    if (id == 0x0F43B675)  // Cluster ID
      return 0;  // no entries found

    if (id == 0x0C53BB6B)  // Cues ID
      return 0;  // no entries found

    pos += len;  // consume id field

    if ((cluster_stop >= 0) && (pos >= cluster_stop))
      return E_FILE_FORMAT_INVALID;

    // read size field

    if ((pos + 1) > avail) {
      len = 1;
      return E_BUFFER_NOT_FULL;
    }

    result = GetUIntLength(pReader, pos, len);

    if (result < 0)  // error
      return static_cast<long>(result);

    if (result > 0)  // underflow
      return E_BUFFER_NOT_FULL;

    if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > avail)
      return E_BUFFER_NOT_FULL;

    const long long size = ReadUInt(pReader, pos, len);

    if (size < 0)  // error
      return static_cast<long>(size);

    pos += len;  // consume size field

    // pos now points to start of payload

    if ((cluster_stop >= 0) && (pos > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if (size == 0)  // weird
      continue;

    const long long unknown_size = (1LL << (7 * len)) - 1;

    if (size == unknown_size)
      return E_FILE_FORMAT_INVALID;  // not supported inside cluster

    if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
      return E_FILE_FORMAT_INVALID;

    if (id == 0x20)  // BlockGroup ID
      return 1;  // have at least one entry

    if (id == 0x23)  // SimpleBlock ID
      return 1;  // have at least one entry

    pos += size;  // consume payload
    assert((cluster_stop < 0) || (pos <= cluster_stop));
  }
}

long long Cluster::GetTimeCode() const {
  long long pos;
  long len;

  const long status = Load(pos, len);

  if (status < 0)  // error
    return status;

  return m_timecode;
}

long long Cluster::GetTime() const {
  const long long tc = GetTimeCode();

  if (tc < 0)
    return tc;

  const SegmentInfo* const pInfo = m_pSegment->GetInfo();
  assert(pInfo);

  const long long scale = pInfo->GetTimeCodeScale();
  assert(scale >= 1);

  const long long t = m_timecode * scale;

  return t;
}

long long Cluster::GetFirstTime() const {
  const BlockEntry* pEntry;

  const long status = GetFirst(pEntry);

  if (status < 0)  // error
    return status;

  if (pEntry == NULL)  // empty cluster
    return GetTime();

  const Block* const pBlock = pEntry->GetBlock();
  assert(pBlock);

  return pBlock->GetTime(this);
}

long long Cluster::GetLastTime() const {
  const BlockEntry* pEntry;

  const long status = GetLast(pEntry);

  if (status < 0)  // error
    return status;

  if (pEntry == NULL)  // empty cluster
    return GetTime();

  const Block* const pBlock = pEntry->GetBlock();
  assert(pBlock);

  return pBlock->GetTime(this);
}

long Cluster::CreateBlock(long long id,
                          long long pos,  // absolute pos of payload
                          long long size, long long discard_padding) {
  assert((id == 0x20) || (id == 0x23));  // BlockGroup or SimpleBlock

  if (m_entries_count < 0) {  // haven't parsed anything yet
    assert(m_entries == NULL);
    assert(m_entries_size == 0);

    m_entries_size = 1024;
    m_entries = new BlockEntry* [m_entries_size];

    m_entries_count = 0;
  } else {
    assert(m_entries);
    assert(m_entries_size > 0);
    assert(m_entries_count <= m_entries_size);

    if (m_entries_count >= m_entries_size) {
      const long entries_size = 2 * m_entries_size;

      BlockEntry** const entries = new BlockEntry* [entries_size];
      assert(entries);

      BlockEntry** src = m_entries;
      BlockEntry** const src_end = src + m_entries_count;

      BlockEntry** dst = entries;

      while (src != src_end)
        *dst++ = *src++;

      delete[] m_entries;

      m_entries = entries;
      m_entries_size = entries_size;
    }
  }

  if (id == 0x20)  // BlockGroup ID
    return CreateBlockGroup(pos, size, discard_padding);
  else  // SimpleBlock ID
    return CreateSimpleBlock(pos, size);
}

long Cluster::CreateBlockGroup(long long start_offset, long long size,
                               long long discard_padding) {
  assert(m_entries);
  assert(m_entries_size > 0);
  assert(m_entries_count >= 0);
  assert(m_entries_count < m_entries_size);

  IMkvReader* const pReader = m_pSegment->m_pReader;

  long long pos = start_offset;
  const long long stop = start_offset + size;

  // For WebM files, there is a bias towards previous reference times
  //(in order to support alt-ref frames, which refer back to the previous
  // keyframe).  Normally a 0 value is not possible, but here we tenatively
  // allow 0 as the value of a reference frame, with the interpretation
  // that this is a "previous" reference time.

  long long prev = 1;  // nonce
  long long next = 0;  // nonce
  long long duration = -1;  // really, this is unsigned

  long long bpos = -1;
  long long bsize = -1;

  while (pos < stop) {
    long len;
    const long long id = ReadUInt(pReader, pos, len);
    assert(id >= 0);  // TODO
    assert((pos + len) <= stop);

    pos += len;  // consume ID

    const long long size = ReadUInt(pReader, pos, len);
    assert(size >= 0);  // TODO
    assert((pos + len) <= stop);

    pos += len;  // consume size

    if (id == 0x21) {  // Block ID
      if (bpos < 0) {  // Block ID
        bpos = pos;
        bsize = size;
      }
    } else if (id == 0x1B) {  // Duration ID
      assert(size <= 8);

      duration = UnserializeUInt(pReader, pos, size);
      assert(duration >= 0);  // TODO
    } else if (id == 0x7B) {  // ReferenceBlock
      assert(size <= 8);
      const long size_ = static_cast<long>(size);

      long long time;

      long status = UnserializeInt(pReader, pos, size_, time);
      assert(status == 0);
      if (status != 0)
        return -1;

      if (time <= 0)  // see note above
        prev = time;
      else  // weird
        next = time;
    }

    pos += size;  // consume payload
    assert(pos <= stop);
  }

  assert(pos == stop);
  assert(bpos >= 0);
  assert(bsize >= 0);

  const long idx = m_entries_count;

  BlockEntry** const ppEntry = m_entries + idx;
  BlockEntry*& pEntry = *ppEntry;

  pEntry = new (std::nothrow)
      BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding);

  if (pEntry == NULL)
    return -1;  // generic error

  BlockGroup* const p = static_cast<BlockGroup*>(pEntry);

  const long status = p->Parse();

  if (status == 0) {  // success
    ++m_entries_count;
    return 0;
  }

  delete pEntry;
  pEntry = 0;

  return status;
}

long Cluster::CreateSimpleBlock(long long st, long long sz) {
  assert(m_entries);
  assert(m_entries_size > 0);
  assert(m_entries_count >= 0);
  assert(m_entries_count < m_entries_size);

  const long idx = m_entries_count;

  BlockEntry** const ppEntry = m_entries + idx;
  BlockEntry*& pEntry = *ppEntry;

  pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz);

  if (pEntry == NULL)
    return -1;  // generic error

  SimpleBlock* const p = static_cast<SimpleBlock*>(pEntry);

  const long status = p->Parse();

  if (status == 0) {
    ++m_entries_count;
    return 0;
  }

  delete pEntry;
  pEntry = 0;

  return status;
}

long Cluster::GetFirst(const BlockEntry*& pFirst) const {
  if (m_entries_count <= 0) {
    long long pos;
    long len;

    const long status = Parse(pos, len);

    if (status < 0) {  // error
      pFirst = NULL;
      return status;
    }

    if (m_entries_count <= 0) {  // empty cluster
      pFirst = NULL;
      return 0;
    }
  }

  assert(m_entries);

  pFirst = m_entries[0];
  assert(pFirst);

  return 0;  // success
}

long Cluster::GetLast(const BlockEntry*& pLast) const {
  for (;;) {
    long long pos;
    long len;

    const long status = Parse(pos, len);

    if (status < 0) {  // error
      pLast = NULL;
      return status;
    }

    if (status > 0)  // no new block
      break;
  }

  if (m_entries_count <= 0) {
    pLast = NULL;
    return 0;
  }

  assert(m_entries);

  const long idx = m_entries_count - 1;

  pLast = m_entries[idx];
  assert(pLast);

  return 0;
}

long Cluster::GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const {
  assert(pCurr);
  assert(m_entries);
  assert(m_entries_count > 0);

  size_t idx = pCurr->GetIndex();
  assert(idx < size_t(m_entries_count));
  assert(m_entries[idx] == pCurr);

  ++idx;

  if (idx >= size_t(m_entries_count)) {
    long long pos;
    long len;

    const long status = Parse(pos, len);

    if (status < 0) {  // error
      pNext = NULL;
      return status;
    }

    if (status > 0) {
      pNext = NULL;
      return 0;
    }

    assert(m_entries);
    assert(m_entries_count > 0);
    assert(idx < size_t(m_entries_count));
  }

  pNext = m_entries[idx];
  assert(pNext);

  return 0;
}

long Cluster::GetEntryCount() const { return m_entries_count; }

const BlockEntry* Cluster::GetEntry(const Track* pTrack,
                                    long long time_ns) const {
  assert(pTrack);

  if (m_pSegment == NULL)  // this is the special EOS cluster
    return pTrack->GetEOS();

#if 0

    LoadBlockEntries();

    if ((m_entries == NULL) || (m_entries_count <= 0))
        return NULL;  //return EOS here?

    const BlockEntry* pResult = pTrack->GetEOS();

    BlockEntry** i = m_entries;
    assert(i);

    BlockEntry** const j = i + m_entries_count;

    while (i != j)
    {
        const BlockEntry* const pEntry = *i++;
        assert(pEntry);
        assert(!pEntry->EOS());

        const Block* const pBlock = pEntry->GetBlock();
        assert(pBlock);

        if (pBlock->GetTrackNumber() != pTrack->GetNumber())
            continue;

        if (pTrack->VetEntry(pEntry))
        {
            if (time_ns < 0)  //just want first candidate block
                return pEntry;

            const long long ns = pBlock->GetTime(this);

            if (ns > time_ns)
                break;

            pResult = pEntry;
        }
        else if (time_ns >= 0)
        {
            const long long ns = pBlock->GetTime(this);

            if (ns > time_ns)
                break;
        }
    }

    return pResult;

#else

  const BlockEntry* pResult = pTrack->GetEOS();

  long index = 0;

  for (;;) {
    if (index >= m_entries_count) {
      long long pos;
      long len;

      const long status = Parse(pos, len);
      assert(status >= 0);

      if (status > 0)  // completely parsed, and no more entries
        return pResult;

      if (status < 0)  // should never happen
        return 0;

      assert(m_entries);
      assert(index < m_entries_count);
    }

    const BlockEntry* const pEntry = m_entries[index];
    assert(pEntry);
    assert(!pEntry->EOS());

    const Block* const pBlock = pEntry->GetBlock();
    assert(pBlock);

    if (pBlock->GetTrackNumber() != pTrack->GetNumber()) {
      ++index;
      continue;
    }

    if (pTrack->VetEntry(pEntry)) {
      if (time_ns < 0)  // just want first candidate block
        return pEntry;

      const long long ns = pBlock->GetTime(this);

      if (ns > time_ns)
        return pResult;

      pResult = pEntry;  // have a candidate
    } else if (time_ns >= 0) {
      const long long ns = pBlock->GetTime(this);

      if (ns > time_ns)
        return pResult;
    }

    ++index;
  }

#endif
}

const BlockEntry* Cluster::GetEntry(const CuePoint& cp,
                                    const CuePoint::TrackPosition& tp) const {
  assert(m_pSegment);

#if 0

    LoadBlockEntries();

    if (m_entries == NULL)
        return NULL;

    const long long count = m_entries_count;

    if (count <= 0)
        return NULL;

    const long long tc = cp.GetTimeCode();

    if ((tp.m_block > 0) && (tp.m_block <= count))
    {
        const size_t block = static_cast<size_t>(tp.m_block);
        const size_t index = block - 1;

        const BlockEntry* const pEntry = m_entries[index];
        assert(pEntry);
        assert(!pEntry->EOS());

        const Block* const pBlock = pEntry->GetBlock();
        assert(pBlock);

        if ((pBlock->GetTrackNumber() == tp.m_track) &&
            (pBlock->GetTimeCode(this) == tc))
        {
            return pEntry;
        }
    }

    const BlockEntry* const* i = m_entries;
    const BlockEntry* const* const j = i + count;

    while (i != j)
    {
#ifdef _DEBUG
        const ptrdiff_t idx = i - m_entries;
        idx;
#endif

        const BlockEntry* const pEntry = *i++;
        assert(pEntry);
        assert(!pEntry->EOS());

        const Block* const pBlock = pEntry->GetBlock();
        assert(pBlock);

        if (pBlock->GetTrackNumber() != tp.m_track)
            continue;

        const long long tc_ = pBlock->GetTimeCode(this);
        assert(tc_ >= 0);

        if (tc_ < tc)
            continue;

        if (tc_ > tc)
            return NULL;

        const Tracks* const pTracks = m_pSegment->GetTracks();
        assert(pTracks);

        const long tn = static_cast<long>(tp.m_track);
        const Track* const pTrack = pTracks->GetTrackByNumber(tn);

        if (pTrack == NULL)
            return NULL;

        const long long type = pTrack->GetType();

        if (type == 2)  //audio
            return pEntry;

        if (type != 1)  //not video
            return NULL;

        if (!pBlock->IsKey())
            return NULL;

        return pEntry;
    }

    return NULL;

#else

  const long long tc = cp.GetTimeCode();

  if (tp.m_block > 0) {
    const long block = static_cast<long>(tp.m_block);
    const long index = block - 1;

    while (index >= m_entries_count) {
      long long pos;
      long len;

      const long status = Parse(pos, len);

      if (status < 0)  // TODO: can this happen?
        return NULL;

      if (status > 0)  // nothing remains to be parsed
        return NULL;
    }

    const BlockEntry* const pEntry = m_entries[index];
    assert(pEntry);
    assert(!pEntry->EOS());

    const Block* const pBlock = pEntry->GetBlock();
    assert(pBlock);

    if ((pBlock->GetTrackNumber() == tp.m_track) &&
        (pBlock->GetTimeCode(this) == tc)) {
      return pEntry;
    }
  }

  long index = 0;

  for (;;) {
    if (index >= m_entries_count) {
      long long pos;
      long len;

      const long status = Parse(pos, len);

      if (status < 0)  // TODO: can this happen?
        return NULL;

      if (status > 0)  // nothing remains to be parsed
        return NULL;

      assert(m_entries);
      assert(index < m_entries_count);
    }

    const BlockEntry* const pEntry = m_entries[index];
    assert(pEntry);
    assert(!pEntry->EOS());

    const Block* const pBlock = pEntry->GetBlock();
    assert(pBlock);

    if (pBlock->GetTrackNumber() != tp.m_track) {
      ++index;
      continue;
    }

    const long long tc_ = pBlock->GetTimeCode(this);

    if (tc_ < tc) {
      ++index;
      continue;
    }

    if (tc_ > tc)
      return NULL;

    const Tracks* const pTracks = m_pSegment->GetTracks();
    assert(pTracks);

    const long tn = static_cast<long>(tp.m_track);
    const Track* const pTrack = pTracks->GetTrackByNumber(tn);

    if (pTrack == NULL)
      return NULL;

    const long long type = pTrack->GetType();

    if (type == 2)  // audio
      return pEntry;

    if (type != 1)  // not video
      return NULL;

    if (!pBlock->IsKey())
      return NULL;

    return pEntry;
  }

#endif
}

#if 0
const BlockEntry* Cluster::GetMaxKey(const VideoTrack* pTrack) const
{
    assert(pTrack);

    if (m_pSegment == NULL)  //EOS
        return pTrack->GetEOS();

    LoadBlockEntries();

    if ((m_entries == NULL) || (m_entries_count <= 0))
        return pTrack->GetEOS();

    BlockEntry** i = m_entries + m_entries_count;
    BlockEntry** const j = m_entries;

    while (i != j)
    {
        const BlockEntry* const pEntry = *--i;
        assert(pEntry);
        assert(!pEntry->EOS());

        const Block* const pBlock = pEntry->GetBlock();
        assert(pBlock);

        if (pBlock->GetTrackNumber() != pTrack->GetNumber())
            continue;

        if (pBlock->IsKey())
            return pEntry;
    }

    return pTrack->GetEOS();  //no satisfactory block found
}
#endif

BlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {}

BlockEntry::~BlockEntry() {}

bool BlockEntry::EOS() const { return (GetKind() == kBlockEOS); }

const Cluster* BlockEntry::GetCluster() const { return m_pCluster; }

long BlockEntry::GetIndex() const { return m_index; }

SimpleBlock::SimpleBlock(Cluster* pCluster, long idx, long long start,
                         long long size)
    : BlockEntry(pCluster, idx), m_block(start, size, 0) {}

long SimpleBlock::Parse() { return m_block.Parse(m_pCluster); }

BlockEntry::Kind SimpleBlock::GetKind() const { return kBlockSimple; }

const Block* SimpleBlock::GetBlock() const { return &m_block; }

BlockGroup::BlockGroup(Cluster* pCluster, long idx, long long block_start,
                       long long block_size, long long prev, long long next,
                       long long duration, long long discard_padding)
    : BlockEntry(pCluster, idx),
      m_block(block_start, block_size, discard_padding),
      m_prev(prev),
      m_next(next),
      m_duration(duration) {}

long BlockGroup::Parse() {
  const long status = m_block.Parse(m_pCluster);

  if (status)
    return status;

  m_block.SetKey((m_prev > 0) && (m_next <= 0));

  return 0;
}

#if 0
void BlockGroup::ParseBlock(long long start, long long size)
{
    IMkvReader* const pReader = m_pCluster->m_pSegment->m_pReader;

    Block* const pBlock = new Block(start, size, pReader);
    assert(pBlock);  //TODO

    //TODO: the Matroska spec says you have multiple blocks within the
    //same block group, with blocks ranked by priority (the flag bits).

    assert(m_pBlock == NULL);
    m_pBlock = pBlock;
}
#endif

BlockEntry::Kind BlockGroup::GetKind() const { return kBlockGroup; }

const Block* BlockGroup::GetBlock() const { return &m_block; }

long long BlockGroup::GetPrevTimeCode() const { return m_prev; }

long long BlockGroup::GetNextTimeCode() const { return m_next; }

long long BlockGroup::GetDurationTimeCode() const { return m_duration; }

Block::Block(long long start, long long size_, long long discard_padding)
    : m_start(start),
      m_size(size_),
      m_track(0),
      m_timecode(-1),
      m_flags(0),
      m_frames(NULL),
      m_frame_count(-1),
      m_discard_padding(discard_padding) {}

Block::~Block() { delete[] m_frames; }

long Block::Parse(const Cluster* pCluster) {
  if (pCluster == NULL)
    return -1;

  if (pCluster->m_pSegment == NULL)
    return -1;

  assert(m_start >= 0);
  assert(m_size >= 0);
  assert(m_track <= 0);
  assert(m_frames == NULL);
  assert(m_frame_count <= 0);

  long long pos = m_start;
  const long long stop = m_start + m_size;

  long len;

  IMkvReader* const pReader = pCluster->m_pSegment->m_pReader;

  m_track = ReadUInt(pReader, pos, len);

  if (m_track <= 0)
    return E_FILE_FORMAT_INVALID;

  if ((pos + len) > stop)
    return E_FILE_FORMAT_INVALID;

  pos += len;  // consume track number

  if ((stop - pos) < 2)
    return E_FILE_FORMAT_INVALID;

  long status;
  long long value;

  status = UnserializeInt(pReader, pos, 2, value);

  if (status)
    return E_FILE_FORMAT_INVALID;

  if (value < SHRT_MIN)
    return E_FILE_FORMAT_INVALID;

  if (value > SHRT_MAX)
    return E_FILE_FORMAT_INVALID;

  m_timecode = static_cast<short>(value);

  pos += 2;

  if ((stop - pos) <= 0)
    return E_FILE_FORMAT_INVALID;

  status = pReader->Read(pos, 1, &m_flags);

  if (status)
    return E_FILE_FORMAT_INVALID;

  const int lacing = int(m_flags & 0x06) >> 1;

  ++pos;  // consume flags byte

  if (lacing == 0) {  // no lacing
    if (pos > stop)
      return E_FILE_FORMAT_INVALID;

    m_frame_count = 1;
    m_frames = new Frame[m_frame_count];

    Frame& f = m_frames[0];
    f.pos = pos;

    const long long frame_size = stop - pos;

    if (frame_size > LONG_MAX)
      return E_FILE_FORMAT_INVALID;

    f.len = static_cast<long>(frame_size);

    return 0;  // success
  }

  if (pos >= stop)
    return E_FILE_FORMAT_INVALID;

  unsigned char biased_count;

  status = pReader->Read(pos, 1, &biased_count);

  if (status)
    return E_FILE_FORMAT_INVALID;

  ++pos;  // consume frame count
  assert(pos <= stop);

  m_frame_count = int(biased_count) + 1;

  m_frames = new Frame[m_frame_count];
  assert(m_frames);

  if (lacing == 1) {  // Xiph
    Frame* pf = m_frames;
    Frame* const pf_end = pf + m_frame_count;

    long size = 0;
    int frame_count = m_frame_count;

    while (frame_count > 1) {
      long frame_size = 0;

      for (;;) {
        unsigned char val;

        if (pos >= stop)
          return E_FILE_FORMAT_INVALID;

        status = pReader->Read(pos, 1, &val);

        if (status)
          return E_FILE_FORMAT_INVALID;

        ++pos;  // consume xiph size byte

        frame_size += val;

        if (val < 255)
          break;
      }

      Frame& f = *pf++;
      assert(pf < pf_end);

      f.pos = 0;  // patch later

      f.len = frame_size;
      size += frame_size;  // contribution of this frame

      --frame_count;
    }

    assert(pf < pf_end);
    assert(pos <= stop);

    {
      Frame& f = *pf++;

      if (pf != pf_end)
        return E_FILE_FORMAT_INVALID;

      f.pos = 0;  // patch later

      const long long total_size = stop - pos;

      if (total_size < size)
        return E_FILE_FORMAT_INVALID;

      const long long frame_size = total_size - size;

      if (frame_size > LONG_MAX)
        return E_FILE_FORMAT_INVALID;

      f.len = static_cast<long>(frame_size);
    }

    pf = m_frames;
    while (pf != pf_end) {
      Frame& f = *pf++;
      assert((pos + f.len) <= stop);

      f.pos = pos;
      pos += f.len;
    }

    assert(pos == stop);
  } else if (lacing == 2) {  // fixed-size lacing
    const long long total_size = stop - pos;

    if ((total_size % m_frame_count) != 0)
      return E_FILE_FORMAT_INVALID;

    const long long frame_size = total_size / m_frame_count;

    if (frame_size > LONG_MAX)
      return E_FILE_FORMAT_INVALID;

    Frame* pf = m_frames;
    Frame* const pf_end = pf + m_frame_count;

    while (pf != pf_end) {
      assert((pos + frame_size) <= stop);

      Frame& f = *pf++;

      f.pos = pos;
      f.len = static_cast<long>(frame_size);

      pos += frame_size;
    }

    assert(pos == stop);
  } else {
    assert(lacing == 3);  // EBML lacing

    if (pos >= stop)
      return E_FILE_FORMAT_INVALID;

    long size = 0;
    int frame_count = m_frame_count;

    long long frame_size = ReadUInt(pReader, pos, len);

    if (frame_size < 0)
      return E_FILE_FORMAT_INVALID;

    if (frame_size > LONG_MAX)
      return E_FILE_FORMAT_INVALID;

    if ((pos + len) > stop)
      return E_FILE_FORMAT_INVALID;

    pos += len;  // consume length of size of first frame

    if ((pos + frame_size) > stop)
      return E_FILE_FORMAT_INVALID;

    Frame* pf = m_frames;
    Frame* const pf_end = pf + m_frame_count;

    {
      Frame& curr = *pf;

      curr.pos = 0;  // patch later

      curr.len = static_cast<long>(frame_size);
      size += curr.len;  // contribution of this frame
    }

    --frame_count;

    while (frame_count > 1) {
      if (pos >= stop)
        return E_FILE_FORMAT_INVALID;

      assert(pf < pf_end);

      const Frame& prev = *pf++;
      assert(prev.len == frame_size);
      if (prev.len != frame_size)
        return E_FILE_FORMAT_INVALID;

      assert(pf < pf_end);

      Frame& curr = *pf;

      curr.pos = 0;  // patch later

      const long long delta_size_ = ReadUInt(pReader, pos, len);

      if (delta_size_ < 0)
        return E_FILE_FORMAT_INVALID;

      if ((pos + len) > stop)
        return E_FILE_FORMAT_INVALID;

      pos += len;  // consume length of (delta) size
      assert(pos <= stop);

      const int exp = 7 * len - 1;
      const long long bias = (1LL << exp) - 1LL;
      const long long delta_size = delta_size_ - bias;

      frame_size += delta_size;

      if (frame_size < 0)
        return E_FILE_FORMAT_INVALID;

      if (frame_size > LONG_MAX)
        return E_FILE_FORMAT_INVALID;

      curr.len = static_cast<long>(frame_size);
      size += curr.len;  // contribution of this frame

      --frame_count;
    }

    {
      assert(pos <= stop);
      assert(pf < pf_end);

      const Frame& prev = *pf++;
      assert(prev.len == frame_size);
      if (prev.len != frame_size)
        return E_FILE_FORMAT_INVALID;

      assert(pf < pf_end);

      Frame& curr = *pf++;
      assert(pf == pf_end);

      curr.pos = 0;  // patch later

      const long long total_size = stop - pos;

      if (total_size < size)
        return E_FILE_FORMAT_INVALID;

      frame_size = total_size - size;

      if (frame_size > LONG_MAX)
        return E_FILE_FORMAT_INVALID;

      curr.len = static_cast<long>(frame_size);
    }

    pf = m_frames;
    while (pf != pf_end) {
      Frame& f = *pf++;
      assert((pos + f.len) <= stop);

      f.pos = pos;
      pos += f.len;
    }

    assert(pos == stop);
  }

  return 0;  // success
}

long long Block::GetTimeCode(const Cluster* pCluster) const {
  if (pCluster == 0)
    return m_timecode;

  const long long tc0 = pCluster->GetTimeCode();
  assert(tc0 >= 0);

  const long long tc = tc0 + m_timecode;

  return tc;  // unscaled timecode units
}

long long Block::GetTime(const Cluster* pCluster) const {
  assert(pCluster);

  const long long tc = GetTimeCode(pCluster);

  const Segment* const pSegment = pCluster->m_pSegment;
  const SegmentInfo* const pInfo = pSegment->GetInfo();
  assert(pInfo);

  const long long scale = pInfo->GetTimeCodeScale();
  assert(scale >= 1);

  const long long ns = tc * scale;

  return ns;
}

long long Block::GetTrackNumber() const { return m_track; }

bool Block::IsKey() const {
  return ((m_flags & static_cast<unsigned char>(1 << 7)) != 0);
}

void Block::SetKey(bool bKey) {
  if (bKey)
    m_flags |= static_cast<unsigned char>(1 << 7);
  else
    m_flags &= 0x7F;
}

bool Block::IsInvisible() const { return bool(int(m_flags & 0x08) != 0); }

Block::Lacing Block::GetLacing() const {
  const int value = int(m_flags & 0x06) >> 1;
  return static_cast<Lacing>(value);
}

int Block::GetFrameCount() const { return m_frame_count; }

const Block::Frame& Block::GetFrame(int idx) const {
  assert(idx >= 0);
  assert(idx < m_frame_count);

  const Frame& f = m_frames[idx];
  assert(f.pos > 0);
  assert(f.len > 0);

  return f;
}

long Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const {
  assert(pReader);
  assert(buf);

  const long status = pReader->Read(pos, len, buf);
  return status;
}

long long Block::GetDiscardPadding() const { return m_discard_padding; }

}  // end namespace mkvparser
