2018-03-06 23:09:15 +01:00
|
|
|
#ifndef TAG_PARSER_OGGCONTAINER_H
|
|
|
|
#define TAG_PARSER_OGGCONTAINER_H
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
#include "./oggiterator.h"
|
2015-09-06 19:57:33 +02:00
|
|
|
#include "./oggpage.h"
|
|
|
|
#include "./oggstream.h"
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2015-09-06 19:57:33 +02:00
|
|
|
#include "../vorbis/vorbiscomment.h"
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2015-09-06 19:57:33 +02:00
|
|
|
#include "../genericcontainer.h"
|
2015-04-22 19:22:01 +02:00
|
|
|
|
|
|
|
#include <tuple>
|
2018-03-07 01:17:50 +01:00
|
|
|
#include <unordered_map>
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2016-05-14 00:24:01 +02:00
|
|
|
namespace IoUtilities {
|
2018-03-07 01:17:50 +01:00
|
|
|
template <std::size_t bufferSize> class CopyHelper;
|
2016-05-14 00:24:01 +02:00
|
|
|
}
|
|
|
|
|
2018-03-06 23:09:15 +01:00
|
|
|
namespace TagParser {
|
2015-04-22 19:22:01 +02:00
|
|
|
|
|
|
|
class MediaFileInfo;
|
2016-05-14 00:24:01 +02:00
|
|
|
class OggContainer;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief The OggParameter struct holds the OGG parameter for a VorbisComment.
|
|
|
|
*/
|
2018-03-07 01:17:50 +01:00
|
|
|
struct TAG_PARSER_EXPORT OggParameter {
|
2018-07-10 14:11:11 +02:00
|
|
|
constexpr OggParameter();
|
2016-05-14 00:24:01 +02:00
|
|
|
void set(std::size_t pageIndex, std::size_t segmentIndex, bool lastMetaDataBlock, GeneralMediaFormat streamFormat = GeneralMediaFormat::Vorbis);
|
|
|
|
|
|
|
|
std::size_t firstPageIndex;
|
|
|
|
std::size_t firstSegmentIndex;
|
|
|
|
std::size_t lastPageIndex;
|
|
|
|
std::size_t lastSegmentIndex;
|
|
|
|
GeneralMediaFormat streamFormat;
|
2018-08-29 22:31:30 +02:00
|
|
|
bool lastMetaDataBlock;
|
2016-05-14 00:24:01 +02:00
|
|
|
bool removed;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Creates new parameters.
|
|
|
|
* \remarks The OggContainer class is responsible for assigning sane values.
|
|
|
|
*/
|
2018-07-10 14:11:11 +02:00
|
|
|
constexpr OggParameter::OggParameter()
|
2018-03-07 01:17:50 +01:00
|
|
|
: firstPageIndex(0)
|
|
|
|
, firstSegmentIndex(0)
|
|
|
|
, lastPageIndex(0)
|
|
|
|
, lastSegmentIndex(0)
|
|
|
|
, streamFormat(GeneralMediaFormat::Vorbis)
|
2018-08-29 22:31:30 +02:00
|
|
|
, lastMetaDataBlock(false)
|
2018-03-07 01:17:50 +01:00
|
|
|
, removed(false)
|
|
|
|
{
|
|
|
|
}
|
2016-05-14 00:24:01 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Sets the firstPageIndex/lastPageIndex, the firstSegmentIndex/lastSegmentIndex, whether the associated meta data block is the last one and the streamFormat.
|
|
|
|
* \remarks Whether the associated meta data block is the last one is only relevant for FLAC streams.
|
|
|
|
*/
|
|
|
|
inline void OggParameter::set(std::size_t pageIndex, std::size_t segmentIndex, bool lastMetaDataBlock, GeneralMediaFormat streamFormat)
|
|
|
|
{
|
|
|
|
firstPageIndex = lastPageIndex = pageIndex;
|
|
|
|
firstSegmentIndex = lastSegmentIndex = segmentIndex;
|
|
|
|
this->lastMetaDataBlock = lastMetaDataBlock;
|
|
|
|
this->streamFormat = streamFormat;
|
|
|
|
}
|
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
class TAG_PARSER_EXPORT OggVorbisComment : public VorbisComment {
|
2016-05-14 00:24:01 +02:00
|
|
|
friend class OggContainer;
|
|
|
|
|
|
|
|
public:
|
|
|
|
OggVorbisComment();
|
2018-08-29 22:31:56 +02:00
|
|
|
TagType type() const override;
|
|
|
|
const char *typeName() const override;
|
|
|
|
bool supportsTarget() const override;
|
2016-05-14 00:24:01 +02:00
|
|
|
|
|
|
|
OggParameter &oggParams();
|
|
|
|
const OggParameter &oggParams() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
OggParameter m_oggParams;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Constructs a new OGG Vorbis comment.
|
|
|
|
*/
|
|
|
|
inline OggVorbisComment::OggVorbisComment()
|
2018-03-07 01:17:50 +01:00
|
|
|
{
|
|
|
|
}
|
2016-05-14 00:24:01 +02:00
|
|
|
|
|
|
|
inline TagType OggVorbisComment::type() const
|
|
|
|
{
|
|
|
|
return TagType::OggVorbisComment;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns true; the target is used to specifiy the stream.
|
|
|
|
* \sa OggContainer::createTag(), TagTarget
|
|
|
|
*/
|
|
|
|
inline bool OggVorbisComment::supportsTarget() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the OGG parameter for the comment.
|
|
|
|
*
|
|
|
|
* Consists of first page index, first segment index, last page index, last segment index and tag index (in this order).
|
|
|
|
* These values are used and managed by the OggContainer class and do not affect the behavior of the VorbisComment instance.
|
|
|
|
*/
|
|
|
|
inline OggParameter &OggVorbisComment::oggParams()
|
|
|
|
{
|
|
|
|
return m_oggParams;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns the OGG parameter for the comment.
|
|
|
|
*
|
|
|
|
* Consists of first page index, first segment index, last page index, last segment index and tag index (in this order).
|
|
|
|
* These values are used and managed by the OggContainer class and do not affect the behavior of the VorbisComment instance.
|
|
|
|
*/
|
|
|
|
inline const OggParameter &OggVorbisComment::oggParams() const
|
|
|
|
{
|
|
|
|
return m_oggParams;
|
|
|
|
}
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
class TAG_PARSER_EXPORT OggContainer : public GenericContainer<MediaFileInfo, OggVorbisComment, OggStream, OggPage> {
|
2015-04-22 19:22:01 +02:00
|
|
|
friend class OggStream;
|
|
|
|
|
|
|
|
public:
|
|
|
|
OggContainer(MediaFileInfo &fileInfo, uint64 startOffset);
|
2018-03-05 17:49:29 +01:00
|
|
|
~OggContainer() override;
|
2015-04-22 19:22:01 +02:00
|
|
|
|
|
|
|
bool isChecksumValidationEnabled() const;
|
|
|
|
void setChecksumValidationEnabled(bool enabled);
|
2018-03-05 17:49:29 +01:00
|
|
|
void reset() override;
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-05 17:49:29 +01:00
|
|
|
OggVorbisComment *createTag(const TagTarget &target) override;
|
|
|
|
OggVorbisComment *tag(std::size_t index) override;
|
|
|
|
std::size_t tagCount() const override;
|
|
|
|
bool removeTag(Tag *tag) override;
|
|
|
|
void removeAllTags() override;
|
2016-03-22 22:52:36 +01:00
|
|
|
|
2015-04-22 19:22:01 +02:00
|
|
|
protected:
|
2018-03-05 17:49:29 +01:00
|
|
|
void internalParseHeader(Diagnostics &diag) override;
|
|
|
|
void internalParseTags(Diagnostics &diag) override;
|
|
|
|
void internalParseTracks(Diagnostics &diag) override;
|
|
|
|
void internalMakeFile(Diagnostics &diag, AbortableProgressFeedback &progress) override;
|
2015-04-22 19:22:01 +02:00
|
|
|
|
|
|
|
private:
|
2018-03-07 01:17:50 +01:00
|
|
|
void announceComment(
|
|
|
|
std::size_t pageIndex, std::size_t segmentIndex, bool lastMetaDataBlock, GeneralMediaFormat mediaFormat = GeneralMediaFormat::Vorbis);
|
|
|
|
void makeVorbisCommentSegment(std::stringstream &buffer, IoUtilities::CopyHelper<65307> ©Helper, std::vector<uint32> &newSegmentSizes,
|
|
|
|
VorbisComment *comment, OggParameter *params, Diagnostics &diag);
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
std::unordered_map<uint32, std::vector<std::unique_ptr<OggStream>>::size_type> m_streamsBySerialNo;
|
2015-08-16 23:39:42 +02:00
|
|
|
|
2015-04-22 19:22:01 +02:00
|
|
|
OggIterator m_iterator;
|
|
|
|
bool m_validateChecksums;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Returns whether checksum validation is enabled.
|
|
|
|
*
|
|
|
|
* If checksum validation is enabled, the parser will validate the OGG pages by
|
|
|
|
* checking the CRC32 checksum.
|
|
|
|
*
|
|
|
|
* \sa setChecksumValidationEnabled()
|
|
|
|
*/
|
|
|
|
inline bool OggContainer::isChecksumValidationEnabled() const
|
|
|
|
{
|
|
|
|
return m_validateChecksums;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Sets whether checksum validation is enabled.
|
|
|
|
* \sa isChecksumValidationEnabled()
|
|
|
|
*/
|
|
|
|
inline void OggContainer::setChecksumValidationEnabled(bool enabled)
|
|
|
|
{
|
|
|
|
m_validateChecksums = enabled;
|
|
|
|
}
|
|
|
|
|
2018-03-07 01:17:50 +01:00
|
|
|
} // namespace TagParser
|
2015-04-22 19:22:01 +02:00
|
|
|
|
2018-03-06 23:09:15 +01:00
|
|
|
#endif // TAG_PARSER_OGGCONTAINER_H
|