Ebml: remove version check, since we already force Version to be > 7.7
[vlc/davidf-public.git] / modules / demux / mkv / Ebml_parser.cpp
blobe9b01cdd03e5f7cfe06c38da84e90295dd6f9c7f
2 /*****************************************************************************
3 * mkv.cpp : matroska demuxer
4 *****************************************************************************
5 * Copyright (C) 2003-2004 the VideoLAN team
6 * $Id$
8 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * Steve Lhomme <steve.lhomme@free.fr>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
25 #include "Ebml_parser.hpp"
27 /*****************************************************************************
28 * Ebml Stream parser
29 *****************************************************************************/
30 EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux )
32 int i;
34 m_es = es;
35 m_got = NULL;
36 m_el[0] = el_start;
37 mi_remain_size[0] = el_start->GetSize();
39 for( i = 1; i < 6; i++ )
41 m_el[i] = NULL;
43 mi_level = 1;
44 mi_user_level = 1;
45 mb_keep = false;
46 mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
49 EbmlParser::~EbmlParser( void )
51 int i;
53 for( i = 1; i < mi_level; i++ )
55 if( !mb_keep )
57 delete m_el[i];
59 mb_keep = false;
63 EbmlElement* EbmlParser::UnGet( uint64 i_block_pos, uint64 i_cluster_pos )
65 if ( mi_user_level > mi_level )
67 while ( mi_user_level != mi_level )
69 delete m_el[mi_user_level];
70 m_el[mi_user_level] = NULL;
71 mi_user_level--;
74 m_got = NULL;
75 mb_keep = false;
76 if ( m_el[1]->GetElementPosition() == i_cluster_pos )
78 m_es->I_O().setFilePointer( i_block_pos, seek_beginning );
79 return (EbmlMaster*) m_el[1];
81 else
83 // seek to the previous Cluster
84 m_es->I_O().setFilePointer( i_cluster_pos, seek_beginning );
85 mi_level--;
86 mi_user_level--;
87 delete m_el[mi_level];
88 m_el[mi_level] = NULL;
89 return NULL;
93 void EbmlParser::Up( void )
95 if( mi_user_level == mi_level )
97 fprintf( stderr," arrrrrrrrrrrrrg Up cannot escape itself\n" );
100 mi_user_level--;
103 void EbmlParser::Down( void )
105 mi_user_level++;
106 mi_level++;
109 void EbmlParser::Keep( void )
111 mb_keep = true;
114 int EbmlParser::GetLevel( void )
116 return mi_user_level;
119 void EbmlParser::Reset( demux_t *p_demux )
121 while ( mi_level > 0)
123 delete m_el[mi_level];
124 m_el[mi_level] = NULL;
125 mi_level--;
127 mi_user_level = mi_level = 1;
128 // a little faster and cleaner
129 m_es->I_O().setFilePointer( static_cast<KaxSegment*>(m_el[0])->GetGlobalPosition(0) );
130 mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
134 /* This function workarounds a bug in KaxBlockVirtual implementation */
135 class KaxBlockVirtualWorkaround : public KaxBlockVirtual
137 public:
138 void Fix()
140 if( Data == DataBlock )
141 SetBuffer( NULL, 0 );
145 EbmlElement *EbmlParser::Get( void )
147 int i_ulev = 0;
149 if( mi_user_level != mi_level )
151 return NULL;
153 if( m_got )
155 EbmlElement *ret = m_got;
156 m_got = NULL;
158 return ret;
161 if( m_el[mi_level] )
163 m_el[mi_level]->SkipData( *m_es, m_el[mi_level]->Generic().Context );
164 if( !mb_keep )
166 if( MKV_IS_ID( m_el[mi_level], KaxBlockVirtual ) )
167 static_cast<KaxBlockVirtualWorkaround*>(m_el[mi_level])->Fix();
168 delete m_el[mi_level];
170 mb_keep = false;
173 m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, mb_dummy != 0, 1 );
174 // mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
175 if( i_ulev > 0 )
177 while( i_ulev > 0 )
179 if( mi_level == 1 )
181 mi_level = 0;
182 return NULL;
185 delete m_el[mi_level - 1];
186 m_got = m_el[mi_level -1] = m_el[mi_level];
187 m_el[mi_level] = NULL;
189 mi_level--;
190 i_ulev--;
192 return NULL;
194 else if( m_el[mi_level] == NULL )
196 fprintf( stderr," m_el[mi_level] == NULL\n" );
199 return m_el[mi_level];
202 bool EbmlParser::IsTopPresent( EbmlElement *el )
204 for( int i = 0; i < mi_level; i++ )
206 if( m_el[i] && m_el[i] == el )
207 return true;
209 return false;