3939
4040using namespace TagLib ;
4141
42- EBML::Element *EBML::Element::factory (File &file)
42+ #define RETURN_ELEMENT_FOR_CASE (eid ) \
43+ case (eid): return make_unique_element<eid>(id, sizeLength, dataSize, offset)
44+
45+ std::unique_ptr<EBML::Element> EBML::Element::factory(File &file)
4346{
4447 // Get the element ID
4548 offset_t offset = file.tell ();
46- Id id = readId (file);
47- if (!id ) {
49+ unsigned int uintId = readId (file);
50+ if (!uintId ) {
4851 debug (" Failed to parse EMBL ElementID" );
4952 return nullptr ;
5053 }
@@ -55,73 +58,62 @@ EBML::Element *EBML::Element::factory(File &file)
5558 return nullptr ;
5659
5760 // Return the subclass
61+ // The enum switch without default will give us a warning if an ID is missing
62+ auto id = static_cast <Id>(uintId);
5863 switch (id) {
59- case ElementIDs::EBMLHeader:
60- return new Element (id, sizeLength, dataSize);
61-
62- case ElementIDs::MkSegment:
63- return new MkSegment (sizeLength, dataSize, offset);
64-
65- case ElementIDs::MkInfo:
66- return new MkInfo (sizeLength, dataSize, offset);
67-
68- case ElementIDs::MkTracks:
69- return new MkTracks (sizeLength, dataSize, offset);
70-
71- case ElementIDs::MkTags:
72- return new MkTags (sizeLength, dataSize, offset);
73-
74- case ElementIDs::MkAttachments:
75- return new MkAttachments (sizeLength, dataSize, offset);
76-
77- case ElementIDs::MkTag:
78- case ElementIDs::MkTagTargets:
79- case ElementIDs::MkSimpleTag:
80- case ElementIDs::MkAttachedFile:
81- case ElementIDs::MkSeek:
82- case ElementIDs::MkTrackEntry:
83- case ElementIDs::MkAudio:
84- return new MasterElement (id, sizeLength, dataSize, offset);
85-
86- case ElementIDs::MkTagName:
87- case ElementIDs::MkTagString:
88- case ElementIDs::MkAttachedFileName:
89- case ElementIDs::MkAttachedFileDescription:
90- return new UTF8StringElement (id, sizeLength, dataSize);
91-
92- case ElementIDs::MkTagLanguage:
93- case ElementIDs::MkAttachedFileMediaType:
94- case ElementIDs::MkCodecID:
95- return new Latin1StringElement (id, sizeLength, dataSize);
96-
97- case ElementIDs::MkTagTargetTypeValue:
98- case ElementIDs::MkAttachedFileUID:
99- case ElementIDs::MkSeekPosition:
100- case ElementIDs::MkTimestampScale:
101- case ElementIDs::MkBitDepth:
102- case ElementIDs::MkChannels:
103- return new UIntElement (id, sizeLength, dataSize);
104-
105- case ElementIDs::MkAttachedFileData:
106- case ElementIDs::MkSeekID:
107- return new BinaryElement (id, sizeLength, dataSize);
108-
109- case ElementIDs::MkDuration:
110- case ElementIDs::MkSamplingFrequency:
111- return new FloatElement (id, sizeLength, dataSize);
112-
113- case ElementIDs::MkSeekHead:
114- return new MkSeekHead (sizeLength, dataSize, offset);
115-
116- case ElementIDs::VoidElement:
117- return new VoidElement (sizeLength, dataSize);
118-
119- default :
120- return new Element (id, sizeLength, dataSize);
64+ RETURN_ELEMENT_FOR_CASE (Id::EBMLHeader);
65+ RETURN_ELEMENT_FOR_CASE (Id::MkSegment);
66+ RETURN_ELEMENT_FOR_CASE (Id::MkInfo);
67+ RETURN_ELEMENT_FOR_CASE (Id::MkTracks);
68+ RETURN_ELEMENT_FOR_CASE (Id::MkTags);
69+ RETURN_ELEMENT_FOR_CASE (Id::MkAttachments);
70+ RETURN_ELEMENT_FOR_CASE (Id::MkTag);
71+ RETURN_ELEMENT_FOR_CASE (Id::MkTagTargets);
72+ RETURN_ELEMENT_FOR_CASE (Id::MkSimpleTag);
73+ RETURN_ELEMENT_FOR_CASE (Id::MkAttachedFile);
74+ RETURN_ELEMENT_FOR_CASE (Id::MkSeek);
75+ RETURN_ELEMENT_FOR_CASE (Id::MkTrackEntry);
76+ RETURN_ELEMENT_FOR_CASE (Id::MkAudio);
77+ RETURN_ELEMENT_FOR_CASE (Id::MkTagName);
78+ RETURN_ELEMENT_FOR_CASE (Id::MkTagString);
79+ RETURN_ELEMENT_FOR_CASE (Id::MkAttachedFileName);
80+ RETURN_ELEMENT_FOR_CASE (Id::MkAttachedFileDescription);
81+ RETURN_ELEMENT_FOR_CASE (Id::MkTagLanguage);
82+ RETURN_ELEMENT_FOR_CASE (Id::MkAttachedFileMediaType);
83+ RETURN_ELEMENT_FOR_CASE (Id::MkCodecID);
84+ RETURN_ELEMENT_FOR_CASE (Id::MkTagTargetTypeValue);
85+ RETURN_ELEMENT_FOR_CASE (Id::MkTagsLanguageDefault);
86+ RETURN_ELEMENT_FOR_CASE (Id::MkAttachedFileUID);
87+ RETURN_ELEMENT_FOR_CASE (Id::MkSeekPosition);
88+ RETURN_ELEMENT_FOR_CASE (Id::MkTimestampScale);
89+ RETURN_ELEMENT_FOR_CASE (Id::MkBitDepth);
90+ RETURN_ELEMENT_FOR_CASE (Id::MkChannels);
91+ RETURN_ELEMENT_FOR_CASE (Id::MkAttachedFileData);
92+ RETURN_ELEMENT_FOR_CASE (Id::MkSeekID);
93+ RETURN_ELEMENT_FOR_CASE (Id::MkDuration);
94+ RETURN_ELEMENT_FOR_CASE (Id::MkSamplingFrequency);
95+ RETURN_ELEMENT_FOR_CASE (Id::MkSeekHead);
96+ RETURN_ELEMENT_FOR_CASE (Id::VoidElement);
97+ RETURN_ELEMENT_FOR_CASE (Id::MkCluster);
98+ RETURN_ELEMENT_FOR_CASE (Id::MkCodecState);
99+ RETURN_ELEMENT_FOR_CASE (Id::MkTagBinary);
100+ RETURN_ELEMENT_FOR_CASE (Id::MkCues);
101+ RETURN_ELEMENT_FOR_CASE (Id::MkCuePoint);
102+ RETURN_ELEMENT_FOR_CASE (Id::MkCueTime);
103+ RETURN_ELEMENT_FOR_CASE (Id::MkCueTrackPositions);
104+ RETURN_ELEMENT_FOR_CASE (Id::MkCueTrack);
105+ RETURN_ELEMENT_FOR_CASE (Id::MkCueClusterPosition);
106+ RETURN_ELEMENT_FOR_CASE (Id::MkCueRelativePosition);
107+ RETURN_ELEMENT_FOR_CASE (Id::MkCueDuration);
108+ RETURN_ELEMENT_FOR_CASE (Id::MkCueBlockNumber);
109+ RETURN_ELEMENT_FOR_CASE (Id::MkCueCodecState);
110+ RETURN_ELEMENT_FOR_CASE (Id::MkCueReference);
111+ RETURN_ELEMENT_FOR_CASE (Id::MkCueRefTime);
121112 }
113+ return std::make_unique<Element>(id, sizeLength, dataSize);
122114}
123115
124- EBML::Element::Id EBML::Element::readId (File &file)
116+ unsigned int EBML::Element::readId (File &file)
125117{
126118 auto buffer = file.readBlock (1 );
127119 if (buffer.size () != 1 ) {
@@ -161,6 +153,7 @@ ByteVector EBML::Element::renderId() const
161153{
162154 int numBytes = idSize (id);
163155 static const auto byteOrder = Utils::systemByteOrder ();
164- uint32_t data = byteOrder == Utils::LittleEndian ? Utils::byteSwap (id) : id;
156+ auto uintId = static_cast <uint32_t >(id);
157+ uint32_t data = byteOrder == Utils::LittleEndian ? Utils::byteSwap (uintId) : uintId;
165158 return ByteVector (reinterpret_cast <char *>(&data) + (4 - numBytes), numBytes);
166159}
0 commit comments