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> 18 using namespace ConversionUtilities;
30 case KnownField::Vendor:
40 case KnownField::Vendor:
50 using namespace VorbisCommentIds;
70 case KnownField::PartNumber:
76 case KnownField::EncoderSettings:
86 case KnownField::Language:
97 KnownField VorbisComment::internallyGetKnownField(
const IdentifierType &
id)
const 99 using namespace VorbisCommentIds;
101 static const map<string, KnownField, CaseInsensitiveStringComparer> fieldMap({
123 const auto knownField(fieldMap.find(
id));
124 return knownField != fieldMap.cend() ? knownField->second : KnownField::Invalid;
130 template <
class StreamType>
void VorbisComment::internalParse(StreamType &stream, uint64 maxSize,
VorbisCommentFlags flags,
Diagnostics &diag)
133 static const string context(
"parsing Vorbis comment");
134 uint64 startOffset = static_cast<uint64>(stream.tellg());
138 bool skipSignature = flags & VorbisCommentFlags::NoSignature;
139 if (!skipSignature) {
142 skipSignature = (ConversionUtilities::BE::toUInt64(sig) & 0xffffffffffffff00u) == 0x03766F7262697300u;
149 const auto vendorSize = LE::toUInt32(sig);
150 if (vendorSize <= maxSize) {
151 auto buff = make_unique<char[]>(vendorSize);
152 stream.read(buff.get(), vendorSize);
156 diag.emplace_back(DiagLevel::Critical,
"Vendor information is truncated.", context);
157 throw TruncatedDataException();
159 maxSize -= vendorSize;
164 uint32 fieldCount = LE::toUInt32(sig);
165 for (uint32 i = 0; i < fieldCount; ++i) {
167 VorbisCommentField field;
169 field.parse(stream, maxSize, diag);
170 fields().emplace(field.id(), move(field));
171 }
catch (
const TruncatedDataException &) {
173 }
catch (
const Failure &) {
177 if (!(flags & VorbisCommentFlags::NoFramingByte)) {
180 m_size = static_cast<uint32>(static_cast<uint64>(stream.tellg()) - startOffset);
182 diag.emplace_back(DiagLevel::Critical,
"Signature is invalid.", context);
183 throw InvalidDataException();
185 }
catch (
const TruncatedDataException &) {
186 m_size = static_cast<uint32>(static_cast<uint64>(stream.tellg()) - startOffset);
187 diag.emplace_back(DiagLevel::Critical,
"Vorbis comment is truncated.", context);
201 internalParse(iterator, iterator.
streamSize(), flags, diag);
213 internalParse(stream, maxSize, flags, diag);
226 static const string context(
"making Vorbis comment");
229 m_vendor.toString(vendor);
230 }
catch (
const ConversionException &) {
231 diag.emplace_back(DiagLevel::Warning,
"Can not convert the assigned vendor to string.", context);
233 BinaryWriter writer(&stream);
234 if (!(flags & VorbisCommentFlags::NoSignature)) {
236 static const char sig[7] = { 0x03, 0x76, 0x6F, 0x72, 0x62, 0x69, 0x73 };
237 stream.write(sig,
sizeof(sig));
240 writer.writeUInt32LE(vendor.size());
241 writer.writeString(vendor);
243 const auto fieldCountOffset = stream.tellp();
244 writer.writeUInt32LE(0);
246 uint32 fieldsWritten = 0;
247 for (
auto i : fields()) {
251 if (field.
make(writer, flags, diag)) {
259 const auto framingByteOffset = stream.tellp();
260 stream.seekp(fieldCountOffset);
261 writer.writeUInt32LE(fieldsWritten);
262 stream.seekp(framingByteOffset);
264 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...