Skip to content

Commit

Permalink
use a templated type for default values
Browse files Browse the repository at this point in the history
So the default value is hardcoded in the class semantic info and not
set in the constructor.

A new EbmlElement subclass is created for EbmlElement types that may
have a default value.

An IsSameValue() method is added to compare an element to a value. This
is used by the EbmlElementDefault class to tell if the element value is
the same as the default when there is one.
  • Loading branch information
robUx4 committed Jan 1, 2024
1 parent f427f72 commit 51c2767
Show file tree
Hide file tree
Showing 16 changed files with 260 additions and 221 deletions.
15 changes: 11 additions & 4 deletions ebml/EbmlDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ namespace libebml {
\class EbmlDate
\brief Handle all operations related to an EBML date
*/
class EBML_DLL_API EbmlDate : public EbmlElement {
class EBML_DLL_API EbmlDate : public EbmlElementDefault<std::int64_t> {
public:
EbmlDate(const EbmlCallbacks & classInfo) :EbmlElement(classInfo, 8, false) {}
EbmlDate(const EbmlCallbacksDefault<std::int64_t> & classInfo) :EbmlElementDefault<std::int64_t>(classInfo, 8)
{
if (classInfo.HasDefault())
{
auto def = static_cast<const EbmlCallbacksWithDefault<std::int64_t> &>(classInfo);
SetValue(def.DefaultValue());
}
}

/*!
\brief set the date with a UNIX/C/EPOCH form
Expand Down Expand Up @@ -52,8 +59,8 @@ class EBML_DLL_API EbmlDate : public EbmlElement {

filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA) override;

bool IsDefaultValue() const override {
return false;
bool operator==(const std::int64_t & val) const override {
return val == Value;
}

private:
Expand Down
174 changes: 138 additions & 36 deletions ebml/EbmlElement.h

Large diffs are not rendered by default.

14 changes: 4 additions & 10 deletions ebml/EbmlFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ namespace libebml {
\class EbmlFloat
\brief Handle all operations on a float EBML element
*/
class EBML_DLL_API EbmlFloat : public EbmlElement {
class EBML_DLL_API EbmlFloat : public EbmlElementDefault<double> {
public:
enum Precision {
FLOAT_32
,FLOAT_64
};

EbmlFloat(const EbmlCallbacks &, Precision prec = FLOAT_32);
EbmlFloat(const EbmlCallbacks &, double DefaultValue, Precision prec = FLOAT_32);
EbmlFloat(const EbmlCallbacksDefault<double> &, Precision prec = FLOAT_32);

bool ValidateSize() const override
{
Expand Down Expand Up @@ -54,17 +53,12 @@ class EBML_DLL_API EbmlFloat : public EbmlElement {
EbmlFloat &SetValue(double NewValue);
double GetValue() const;

void SetDefaultValue(double);

double DefaultVal() const;

bool IsDefaultValue() const override {
return (DefaultISset() && Value == DefaultValue);
bool operator==(const double & val) const override {
return val == Value;
}

private:
double Value; /// The actual value of the element
double DefaultValue;
};

} // namespace libebml
Expand Down
14 changes: 4 additions & 10 deletions ebml/EbmlSInteger.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ const int DEFAULT_INT_SIZE = 1; ///< optimal size stored
\class EbmlSInteger
\brief Handle all operations on a signed integer EBML element
*/
class EBML_DLL_API EbmlSInteger : public EbmlElement {
class EBML_DLL_API EbmlSInteger : public EbmlElementDefault<std::int64_t> {
public:
EbmlSInteger(const EbmlCallbacks &);
explicit EbmlSInteger(const EbmlCallbacks &, std::int64_t DefaultValue);
EbmlSInteger(const EbmlCallbacksDefault<std::int64_t> &);

/*!
Set the default size of the integer (usually 1,2,4 or 8)
Expand All @@ -49,17 +48,12 @@ class EBML_DLL_API EbmlSInteger : public EbmlElement {
EbmlSInteger &SetValue(std::int64_t NewValue);
std::int64_t GetValue() const;

void SetDefaultValue(std::int64_t aValue) {assert(!DefaultISset()); DefaultValue = aValue; SetDefaultIsSet();}

std::int64_t DefaultVal() const {assert(DefaultISset()); return DefaultValue;}

bool IsDefaultValue() const override {
return (DefaultISset() && Value == DefaultValue);
bool operator==(const std::int64_t & val) const override {
return val == Value;
}

private:
std::int64_t Value; /// The actual value of the element
std::int64_t DefaultValue;
};

} // namespace libebml
Expand Down
14 changes: 4 additions & 10 deletions ebml/EbmlString.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ namespace libebml {
\class EbmlString
\brief Handle all operations on a printable string EBML element
*/
class EBML_DLL_API EbmlString : public EbmlElement {
class EBML_DLL_API EbmlString : public EbmlElementDefault<const char *> {
public:
EbmlString(const EbmlCallbacks &);
explicit EbmlString(const EbmlCallbacks &, const std::string & aDefaultValue);
EbmlString(const EbmlCallbacksDefault<const char *> &);

bool ValidateSize() const override {return GetSize() < 0x7FFFFFFF;} // any size is possible
filepos_t RenderData(IOCallback & output, bool bForceRender, ShouldWrite writeFilter = WriteSkipDefault) override;
Expand All @@ -35,17 +34,12 @@ class EBML_DLL_API EbmlString : public EbmlElement {
EbmlString &SetValue(std::string const &NewValue);
std::string GetValue() const;

void SetDefaultValue(std::string &);

const std::string & DefaultVal() const;

bool IsDefaultValue() const override {
return (DefaultISset() && Value == DefaultValue);
bool operator==(const char * const & val) const override {
return val == Value;
}

private:
std::string Value; /// The actual value of the element
std::string DefaultValue;
};

} // namespace libebml
Expand Down
14 changes: 7 additions & 7 deletions ebml/EbmlSubHead.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,37 @@

namespace libebml {

DECLARE_EBML_UINTEGER(EVersion)
DECLARE_EBML_UINTEGER_DEF(EVersion)
public:
EBML_CONCRETE_CLASS(EVersion)
};

DECLARE_EBML_UINTEGER(EReadVersion)
DECLARE_EBML_UINTEGER_DEF(EReadVersion)
public:
EBML_CONCRETE_CLASS(EReadVersion)
};

DECLARE_EBML_UINTEGER(EMaxIdLength)
DECLARE_EBML_UINTEGER_DEF(EMaxIdLength)
public:
EBML_CONCRETE_CLASS(EMaxIdLength)
};

DECLARE_EBML_UINTEGER(EMaxSizeLength)
DECLARE_EBML_UINTEGER_DEF(EMaxSizeLength)
public:
EBML_CONCRETE_CLASS(EMaxSizeLength)
};

DECLARE_EBML_STRING(EDocType)
DECLARE_EBML_STRING_DEF(EDocType)
public:
EBML_CONCRETE_CLASS(EDocType)
};

DECLARE_EBML_UINTEGER(EDocTypeVersion)
DECLARE_EBML_UINTEGER_DEF(EDocTypeVersion)
public:
EBML_CONCRETE_CLASS(EDocTypeVersion)
};

DECLARE_EBML_UINTEGER(EDocTypeReadVersion)
DECLARE_EBML_UINTEGER_DEF(EDocTypeReadVersion)
public:
EBML_CONCRETE_CLASS(EDocTypeReadVersion)
};
Expand Down
14 changes: 4 additions & 10 deletions ebml/EbmlUInteger.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ const int DEFAULT_UINT_SIZE = 0; ///< optimal size stored
\class EbmlUInteger
\brief Handle all operations on an unsigned integer EBML element
*/
class EBML_DLL_API EbmlUInteger : public EbmlElement {
class EBML_DLL_API EbmlUInteger : public EbmlElementDefault<std::uint64_t> {
public:
EbmlUInteger(const EbmlCallbacks &);
explicit EbmlUInteger(const EbmlCallbacks &, std::uint64_t DefaultValue);
EbmlUInteger(const EbmlCallbacksDefault<std::uint64_t> &);

/*!
Set the default size of the integer (usually 1,2,4 or 8)
Expand All @@ -47,17 +46,12 @@ class EBML_DLL_API EbmlUInteger : public EbmlElement {
EbmlUInteger &SetValue(std::uint64_t NewValue);
std::uint64_t GetValue() const;

void SetDefaultValue(std::uint64_t);

std::uint64_t DefaultVal() const;

bool IsDefaultValue() const override {
return (DefaultISset() && Value == DefaultValue);
bool operator==(const std::uint64_t & val) const override {
return val == Value;
}

private:
std::uint64_t Value; /// The actual value of the element
std::uint64_t DefaultValue;
};

} // namespace libebml
Expand Down
14 changes: 4 additions & 10 deletions ebml/EbmlUnicodeString.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,9 @@ class EBML_DLL_API UTFstring {
\brief Handle all operations on a Unicode string EBML element
\note internally treated as a string made of wide characters (ie UCS-2 or UCS-4 depending on the machine)
*/
class EBML_DLL_API EbmlUnicodeString : public EbmlElement {
class EBML_DLL_API EbmlUnicodeString : public EbmlElementDefault<const wchar_t *> {
public:
EbmlUnicodeString(const EbmlCallbacks &);
explicit EbmlUnicodeString(const EbmlCallbacks &, const UTFstring & DefaultValue);
EbmlUnicodeString(const EbmlCallbacksDefault<const wchar_t *> &);

bool ValidateSize() const override {return true;} // any size is possible
filepos_t RenderData(IOCallback & output, bool bForceRender, ShouldWrite writeFilter = WriteSkipDefault) override;
Expand All @@ -83,17 +82,12 @@ class EBML_DLL_API EbmlUnicodeString : public EbmlElement {
UTFstring GetValue() const;
std::string GetValueUTF8() const;

void SetDefaultValue(UTFstring &);

const UTFstring & DefaultVal() const;

bool IsDefaultValue() const override {
return (DefaultISset() && Value == DefaultValue);
bool operator==(const wchar_t * const & val) const override {
return static_cast<UTFstring>(val) == Value;
}

private:
UTFstring Value; /// The actual value of the element
UTFstring DefaultValue;
};

} // namespace libebml
Expand Down
29 changes: 7 additions & 22 deletions src/EbmlFloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,15 @@

namespace libebml {

EbmlFloat::EbmlFloat(const EbmlCallbacks & classInfo, const EbmlFloat::Precision prec)
:EbmlElement(classInfo, 0, false)
EbmlFloat::EbmlFloat(const EbmlCallbacksDefault<double> & classInfo, const EbmlFloat::Precision prec)
:EbmlElementDefault(classInfo, 0)
{
SetPrecision(prec);
}

EbmlFloat::EbmlFloat(const EbmlCallbacks & classInfo, const double aDefaultValue, const EbmlFloat::Precision prec)
:EbmlElement(classInfo, 0, true), Value(aDefaultValue), DefaultValue(aDefaultValue)
{
SetDefaultIsSet();
SetPrecision(prec);
}

void EbmlFloat::SetDefaultValue(double aValue)
{
assert(!DefaultISset());
DefaultValue = aValue;
SetDefaultIsSet();
}

double EbmlFloat::DefaultVal() const
{
assert(DefaultISset());
return DefaultValue;
if (classInfo.HasDefault())
{
auto def = static_cast<const EbmlCallbacksWithDefault<double> &>(classInfo);
SetValue(def.DefaultValue());
}
}

EbmlFloat::operator float() const {return static_cast<float>(Value);}
Expand Down
7 changes: 3 additions & 4 deletions src/EbmlMaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,12 @@ bool EbmlMaster::CheckMandatory() const
for (EltIdx = 0; EltIdx < EBML_CTX_SIZE(MasterContext); EltIdx++) {
if (EBML_CTX_IDX(MasterContext,EltIdx).IsMandatory()) {
if (FindElt(EBML_CTX_IDX_INFO(MasterContext,EltIdx)) == nullptr) {
const auto testElement = &EBML_CTX_IDX(MasterContext,EltIdx).Create();
const bool hasDefaultValue = testElement->DefaultISset();
delete testElement;
const auto & semcb = EBML_CTX_IDX(MasterContext,EltIdx).GetCallbacks();
const bool hasDefaultValue = semcb.HasDefault();

#if !defined(NDEBUG)
// you are missing this Mandatory element
// const char * MissingName = EBML_INFO_NAME(EBML_CTX_IDX_INFO(MasterContext,EltIdx));
// const char * MissingName = semcb.GetName();
#endif // !NDEBUG
if (!hasDefaultValue)
return false;
Expand Down
14 changes: 7 additions & 7 deletions src/EbmlSInteger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ ToSigned(std::uint64_t u) {

namespace libebml {

EbmlSInteger::EbmlSInteger(const EbmlCallbacks & classInfo)
:EbmlElement(classInfo, DEFAULT_INT_SIZE, false)
{}

EbmlSInteger::EbmlSInteger(const EbmlCallbacks & classInfo, std::int64_t aDefaultValue)
:EbmlElement(classInfo, DEFAULT_INT_SIZE, true), Value(aDefaultValue)
EbmlSInteger::EbmlSInteger(const EbmlCallbacksDefault<std::int64_t> & classInfo)
:EbmlElementDefault(classInfo, DEFAULT_INT_SIZE)
{
SetDefaultIsSet();
if (classInfo.HasDefault())
{
auto def = static_cast<const EbmlCallbacksWithDefault<std::int64_t> &>(classInfo);
SetValue(def.DefaultValue());
}
}

EbmlSInteger::operator std::int8_t() const {return static_cast<std::int8_t>(Value);}
Expand Down
42 changes: 7 additions & 35 deletions src/EbmlString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,16 @@

namespace libebml {

EbmlString::EbmlString(const EbmlCallbacks & classInfo)
:EbmlElement(classInfo, 0, false)
EbmlString::EbmlString(const EbmlCallbacksDefault<const char *> & classInfo)
:EbmlElementDefault(classInfo, 0)
{
SetDefaultSize(0);
/* done automatically
SetSize_(Value.length());
if (GetDefaultSize() > GetSize())
SetSize_(GetDefaultSize());*/
}

EbmlString::EbmlString(const EbmlCallbacks & classInfo, const std::string & aDefaultValue)
:EbmlElement(classInfo, 0, true), Value(aDefaultValue), DefaultValue(aDefaultValue)
{
SetDefaultSize(0);
SetDefaultIsSet();
/* done automatically
SetSize_(Value.length());
if (GetDefaultSize() > GetSize())
SetSize_(GetDefaultSize());*/
}

/*!
\todo Cloning should be on the same exact type !
*/
void EbmlString::SetDefaultValue(std::string & aValue)
{
assert(!DefaultISset());
DefaultValue = aValue;
SetDefaultIsSet();
}

const std::string & EbmlString::DefaultVal() const
{
assert(DefaultISset());
return DefaultValue;
if (classInfo.HasDefault())
{
auto def = static_cast<const EbmlCallbacksWithDefault<const char *> &>(classInfo);
SetValue(def.DefaultValue());
}
}


/*!
\todo handle exception on errors
*/
Expand Down
Loading

0 comments on commit 51c2767

Please sign in to comment.