4 #include "../ogg/oggiterator.h" 6 #include "../diagnostics.h" 7 #include "../exceptions.h" 9 #include <c++utilities/io/binaryreader.h> 10 #include <c++utilities/io/binarywriter.h> 11 #include <c++utilities/io/copy.h> 30 case KnownField::Vendor:
40 case KnownField::Vendor:
50 using namespace VorbisCommentIds;
70 case KnownField::PartNumber:
76 case KnownField::EncoderSettings:
84 case KnownField::Language:
93 KnownField VorbisComment::internallyGetKnownField(
const IdentifierType &
id)
const 95 using namespace VorbisCommentIds;
102 const auto knownField(fieldMap.find(
id));
103 return knownField != fieldMap.cend() ? knownField->second : KnownField::Invalid;
109 template <
class StreamType>
void VorbisComment::internalParse(StreamType &stream, uint64 maxSize,
VorbisCommentFlags flags,
Diagnostics &diag)
112 static const string context(
"parsing Vorbis comment");
113 uint64 startOffset =
static_cast<uint64
>(stream.tellg());
117 bool skipSignature = flags & VorbisCommentFlags::NoSignature;
118 if (!skipSignature) {
121 skipSignature = (ConversionUtilities::BE::toUInt64(sig) & 0xffffffffffffff00u) == 0x03766F7262697300u;
128 const auto vendorSize = LE::toUInt32(sig);
129 if (vendorSize <= maxSize) {
130 auto buff = make_unique<char[]>(vendorSize);
131 stream.read(buff.get(), vendorSize);
135 diag.emplace_back(DiagLevel::Critical,
"Vendor information is truncated.", context);
136 throw TruncatedDataException();
138 maxSize -= vendorSize;
143 uint32 fieldCount = LE::toUInt32(sig);
144 for (uint32 i = 0; i < fieldCount; ++i) {
146 VorbisCommentField field;
148 field.parse(stream, maxSize, diag);
149 fields().emplace(field.id(), move(field));
150 }
catch (
const TruncatedDataException &) {
152 }
catch (
const Failure &) {
156 if (!(flags & VorbisCommentFlags::NoFramingByte)) {
159 m_size =
static_cast<uint32
>(
static_cast<uint64
>(stream.tellg()) - startOffset);
161 diag.emplace_back(DiagLevel::Critical,
"Signature is invalid.", context);
162 throw InvalidDataException();
164 }
catch (
const TruncatedDataException &) {
165 m_size =
static_cast<uint32
>(
static_cast<uint64
>(stream.tellg()) - startOffset);
166 diag.emplace_back(DiagLevel::Critical,
"Vorbis comment is truncated.", context);
180 internalParse(iterator, iterator.
streamSize(), flags, diag);
192 internalParse(stream, maxSize, flags, diag);
205 static const string context(
"making Vorbis comment");
208 m_vendor.toString(vendor);
209 }
catch (
const ConversionException &) {
210 diag.emplace_back(DiagLevel::Warning,
"Can not convert the assigned vendor to string.", context);
212 BinaryWriter writer(&stream);
213 if (!(flags & VorbisCommentFlags::NoSignature)) {
215 static const char sig[7] = { 0x03, 0x76, 0x6F, 0x72, 0x62, 0x69, 0x73 };
216 stream.write(sig,
sizeof(sig));
219 writer.writeUInt32LE(vendor.size());
220 writer.writeString(vendor);
222 const auto fieldCountOffset = stream.tellp();
223 writer.writeUInt32LE(0);
225 uint32 fieldsWritten = 0;
226 for (
auto i : fields()) {
230 if (field.
make(writer, flags, diag)) {
238 const auto framingByteOffset = stream.tellp();
239 stream.seekp(fieldCountOffset);
240 writer.writeUInt32LE(fieldsWritten);
241 stream.seekp(framingByteOffset);
243 if (!(flags & VorbisCommentFlags::NoFramingByte)) {
constexpr TAG_PARSER_EXPORT const char * encoder()
The FieldMapBasedTag provides a generic implementation of Tag which stores the tag fields using std::...
uint64 streamSize() const
Returns the stream size (which has been specified when constructing the iterator).
VorbisCommentFlags
The VorbisCommentFlags enum specifies flags which controls parsing and making of Vorbis comments...
typename FieldMapBasedTagTraits< VorbisComment >::FieldType::IdentifierType IdentifierType
The OggIterator class helps iterating through all segments of an OGG bitstream.
constexpr TAG_PARSER_EXPORT const char * lyricist()
KnownField
Specifies the field.
constexpr TAG_PARSER_EXPORT const char * language()
constexpr TAG_PARSER_EXPORT const char * encoderSettings()
bool isEmpty() const
Returns an indication whether an value is assigned.
constexpr TAG_PARSER_EXPORT const char * comment()
Contains utility classes helping to read and write streams.
constexpr TAG_PARSER_EXPORT const char * partNumber()
constexpr TAG_PARSER_EXPORT const char * album()
constexpr TAG_PARSER_EXPORT const char * title()
constexpr TAG_PARSER_EXPORT const char * genre()
constexpr TAG_PARSER_EXPORT const char * artist()
constexpr TAG_PARSER_EXPORT const char * composer()
The TagValue class wraps values of different types.
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
constexpr TAG_PARSER_EXPORT const char * description()
Contains all classes and functions of the TagInfo library.
The Diagnostics class is a container for DiagMessage.
TagValue & value()
Returns the value of the current TagField.
#define CHECK_MAX_SIZE(sizeDenotation)
Throws TruncatedDataException() if the specified sizeDenotation exceeds maxSize; otherwise maxSize is...