diff --git a/ebml/EbmlElement.h b/ebml/EbmlElement.h index abcf9f4..6c0727a 100644 --- a/ebml/EbmlElement.h +++ b/ebml/EbmlElement.h @@ -83,14 +83,14 @@ class EbmlElement; #if defined(EBML_STRICT_API) #define EBML_CONCRETE_CLASS(Type) \ public: \ - virtual const EbmlSemanticContext &Context() const {return ClassInfos.Context;} \ - virtual const char *DebugName() const {return ClassInfos.DebugName;} \ - virtual operator const EbmlId &() const {return ClassInfos.GlobalId;} \ + virtual const EbmlSemanticContext &Context() const {return ClassInfos.GetContext();} \ + virtual const char *DebugName() const {return ClassInfos.GetName();} \ + virtual operator const EbmlId &() const {return ClassInfos.ClassId();} \ virtual EbmlElement & CreateElement() const {return Create();} \ virtual EbmlElement * Clone() const { return new Type(*this); } \ static EbmlElement & Create() {return *(new Type);} \ static const EbmlCallbacks & ClassInfo() {return ClassInfos;} \ - static const EbmlId & ClassId() {return ClassInfos.GlobalId;} \ + static const EbmlId & ClassId() {return ClassInfos.ClassId();} \ private: \ static const EbmlCallbacks ClassInfos; \ @@ -98,6 +98,18 @@ class EbmlElement; #define EBML_ID(ref) ref::ClassId() #define EBML_CONTEXT(e) (e)->Context() #define EBML_NAME(e) (e)->DebugName() + +#define EBML_INFO_ID(cb) (cb).ClassId() +#define EBML_INFO_NAME(cb) (cb).GetName() +#define EBML_INFO_CREATE(cb) (cb).NewElement() +#define EBML_INFO_CONTEXT(cb) (cb).GetContext() + +#define EBML_SEM_UNIQUE(s) (s).IsUnique() +#define EBML_SEM_INFO(s) (const EbmlCallbacks &)(s) + +#define EBML_CTX_SIZE(c) (c).GetSize() +#define EBML_CTX_MASTER(c) (c).GetMaster() +#define EBML_CTX_PARENT(c) (c).Parent() #else #define EBML_CONCRETE_CLASS(Type) \ public: \ @@ -112,6 +124,18 @@ class EbmlElement; #define EBML_ID(ref) ref::ClassInfos.GlobalId #define EBML_CONTEXT(e) (e)->Generic().Context #define EBML_NAME(e) (e)->Generic().DebugName + +#define EBML_INFO_ID(cb) (cb).GlobalId +#define EBML_INFO_NAME(cb) (cb).DebugName +#define EBML_INFO_CREATE(cb) (cb).Create() +#define EBML_INFO_CONTEXT(cb) (cb).Context + +#define EBML_SEM_UNIQUE(s) (s).Unique +#define EBML_SEM_INFO(s) (s).GetCallbacks + +#define EBML_CTX_SIZE(c) (c).Size +#define EBML_CTX_MASTER(c) (c).MasterElt +#define EBML_CTX_PARENT(c) (c).UpTable #endif // functions for generic handling of data (should be static to all classes) @@ -125,8 +149,17 @@ class EBML_DLL_API EbmlCallbacks { ,GlobalId(aGlobalId) ,DebugName(aDebugName) ,Context(aContext) - {} + { + } + inline const EbmlId & ClassId() const { return GlobalId; } + inline const EbmlSemanticContext & GetContext() const { return Context; } + inline const char * GetName() const { return DebugName; } + inline EbmlElement & NewElement() const { return Create(); } + +#if defined(EBML_STRICT_API) + private: +#endif EbmlElement & (*Create)(); const EbmlId & GlobalId; const char * DebugName; @@ -142,6 +175,14 @@ class EBML_DLL_API EbmlSemantic { EbmlSemantic(bool aMandatory, bool aUnique, const EbmlCallbacks & aGetCallbacks) :Mandatory(aMandatory), Unique(aUnique), GetCallbacks(aGetCallbacks) {} + inline bool IsMandatory() const { return Mandatory; } + inline bool IsUnique() const { return Unique; } + inline EbmlElement & Create() const { return EBML_INFO_CREATE(GetCallbacks); } + inline operator const EbmlCallbacks &() { return GetCallbacks; } + +#if defined(EBML_STRICT_API) + private: +#endif bool Mandatory; ///< wether the element is mandatory in the context or not bool Unique; const EbmlCallbacks & GetCallbacks; @@ -155,7 +196,7 @@ typedef const class EbmlSemanticContext & (*_GetSemanticContext)(); */ class EBML_DLL_API EbmlSemanticContext { public: - EbmlSemanticContext(unsigned int aSize, + EbmlSemanticContext(size_t aSize, const EbmlSemantic *aMyTable, const EbmlSemanticContext *aUpTable, const _GetSemanticContext aGetGlobalContext, @@ -169,12 +210,19 @@ class EBML_DLL_API EbmlSemanticContext { (MasterElt != aElt.MasterElt)); } + inline size_t GetSize() const { return Size; } + inline const EbmlCallbacks* GetMaster() const { return MasterElt; } + inline const EbmlSemanticContext* Parent() const { return UpTable; } - unsigned int Size; ///< number of elements in the table - const EbmlSemantic *MyTable; ///< First element in the table + const EbmlSemantic *MyTable; ///< First element in the table + const _GetSemanticContext GetGlobalContext; ///< global elements supported at this level + +#if defined(EBML_STRICT_API) + private: +#endif + size_t Size; ///< number of elements in the table const EbmlSemanticContext *UpTable; ///< Parent element /// \todo replace with the global context directly - const _GetSemanticContext GetGlobalContext; ///< global elements supported at this level const EbmlCallbacks *MasterElt; }; diff --git a/src/EbmlElement.cpp b/src/EbmlElement.cpp index cfde244..e791fcc 100644 --- a/src/EbmlElement.cpp +++ b/src/EbmlElement.cpp @@ -259,7 +259,7 @@ EbmlElement * EbmlElement::FindNextID(IOCallback & DataStream, const EbmlCallbac if (PossibleId[0] & BitMask) { // this is the last octet of the ID // check wether that's the one we're looking for -/* if (PossibleID == ClassInfos.GlobalId) { +/* if (PossibleID == EBML_INFO_ID(ClassInfos)) { break; } else { /// \todo This element should be skipped (use a context ?) @@ -286,9 +286,9 @@ EbmlElement * EbmlElement::FindNextID(IOCallback & DataStream, const EbmlCallbac EbmlElement *Result = NULL; EbmlId PossibleID(PossibleId, PossibleID_Length); - if (PossibleID == ClassInfos.GlobalId) { + if (PossibleID == EBML_INFO_ID(ClassInfos)) { // the element is the one expected - Result = &ClassInfos.Create(); + Result = &EBML_INFO_CREATE(ClassInfos); } else { /// \todo find the element in the context Result = new EbmlDummy(PossibleID); @@ -465,17 +465,17 @@ EbmlElement * EbmlElement::SkipData(EbmlStream & DataStream, const EbmlSemanticC if (Result != NULL) { unsigned int EltIndex; // data known in this Master's context - for (EltIndex = 0; EltIndex < Context.Size; EltIndex++) { - if (EbmlId(*Result) == Context.MyTable[EltIndex].GetCallbacks.GlobalId) { + for (EltIndex = 0; EltIndex < EBML_CTX_SIZE(Context); EltIndex++) { + if (EbmlId(*Result) == EBML_INFO_ID(EBML_SEM_INFO(Context.MyTable[EltIndex]))) { // skip the data with its own context - Result = Result->SkipData(DataStream, Context.MyTable[EltIndex].GetCallbacks.Context, NULL); + Result = Result->SkipData(DataStream, EBML_INFO_CONTEXT(EBML_SEM_INFO(Context.MyTable[EltIndex])), NULL); break; // let's go to the next ID } } - if (EltIndex >= Context.Size) { - if (Context.UpTable != NULL) { - Result = SkipData(DataStream, *Context.UpTable, Result); + if (EltIndex >= EBML_CTX_SIZE(Context)) { + if (EBML_CTX_PARENT(Context) != NULL) { + Result = SkipData(DataStream, *EBML_CTX_PARENT(Context), Result); } else { assert(Context.GetGlobalContext != NULL); if (Context != Context.GetGlobalContext()) { @@ -500,9 +500,9 @@ EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const Eb EbmlElement *Result = NULL; // elements at the current level - for (ContextIndex = 0; ContextIndex < Context.Size; ContextIndex++) { - if (aID == Context.MyTable[ContextIndex].GetCallbacks.GlobalId) { - return &Context.MyTable[ContextIndex].GetCallbacks.Create(); + for (ContextIndex = 0; ContextIndex < EBML_CTX_SIZE(Context); ContextIndex++) { + if (aID == EBML_INFO_ID(EBML_SEM_INFO(Context.MyTable[ContextIndex]))) { + return &Context.MyTable[ContextIndex].Create(); } } @@ -524,16 +524,16 @@ EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const Eb } // parent elements - if (Context.MasterElt != NULL && aID == Context.MasterElt->GlobalId) { + if (EBML_CTX_MASTER(Context) != NULL && aID == EBML_INFO_ID(*EBML_CTX_MASTER(Context))) { LowLevel++; // already one level up (same as context) - return &Context.MasterElt->Create(); + return &EBML_INFO_CREATE(*EBML_CTX_MASTER(Context)); } // check wether it's not part of an upper context - if (Context.UpTable != NULL) { + if (EBML_CTX_PARENT(Context) != NULL) { LowLevel++; MaxLowerLevel++; - return CreateElementUsingContext(aID, *Context.UpTable, LowLevel, IsGlobalContext, bAllowDummy, MaxLowerLevel); + return CreateElementUsingContext(aID, *EBML_CTX_PARENT(Context), LowLevel, IsGlobalContext, bAllowDummy, MaxLowerLevel); } if (!IsGlobalContext && bAllowDummy) { diff --git a/src/EbmlMaster.cpp b/src/EbmlMaster.cpp index 27dab9f..15cf3b7 100644 --- a/src/EbmlMaster.cpp +++ b/src/EbmlMaster.cpp @@ -179,7 +179,7 @@ uint64 EbmlMaster::ReadData(IOCallback & input, ScopeMode ReadFully) */ bool EbmlMaster::ProcessMandatory() { - if (Context.Size == 0) + if (EBML_CTX_SIZE(Context) == 0) { return true; } @@ -187,10 +187,10 @@ bool EbmlMaster::ProcessMandatory() assert(Context.MyTable != NULL); unsigned int EltIdx; - for (EltIdx = 0; EltIdx < Context.Size; EltIdx++) { - if (Context.MyTable[EltIdx].Mandatory && Context.MyTable[EltIdx].Unique) { - assert(Context.MyTable[EltIdx].GetCallbacks.Create != NULL); - PushElement(Context.MyTable[EltIdx].GetCallbacks.Create()); + for (EltIdx = 0; EltIdx < EBML_CTX_SIZE(Context); EltIdx++) { + if (Context.MyTable[EltIdx].IsMandatory() && Context.MyTable[EltIdx].IsUnique()) { +// assert(Context.MyTable[EltIdx].Create() != NULL); + PushElement(Context.MyTable[EltIdx].Create()); } } return true; @@ -201,12 +201,12 @@ bool EbmlMaster::CheckMandatory() const assert(Context.MyTable != NULL); unsigned int EltIdx; - for (EltIdx = 0; EltIdx < Context.Size; EltIdx++) { - if (Context.MyTable[EltIdx].Mandatory) { - if (FindElt(Context.MyTable[EltIdx].GetCallbacks) == NULL) { + for (EltIdx = 0; EltIdx < EBML_CTX_SIZE(Context); EltIdx++) { + if (Context.MyTable[EltIdx].IsMandatory()) { + if (FindElt(EBML_SEM_INFO(Context.MyTable[EltIdx])) == NULL) { #if defined(_DEBUG) || defined(DEBUG) // you are missing this Mandatory element -// const char * MissingName = Context.MyTable[EltIdx].GetCallbacks.DebugName; +// const char * MissingName = EBML_INFO_NAME(EBML_SEM_INFO(Context.MyTable[EltIdx])); #endif // DEBUG return false; } @@ -243,14 +243,14 @@ std::vector EbmlMaster::FindAllMissingElements() } } unsigned int EltIdx; - for (EltIdx = 0; EltIdx < Context.Size; EltIdx++) { - if (Context.MyTable[EltIdx].Mandatory) { - if (FindElt(Context.MyTable[EltIdx].GetCallbacks) == NULL) { + for (EltIdx = 0; EltIdx < EBML_CTX_SIZE(Context); EltIdx++) { + if (Context.MyTable[EltIdx].IsMandatory()) { + if (FindElt(EBML_SEM_INFO(Context.MyTable[EltIdx])) == NULL) { std::string missingElement; missingElement = "Missing element \""; - missingElement.append(Context.MyTable[EltIdx].GetCallbacks.DebugName); + missingElement.append(EBML_INFO_NAME(EBML_SEM_INFO(Context.MyTable[EltIdx]))); missingElement.append("\" in EbmlMaster \""); - missingElement.append(Context.MasterElt->DebugName); + missingElement.append(EBML_INFO_NAME(*EBML_CTX_MASTER(Context))); missingElement.append("\""); missingElements.push_back(missingElement); } @@ -266,7 +266,7 @@ EbmlElement *EbmlMaster::FindElt(const EbmlCallbacks & Callbacks) const for (Index = 0; Index < ElementList.size(); Index++) { EbmlElement * tmp = ElementList[Index]; - if (EbmlId(*tmp) == Callbacks.GlobalId) + if (EbmlId(*tmp) == EBML_INFO_ID(Callbacks)) return tmp; } @@ -278,13 +278,13 @@ EbmlElement *EbmlMaster::FindFirstElt(const EbmlCallbacks & Callbacks, bool bCre size_t Index; for (Index = 0; Index < ElementList.size(); Index++) { - if (EbmlId(*(ElementList[Index])) == Callbacks.GlobalId) + if (EbmlId(*(ElementList[Index])) == EBML_INFO_ID(Callbacks)) return ElementList[Index]; } - if (bCreateIfNull && Callbacks.Create != NULL) { + if (bCreateIfNull) { // add the element - EbmlElement *NewElt = &(Callbacks.Create()); + EbmlElement *NewElt = &EBML_INFO_CREATE(Callbacks); if (NewElt == NULL) return NULL; @@ -303,7 +303,7 @@ EbmlElement *EbmlMaster::FindFirstElt(const EbmlCallbacks & Callbacks) const size_t Index; for (Index = 0; Index < ElementList.size(); Index++) { - if (EbmlId(*(ElementList[Index])) == Callbacks.GlobalId) + if (EbmlId(*(ElementList[Index])) == EBML_INFO_ID(Callbacks)) return ElementList[Index]; } @@ -375,7 +375,7 @@ EbmlElement *EbmlMaster::FindNextElt(const EbmlElement & PastElt) const EbmlElement *EbmlMaster::AddNewElt(const EbmlCallbacks & Callbacks) { // add the element - EbmlElement *NewElt = &(Callbacks.Create()); + EbmlElement *NewElt = &EBML_INFO_CREATE(Callbacks); if (NewElt == NULL) return NULL;