// 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.

#ifndef MKVPARSER_HPP
#define MKVPARSER_HPP

#include <cstdlib>
#include <cstdio>
#include <cstddef>

namespace mkvparser {

const int E_FILE_FORMAT_INVALID = -2;
const int E_BUFFER_NOT_FULL = -3;

class IMkvReader {
 public:
  virtual int Read(long long pos, long len, unsigned char* buf) = 0;
  virtual int Length(long long* total, long long* available) = 0;

 protected:
  virtual ~IMkvReader();
};

long long GetUIntLength(IMkvReader*, long long, long&);
long long ReadUInt(IMkvReader*, long long, long&);
long long UnserializeUInt(IMkvReader*, long long pos, long long size);

long UnserializeFloat(IMkvReader*, long long pos, long long size, double&);
long UnserializeInt(IMkvReader*, long long pos, long len, long long& result);

long UnserializeString(IMkvReader*, long long pos, long long size, char*& str);

long ParseElementHeader(IMkvReader* pReader,
                        long long& pos,  // consume id and size fields
                        long long stop,  // if you know size of element's parent
                        long long& id, long long& size);

bool Match(IMkvReader*, long long&, unsigned long, long long&);
bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&);

void GetVersion(int& major, int& minor, int& build, int& revision);

struct EBMLHeader {
  EBMLHeader();
  ~EBMLHeader();
  long long m_version;
  long long m_readVersion;
  long long m_maxIdLength;
  long long m_maxSizeLength;
  char* m_docType;
  long long m_docTypeVersion;
  long long m_docTypeReadVersion;

  long long Parse(IMkvReader*, long long&);
  void Init();
};

class Segment;
class Track;
class Cluster;

class Block {
  Block(const Block&);
  Block& operator=(const Block&);

 public:
  const long long m_start;
  const long long m_size;

  Block(long long start, long long size, long long discard_padding);
  ~Block();

  long Parse(const Cluster*);

  long long GetTrackNumber() const;
  long long GetTimeCode(const Cluster*) const;  // absolute, but not scaled
  long long GetTime(const Cluster*) const;  // absolute, and scaled (ns)
  bool IsKey() const;
  void SetKey(bool);
  bool IsInvisible() const;

  enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml };
  Lacing GetLacing() const;

  int GetFrameCount() const;  // to index frames: [0, count)

  struct Frame {
    long long pos;  // absolute offset
    long len;

    long Read(IMkvReader*, unsigned char*) const;
  };

  const Frame& GetFrame(int frame_index) const;

  long long GetDiscardPadding() const;

 private:
  long long m_track;  // Track::Number()
  short m_timecode;  // relative to cluster
  unsigned char m_flags;

  Frame* m_frames;
  int m_frame_count;

 protected:
  const long long m_discard_padding;
};

class BlockEntry {
  BlockEntry(const BlockEntry&);
  BlockEntry& operator=(const BlockEntry&);

 protected:
  BlockEntry(Cluster*, long index);

 public:
  virtual ~BlockEntry();

  bool EOS() const;
  const Cluster* GetCluster() const;
  long GetIndex() const;
  virtual const Block* GetBlock() const = 0;

  enum Kind { kBlockEOS, kBlockSimple, kBlockGroup };
  virtual Kind GetKind() const = 0;

 protected:
  Cluster* const m_pCluster;
  const long m_index;
};

class SimpleBlock : public BlockEntry {
  SimpleBlock(const SimpleBlock&);
  SimpleBlock& operator=(const SimpleBlock&);

 public:
  SimpleBlock(Cluster*, long index, long long start, long long size);
  long Parse();

  Kind GetKind() const;
  const Block* GetBlock() const;

 protected:
  Block m_block;
};

class BlockGroup : public BlockEntry {
  BlockGroup(const BlockGroup&);
  BlockGroup& operator=(const BlockGroup&);

 public:
  BlockGroup(Cluster*, long index,
             long long block_start,  // absolute pos of block's payload
             long long block_size,  // size of block's payload
             long long prev, long long next, long long duration,
             long long discard_padding);

