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