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)) {
TAG_PARSER_EXPORT const char * composer()
TAG_PARSER_EXPORT const char * language()
FieldMapBasedTagTraits< VorbisComment >::FieldType::IdentifierType IdentifierType
The FieldMapBasedTag provides a generic implementation of Tag which stores the tag fields using std::...
TAG_PARSER_EXPORT const char * description()
uint64 streamSize() const
Returns the stream size (which has been specified when constructing the iterator).
TAG_PARSER_EXPORT const char * lyricist()
TAG_PARSER_EXPORT const char * encoderSettings()
TAG_PARSER_EXPORT const char * genre()
VorbisCommentFlags
The VorbisCommentFlags enum specifies flags which controls parsing and making of Vorbis comments...
The OggIterator class helps iterating through all segments of an OGG bitstream.
KnownField
Specifies the field.
TAG_PARSER_EXPORT const char * comment()
TAG_PARSER_EXPORT const char * partNumber()
bool isEmpty() const
Returns an indication whether an value is assigned.
Contains utility classes helping to read and write streams.
TAG_PARSER_EXPORT const char * artist()
TAG_PARSER_EXPORT const char * encoder()
TAG_PARSER_EXPORT const char * album()
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...
Contains all classes and functions of the TagInfo library.
TAG_PARSER_EXPORT const char * title()
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...