  long Parse();

  Kind GetKind() const;
  const Block* GetBlock() const;

  long long GetPrevTimeCode() const;  // relative to block's time
  long long GetNextTimeCode() const;  // as above
  long long GetDurationTimeCode() const;

 private:
  Block m_block;
  const long long m_prev;
  const long long m_next;
  const long long m_duration;
};

///////////////////////////////////////////////////////////////
// ContentEncoding element
// Elements used to describe if the track data has been encrypted or
// compressed with zlib or header stripping.
class ContentEncoding {
 public:
  enum { kCTR = 1 };

  ContentEncoding();
  ~ContentEncoding();

  // ContentCompression element names
  struct ContentCompression {
    ContentCompression();
    ~ContentCompression();

    unsigned long long algo;
    unsigned char* settings;
    long long settings_len;
  };

  // ContentEncAESSettings element names
  struct ContentEncAESSettings {
    ContentEncAESSettings() : cipher_mode(kCTR) {}
    ~ContentEncAESSettings() {}

    unsigned long long cipher_mode;
  };

  // ContentEncryption element names
  struct ContentEncryption {
    ContentEncryption();
    ~ContentEncryption();

    unsigned long long algo;
    unsigned char* key_id;
    long long key_id_len;
    unsigned char* signature;
    long long signature_len;
    unsigned char* sig_key_id;
    long long sig_key_id_len;
    unsigned long long sig_algo;
    unsigned long long sig_hash_algo;

    ContentEncAESSettings aes_settings;
  };

  // Returns ContentCompression represented by |idx|. Returns NULL if |idx|
  // is out of bounds.
  const ContentCompression* GetCompressionByIndex(unsigned long idx) const;

  // Returns number of ContentCompression elements in this ContentEncoding
  // element.
  unsigned long GetCompressionCount() const;

  // Parses the ContentCompression element from |pReader|. |start| is the
  // starting offset of the ContentCompression payload. |size| is the size in
  // bytes of the ContentCompression payload. |compression| is where the parsed
  // values will be stored.
  long ParseCompressionEntry(long long start, long long size,
                             IMkvReader* pReader,
                             ContentCompression* compression);

  // Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
  // is out of bounds.
  const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;

  // Returns number of ContentEncryption elements in this ContentEncoding
  // element.
  unsigned long GetEncryptionCount() const;

  // Parses the ContentEncAESSettings element from |pReader|. |start| is the
  // starting offset of the ContentEncAESSettings payload. |size| is the
  // size in bytes of the ContentEncAESSettings payload. |encryption| is
  // where the parsed values will be stored.
  long ParseContentEncAESSettingsEntry(long long start, long long size,
                                       IMkvReader* pReader,
                                       ContentEncAESSettings* aes);

  // Parses the ContentEncoding element from |pReader|. |start| is the
  // starting offset of the ContentEncoding payload. |size| is the size in
  // bytes of the ContentEncoding payload. Returns true on success.
  long ParseContentEncodingEntry(long long start, long long size,
                                 IMkvReader* pReader);

  // Parses the ContentEncryption element from |pReader|. |start| is the
  // starting offset of the ContentEncryption payload. |size| is the size in
  // bytes of the ContentEncryption payload. |encryption| is where the parsed
  // values will be stored.
  long ParseEncryptionEntry(long long start, long long size,
                            IMkvReader* pReader, ContentEncryption* encryption);

  unsigned long long encoding_order() const { return encoding_order_; }
  unsigned long long encoding_scope() const { return encoding_scope_; }
  unsigned long long encoding_type() const { return encoding_type_; }

 private:
  // Member variables for list of ContentCompression elements.
  ContentCompression** compression_entries_;
  ContentCompression** compression_entries_end_;

  // Member variables for list of ContentEncryption elements.
  ContentEncryption** encryption_entries_;
  ContentEncryption** encryption_entries_end_;

  // ContentEncoding element names
  unsigned long long encoding_order_;
  unsigned long long encoding_scope_;
  unsigned long long encoding_type_;

  // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
  ContentEncoding(const ContentEncoding&);
  ContentEncoding& operator=(const ContentEncoding&);
};

class Track {
  Track(const Track&);
  Track& operator=(const Track&);

 public:
  class Info;
  static long Create(Segment*, const Info&, long long element_start,
                     long long element_size, Track*&);

  enum Type { kVideo = 1, kAudio = 2, kSubtitle = 0x11, kMetadata = 0x21 };

  Segment* const m_pSegment;
  const long long m_element_start;
  const long long m_element_size;
  virtual ~Track();

  long GetType() const;
  long GetNumber() const;
  unsigned long long GetUid() const;
  const char* GetNameAsUTF8() const;
  const char* GetLanguage() const;
  const char* GetCodecNameAsUTF8() const;
  const char* GetCodecId() const;
  const unsigned char* GetCodecPrivate(size_t&) const;
  bool GetLacing() const;
  unsigned long long GetDefaultDuration() const;
  unsigned long long GetCodecDelay() const;
  unsigned long long GetSeekPreRoll() const;

  const BlockEntry* GetEOS() const;

  struct Settings {
    long long start;
    long long size;
  };

  class Info {
   public:
    Info();
    ~Info();
    int Copy(Info&) const;
    void Clear();
    long type;
    long number;
    unsigned long long uid;
    unsigned long long defaultDuration;
    unsigned long long codecDelay;
    unsigned long long seekPreRoll;
    char* nameAsUTF8;
    char* language;
    char* codecId;
    char* codecNameAsUTF8;
    unsigned char* codecPrivate;
    size_t codecPrivateSize;
    bool lacing;
    Settings settings;

   private:
    Info(const Info&);
    Info& operator=(const Info&);
    int CopyStr(char* Info::*str, Info&) const;
  };

  long GetFirst(const BlockEntry*&) const;
  long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
  virtual bool VetEntry(const BlockEntry*) const;
  virtual long Seek(long long time_ns, const BlockEntry*&) const;

  const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const;
  unsigned long GetContentEncodingCount() const;

  long ParseContentEncodingsEntry(long long start, long long size);

 protected:
  Track(Segment*, long long element_start, long long element_size);

  Info m_info;

  class EOSBlock : public BlockEntry {
   public:
    EOSBlock();

    Kind GetKind() const;
    const Block* GetBlock() const;
  };

  EOSBlock m_eos;

 private:
  ContentEncoding** content_encoding_entries_;
  ContentEncoding** content_encoding_entries_end_;
};

class VideoTrack : public Track {
  VideoTrack(const VideoTrack&);
  VideoTrack& operator=(const VideoTrack&);

  VideoTrack(Segment*, long long element_start, long long element_size);

 public:
  static long Parse(Segment*, const Info&, long long element_start,
                    long long element_size, VideoTrack*&);

  long long GetWidth() const;
  long long GetHeight() const;
  double GetFrameRate() const;

  bool VetEntry(const BlockEntry*) const;
  long Seek(long long time_ns, const BlockEntry*&) const;

 private:
  long long m_width;
  long long m_height;
  double m_rate;
};

class AudioTrack : public Track {
  AudioTrack(const AudioTrack&);
  AudioTrack& operator=(const AudioTrack&);

  AudioTrack(Segment*, long long element_start, long long element_size);

 public:
  static long Parse(Segment*, const Info&, long long element_start,
                    long long element_size, AudioTrack*&);

  double GetSamplingRate() const;
  long long GetChannels() const;
  long long GetBitDepth() const;

 private:
  double m_rate;
  long long m_channels;
  long long m_bitDepth;
};

