diff --git a/ebml/EbmlElement.h b/ebml/EbmlElement.h index bacaf7f1..a7310962 100644 --- a/ebml/EbmlElement.h +++ b/ebml/EbmlElement.h @@ -128,6 +128,12 @@ extern const EbmlSemanticContext Context_EbmlGlobal; #define DEFINE_START_SEMANTIC(x) static const EbmlSemantic ContextList_##x[] = { #define DEFINE_END_SEMANTIC(x) }; #define DEFINE_SEMANTIC_ITEM(m,u,c) EbmlSemantic(m, u, EBML_INFO(c)), +#define DEFINE_SEMANTIC_ITEM_UINT(m,u,d,c) EbmlSemantic(m, u, static_cast(d), EBML_INFO(c)), +#define DEFINE_SEMANTIC_ITEM_SINT(m,u,d,c) EbmlSemantic(m, u, static_cast(d), EBML_INFO(c)), +#define DEFINE_SEMANTIC_ITEM_DATE(m,u,d,c) EbmlSemantic(m, u, static_cast(d,true), EBML_INFO(c)), +#define DEFINE_SEMANTIC_ITEM_FLOAT(m,u,d,c) EbmlSemantic(m, u, static_cast(d), EBML_INFO(c)), +#define DEFINE_SEMANTIC_ITEM_STRING(m,u,d,c) EbmlSemantic(m, u, static_cast(d), EBML_INFO(c)), +#define DEFINE_SEMANTIC_ITEM_UTF8(m,u,d,c) EbmlSemantic(m, u, static_cast(d), EBML_INFO(c)), #define DECLARE_EBML_MASTER(x) class EBML_DLL_API x : public EbmlMaster { \ public: \ @@ -222,18 +228,55 @@ class EBML_DLL_API EbmlCallbacks { */ class EBML_DLL_API EbmlSemantic { public: + struct DefaultValues; + constexpr EbmlSemantic(bool aMandatory, bool aUnique, const EbmlCallbacks & aCallbacks) - :Mandatory(aMandatory), Unique(aUnique), Callbacks(aCallbacks) {} + :Mandatory(aMandatory), Unique(aUnique), defaultValue(), Callbacks(aCallbacks) {} + + constexpr EbmlSemantic(bool aMandatory, bool aUnique, const DefaultValues &def, const EbmlCallbacks & aGetCallbacks) + :Mandatory(aMandatory), Unique(aUnique), defaultValue(def), Callbacks(aGetCallbacks) {} inline bool IsMandatory() const { return Mandatory; } inline bool IsUnique() const { return Unique; } + inline const DefaultValues & DefaultValue() const { return defaultValue; } inline EbmlElement & Create() const { return EBML_INFO_CREATE(Callbacks); } inline explicit operator const EbmlCallbacks &() const { return Callbacks; } inline EbmlCallbacks const &GetCallbacks() const { return Callbacks; } - private: + enum DefaultType { + NO_DEFAULT, + UINTEGER, + SINTEGER, + DATE, + DOUBLE, + STRING, + UNISTRING, + }; + struct DefaultValues { + DefaultType type; + union { + std::uint64_t u64; + std::int64_t i64; + double f; + const char* s; + const wchar_t* ws; + }; + + constexpr DefaultValues(void) : u64(0), type(DefaultType::NO_DEFAULT) {} + constexpr DefaultValues(const DefaultValues &) = default; + constexpr DefaultValues(std::uint64_t u) : u64(u), type(DefaultType::UINTEGER) {} + constexpr DefaultValues(std::int64_t u, bool date = false) : i64(u), type(date ? DefaultType::UINTEGER : DefaultType::DATE) {} + constexpr DefaultValues(double d) : f(d), type(DefaultType::DOUBLE) {} + constexpr DefaultValues(const char *d) : s(d), type(DefaultType::STRING) {} + constexpr DefaultValues(const wchar_t *d) : ws(d), type(DefaultType::UNISTRING) {} + + bool HasDefault() const { return type != DefaultType::NO_DEFAULT; } + }; + + private: const bool Mandatory; ///< whether the element is mandatory in the context or not const bool Unique; + const DefaultValues defaultValue; const EbmlCallbacks & Callbacks; }; diff --git a/src/EbmlHead.cpp b/src/EbmlHead.cpp index b14be5a5..9f9c38da 100644 --- a/src/EbmlHead.cpp +++ b/src/EbmlHead.cpp @@ -12,13 +12,13 @@ namespace libebml { DEFINE_START_SEMANTIC(EbmlHead) -DEFINE_SEMANTIC_ITEM(true, true, EVersion) ///< EBMLVersion -DEFINE_SEMANTIC_ITEM(true, true, EReadVersion) ///< EBMLReadVersion -DEFINE_SEMANTIC_ITEM(true, true, EMaxIdLength) ///< EBMLMaxIdLength -DEFINE_SEMANTIC_ITEM(true, true, EMaxSizeLength) ///< EBMLMaxSizeLength +DEFINE_SEMANTIC_ITEM_UINT(true, true, 1, EVersion) ///< EBMLVersion +DEFINE_SEMANTIC_ITEM_UINT(true, true, 1, EReadVersion) ///< EBMLReadVersion +DEFINE_SEMANTIC_ITEM_UINT(true, true, 4, EMaxIdLength) ///< EBMLMaxIdLength +DEFINE_SEMANTIC_ITEM_UINT(true, true, 8, EMaxSizeLength) ///< EBMLMaxSizeLength DEFINE_SEMANTIC_ITEM(true, true, EDocType) ///< DocType -DEFINE_SEMANTIC_ITEM(true, true, EDocTypeVersion) ///< DocTypeVersion -DEFINE_SEMANTIC_ITEM(true, true, EDocTypeReadVersion) ///< DocTypeReadVersion +DEFINE_SEMANTIC_ITEM_UINT(true, true, 1, EDocTypeVersion) ///< DocTypeVersion +DEFINE_SEMANTIC_ITEM_UINT(true, true, 1, EDocTypeReadVersion) ///< DocTypeReadVersion DEFINE_END_SEMANTIC(EbmlHead) DEFINE_EBML_MASTER_ORPHAN(EbmlHead, 0x1A45DFA3, 4, "EBMLHead\0ratamapaga")