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
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...
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()
TAG_PARSER_EXPORT const char * title()
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...