class Tracks {
  Tracks(const Tracks&);
  Tracks& operator=(const Tracks&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  Tracks(Segment*, long long start, long long size, long long element_start,
         long long element_size);

  ~Tracks();

  long Parse();

  unsigned long GetTracksCount() const;

  const Track* GetTrackByNumber(long tn) const;
  const Track* GetTrackByIndex(unsigned long idx) const;

 private:
  Track** m_trackEntries;
  Track** m_trackEntriesEnd;

  long ParseTrackEntry(long long payload_start, long long payload_size,
                       long long element_start, long long element_size,
                       Track*&) const;
};

class Chapters {
  Chapters(const Chapters&);
  Chapters& operator=(const Chapters&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  Chapters(Segment*, long long payload_start, long long payload_size,
           long long element_start, long long element_size);

  ~Chapters();

  long Parse();

  class Atom;
  class Edition;

  class Display {
    friend class Atom;
    Display();
    Display(const Display&);
    ~Display();
    Display& operator=(const Display&);

   public:
    const char* GetString() const;
    const char* GetLanguage() const;
    const char* GetCountry() const;

   private:
    void Init();
    void ShallowCopy(Display&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);

    char* m_string;
    char* m_language;
    char* m_country;
  };

  class Atom {
    friend class Edition;
    Atom();
    Atom(const Atom&);
    ~Atom();
    Atom& operator=(const Atom&);

   public:
    unsigned long long GetUID() const;
    const char* GetStringUID() const;

    long long GetStartTimecode() const;
    long long GetStopTimecode() const;

    long long GetStartTime(const Chapters*) const;
    long long GetStopTime(const Chapters*) const;

    int GetDisplayCount() const;
    const Display* GetDisplay(int index) const;

   private:
    void Init();
    void ShallowCopy(Atom&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);
    static long long GetTime(const Chapters*, long long timecode);

    long ParseDisplay(IMkvReader*, long long pos, long long size);
    bool ExpandDisplaysArray();

    char* m_string_uid;
    unsigned long long m_uid;
    long long m_start_timecode;
    long long m_stop_timecode;

    Display* m_displays;
    int m_displays_size;
    int m_displays_count;
  };

  class Edition {
    friend class Chapters;
    Edition();
    Edition(const Edition&);
    ~Edition();
    Edition& operator=(const Edition&);

   public:
    int GetAtomCount() const;
    const Atom* GetAtom(int index) const;

   private:
    void Init();
    void ShallowCopy(Edition&) const;
    void Clear();
    long Parse(IMkvReader*, long long pos, long long size);

    long ParseAtom(IMkvReader*, long long pos, long long size);
    bool ExpandAtomsArray();

    Atom* m_atoms;
    int m_atoms_size;
    int m_atoms_count;
  };

  int GetEditionCount() const;
  const Edition* GetEdition(int index) const;

 private:
  long ParseEdition(long long pos, long long size);
  bool ExpandEditionsArray();

  Edition* m_editions;
  int m_editions_size;
  int m_editions_count;
};

class SegmentInfo {
  SegmentInfo(const SegmentInfo&);
  SegmentInfo& operator=(const SegmentInfo&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  SegmentInfo(Segment*, long long start, long long size,
              long long element_start, long long element_size);

  ~SegmentInfo();

  long Parse();

  long long GetTimeCodeScale() const;
  long long GetDuration() const;  // scaled
  const char* GetMuxingAppAsUTF8() const;
  const char* GetWritingAppAsUTF8() const;
  const char* GetTitleAsUTF8() const;

 private:
  long long m_timecodeScale;
  double m_duration;
  char* m_pMuxingAppAsUTF8;
  char* m_pWritingAppAsUTF8;
  char* m_pTitleAsUTF8;
};

class SeekHead {
  SeekHead(const SeekHead&);
  SeekHead& operator=(const SeekHead&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  SeekHead(Segment*, long long start, long long size, long long element_start,
           long long element_size);

  ~SeekHead();

  long Parse();

  struct Entry {
    // the SeekHead entry payload
    long long id;
    long long pos;

    // absolute pos of SeekEntry ID
    long long element_start;

    // SeekEntry ID size + size size + payload
    long long element_size;
  };

  int GetCount() const;
  const Entry* GetEntry(int idx) const;

  struct VoidElement {
    // absolute pos of Void ID
    long long element_start;

    // ID size + size size + payload size
    long long element_size;
  };

  int GetVoidElementCount() const;
  const VoidElement* GetVoidElement(int idx) const;

 private:
  Entry* m_entries;
  int m_entry_count;

  VoidElement* m_void_elements;
  int m_void_element_count;

  static bool ParseEntry(IMkvReader*,
                         long long pos,  // payload
                         long long size, Entry*);
};

class Cues;
class CuePoint {
  friend class Cues;

