Matroska-Org / libebml

a C++ library to parse EBML files
GNU Lesser General Public License v2.1
140 stars 47 forks source link

Setting EbmlString from an EbmlMaster to default value wont work #55

Closed lattice0 closed 4 years ago

lattice0 commented 4 years ago

I created my own EbmlHead class subclassing from EbmlMaster and did this:

DEFINE_EBML_UINTEGER_DEF(EVersion, 0x4286, 2, OrwellEbmlHead, "EBMLVersion", 1)
DEFINE_EBML_UINTEGER_DEF(EReadVersion, 0x42F7, 2, OrwellEbmlHead, "EBMLReadVersion", 1)
DEFINE_EBML_UINTEGER_DEF(EMaxIdLength, 0x42F2, 2, OrwellEbmlHead, "EBMLMaxIdLength", 4)
DEFINE_EBML_UINTEGER_DEF(EMaxSizeLength, 0x42F3, 2, OrwellEbmlHead, "EBMLMaxSizeLength", 8)
DEFINE_EBML_STRING_DEF(EDocType, 0x4282, 2, OrwellEbmlHead, "EBMLDocType", "orwell")
DEFINE_EBML_UINTEGER_DEF(EDocTypeVersion, 0x4287, 2, OrwellEbmlHead, "EBMLDocTypeVersion", 1)
DEFINE_EBML_UINTEGER_DEF(EDocTypeReadVersion, 0x4285, 2, OrwellEbmlHead, "EBMLDocTypeReadVersion", 1)

Then if I try to do

    EbmlHead FileHead;
    *static_cast<EbmlUInteger *>(&GetChild<EVersion>(FileHead)) = 1;
    *static_cast<EbmlUInteger *>(&GetChild<EReadVersion>(FileHead)) = 1;
    *static_cast<EbmlUInteger *>(&GetChild<EMaxIdLength>(FileHead)) = 4;
    *static_cast<EbmlUInteger *>(&GetChild<EMaxSizeLength>(FileHead)) = 8;
    *static_cast<EbmlString *>(&GetChild<EDocType>(FileHead)) = "something";
    *static_cast<EbmlUInteger *>(&GetChild<EDocTypeVersion>(FileHead)) = 1;
    *static_cast<EbmlUInteger *>(&GetChild<EDocTypeReadVersion>(FileHead)) = 1;
    FileHead.RenderData(stdIOCallback, true);

I get the expected binary file. But if

something

in

*static_cast<EbmlString *>(&GetChild<EDocType>(FileHead)) = "something";

is renamed to

orwell

which is the default value defined for EDocType as you can see, then I get a file with 0 bytes. Shouldn't it be a bug?

I also tried to simply do

    EbmlHead FileHead;

    FileHead.RenderData(stdIOCallback, true);

assuming it would write to the file since I already gave default values for every class, but it won't work, I get a file with 0 bytes

mbunkus commented 4 years ago

RenderData has a third parameter that controls whether elements that are set to their default value are written to the file or not. That parameter's default value is false, meaning "do not write elements set to their respective default values to the file". As you don't pass that third parameter to RenderData, the file not containing the orwell string is expected.