4 #include "../flac/flacmetadata.h" 6 #include "../ogg/oggiterator.h" 8 #include "../id3/id3v2frame.h" 10 #include "../diagnostics.h" 11 #include "../exceptions.h" 13 #include <c++utilities/conversion/binaryconversion.h> 14 #include <c++utilities/conversion/stringconversion.h> 15 #include <c++utilities/io/binaryreader.h> 16 #include <c++utilities/io/binarywriter.h> 17 #include <c++utilities/io/catchiofailure.h> 36 VorbisCommentField::VorbisCommentField()
43 VorbisCommentField::VorbisCommentField(
const IdentifierType &
id,
const TagValue &value)
51 template <
class StreamType>
void VorbisCommentField::internalParse(StreamType &stream, uint64 &maxSize,
Diagnostics &diag)
53 static const string context(
"parsing Vorbis comment field");
62 if (
const auto size = LE::toUInt32(buff)) {
63 if (size <= maxSize) {
66 auto data = make_unique<char[]>(size);
67 stream.read(data.get(), size);
69 for (
const char *i = data.get(), *end = data.get() + size; i != end && *i !=
'='; ++i, ++idSize)
72 setId(
string(data.get(), idSize));
76 throw InvalidDataException();
80 auto decoded = decodeBase64(data.get() + idSize + 1, size - idSize - 1);
81 stringstream bufferStream(ios_base::in | ios_base::out | ios_base::binary);
82 bufferStream.exceptions(ios_base::failbit | ios_base::badbit);
83 bufferStream.rdbuf()->pubsetbuf(reinterpret_cast<char *>(decoded.first.get()), decoded.second);
84 FlacMetaDataBlockPicture pictureBlock(
value());
85 pictureBlock.parse(bufferStream, decoded.second);
87 }
catch (
const TruncatedDataException &) {
90 }
catch (
const ConversionException &) {
91 diag.emplace_back(
DiagLevel::Critical,
"Base64 coding of METADATA_BLOCK_PICTURE is invalid.", context);
92 throw InvalidDataException();
95 diag.emplace_back(
DiagLevel::Critical,
"An IO error occured when reading the METADATA_BLOCK_PICTURE struct.", context);
98 }
else if (
id().size() + 1 < size) {
104 throw TruncatedDataException();
122 internalParse(iterator, maxSize, diag);
137 internalParse(iterator, maxSize, diag);
152 internalParse(stream, maxSize, diag);
166 static const string context(
"making Vorbis comment field");
179 diag.emplace_back(
DiagLevel::Critical,
"Assigned value of cover field is not picture data.", context);
187 auto buffer = make_unique<char[]>(requiredSize);
188 stringstream bufferStream(ios_base::in | ios_base::out | ios_base::binary);
189 bufferStream.exceptions(ios_base::failbit | ios_base::badbit);
190 bufferStream.rdbuf()->pubsetbuf(buffer.get(), requiredSize);
192 pictureBlock.
make(bufferStream);
193 valueString = encodeBase64(reinterpret_cast<byte *>(buffer.get()), requiredSize);
196 diag.emplace_back(
DiagLevel::Critical,
"An IO error occured when writing the METADATA_BLOCK_PICTURE struct.", context);
203 writer.writeUInt32LE(
id().size() + 1 + valueString.size());
204 writer.writeString(
id());
205 writer.writeChar(
'=');
206 writer.writeString(valueString);
207 }
catch (
const ConversionException &) {
208 diag.emplace_back(
DiagLevel::Critical,
"Assigned value can not be converted appropriately.", context);
void setTypeInfo(const TypeInfoType &typeInfo)
Sets the type info of the current TagField.
uint64 streamSize() const
Returns the stream size (which has been specified when constructing the iterator).
void setValue(const TagValue &value)
Sets the value of the current TagField.
VorbisCommentFlags
The VorbisCommentFlags enum specifies flags which controls parsing and making of Vorbis comments...
uint64 currentCharacterOffset() const
Returns the offset of the current character in the input stream if the iterator is valid; otherwise a...
Contains utility classes helping to read and write streams.
const TypeInfoType & typeInfo() const
Returns the type info of the current TagField.
The TagField class is used by FieldMapBasedTag to store the fields.
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
void setId(const IdentifierType &id)
Sets the id of the current Tag Field.
TagValue & value()
Returns the value of the current TagField.