  CuePoint(long, long long);
  ~CuePoint();

  CuePoint(const CuePoint&);
  CuePoint& operator=(const CuePoint&);

 public:
  long long m_element_start;
  long long m_element_size;

  void Load(IMkvReader*);

  long long GetTimeCode() const;  // absolute but unscaled
  long long GetTime(const Segment*) const;  // absolute and scaled (ns units)

  struct TrackPosition {
    long long m_track;
    long long m_pos;  // of cluster
    long long m_block;
    // codec_state  //defaults to 0
    // reference = clusters containing req'd referenced blocks
    //  reftime = timecode of the referenced block

    void Parse(IMkvReader*, long long, long long);
  };

  const TrackPosition* Find(const Track*) const;

 private:
  const long m_index;
  long long m_timecode;
  TrackPosition* m_track_positions;
  size_t m_track_positions_count;
};

class Cues {
  friend class Segment;

  Cues(Segment*, long long start, long long size, long long element_start,
       long long element_size);
  ~Cues();

  Cues(const Cues&);
  Cues& operator=(const Cues&);

 public:
  Segment* const m_pSegment;
  const long long m_start;
  const long long m_size;
  const long long m_element_start;
  const long long m_element_size;

  bool Find(  // lower bound of time_ns
      long long time_ns, const Track*, const CuePoint*&,
      const CuePoint::TrackPosition*&) const;

#if 0
    bool FindNext(  //upper_bound of time_ns
        long long time_ns,
        const Track*,
        const CuePoint*&,
        const CuePoint::TrackPosition*&) const;
#endif

  const CuePoint* GetFirst() const;
  const CuePoint* GetLast() const;
  const CuePoint* GetNext(const CuePoint*) const;

  const BlockEntry* GetBlock(const CuePoint*,
                             const CuePoint::TrackPosition*) const;

  bool LoadCuePoint() const;
  long GetCount() const;  // loaded only
  // long GetTotal() const;  //loaded + preloaded
  bool DoneParsing() const;

 private:
  void Init() const;
  void PreloadCuePoint(long&, long long) const;

  mutable CuePoint** m_cue_points;
  mutable long m_count;
  mutable long m_preload_count;
  mutable long long m_pos;
};

class Cluster {
  friend class Segment;

  Cluster(const Cluster&);
  Cluster& operator=(const Cluster&);

 public:
  Segment* const m_pSegment;

 public:
  static Cluster* Create(Segment*,
                         long index,  // index in segment
                         long long off);  // offset relative to segment
  // long long element_size);

  Cluster();  // EndOfStream
  ~Cluster();

  bool EOS() const;

  long long GetTimeCode() const;  // absolute, but not scaled
  long long GetTime() const;  // absolute, and scaled (nanosecond units)
  long long GetFirstTime() const;  // time (ns) of first (earliest) block
  long long GetLastTime() const;  // time (ns) of last (latest) block

  long GetFirst(const BlockEntry*&) const;
  long GetLast(const BlockEntry*&) const;
  long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;

  const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
  const BlockEntry* GetEntry(const CuePoint&,
                             const CuePoint::TrackPosition&) const;
  // const BlockEntry* GetMaxKey(const VideoTrack*) const;

  //    static bool HasBlockEntries(const Segment*, long long);

  static long HasBlockEntries(const Segment*, long long idoff, long long& pos,
                              long& size);

  long GetEntryCount() const;

  long Load(long long& pos, long& size) const;

  long Parse(long long& pos, long& size) const;
  long GetEntry(long index, const mkvparser::BlockEntry*&) const;

