mirror of
https://github.com/taglib/taglib.git
synced 2026-02-08 00:10:15 -05:00
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.
This commit is contained in:
@ -52,7 +52,7 @@ std::unique_ptr<EBML::Element> EBML::Element::factory(File &file)
|
||||
}
|
||||
|
||||
// Get the size length and data length
|
||||
const auto &[sizeLength, dataSize] = readVINT<offset_t>(file);
|
||||
const auto &[sizeLength, dataSize] = readVINT(file);
|
||||
if(!sizeLength)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@ -52,10 +52,12 @@ EBML::FloatElement::FloatVariantType EBML::FloatElement::getValue() const
|
||||
double EBML::FloatElement::getValueAsDouble(double defaultValue) const
|
||||
{
|
||||
if(std::holds_alternative<double>(value)) {
|
||||
return std::get<double>(value);
|
||||
// get_if() used instead of get() to support restricted compilers
|
||||
return *std::get_if<double>(&value);
|
||||
}
|
||||
if(std::holds_alternative<float>(value)) {
|
||||
return std::get<float>(value);
|
||||
// get_if() used instead of get() to support restricted compilers
|
||||
return *std::get_if<float>(&value);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
@ -93,10 +95,12 @@ ByteVector EBML::FloatElement::render()
|
||||
{
|
||||
ByteVector data;
|
||||
if(std::holds_alternative<double>(value)) {
|
||||
data = ByteVector::fromFloat64BE(std::get<double>(value));
|
||||
// get_if() used instead of get() to support restricted compilers
|
||||
data = ByteVector::fromFloat64BE(*std::get_if<double>(&value));
|
||||
}
|
||||
else if(std::holds_alternative<float>(value)) {
|
||||
data = ByteVector::fromFloat32BE(std::get<float>(value));
|
||||
// get_if() used instead of get() to support restricted compilers
|
||||
data = ByteVector::fromFloat32BE(*std::get_if<float>(&value));
|
||||
}
|
||||
ByteVector buffer = renderId();
|
||||
buffer.append(renderVINT(data.size(), 0));
|
||||
|
||||
@ -71,33 +71,25 @@ namespace TagLib::EBML {
|
||||
template unsigned int VINTSizeLength<8>(uint8_t firstByte);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::pair<int, T> EBML::readVINT(File &file)
|
||||
std::pair<unsigned int, uint64_t> EBML::readVINT(File &file)
|
||||
{
|
||||
static_assert(sizeof(T) == 8);
|
||||
auto buffer = file.readBlock(1);
|
||||
if(buffer.size() != 1) {
|
||||
debug("Failed to read VINT size");
|
||||
return {0, 0};
|
||||
}
|
||||
unsigned int nb_bytes = VINTSizeLength<8>(*buffer.begin());
|
||||
if(!nb_bytes)
|
||||
unsigned int numBytes = VINTSizeLength<8>(*buffer.begin());
|
||||
if(!numBytes)
|
||||
return {0, 0};
|
||||
|
||||
if(nb_bytes > 1)
|
||||
buffer.append(file.readBlock(nb_bytes - 1));
|
||||
const int bitsToShift = static_cast<int>(sizeof(T) * 8) - 7 * nb_bytes;
|
||||
offset_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
|
||||
return { nb_bytes, static_cast<T>(buffer.toLongLong(true)) & mask };
|
||||
if(numBytes > 1)
|
||||
buffer.append(file.readBlock(numBytes - 1));
|
||||
const int bitsToShift = static_cast<int>(sizeof(uint64_t) * 8) - 7 * numBytes;
|
||||
const uint64_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
|
||||
return { numBytes, buffer.toULongLong(true) & mask };
|
||||
}
|
||||
|
||||
namespace TagLib::EBML {
|
||||
template std::pair<int, offset_t> readVINT<offset_t>(File &file);
|
||||
template std::pair<int, uint64_t> readVINT<uint64_t>(File &file);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::pair<int, T> EBML::parseVINT(const ByteVector &buffer)
|
||||
std::pair<unsigned int, uint64_t> EBML::parseVINT(const ByteVector &buffer)
|
||||
{
|
||||
if(buffer.isEmpty())
|
||||
return {0, 0};
|
||||
@ -106,14 +98,9 @@ std::pair<int, T> EBML::parseVINT(const ByteVector &buffer)
|
||||
if(!numBytes)
|
||||
return {0, 0};
|
||||
|
||||
const int bitsToShift = static_cast<int>(sizeof(T) * 8) - 7 * numBytes;
|
||||
offset_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
|
||||
return { numBytes, static_cast<T>(buffer.toLongLong(true)) & mask };
|
||||
}
|
||||
|
||||
namespace TagLib::EBML {
|
||||
template std::pair<int, offset_t> parseVINT<offset_t>(const ByteVector &buffer);
|
||||
template std::pair<int, uint64_t> parseVINT<uint64_t>(const ByteVector &buffer);
|
||||
const int bitsToShift = static_cast<int>(sizeof(uint64_t) * 8) - 7 * numBytes;
|
||||
const uint64_t mask = 0xFFFFFFFFFFFFFFFF >> bitsToShift;
|
||||
return { numBytes, buffer.toULongLong(true) & mask };
|
||||
}
|
||||
|
||||
ByteVector EBML::renderVINT(uint64_t number, int minSizeLength)
|
||||
|
||||
@ -37,11 +37,9 @@ namespace TagLib {
|
||||
template <int maxSizeLength>
|
||||
unsigned int VINTSizeLength(uint8_t firstByte);
|
||||
|
||||
template <typename T>
|
||||
std::pair<int, T> readVINT(File &file);
|
||||
std::pair<unsigned int, uint64_t> readVINT(File &file);
|
||||
|
||||
template <typename T>
|
||||
std::pair<int, T> parseVINT(const ByteVector &buffer);
|
||||
std::pair<unsigned int, uint64_t> parseVINT(const ByteVector &buffer);
|
||||
|
||||
ByteVector renderVINT(uint64_t number, int minSizeLength);
|
||||
|
||||
|
||||
@ -66,28 +66,32 @@ ByteVector Matroska::Cues::renderInternal()
|
||||
// Relative position, optional
|
||||
if(cueTrack->getRelativePosition().has_value()) {
|
||||
auto relativePosition = EBML::make_unique_element<EBML::Element::Id::MkCueRelativePosition>();
|
||||
relativePosition->setValue(cueTrack->getRelativePosition().value());
|
||||
// operator*() used instead of value() to support restricted compilers
|
||||
relativePosition->setValue(*cueTrack->getRelativePosition());
|
||||
cueTrackElement->appendElement(std::move(relativePosition));
|
||||
}
|
||||
|
||||
// Duration, optional
|
||||
if(cueTrack->getDuration().has_value()) {
|
||||
auto duration = EBML::make_unique_element<EBML::Element::Id::MkCueDuration>();
|
||||
duration->setValue(cueTrack->getDuration().value());
|
||||
// operator*() used instead of value() to support restricted compilers
|
||||
duration->setValue(*cueTrack->getDuration());
|
||||
cueTrackElement->appendElement(std::move(duration));
|
||||
}
|
||||
|
||||
// Block number, optional
|
||||
if(cueTrack->getBlockNumber().has_value()) {
|
||||
auto blockNumber = EBML::make_unique_element<EBML::Element::Id::MkCueBlockNumber>();
|
||||
blockNumber->setValue(cueTrack->getBlockNumber().value());
|
||||
// operator*() used instead of value() to support restricted compilers
|
||||
blockNumber->setValue(*cueTrack->getBlockNumber());
|
||||
cueTrackElement->appendElement(std::move(blockNumber));
|
||||
}
|
||||
|
||||
// Codec state, not in version 1
|
||||
if(cueTrack->getCodecState().has_value()) {
|
||||
auto codecState = EBML::make_unique_element<EBML::Element::Id::MkCueCodecState>();
|
||||
codecState->setValue(cueTrack->getCodecState().value());
|
||||
// operator*() used instead of value() to support restricted compilers
|
||||
codecState->setValue(*cueTrack->getCodecState());
|
||||
cueTrackElement->appendElement(std::move(codecState));
|
||||
}
|
||||
|
||||
@ -209,8 +213,9 @@ bool Matroska::CueTrack::isValid(TagLib::File &file, offset_t segmentDataOffset)
|
||||
debug("No cluster found at position");
|
||||
return false;
|
||||
}
|
||||
if(codecState.has_value() && codecState.value() != 0) {
|
||||
file.seek(segmentDataOffset + codecState.value());
|
||||
if(codecState.has_value() && *codecState != 0) {
|
||||
// operator*() used instead of value() to support restricted compilers
|
||||
file.seek(segmentDataOffset + *codecState);
|
||||
if(EBML::Element::readId(file) != static_cast<unsigned int>(EBML::Element::Id::MkCodecState)) {
|
||||
debug("No codec state found at position");
|
||||
return false;
|
||||
@ -296,8 +301,9 @@ bool Matroska::CueTrack::adjustOffset(offset_t offset, offset_t delta)
|
||||
clusterPosition += delta;
|
||||
ret = true;
|
||||
}
|
||||
// operator*() used instead of value() to support restricted compilers
|
||||
if(offset_t codecStateValue;
|
||||
codecState.has_value() && (codecStateValue = codecState.value()) != 0 &&
|
||||
codecState.has_value() && (codecStateValue = *codecState) != 0 &&
|
||||
codecStateValue > offset) {
|
||||
codecState = codecStateValue + delta;
|
||||
ret = true;
|
||||
|
||||
@ -126,7 +126,8 @@ Matroska::SimpleTag::ValueType Matroska::SimpleTag::type() const
|
||||
String Matroska::SimpleTag::toString() const
|
||||
{
|
||||
if(std::holds_alternative<String>(d->value)) {
|
||||
return std::get<String>(d->value);
|
||||
// get_if() used instead of get() to support restricted compilers
|
||||
return *std::get_if<String>(&d->value);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@ -134,7 +135,8 @@ String Matroska::SimpleTag::toString() const
|
||||
ByteVector Matroska::SimpleTag::toByteVector() const
|
||||
{
|
||||
if(std::holds_alternative<ByteVector>(d->value)) {
|
||||
return std::get<ByteVector>(d->value);
|
||||
// get_if() used instead of get() to support restricted compilers
|
||||
return *std::get_if<ByteVector>(&d->value);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user