Skip to content

Commit d83d751

Browse files
committed
Matroska: Fix build with older macOS and 32-bit Android compilers
When building for macOS < 10.14, the API for std::optional and std::variant is restricted error: 'value' is unavailable: introduced in macOS 10.14 error: 'get<..>' is unavailable: introduced in macOS 10.14 There was also an issue with Android armeabi-v7a where long is not 64 bit and a static assertion failed.
1 parent f4e7a74 commit d83d751

6 files changed

Lines changed: 40 additions & 43 deletions

File tree

taglib/matroska/ebml/ebmlelement.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ std::unique_ptr<EBML::Element> EBML::Element::factory(File &file)
5252
}
5353

5454
// Get the size length and data length
55-
const auto &[sizeLength, dataSize] = readVINT<offset_t>(file);
55+
const auto &[sizeLength, dataSize] = readVINT(file);
5656
if(!sizeLength)
5757
return nullptr;
5858

taglib/matroska/ebml/ebmlfloatelement.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ EBML::FloatElement::FloatVariantType EBML::FloatElement::getValue() const
5252
double EBML::FloatElement::getValueAsDouble(double defaultValue) const
5353
{
5454
if(std::holds_alternative<double>(value)) {
55-
return std::get<double>(value);
55+
// get_if() used instead of get() to support restricted compilers
56+
return *std::get_if<double>(&value);
5657
}
5758
if(std::holds_alternative<float>(value)) {
58-
return std::get<float>(value);
59+
// get_if() used instead of get() to support restricted compilers
60+
return *std::get_if<float>(&value);
5961
}
6062
return defaultValue;
6163
}
@@ -93,10 +95,12 @@ ByteVector EBML::FloatElement::render()
9395
{
9496
ByteVector data;
9597
if(std::holds_alternative<double>(value)) {
96-
data = ByteVector::fromFloat64BE(std::get<double>(value));
98+
// get_if() used instead of get() to support restricted compilers
99+
data = ByteVector::fromFloat64BE(*std::get_if<double>(&value));
97100
}
98101
else if(std::holds_alternative<float>(value)) {
99-
data = ByteVector::fromFloat32BE(std::get<float>(value));
102+
// get_if() used instead of get() to support restricted compilers
103+
data = ByteVector::fromFloat32BE(*std::get_if<float>(&value));
100104
}
101105
ByteVector buffer = renderId();
102106
buffer.append(renderVINT(data.size(), 0));

taglib/matroska/ebml/ebmlutils.cpp

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -71,33 +71,25 @@ namespace TagLib::EBML {
7171
template unsigned int VINTSizeLength<8>(uint8_t firstByte);
7272
}
7373

74-
template <typename T>
75-
std::pair<int, T> EBML::readVINT(File &file)
74+
std::pair<unsigned int, uint64_t> EBML::readVINT(File &file)
7675
{
77-
static_assert(sizeof(T) == 8);
7876
auto buffer = file.readBlock(1);
7977
if(buffer.size() != 1) {
8078
debug("Failed to read VINT size");
8179
return {0, 0};
8280
}
83-
unsigned int nb_bytes = VINTSizeLength<8>(*buffer.begin());
84-
if(!nb_bytes)
81+
unsigned int numBytes = VINTSizeLength<8>(*buffer.begin());
82+
if(!numBytes)
8583
return {0, 0};
8684

87-
if(nb_bytes > 1)
88-
buffer.append(file.readBlock(nb_bytes - 1));
89-
const int bitsToShift = static_cast<int>(sizeof(T) * 8) - 7 * nb_bytes;
90-
offset_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
91-
return { nb_bytes, static_cast<T>(buffer.toLongLong(true)) & mask };
92-
}
93-
94-
namespace TagLib::EBML {
95-
template std::pair<int, offset_t> readVINT<offset_t>(File &file);
96-
template std::pair<int, uint64_t> readVINT<uint64_t>(File &file);
85+
if(numBytes > 1)
86+
buffer.append(file.readBlock(numBytes - 1));
87+
const int bitsToShift = static_cast<int>(sizeof(uint64_t) * 8) - 7 * numBytes;
88+
const uint64_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
89+
return { numBytes, buffer.toULongLong(true) & mask };
9790
}
9891

99-
template <typename T>
100-
std::pair<int, T> EBML::parseVINT(const ByteVector &buffer)
92+
std::pair<unsigned int, uint64_t> EBML::parseVINT(const ByteVector &buffer)
10193
{
10294
if(buffer.isEmpty())
10395
return {0, 0};
@@ -106,14 +98,9 @@ std::pair<int, T> EBML::parseVINT(const ByteVector &buffer)
10698
if(!numBytes)
10799
return {0, 0};
108100

109-
const int bitsToShift = static_cast<int>(sizeof(T) * 8) - 7 * numBytes;
110-
offset_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
111-
return { numBytes, static_cast<T>(buffer.toLongLong(true)) & mask };
112-
}
113-
114-
namespace TagLib::EBML {
115-
template std::pair<int, offset_t> parseVINT<offset_t>(const ByteVector &buffer);
116-
template std::pair<int, uint64_t> parseVINT<uint64_t>(const ByteVector &buffer);
101+
const int bitsToShift = static_cast<int>(sizeof(uint64_t) * 8) - 7 * numBytes;
102+
const uint64_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
103+
return { numBytes, buffer.toULongLong(true) & mask };
117104
}
118105

119106
ByteVector EBML::renderVINT(uint64_t number, int minSizeLength)

taglib/matroska/ebml/ebmlutils.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,9 @@ namespace TagLib {
3737
template <int maxSizeLength>
3838
unsigned int VINTSizeLength(uint8_t firstByte);
3939

40-
template <typename T>
41-
std::pair<int, T> readVINT(File &file);
40+
std::pair<unsigned int, uint64_t> readVINT(File &file);
4241

43-
template <typename T>
44-
std::pair<int, T> parseVINT(const ByteVector &buffer);
42+
std::pair<unsigned int, uint64_t> parseVINT(const ByteVector &buffer);
4543

4644
ByteVector renderVINT(uint64_t number, int minSizeLength);
4745

taglib/matroska/matroskacues.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,28 +66,32 @@ ByteVector Matroska::Cues::renderInternal()
6666
// Relative position, optional
6767
if(cueTrack->getRelativePosition().has_value()) {
6868
auto relativePosition = EBML::make_unique_element<EBML::Element::Id::MkCueRelativePosition>();
69-
relativePosition->setValue(cueTrack->getRelativePosition().value());
69+
// operator*() used instead of value() to support restricted compilers
70+
relativePosition->setValue(*cueTrack->getRelativePosition());
7071
cueTrackElement->appendElement(std::move(relativePosition));
7172
}
7273

7374
// Duration, optional
7475
if(cueTrack->getDuration().has_value()) {
7576
auto duration = EBML::make_unique_element<EBML::Element::Id::MkCueDuration>();
76-
duration->setValue(cueTrack->getDuration().value());
77+
// operator*() used instead of value() to support restricted compilers
78+
duration->setValue(*cueTrack->getDuration());
7779
cueTrackElement->appendElement(std::move(duration));
7880
}
7981

8082
// Block number, optional
8183
if(cueTrack->getBlockNumber().has_value()) {
8284
auto blockNumber = EBML::make_unique_element<EBML::Element::Id::MkCueBlockNumber>();
83-
blockNumber->setValue(cueTrack->getBlockNumber().value());
85+
// operator*() used instead of value() to support restricted compilers
86+
blockNumber->setValue(*cueTrack->getBlockNumber());
8487
cueTrackElement->appendElement(std::move(blockNumber));
8588
}
8689

8790
// Codec state, not in version 1
8891
if(cueTrack->getCodecState().has_value()) {
8992
auto codecState = EBML::make_unique_element<EBML::Element::Id::MkCueCodecState>();
90-
codecState->setValue(cueTrack->getCodecState().value());
93+
// operator*() used instead of value() to support restricted compilers
94+
codecState->setValue(*cueTrack->getCodecState());
9195
cueTrackElement->appendElement(std::move(codecState));
9296
}
9397

@@ -209,8 +213,9 @@ bool Matroska::CueTrack::isValid(TagLib::File &file, offset_t segmentDataOffset)
209213
debug("No cluster found at position");
210214
return false;
211215
}
212-
if(codecState.has_value() && codecState.value() != 0) {
213-
file.seek(segmentDataOffset + codecState.value());
216+
if(codecState.has_value() && *codecState != 0) {
217+
// operator*() used instead of value() to support restricted compilers
218+
file.seek(segmentDataOffset + *codecState);
214219
if(EBML::Element::readId(file) != static_cast<unsigned int>(EBML::Element::Id::MkCodecState)) {
215220
debug("No codec state found at position");
216221
return false;
@@ -296,8 +301,9 @@ bool Matroska::CueTrack::adjustOffset(offset_t offset, offset_t delta)
296301
clusterPosition += delta;
297302
ret = true;
298303
}
304+
// operator*() used instead of value() to support restricted compilers
299305
if(offset_t codecStateValue;
300-
codecState.has_value() && (codecStateValue = codecState.value()) != 0 &&
306+
codecState.has_value() && (codecStateValue = *codecState) != 0 &&
301307
codecStateValue > offset) {
302308
codecState = codecStateValue + delta;
303309
ret = true;

taglib/matroska/matroskasimpletag.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,17 @@ Matroska::SimpleTag::ValueType Matroska::SimpleTag::type() const
126126
String Matroska::SimpleTag::toString() const
127127
{
128128
if(std::holds_alternative<String>(d->value)) {
129-
return std::get<String>(d->value);
129+
// get_if() used instead of get() to support restricted compilers
130+
return *std::get_if<String>(&d->value);
130131
}
131132
return {};
132133
}
133134

134135
ByteVector Matroska::SimpleTag::toByteVector() const
135136
{
136137
if(std::holds_alternative<ByteVector>(d->value)) {
137-
return std::get<ByteVector>(d->value);
138+
// get_if() used instead of get() to support restricted compilers
139+
return *std::get_if<ByteVector>(&d->value);
138140
}
139141
return {};
140142
}

0 commit comments

Comments
 (0)