00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #ifndef LIBEBML_ELEMENT_H
00035 #define LIBEBML_ELEMENT_H
00036
00037 #include "EbmlTypes.h"
00038 #include "EbmlId.h"
00039 #include "IOCallback.h"
00040
00041 START_LIBEBML_NAMESPACE
00042
00046 int EBML_DLL_API CodedSizeLength(uint64 Length, unsigned int SizeLength, bool bSizeIsFinite = true);
00047
00052 int EBML_DLL_API CodedValueLength(uint64 Length, int CodedSize, binary * OutBuffer);
00053
00058 uint64 EBML_DLL_API ReadCodedSizeValue(const binary * InBuffer, uint32 & BufferSize, uint64 & SizeUnknown);
00059
00063 int EBML_DLL_API CodedSizeLengthSigned(int64 Length, unsigned int SizeLength);
00064
00069 int EBML_DLL_API CodedValueLengthSigned(int64 Length, int CodedSize, binary * OutBuffer);
00070
00075 int64 EBML_DLL_API ReadCodedSizeSignedValue(const binary * InBuffer, uint32 & BufferSize, uint64 & SizeUnknown);
00076
00077 class EbmlStream;
00078 class EbmlSemanticContext;
00079 class EbmlElement;
00080
00081 extern const EbmlSemanticContext Context_EbmlGlobal;
00082
00083 #define DEFINE_xxx_CONTEXT(x,global) \
00084 const EbmlSemanticContext Context_##x = EbmlSemanticContext(countof(ContextList_##x), ContextList_##x, NULL, global, NULL); \
00085
00086 #define DEFINE_xxx_MASTER(x,id,idl,parent,name,global) \
00087 const EbmlId Id_##x (id, idl); \
00088 const EbmlSemanticContext Context_##x = EbmlSemanticContext(countof(ContextList_##x), ContextList_##x, &Context_##parent, global, &EBML_INFO(x)); \
00089 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x); \
00090 x::x() :EbmlMaster(Context_##x) {}
00091
00092 #define DEFINE_xxx_MASTER_CONS(x,id,idl,parent,name,global) \
00093 const EbmlId Id_##x (id, idl); \
00094 const EbmlSemanticContext Context_##x = EbmlSemanticContext(countof(ContextList_##x), ContextList_##x, &Context_##parent, global, &EBML_INFO(x)); \
00095 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x);
00096
00097 #define DEFINE_xxx_MASTER_ORPHAN(x,id,idl,name,global) \
00098 const EbmlId Id_##x (id, idl); \
00099 const EbmlSemanticContext Context_##x = EbmlSemanticContext(countof(ContextList_##x), ContextList_##x, NULL, global, &EBML_INFO(x)); \
00100 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x); \
00101
00102 #define DEFINE_xxx_CLASS(x,id,idl,parent,name,global) \
00103 const EbmlId Id_##x (id, idl); \
00104 const EbmlSemanticContext Context_##x = EbmlSemanticContext(0, NULL, &Context_##parent, global, &EBML_INFO(x)); \
00105 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x); \
00106 x::x() {}
00107
00108 #define DEFINE_xxx_CLASS_CONS(x,id,idl,parent,name,global) \
00109 const EbmlId Id_##x (id, idl); \
00110 const EbmlSemanticContext Context_##x = EbmlSemanticContext(0, NULL, &Context_##parent, global, &EBML_INFO(x)); \
00111 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x);
00112
00113 #define DEFINE_xxx_UINTEGER_DEF(x,id,idl,parent,name,global,defval) \
00114 const EbmlId Id_##x (id, idl); \
00115 const EbmlSemanticContext Context_##x = EbmlSemanticContext(0, NULL, &Context_##parent, global, &EBML_INFO(x)); \
00116 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x); \
00117 x::x() :EbmlUInteger(defval) {}
00118
00119 #define DEFINE_xxx_STRING_DEF(x,id,idl,parent,name,global,defval) \
00120 const EbmlId Id_##x (id, idl); \
00121 const EbmlSemanticContext Context_##x = EbmlSemanticContext(0, NULL, &Context_##parent, global, &EBML_INFO(x)); \
00122 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x); \
00123 x::x() :EbmlString(defval) {}
00124
00125 #define DEFINE_xxx_FLOAT_DEF(x,id,idl,parent,name,global,defval) \
00126 const EbmlId Id_##x (id, idl); \
00127 const EbmlSemanticContext Context_##x = EbmlSemanticContext(0, NULL, &Context_##parent, global, &EBML_INFO(x)); \
00128 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x); \
00129 x::x() :EbmlFloat(defval) {}
00130
00131 #define DEFINE_xxx_CLASS_GLOBAL(x,id,idl,name,global) \
00132 const EbmlId Id_##x (id, idl); \
00133 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_EbmlGlobal); \
00134
00135 #define DEFINE_xxx_CLASS_ORPHAN(x,id,idl,name,global) \
00136 const EbmlId Id_##x (id, idl); \
00137 const EbmlSemanticContext Context_##x = EbmlSemanticContext(0, NULL, NULL, global, NULL); \
00138 const EbmlCallbacks x::ClassInfos(x::Create, Id_##x, name, Context_##x); \
00139
00140 #define DEFINE_EBML_CONTEXT(x) DEFINE_xxx_CONTEXT(x,*GetEbmlGlobal_Context)
00141 #define DEFINE_EBML_MASTER(x,id,idl,parent,name) DEFINE_xxx_MASTER(x,id,idl,parent,name,*GetEbmlGlobal_Context)
00142 #define DEFINE_EBML_MASTER_ORPHAN(x,id,idl,name) DEFINE_xxx_MASTER_ORPHAN(x,id,idl,name,*GetEbmlGlobal_Context)
00143 #define DEFINE_EBML_CLASS(x,id,idl,parent,name) DEFINE_xxx_CLASS(x,id,idl,parent,name,*GetEbmlGlobal_Context)
00144 #define DEFINE_EBML_CLASS_GLOBAL(x,id,idl,name) DEFINE_xxx_CLASS_GLOBAL(x,id,idl,name,*GetEbmlGlobal_Context)
00145 #define DEFINE_EBML_CLASS_ORPHAN(x,id,idl,name) DEFINE_xxx_CLASS_ORPHAN(x,id,idl,name,*GetEbmlGlobal_Context)
00146 #define DEFINE_EBML_UINTEGER_DEF(x,id,idl,parent,name,val) DEFINE_xxx_UINTEGER_DEF(x,id,idl,parent,name,*GetEbmlGlobal_Context,val)
00147 #define DEFINE_EBML_STRING_DEF(x,id,idl,parent,name,val) DEFINE_xxx_STRING_DEF(x,id,idl,parent,name,*GetEbmlGlobal_Context,val)
00148 #define DEFINE_EBML_BINARY_CONS(x,id,idl,parent,name) DEFINE_xxx_CLASS_CONS(x,id,idl,parent,name,*GetEbmlGlobal_Context)
00149
00150 #define DEFINE_SEMANTIC_CONTEXT(x)
00151 #define DEFINE_START_SEMANTIC(x) static const EbmlSemantic ContextList_##x[] = {
00152 #define DEFINE_END_SEMANTIC(x) };
00153 #define DEFINE_SEMANTIC_ITEM(m,u,c) EbmlSemantic(m, u, EBML_INFO(c)),
00154
00155 #define DECLARE_EBML_MASTER(x) class EBML_DLL_API x : public EbmlMaster { \
00156 public: \
00157 x();
00158 #define DECLARE_EBML_UINTEGER(x) class EBML_DLL_API x : public EbmlUInteger { \
00159 public: \
00160 x();
00161 #define DECLARE_EBML_STRING(x) class EBML_DLL_API x : public EbmlString { \
00162 public: \
00163 x();
00164 #define DECLARE_EBML_BINARY(x) class EBML_DLL_API x : public EbmlBinary { \
00165 public: \
00166 x();
00167
00168 #if defined(EBML_STRICT_API)
00169 #define EBML_CONCRETE_CLASS(Type) \
00170 public: \
00171 virtual const EbmlSemanticContext &Context() const {return ClassInfos.GetContext();} \
00172 virtual const char *DebugName() const {return ClassInfos.GetName();} \
00173 virtual operator const EbmlId &() const {return ClassInfos.ClassId();} \
00174 virtual EbmlElement & CreateElement() const {return Create();} \
00175 virtual EbmlElement * Clone() const { return new Type(*this); } \
00176 static EbmlElement & Create() {return *(new Type);} \
00177 static const EbmlCallbacks & ClassInfo() {return ClassInfos;} \
00178 static const EbmlId & ClassId() {return ClassInfos.ClassId();} \
00179 private: \
00180 static const EbmlCallbacks ClassInfos; \
00181
00182 #define EBML_CONCRETE_DUMMY_CLASS(Type) \
00183 public: \
00184 virtual const EbmlSemanticContext &Context() const {return *static_cast<EbmlSemanticContext*>(NULL);} \
00185 virtual const char *DebugName() const {return "DummyElement";} \
00186 virtual operator const EbmlId &(); \
00187 virtual EbmlElement & CreateElement() const {return Create();} \
00188 virtual EbmlElement * Clone() const { return new Type(*this); } \
00189 static EbmlElement & Create() {return *(new Type);} \
00190 static const EbmlId & ClassId(); \
00191 static const EbmlCallbacks ClassInfos; \
00192
00193
00194 #define EBML_INFO(ref) ref::ClassInfo()
00195 #define EBML_ID(ref) ref::ClassId()
00196 #define EBML_CLASS_SEMCONTEXT(ref) Context_##ref
00197 #define EBML_CLASS_CONTEXT(ref) ref::ClassInfo().GetContext()
00198 #define EBML_CLASS_CALLBACK(ref) ref::ClassInfo()
00199 #define EBML_CONTEXT(e) (e)->Context()
00200 #define EBML_NAME(e) (e)->DebugName()
00201
00202 #define EBML_INFO_ID(cb) (cb).ClassId()
00203 #define EBML_INFO_NAME(cb) (cb).GetName()
00204 #define EBML_INFO_CREATE(cb) (cb).NewElement()
00205 #define EBML_INFO_CONTEXT(cb) (cb).GetContext()
00206
00207 #define EBML_SEM_UNIQUE(s) (s).IsUnique()
00208 #define EBML_SEM_CONTEXT(s) ((const EbmlCallbacks &)(s)).GetContext()
00209 #define EBML_SEM_CREATE(s) (s).Create()
00210
00211 #define EBML_CTX_SIZE(c) (c).GetSize()
00212 #define EBML_CTX_MASTER(c) (c).GetMaster()
00213 #define EBML_CTX_PARENT(c) (c).Parent()
00214 #define EBML_CTX_IDX(c,i) (c).GetSemantic(i)
00215 #define EBML_CTX_IDX_INFO(c,i) (const EbmlCallbacks &)((c).GetSemantic(i))
00216 #define EBML_CTX_IDX_ID(c,i) ((const EbmlCallbacks &)((c).GetSemantic(i))).ClassId()
00217 #else
00218 #define EBML_CONCRETE_CLASS(Type) \
00219 public: \
00220 virtual const EbmlCallbacks & Generic() const {return ClassInfos;} \
00221 virtual operator const EbmlId &() const {return ClassInfos.GlobalId;} \
00222 virtual EbmlElement & CreateElement() const {return Create();} \
00223 virtual EbmlElement * Clone() const { return new Type(*this); } \
00224 static EbmlElement & Create() {return *(new Type);} \
00225 static const EbmlCallbacks ClassInfos; \
00226
00227 #define EBML_CONCRETE_DUMMY_CLASS(Type) \
00228 public: \
00229 virtual const EbmlCallbacks & Generic() const {return ClassInfos;} \
00230 virtual operator const EbmlId &(); \
00231 virtual EbmlElement & CreateElement() const {return Create();} \
00232 virtual EbmlElement * Clone() const { return new Type(*this); } \
00233 static EbmlElement & Create() {return *(new Type);} \
00234 static const EbmlCallbacks ClassInfos; \
00235
00236
00237 #define EBML_INFO(ref) ref::ClassInfos
00238 #define EBML_ID(ref) ref::ClassInfos.GlobalId
00239 #define EBML_CLASS_SEMCONTEXT(ref) Context_##ref
00240 #define EBML_CLASS_CONTEXT(ref) ref::ClassInfos.Context
00241 #define EBML_CLASS_CALLBACK(ref) ref::ClassInfos
00242 #define EBML_CONTEXT(e) (e)->Generic().Context
00243 #define EBML_NAME(e) (e)->Generic().DebugName
00244
00245 #define EBML_INFO_ID(cb) (cb).GlobalId
00246 #define EBML_INFO_NAME(cb) (cb).DebugName
00247 #define EBML_INFO_CREATE(cb) (cb).Create()
00248 #define EBML_INFO_CONTEXT(cb) (cb).Context
00249
00250 #define EBML_SEM_UNIQUE(s) (s).Unique
00251 #define EBML_SEM_CONTEXT(s) (s).GetCallbacks.Context
00252 #define EBML_SEM_CREATE(s) (s).Create()
00253
00254 #define EBML_CTX_SIZE(c) (c).Size
00255 #define EBML_CTX_MASTER(c) (c).MasterElt
00256 #define EBML_CTX_PARENT(c) (c).UpTable
00257 #define EBML_CTX_IDX(c,i) (c).MyTable[(i)]
00258 #define EBML_CTX_IDX_INFO(c,i) (c).MyTable[(i)].GetCallbacks
00259 #define EBML_CTX_IDX_ID(c,i) (c).MyTable[(i)].GetCallbacks.GlobalId
00260 #endif
00261
00262 #if !defined(INVALID_FILEPOS_T)
00263 #define INVALID_FILEPOS_T 0
00264 #endif
00265
00266 #define EBML_DEF_CONS
00267 #define EBML_DEF_SEP
00268 #define EBML_DEF_PARAM
00269 #define EBML_DEF_BINARY_INIT
00270 #define EBML_DEF_BINARY_CTX(x)
00271 #define EBML_DEF_SINTEGER(x)
00272 #define EBML_DEF_BINARY(x)
00273 #define EBML_EXTRA_PARAM
00274 #define EBML_EXTRA_CALL
00275 #define EBML_EXTRA_DEF
00276
00277
00281 class EBML_DLL_API EbmlCallbacks {
00282 public:
00283 EbmlCallbacks(EbmlElement & (*Creator)(), const EbmlId & aGlobalId, const char * aDebugName, const EbmlSemanticContext & aContext);
00284
00285 inline const EbmlId & ClassId() const { return GlobalId; }
00286 inline const EbmlSemanticContext & GetContext() const { return Context; }
00287 inline const char * GetName() const { return DebugName; }
00288 inline EbmlElement & NewElement() const { return Create(); }
00289
00290 #if defined(EBML_STRICT_API)
00291 private:
00292 #endif
00293 EbmlElement & (*Create)();
00294 const EbmlId & GlobalId;
00295 const char * DebugName;
00296 const EbmlSemanticContext & Context;
00297 };
00298
00303 class EBML_DLL_API EbmlSemantic {
00304 public:
00305 EbmlSemantic(bool aMandatory, bool aUnique, const EbmlCallbacks & aGetCallbacks)
00306 :Mandatory(aMandatory), Unique(aUnique), GetCallbacks(aGetCallbacks) {}
00307
00308 inline bool IsMandatory() const { return Mandatory; }
00309 inline bool IsUnique() const { return Unique; }
00310 inline EbmlElement & Create() const { return EBML_INFO_CREATE(GetCallbacks); }
00311 inline operator const EbmlCallbacks &() const { return GetCallbacks; }
00312
00313 #if defined(EBML_STRICT_API)
00314 private:
00315 #endif
00316 bool Mandatory;
00317 bool Unique;
00318 const EbmlCallbacks & GetCallbacks;
00319 };
00320
00321 typedef const class EbmlSemanticContext & (*_GetSemanticContext)();
00322
00327 class EBML_DLL_API EbmlSemanticContext {
00328 public:
00329 EbmlSemanticContext(size_t aSize,
00330 const EbmlSemantic *aMyTable,
00331 const EbmlSemanticContext *aUpTable,
00332 const _GetSemanticContext aGetGlobalContext,
00333 const EbmlCallbacks *aMasterElt)
00334 : GetGlobalContext(aGetGlobalContext), MyTable(aMyTable), Size(aSize),
00335 UpTable(aUpTable), MasterElt(aMasterElt) {}
00336
00337 bool operator!=(const EbmlSemanticContext & aElt) const {
00338 return ((Size != aElt.Size) || (MyTable != aElt.MyTable) ||
00339 (UpTable != aElt.UpTable) || (GetGlobalContext != aElt.GetGlobalContext) |
00340 (MasterElt != aElt.MasterElt));
00341 }
00342
00343 inline size_t GetSize() const { return Size; }
00344 inline const EbmlCallbacks* GetMaster() const { return MasterElt; }
00345 inline const EbmlSemanticContext* Parent() const { return UpTable; }
00346 const EbmlSemantic & GetSemantic(size_t i) const;
00347
00348 const _GetSemanticContext GetGlobalContext;
00349
00350 #if defined(EBML_STRICT_API)
00351 private:
00352 #endif
00353 const EbmlSemantic *MyTable;
00354 size_t Size;
00355 const EbmlSemanticContext *UpTable;
00356
00357 const EbmlCallbacks *MasterElt;
00358 };
00359
00364 class EBML_DLL_API EbmlElement {
00365 public:
00366 EbmlElement(uint64 aDefaultSize, bool bValueSet = false);
00367 virtual ~EbmlElement();
00368
00370 void SetSizeLength(int NewSizeLength) {SizeLength = NewSizeLength;}
00371 int GetSizeLength() const {return SizeLength;}
00372
00373 static EbmlElement * FindNextElement(IOCallback & DataStream, const EbmlSemanticContext & Context, int & UpperLevel, uint64 MaxDataSize, bool AllowDummyElt, unsigned int MaxLowerLevel = 1);
00374 static EbmlElement * FindNextID(IOCallback & DataStream, const EbmlCallbacks & ClassInfos, uint64 MaxDataSize);
00375
00379 EbmlElement * FindNext(IOCallback & DataStream, uint64 MaxDataSize);
00380
00381 EbmlElement * SkipData(EbmlStream & DataStream, const EbmlSemanticContext & Context, EbmlElement * TestReadElt = NULL, bool AllowDummyElt = false);
00382
00387 virtual EbmlElement * Clone() const = 0;
00388
00389 virtual operator const EbmlId &() const = 0;
00390 #if defined(EBML_STRICT_API)
00391 virtual const char *DebugName() const = 0;
00392 virtual const EbmlSemanticContext &Context() const = 0;
00393 #else
00394
00395 virtual const EbmlCallbacks & Generic() const = 0;
00396 #endif
00397 virtual EbmlElement & CreateElement() const = 0;
00398
00399
00400 virtual bool SetSizeInfinite(bool bIsInfinite = true) {return !bIsInfinite;}
00401
00402 virtual bool ValidateSize() const = 0;
00403
00404 uint64 GetElementPosition() const {
00405 return ElementPosition;
00406 }
00407
00408 uint64 ElementSize(bool bWithDefault = false) const;
00409
00410 filepos_t Render(IOCallback & output, bool bWithDefault = false, bool bKeepPosition = false, bool bForceRender = false);
00411
00412 virtual filepos_t UpdateSize(bool bWithDefault = false, bool bForceRender = false) = 0;
00413 virtual filepos_t GetSize() const {return Size;}
00414
00415 virtual filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA) = 0;
00416 virtual void Read(EbmlStream & inDataStream, const EbmlSemanticContext & Context, int & UpperEltFound, EbmlElement * & FoundElt, bool AllowDummyElt = false, ScopeMode ReadFully = SCOPE_ALL_DATA);
00417
00418 bool IsLocked() const {return bLocked;}
00419 void Lock(bool bLock = true) { bLocked = bLock;}
00420
00424 virtual bool IsSmallerThan(const EbmlElement *Cmp) const;
00425 static bool CompareElements(const EbmlElement *A, const EbmlElement *B);
00426
00427 virtual bool IsDummy() const {return false;}
00428 virtual bool IsMaster() const {return false;}
00429
00430 uint8 HeadSize() const {
00431 return EBML_ID_LENGTH((const EbmlId&)*this) + CodedSizeLength(Size, SizeLength, bSizeIsFinite);
00432 }
00433
00438 bool ForceSize(uint64 NewSize);
00439
00440 filepos_t OverwriteHead(IOCallback & output, bool bKeepPosition = false);
00441
00445 uint32 VoidMe(IOCallback & output, bool bWithDefault = false);
00446
00447 bool DefaultISset() const {return DefaultIsSet;}
00448 virtual bool IsDefaultValue() const = 0;
00449 bool IsFiniteSize() const {return bSizeIsFinite;}
00450
00454 virtual void SetDefaultSize(uint64 aDefaultSize) {DefaultSize = aDefaultSize;}
00455
00456 bool ValueIsSet() const {return bValueIsSet;}
00457
00458 inline uint64 GetEndPosition() const {
00459 assert(bSizeIsFinite);
00460 return SizePosition + CodedSizeLength(Size, SizeLength, bSizeIsFinite) + Size;
00461 }
00462
00463 protected:
00468 static EbmlElement *CreateElementUsingContext(const EbmlId & aID, const EbmlSemanticContext & Context, int & LowLevel, bool IsGlobalContext, bool bAllowDummy = false, unsigned int MaxLowerLevel = 1);
00469
00470 filepos_t RenderHead(IOCallback & output, bool bForceRender, bool bWithDefault = false, bool bKeepPosition = false);
00471 filepos_t MakeRenderHead(IOCallback & output, bool bKeepPosition);
00472
00476 virtual filepos_t RenderData(IOCallback & output, bool bForceRender, bool bWithDefault = false) = 0;
00477
00481 EbmlElement(const EbmlElement & ElementToClone);
00482
00483 inline uint64 GetDefaultSize() const {return DefaultSize;}
00484 inline void SetSize_(uint64 aSize) {Size = aSize;}
00485 inline void SetValueIsSet(bool Set = true) {bValueIsSet = Set;}
00486 inline void SetDefaultIsSet(bool Set = true) {DefaultIsSet = Set;}
00487 inline void SetSizeIsFinite(bool Set = true) {bSizeIsFinite = Set;}
00488 inline uint64 GetSizePosition() const {return SizePosition;}
00489
00490 #if defined(EBML_STRICT_API)
00491 private:
00492 #endif
00493 uint64 Size;
00494 uint64 DefaultSize;
00495 int SizeLength;
00496 bool bSizeIsFinite;
00497 uint64 ElementPosition;
00498 uint64 SizePosition;
00499 bool bValueIsSet;
00500 bool DefaultIsSet;
00501 bool bLocked;
00502 };
00503
00504 END_LIBEBML_NAMESPACE
00505
00506 #endif // LIBEBML_ELEMENT_H