vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / plugins / matroska / libebml / ebml / EbmlElement.h
blobfd2198c7a1f4d3963aca1a39f849e30ce30bf263
1 /****************************************************************************
2 ** libebml : parse EBML files, see http://embl.sourceforge.net/
3 **
4 ** <file/class description>
5 **
6 ** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved.
7 **
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.
12 **
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.
17 **
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
25 ** not clear to you.
27 **********************************************************************/
29 /*!
30 \file
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
37 #include <cassert>
39 #include "EbmlTypes.h"
40 #include "EbmlId.h"
41 #include "IOCallback.h"
43 START_LIBEBML_NAMESPACE
45 /*!
46 \brief The size of the EBML-coded length
48 int EBML_DLL_API CodedSizeLength(uint64 Length, unsigned int SizeLength, bool bSizeIsFinite = true);
50 /*!
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);
56 /*!
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);
62 /*!
63 \brief The size of the EBML-coded signed length
65 int EBML_DLL_API CodedSizeLengthSigned(int64 Length, unsigned int SizeLength);
67 /*!
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);
73 /*!
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);
79 class EbmlStream;
80 class EbmlSemanticContext;
81 class EbmlElement;
83 // functions for generic handling of data (should be static to all classes)
84 /*!
85 \todo Handle default value
87 class EBML_DLL_API EbmlCallbacks {
88 public:
89 EbmlCallbacks(EbmlElement & (*Creator)(), const EbmlId & aGlobalId, const char * aDebugName, const EbmlSemanticContext & aContext)
90 :Create(Creator)
91 ,GlobalId(aGlobalId)
92 ,DebugName(aDebugName)
93 ,Context(aContext)
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 {
107 public:
108 EbmlSemantic(bool aMandatory, bool aUnique, const EbmlCallbacks & aGetCallbacks)
109 :Mandatory(aMandatory), Unique(aUnique), GetCallbacks(aGetCallbacks) {}
111 bool Mandatory;
112 ///< whether the element is mandatory in the context or not
113 bool Unique;
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 {
124 public:
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;
149 \class EbmlElement
150 \brief Hold basic informations about an EBML element (ID + length)
152 class EBML_DLL_API EbmlElement {
153 public:
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 {
208 return true;
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;
248 protected:
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)
252 bool bSizeIsFinite;
253 uint64 ElementPosition;
254 uint64 SizePosition;
255 bool bValueIsSet;
256 bool DefaultIsSet;
257 bool bLocked;
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