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;
103 return fieldMap.at(
id);
104 }
catch (out_of_range &) {
105 return KnownField::Invalid;
112 template <
class StreamType>
void VorbisComment::internalParse(StreamType &stream, uint64 maxSize,
VorbisCommentFlags flags,
Diagnostics &diag)
115 static const string context(
"parsing Vorbis comment");
116 uint64 startOffset =
static_cast<uint64
>(stream.tellg());
120 bool skipSignature = flags & VorbisCommentFlags::NoSignature;
121 if (!skipSignature) {
124 skipSignature = (ConversionUtilities::BE::toUInt64(sig) & 0xffffffffffffff00u) == 0x03766F7262697300u;
131 const auto vendorSize = LE::toUInt32(sig);
132 if (vendorSize <= maxSize) {
133 auto buff = make_unique<char[]>(vendorSize);
134 stream.read(buff.get(), vendorSize);
138 diag.emplace_back(DiagLevel::Critical,
"Vendor information is truncated.", context);
139 throw TruncatedDataException();
141 maxSize -= vendorSize;
146 uint32 fieldCount = LE::toUInt32(sig);
147 for (uint32 i = 0; i < fieldCount; ++i) {
149 VorbisCommentField field;
151 field.parse(stream, maxSize, diag);
152 fields().emplace(field.id(), move(field));
153 }
catch (
const TruncatedDataException &) {
155 }
catch (
const Failure &) {
159 if (!(flags & VorbisCommentFlags::NoFramingByte)) {
162 m_size =
static_cast<uint32
>(
static_cast<uint64
>(stream.tellg()) - startOffset);
164 diag.emplace_back(DiagLevel::Critical,
"Signature is invalid.", context);
165 throw InvalidDataException();
167 }
catch (
const TruncatedDataException &) {
168 m_size =
static_cast<uint32
>(
static_cast<uint64
>(stream.tellg()) - startOffset);
169 diag.emplace_back(DiagLevel::Critical,
"Vorbis comment is truncated.", context);
183 internalParse(iterator, iterator.
streamSize(), flags, diag);
195 internalParse(stream, maxSize, flags, diag);
208 static const string context(
"making Vorbis comment");
211 m_vendor.toString(vendor);
212 }
catch (
const ConversionException &) {
213 diag.emplace_back(DiagLevel::Warning,
"Can not convert the assigned vendor to string.", context);
215 BinaryWriter writer(&stream);
216 if (!(flags & VorbisCommentFlags::NoSignature)) {
218 static const char sig[7] = { 0x03, 0x76, 0x6F, 0x72, 0x62, 0x69, 0x73 };
219 stream.write(sig,
sizeof(sig));
222 writer.writeUInt32LE(vendor.size());
223 writer.writeString(vendor);
225 const auto fieldCountOffset = stream.tellp();
226 writer.writeUInt32LE(0);
228 uint32 fieldsWritten = 0;
229 for (
auto i : fields()) {
233 if (field.
make(writer, flags, diag)) {
241 const auto framingByteOffset = stream.tellp();
242 stream.seekp(fieldCountOffset);
243 writer.writeUInt32LE(fieldsWritten);
244 stream.seekp(framingByteOffset);
246 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...