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