1 /****************************************************************************
2 ** libebml : parse EBML files, see http://embl.sourceforge.net/
4 ** <file/class description>
6 ** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved.
8 ** This library is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU Lesser General Public
10 ** License as published by the Free Software Foundation; either
11 ** version 2.1 of the License, or (at your option) any later version.
13 ** This library is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ** Lesser General Public License for more details.
18 ** You should have received a copy of the GNU Lesser General Public
19 ** License along with this library; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 ** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.
24 ** Contact license@matroska.org if any conditions of this licensing are
27 **********************************************************************/
31 \version \$Id: EbmlElement.h 1232 2005-10-15 15:56:52Z robux4 $
32 \author Steve Lhomme <robux4 @ users.sf.net>
34 #ifndef LIBEBML_ELEMENT_H
35 #define LIBEBML_ELEMENT_H
39 #include "EbmlTypes.h"
41 #include "IOCallback.h"
43 START_LIBEBML_NAMESPACE
46 \brief The size of the EBML-coded length
48 int EBML_DLL_API
CodedSizeLength(uint64 Length
, unsigned int SizeLength
, bool bSizeIsFinite
= true);
51 \brief The coded value of the EBML-coded length
52 \note The size of OutBuffer must be 8 octets at least
54 int EBML_DLL_API
CodedValueLength(uint64 Length
, int CodedSize
, binary
* OutBuffer
);
57 \brief Read an EBML-coded value from a buffer
58 \return the value read
60 uint64 EBML_DLL_API
ReadCodedSizeValue(const binary
* InBuffer
, uint32
& BufferSize
, uint64
& SizeUnknown
);
63 \brief The size of the EBML-coded signed length
65 int EBML_DLL_API
CodedSizeLengthSigned(int64 Length
, unsigned int SizeLength
);
68 \brief The coded value of the EBML-coded signed length
69 \note the size of OutBuffer must be 8 octets at least
71 int EBML_DLL_API
CodedValueLengthSigned(int64 Length
, int CodedSize
, binary
* OutBuffer
);
74 \brief Read a signed EBML-coded value from a buffer
75 \return the value read
77 int64 EBML_DLL_API
ReadCodedSizeSignedValue(const binary
* InBuffer
, uint32
& BufferSize
, uint64
& SizeUnknown
);
80 class EbmlSemanticContext
;
83 // functions for generic handling of data (should be static to all classes)
85 \todo Handle default value
87 class EBML_DLL_API EbmlCallbacks
{
89 EbmlCallbacks(EbmlElement
& (*Creator
)(), const EbmlId
& aGlobalId
, const char * aDebugName
, const EbmlSemanticContext
& aContext
)
92 ,DebugName(aDebugName
)
96 EbmlElement
& (*Create
)();
97 const EbmlId
& GlobalId
;
98 const char * DebugName
;
99 const EbmlSemanticContext
& Context
;
103 \brief contains the semantic informations for a given level and all sublevels
104 \todo move the ID in the element class
106 class EBML_DLL_API EbmlSemantic
{
108 EbmlSemantic(bool aMandatory
, bool aUnique
, const EbmlCallbacks
& aGetCallbacks
)
109 :Mandatory(aMandatory
), Unique(aUnique
), GetCallbacks(aGetCallbacks
) {}
112 ///< whether the element is mandatory in the context or not
114 const EbmlCallbacks
& GetCallbacks
;
117 typedef const class EbmlSemanticContext
& (*_GetSemanticContext
)();
120 Context of the element
121 \todo allow more than one parent ?
123 class EBML_DLL_API EbmlSemanticContext
{
125 EbmlSemanticContext(unsigned int aSize
,
126 const EbmlSemantic
*aMyTable
,
127 const EbmlSemanticContext
*aUpTable
,
128 const _GetSemanticContext aGetGlobalContext
,
129 const EbmlCallbacks
*aMasterElt
)
130 :Size(aSize
), MyTable(aMyTable
), UpTable(aUpTable
),
131 GetGlobalContext(aGetGlobalContext
), MasterElt(aMasterElt
) {}
133 bool operator!=(const EbmlSemanticContext
& aElt
) const {
134 return ((Size
!= aElt
.Size
) || (MyTable
!= aElt
.MyTable
) ||
135 (UpTable
!= aElt
.UpTable
) || (GetGlobalContext
!= aElt
.GetGlobalContext
) |
136 (MasterElt
!= aElt
.MasterElt
));
140 unsigned int Size
; ///< number of elements in the table
141 const EbmlSemantic
*MyTable
; ///< First element in the table
142 const EbmlSemanticContext
*UpTable
; ///< Parent element
143 /// \todo replace with the global context directly
144 const _GetSemanticContext GetGlobalContext
; ///< global elements supported at this level
145 const EbmlCallbacks
*MasterElt
;
150 \brief Hold basic informations about an EBML element (ID + length)
152 class EBML_DLL_API EbmlElement
{
154 EbmlElement(const uint64 aDefaultSize
, bool bValueSet
= false);
155 virtual ~EbmlElement() {assert(!bLocked
);}
157 /// Set the minimum length that will be used to write the element size (-1 = optimal)
158 void SetSizeLength(const int NewSizeLength
) {SizeLength
= NewSizeLength
;}
159 int GetSizeLength() const {return SizeLength
;}
161 static EbmlElement
* FindNextElement(IOCallback
& DataStream
, const EbmlSemanticContext
& Context
, int & UpperLevel
, uint64 MaxDataSize
, bool AllowDummyElt
, unsigned int MaxLowerLevel
= 1);
162 static EbmlElement
* FindNextID(IOCallback
& DataStream
, const EbmlCallbacks
& ClassInfos
, const uint64 MaxDataSize
);
165 \brief find the next element with the same ID
167 EbmlElement
* FindNext(IOCallback
& DataStream
, const uint64 MaxDataSize
);
169 EbmlElement
* SkipData(EbmlStream
& DataStream
, const EbmlSemanticContext
& Context
, EbmlElement
* TestReadElt
= NULL
, bool AllowDummyElt
= false);
172 \brief Give a copy of the element, all data inside the element is copied
173 \return NULL if there is not enough memory
175 virtual EbmlElement
* Clone() const = 0;
177 virtual operator const EbmlId
&() const = 0;
179 // by default only allow to set element as finite (override when needed)
180 virtual bool SetSizeInfinite(bool bIsInfinite
= true) {return !bIsInfinite
;}
182 virtual bool ValidateSize() const = 0;
184 uint64
GetElementPosition() const {
185 return ElementPosition
;
188 uint64
ElementSize(bool bKeepIntact
= false) const; /// return the size of the header+data, before writing
190 uint32
Render(IOCallback
& output
, bool bKeepIntact
= false, bool bKeepPosition
= false, bool bForceRender
= false);
192 virtual uint64
UpdateSize(bool bKeepIntact
= false, bool bForceRender
= false) = 0; /// update the Size of the Data stored
193 virtual uint64
GetSize() const {return Size
;} /// return the size of the data stored in the element, on reading
195 virtual uint64
ReadData(IOCallback
& input
, ScopeMode ReadFully
= SCOPE_ALL_DATA
) = 0;
196 virtual void Read(EbmlStream
& inDataStream
, const EbmlSemanticContext
& Context
, int & UpperEltFound
, EbmlElement
* & FoundElt
, bool AllowDummyElt
= false, ScopeMode ReadFully
= SCOPE_ALL_DATA
);
198 /// return the generic callback to monitor a derived class
199 virtual const EbmlCallbacks
& Generic() const = 0;
201 bool IsLocked() const {return bLocked
;}
202 void Lock(bool bLock
= true) { bLocked
= bLock
;}
205 \brief default comparison for elements that can't be compared
207 virtual bool operator<(const EbmlElement
& EltB
) const {
211 static bool CompareElements(const EbmlElement
*A
, const EbmlElement
*B
);
213 virtual bool IsDummy() const {return false;}
214 virtual bool IsMaster() const {return false;}
216 uint8
HeadSize() const {
217 return EbmlId(*this).Length
+ CodedSizeLength(Size
, SizeLength
, bSizeIsFinite
);
218 } /// return the size of the head, on reading/writing
221 \brief Force the size of an element
222 \warning only possible if the size is "undefined"
224 bool ForceSize(uint64 NewSize
);
226 uint32
OverwriteHead(IOCallback
& output
, bool bKeepPosition
= false);
229 \brief void the content of the element (replace by EbmlVoid)
231 uint32
VoidMe(IOCallback
& output
, bool bKeepIntact
= false);
233 bool DefaultISset() const {return DefaultIsSet
;}
234 virtual bool IsDefaultValue() const = 0;
235 bool IsFiniteSize() const {return bSizeIsFinite
;}
238 \brief set the default size of an element
240 virtual void SetDefaultSize(const uint64 aDefaultSize
) {DefaultSize
= aDefaultSize
;}
242 bool ValueIsSet() const {return bValueIsSet
;}
244 inline uint64
GetEndPosition() const {
245 return SizePosition
+ CodedSizeLength(Size
, SizeLength
, bSizeIsFinite
) + Size
;
249 uint64 Size
; ///< the size of the data to write
250 uint64 DefaultSize
; ///< Minimum data size to fill on rendering (0 = optimal)
251 int SizeLength
; /// the minimum size on which the size will be written (0 = optimal)
253 uint64 ElementPosition
;
260 \brief find any element in the stream
261 \return a DummyRawElement if the element is unknown or NULL if the element dummy is not allowed
263 static EbmlElement
*CreateElementUsingContext(const EbmlId
& aID
, const EbmlSemanticContext
& Context
, int & LowLevel
, bool IsGlobalContext
, bool bAllowDummy
= false, unsigned int MaxLowerLevel
= 1);
265 uint32
RenderHead(IOCallback
& output
, bool bForceRender
, bool bKeepIntact
= false, bool bKeepPosition
= false);
266 uint32
MakeRenderHead(IOCallback
& output
, bool bKeepPosition
);
269 \brief prepare the data before writing them (in case it's not already done by default)
271 virtual uint32
RenderData(IOCallback
& output
, bool bForceRender
, bool bKeepIntact
= false) = 0;
274 \brief special constructor for cloning
276 EbmlElement(const EbmlElement
& ElementToClone
);
279 END_LIBEBML_NAMESPACE
281 #endif // LIBEBML_ELEMENT_H