 protected:
  Cluster(Segment*, long index, long long element_start);
  // long long element_size);

 public:
  const long long m_element_start;
  long long GetPosition() const;  // offset relative to segment

  long GetIndex() const;
  long long GetElementSize() const;
  // long long GetPayloadSize() const;

  // long long Unparsed() const;

 private:
  long m_index;
  mutable long long m_pos;
  // mutable long long m_size;
  mutable long long m_element_size;
  mutable long long m_timecode;
  mutable BlockEntry** m_entries;
  mutable long m_entries_size;
  mutable long m_entries_count;

  long ParseSimpleBlock(long long, long long&, long&);
  long ParseBlockGroup(long long, long long&, long&);

  long CreateBlock(long long id, long long pos, long long size,
                   long long discard_padding);
  long CreateBlockGroup(long long start_offset, long long size,
                        long long discard_padding);
  long CreateSimpleBlock(long long, long long);
};

class Segment {
  friend class Cues;
  friend class Track;
  friend class VideoTrack;

  Segment(const Segment&);
  Segment& operator=(const Segment&);

 private:
  Segment(IMkvReader*, long long elem_start,
          // long long elem_size,
          long long pos, long long size);

 public:
  IMkvReader* const m_pReader;
  const long long m_element_start;
  // const long long m_element_size;
  const long long m_start;  // posn of segment payload
  const long long m_size;  // size of segment payload
  Cluster m_eos;  // TODO: make private?

  static long long CreateInstance(IMkvReader*, long long, Segment*&);
  ~Segment();

  long Load();  // loads headers and all clusters

  // for incremental loading
  // long long Unparsed() const;
  bool DoneParsing() const;
  long long ParseHeaders();  // stops when first cluster is found
  // long FindNextCluster(long long& pos, long& size) const;
  long LoadCluster(long long& pos, long& size);  // load one cluster
  long LoadCluster();

  long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos,
                 long& size);

#if 0
    //This pair parses one cluster, but only changes the state of the
    //segment object when the cluster is actually added to the index.
    long ParseCluster(long long& cluster_pos, long long& new_pos) const;
    bool AddCluster(long long cluster_pos, long long new_pos);
#endif

  const SeekHead* GetSeekHead() const;
  const Tracks* GetTracks() const;
  const SegmentInfo* GetInfo() const;
  const Cues* GetCues() const;
  const Chapters* GetChapters() const;

  long long GetDuration() const;

  unsigned long GetCount() const;
  const Cluster* GetFirst() const;
  const Cluster* GetLast() const;
  const Cluster* GetNext(const Cluster*);

  const Cluster* FindCluster(long long time_nanoseconds) const;
  // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;

  const Cluster* FindOrPreloadCluster(long long pos);

  long ParseCues(long long cues_off,  // offset relative to start of segment
                 long long& parse_pos, long& parse_len);

 private:
  long long m_pos;  // absolute file posn; what has been consumed so far
  Cluster* m_pUnknownSize;

  SeekHead* m_pSeekHead;
  SegmentInfo* m_pInfo;
  Tracks* m_pTracks;
  Cues* m_pCues;
  Chapters* m_pChapters;
  Cluster** m_clusters;
  long m_clusterCount;  // number of entries for which m_index >= 0
  long m_clusterPreloadCount;  // number of entries for which m_index < 0
  long m_clusterSize;  // array size

  long DoLoadCluster(long long&, long&);
  long DoLoadClusterUnknownSize(long long&, long&);
  long DoParseNext(const Cluster*&, long long&, long&);

  void AppendCluster(Cluster*);
  void PreloadCluster(Cluster*, ptrdiff_t);

  // void ParseSeekHead(long long pos, long long size);
  // void ParseSeekEntry(long long pos, long long size);
  // void ParseCues(long long);

  const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&);
};

}  // end namespace mkvparser

inline long mkvparser::Segment::LoadCluster() {
  long long pos;
  long size;

  return LoadCluster(pos, size);
}

#endif  // MKVPARSER_HPP
