2016-05-14 00:24:01 +02:00
|
|
|
#include "./flactooggmappingheader.h"
|
|
|
|
|
|
|
|
#include "../ogg/oggiterator.h"
|
|
|
|
|
|
|
|
#include "../exceptions.h"
|
|
|
|
|
|
|
|
#include <c++utilities/conversion/binaryconversion.h>
|
|
|
|
|
|
|
|
using namespace std;
|
2019-06-10 22:49:11 +02:00
|
|
|
using namespace CppUtilities;
|
2016-05-14 00:24:01 +02:00
|
|
|
|
2018-03-06 23:09:15 +01:00
|
|
|
namespace TagParser {
|
2016-05-14 00:24:01 +02:00
|
|
|
|
|
|
|
/*!
|
2018-06-03 20:38:32 +02:00
|
|
|
* \class TagParser::FlacToOggMappingHeader
|
2016-05-14 00:24:01 +02:00
|
|
|
* \brief The FlacToOggMappingHeader class is a FLAC-to-Ogg mapping header parser.
|
|
|
|
* \sa https://xiph.org/flac/ogg_mapping.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Parses the FLAC-to-Ogg mapping header which is read using the specified \a iterator.
|
|
|
|
* \remarks The header is assumed to start at the current position of \a iterator.
|
|
|
|
*/
|
|
|
|
void FlacToOggMappingHeader::parseHeader(OggIterator &iterator)
|
|
|
|
{
|
|
|
|
// prepare parsing
|
2021-10-26 15:54:30 +02:00
|
|
|
constexpr auto idSize = 0x05, mappingHeaderSize = 0x0D, blockHeaderSize = 0x04, streamInfoSize = 0x22;
|
|
|
|
char buff[mappingHeaderSize + blockHeaderSize + streamInfoSize - idSize];
|
|
|
|
iterator.read(buff, idSize);
|
2023-05-18 00:50:52 +02:00
|
|
|
if (*buff != 0x7Fu || BE::toInt<std::uint32_t>(buff + 1) != 0x464C4143u) {
|
2016-05-14 00:24:01 +02:00
|
|
|
throw InvalidDataException(); // not FLAC-to-Ogg mapping header
|
|
|
|
}
|
|
|
|
iterator.read(buff, sizeof(buff));
|
|
|
|
|
|
|
|
// parse FLAC-to-Ogg mapping header
|
2019-03-13 19:06:42 +01:00
|
|
|
m_majorVersion = static_cast<std::uint8_t>(*(buff + 0x00));
|
|
|
|
m_minorVersion = static_cast<std::uint8_t>(*(buff + 0x01));
|
2023-05-18 00:50:52 +02:00
|
|
|
m_headerCount = BE::toInt<std::uint16_t>(buff + 0x02);
|
|
|
|
if (BE::toInt<std::uint32_t>(buff + 0x04) != 0x664C6143u) {
|
2016-05-14 00:24:01 +02:00
|
|
|
throw InvalidDataException(); // native FLAC signature not present
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse "METADATA_BLOCK_HEADER"
|
|
|
|
FlacMetaDataBlockHeader header;
|
2021-10-26 15:54:30 +02:00
|
|
|
header.parseHeader(std::string_view(buff + mappingHeaderSize - idSize, blockHeaderSize));
|
2018-03-07 01:17:50 +01:00
|
|
|
if (header.type() != FlacMetaDataBlockType::StreamInfo) {
|
2016-05-14 00:24:01 +02:00
|
|
|
throw InvalidDataException(); // "METADATA_BLOCK_STREAMINFO" expected
|
|
|
|
}
|
2021-10-26 15:54:30 +02:00
|
|
|
if (header.dataSize() < streamInfoSize) {
|
2016-05-14 00:24:01 +02:00
|
|
|
throw TruncatedDataException(); // "METADATA_BLOCK_STREAMINFO" is truncated
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse "METADATA_BLOCK_STREAMINFO"
|
2021-10-26 15:54:30 +02:00
|
|
|
m_streamInfo.parse(std::string_view(buff + mappingHeaderSize + blockHeaderSize - idSize, streamInfoSize));
|
2016-05-14 00:24:01 +02:00
|
|
|
}
|
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
} // namespace TagParser
|