From fc1ec15e3e20439b887783311778c070cc4042ce Mon Sep 17 00:00:00 2001 From: "Stephen F. Booth" Date: Sun, 8 Dec 2024 11:46:10 -0600 Subject: [PATCH] Use ByteVector for byte swaps --- taglib/shn/shnfile.cpp | 138 +++++++++-------------------------------- 1 file changed, 29 insertions(+), 109 deletions(-) diff --git a/taglib/shn/shnfile.cpp b/taglib/shn/shnfile.cpp index 7f0b81d2..9339c29e 100644 --- a/taglib/shn/shnfile.cpp +++ b/taglib/shn/shnfile.cpp @@ -24,7 +24,6 @@ ***************************************************************************/ #include -#include #include "shnfile.h" #include "shnutils.h" @@ -214,87 +213,6 @@ namespace { return true; } }; - -// MARK: Unsigned Integer Reading - -#if 0 - // Utils::byteSwap() is overloaded for unsigned short, unsigned int, and unsigned long long - // Even though uint64_t and unsigned long long are typically the same size they aren't the - // same type which means for template purposes std::is_same_v is false - template || std::is_same_v || std::is_same_v>> - T read_uint(void *p, uintptr_t n, bool big) noexcept - { - T value = *reinterpret_cast(reinterpret_cast(p) + n); - - auto system_big = Utils::systemByteOrder() == Utils::BigEndian; - if(big != system_big) - value = Utils::byteSwap(value); - return value; - } -#endif - - uint64_t read_uint64(void *p, uintptr_t n, bool big) noexcept - { - static_assert(sizeof(uint64_t) == sizeof(unsigned long long), "uint64_t and unsigned long long have different sizes"); - unsigned long long value = *reinterpret_cast(reinterpret_cast(p) + n); - - auto system_big = Utils::systemByteOrder() == Utils::BigEndian; - if(big != system_big) - value = Utils::byteSwap(value); - return static_cast(value); - } - - uint32_t read_uint32(void *p, uintptr_t n, bool big) noexcept - { - static_assert(sizeof(uint32_t) == sizeof(unsigned int), "uint32_t and unsigned int have different sizes"); - unsigned int value = *reinterpret_cast(reinterpret_cast(p) + n); - - auto system_big = Utils::systemByteOrder() == Utils::BigEndian; - if(big != system_big) - value = Utils::byteSwap(value); - return static_cast(value); - } - - uint16_t read_uint16(void *p, uintptr_t n, bool big) noexcept - { - static_assert(sizeof(uint16_t) == sizeof(unsigned short), "uint16_t and unsigned short have different sizes"); - unsigned short value = *reinterpret_cast(reinterpret_cast(p) + n); - - auto system_big = Utils::systemByteOrder() == Utils::BigEndian; - if(big != system_big) - value = Utils::byteSwap(value); - return static_cast(value); - } - - uint64_t read_uint64_big(void *p, uintptr_t n) noexcept - { -// return read_uint(p, n, true); - return read_uint64(p, n, true); - } - - uint32_t read_uint32_big(void *p, uintptr_t n) noexcept - { -// return read_uint(p, n, true); - return read_uint32(p, n, true); - } - - uint32_t read_uint32_little(void *p, uintptr_t n) noexcept - { -// return read_uint(p, n, false); - return read_uint32(p, n, false); - } - - uint16_t read_uint16_big(void *p, uintptr_t n) noexcept - { -// return read_uint(p, n, true); - return read_uint16(p, n, true); - } - - uint16_t read_uint16_little(void *p, uintptr_t n) noexcept - { -// return read_uint(p, n, false); - return read_uint16(p, n, false); - } } // namespace class SHN::File::FilePrivate @@ -472,7 +390,10 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - uint8_t header_bytes [header_size]; + ByteVector header{}; + header.resize(header_size); + + auto iter = header.begin(); for(int32_t i = 0; i < header_size; ++i) { int32_t byte; if(!input.uvar_get(byte, VERBATIM_BYTE_SIZE)) { @@ -481,22 +402,21 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - header_bytes[i] = static_cast(byte); + *iter++ = static_cast(byte); } - // header_bytes is at least CANONICAL_HEADER_SIZE (44) bytes in size + // header is at least CANONICAL_HEADER_SIZE (44) bytes in size - auto chunkID = read_uint32_big(header_bytes, 0); -// auto chunkSize = read_uint32_big(header_bytes, 4); + auto chunkID = header.toUInt(0, true); +// auto chunkSize = header.toUInt(4, true); - const auto chunkData = header_bytes + 8; - const uintptr_t size = header_size - 8; + const auto chunkData = ByteVector(header, 8, header.size() - 8); // WAVE if(chunkID == 0x52494646 /*'RIFF'*/) { - uintptr_t offset = 0; + unsigned int offset = 0; - chunkID = read_uint32_big(chunkData, offset); + chunkID = chunkData.toUInt(offset, true); offset += 4; if(chunkID != 0x57415645 /*'WAVE'*/) { debug("SHN::File::read() -- Missing 'WAVE' in 'RIFF' chunk."); @@ -508,11 +428,11 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) uint32_t dataChunkSize = 0; uint16_t blockAlign = 0; - while(offset < size) { - chunkID = read_uint32_big(chunkData, offset); + while(offset < chunkData.size()) { + chunkID = chunkData.toUInt(offset, true); offset += 4; - auto chunkSize = read_uint32_little(chunkData, offset); + auto chunkSize = chunkData.toUInt(offset, false); offset += 4; switch(chunkID) { @@ -524,7 +444,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto format_tag = read_uint16_little(chunkData, offset); + auto format_tag = chunkData.toUShort(offset, false); offset += 2; if(format_tag != WAVE_FORMAT_PCM) { debug("SHN::File::read() -- Unsupported WAVE format tag."); @@ -532,21 +452,21 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto channels = read_uint16_little(chunkData, offset); + auto channels = chunkData.toUShort(offset, false); offset += 2; if(props.channel_count != channels) debug("SHN::File::read() -- Channel count mismatch between Shorten and 'fmt ' chunk."); - props.sample_rate = static_cast(read_uint32_little(chunkData, offset)); + props.sample_rate = static_cast(chunkData.toUInt(offset, false)); offset += 4; // Skip average bytes per second offset += 4; - blockAlign = read_uint16_little(chunkData, offset); + blockAlign = chunkData.toUShort(offset, false); offset += 2; - props.bits_per_sample = static_cast(read_uint16_little(chunkData, offset)); + props.bits_per_sample = static_cast(chunkData.toUShort(offset, false)); offset += 2; if(chunkSize > 16) @@ -574,9 +494,9 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) } // AIFF else if(chunkID == 0x464f524d /*'FORM'*/) { - uintptr_t offset = 0; + unsigned int offset = 0; - auto chunkID = read_uint32_big(chunkData, offset); + chunkID = chunkData.toUInt(offset, true); offset += 4; if(chunkID != 0x41494646 /*'AIFF'*/ && chunkID != 0x41494643 /*'AIFC'*/) { debug("SHN::File::read() -- Missing 'AIFF' or 'AIFC' in 'FORM' chunk."); @@ -588,11 +508,11 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) // props.big_endian = true; auto sawCommonChunk = false; - while(offset < size) { - chunkID = read_uint32_big(chunkData, offset); + while(offset < chunkData.size()) { + chunkID = chunkData.toUInt(offset, true); offset += 4; - auto chunkSize = read_uint32_big(chunkData, offset); + auto chunkSize = chunkData.toUInt(offset, true); offset += 4; // All chunks must have an even length but the pad byte is not included in ckSize @@ -607,19 +527,19 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto channels = read_uint16_big(chunkData, offset); + auto channels = chunkData.toUShort(offset, true); offset += 2; if(props.channel_count != channels) debug("SHN::File::read() -- Channel count mismatch between Shorten and 'COMM' chunk."); - props.sample_frames = static_cast(read_uint32_big(chunkData, offset)); + props.sample_frames = static_cast(chunkData.toUInt(offset, true)); offset += 4; - props.bits_per_sample = static_cast(read_uint16_big(chunkData, offset)); + props.bits_per_sample = static_cast(chunkData.toUShort(offset, true)); offset += 2; // sample rate is IEEE 754 80-bit extended float (16-bit exponent, 1-bit integer part, 63-bit fraction) - auto exp = static_cast(read_uint16_big(chunkData, offset)) - 16383 - 63; + auto exp = static_cast(chunkData.toUShort(offset, true)) - 16383 - 63; offset += 2; if(exp < -63 || exp > 63) { debug("SHN::File::read() -- exp out of range."); @@ -627,7 +547,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto frac = read_uint64_big(chunkData, offset); + auto frac = chunkData.toULongLong(offset, true); offset += 8; if(exp >= 0) props.sample_rate = static_cast(frac << exp);