4#include "../ogg/oggiterator.h"
6#include "../diagnostics.h"
7#include "../exceptions.h"
9#include <c++utilities/conversion/stringbuilder.h>
10#include <c++utilities/io/binaryreader.h>
11#include <c++utilities/io/binarywriter.h>
12#include <c++utilities/io/copy.h>
50 using namespace VorbisCommentIds;
53 return std::string(
album());
55 return std::string(
artist());
59 return std::string(
cover());
61 return std::string(
date());
63 return std::string(
title());
65 return std::string(
genre());
85 return std::string(
label());
93 return std::string(
lyrics());
105 return std::string(
isrc());
107 return std::string(
rating());
109 return std::string(
bpm());
111 return std::string();
117 using namespace VorbisCommentIds;
119 static const std::map<std::string_view, KnownField, CaseInsensitiveStringComparer> fieldMap({
158template <
class StreamType>
void VorbisComment::internalParse(StreamType &stream, std::uint64_t maxSize,
VorbisCommentFlags flags,
Diagnostics &diag)
161 static const string context(
"parsing Vorbis comment");
162 const auto startOffset =
static_cast<std::uint64_t
>(stream.tellg());
167 if (!skipSignature) {
170 skipSignature = (BE::toUInt64(sig) & 0xffffffffffffff00u) == 0x03766F7262697300u;
177 const auto vendorSize = LE::toUInt32(sig);
178 if (vendorSize <= maxSize) {
179 auto buff = make_unique<char[]>(vendorSize);
180 stream.read(buff.get(), vendorSize);
185 throw TruncatedDataException();
187 maxSize -= vendorSize;
193 for (std::uint32_t i = 0; i <
fieldCount; ++i) {
195 VorbisCommentField field;
197 field.parse(stream, maxSize, diag);
198 fields().emplace(field.id(), move(field));
199 }
catch (
const TruncatedDataException &) {
201 }
catch (
const Failure &) {
208 m_size =
static_cast<std::uint64_t
>(stream.tellg()) - startOffset;
214 const auto [first, end] =
fields().equal_range(yearFieldId);
215 for (
auto i = first; i != end; ++i) {
216 fields().emplace(dateFieldId, std::move(i->second));
218 fields().erase(first, end);
222 throw InvalidDataException();
224 }
catch (
const TruncatedDataException &) {
225 m_size =
static_cast<std::uint64_t
>(stream.tellg()) - startOffset;
231 if constexpr (std::is_same_v<std::decay_t<StreamType>, OggIterator>) {
232 auto bytesRemaining = std::uint64_t();
234 bytesRemaining = stream.remainingBytesInCurrentSegment();
235 if (stream.currentPage().isLastSegmentUnconcluded()) {
236 stream.nextSegment();
238 bytesRemaining += stream.remainingBytesInCurrentSegment();
242 if (bytesRemaining) {
243 diag.emplace_back(
DiagLevel::Warning, argsToString(bytesRemaining,
" bytes left in last segment."), context);
257 internalParse(iterator, iterator.
streamSize(), flags, diag);
269 internalParse(stream, maxSize, flags, diag);
282 static const string context(
"making Vorbis comment");
286 }
catch (
const ConversionException &) {
287 diag.emplace_back(
DiagLevel::Warning,
"Can not convert the assigned vendor to string.", context);
289 BinaryWriter writer(&stream);
292 static const char sig[7] = { 0x03, 0x76, 0x6F, 0x72, 0x62, 0x69, 0x73 };
293 stream.write(sig,
sizeof(sig));
296 writer.writeUInt32LE(
static_cast<std::uint32_t
>(
vendor.size()));
297 writer.writeString(
vendor);
299 const auto fieldCountOffset = stream.tellp();
300 writer.writeUInt32LE(0);
302 std::uint32_t fieldsWritten = 0;
303 for (
auto &i :
fields()) {
307 if (field.
make(writer, flags, diag)) {
315 const auto framingByteOffset = stream.tellp();
316 stream.seekp(fieldCountOffset);
317 writer.writeUInt32LE(fieldsWritten);
318 stream.seekp(framingByteOffset);
The Diagnostics class is a container for DiagMessage.
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
bool setValue(const IdentifierType &id, const TagValue &value)
Assigns the given value to the field with the specified id.
typename FieldMapBasedTagTraits< VorbisComment >::FieldType::IdentifierType IdentifierType
const TagValue & value(const IdentifierType &id) const
Returns the value of the field with the specified id.
const std::multimap< IdentifierType, FieldType, Compare > & fields() const
Returns the fields of the tag by providing direct access to the field map of the tag.
KnownField knownField(const IdentifierType &id) const
Returns the field for the specified ID.
std::size_t fieldCount() const
The OggIterator class helps iterating through all segments of an OGG bitstream.
std::uint64_t streamSize() const
Returns the stream size (which has been specified when constructing the iterator).
TagValue & value()
Returns the value of the current TagField.
The TagValue class wraps values of different types.
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
bool isEmpty() const
Returns whether no or an empty value is assigned.
#define CHECK_MAX_SIZE(sizeDenotation)
Throws TruncatedDataException() if the specified sizeDenotation exceeds maxSize; otherwise maxSize is...
constexpr TAG_PARSER_EXPORT std::string_view rating()
constexpr TAG_PARSER_EXPORT std::string_view album()
constexpr TAG_PARSER_EXPORT std::string_view encoderSettings()
constexpr TAG_PARSER_EXPORT std::string_view encodedBy()
constexpr TAG_PARSER_EXPORT std::string_view description()
constexpr TAG_PARSER_EXPORT std::string_view isrc()
constexpr TAG_PARSER_EXPORT std::string_view title()
constexpr TAG_PARSER_EXPORT std::string_view comment()
constexpr TAG_PARSER_EXPORT std::string_view language()
constexpr TAG_PARSER_EXPORT std::string_view composer()
constexpr TAG_PARSER_EXPORT std::string_view partNumber()
constexpr TAG_PARSER_EXPORT std::string_view conductor()
constexpr TAG_PARSER_EXPORT std::string_view bpm()
constexpr TAG_PARSER_EXPORT std::string_view director()
constexpr TAG_PARSER_EXPORT std::string_view genre()
constexpr TAG_PARSER_EXPORT std::string_view artist()
constexpr TAG_PARSER_EXPORT std::string_view copyright()
constexpr TAG_PARSER_EXPORT std::string_view lyrics()
constexpr TAG_PARSER_EXPORT std::string_view encoder()
constexpr TAG_PARSER_EXPORT std::string_view license()
constexpr TAG_PARSER_EXPORT std::string_view lyricist()
Contains all classes and functions of the TagInfo library.
KnownField
Specifies the field.
VorbisCommentFlags
The VorbisCommentFlags enum specifies flags which controls parsing and making of Vorbis comments.