new macros to hide the internal variables of the context classes
git-svn-id: https://matroska.svn.sourceforge.net/svnroot/matroska/trunk/libebml@23 a6f86f6d-0131-4f8e-9e7b-e335508773d5
This commit is contained in:
parent
d9dd385f9f
commit
71367a12c9
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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<std::string> 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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user