Fix warnings, mostly about implicit int conversions

This should fix all non-erros, leaving only warnings which
are indeed potential problems.

The following warnings should be safe to ignore:

* Conversions of various offsets from uint64 to
  std::streamoff/int64 are safe because such offsets have
  been obtained via tellg() and other functions
  returning std::streamoff in the first place.
* It also works vice-versa since tellg() should not
  return negative offsets with exceptions enabled.
* Conversions from char to unsigned char are also ok.
* Unused diag arguments can be ignored (those might be
  useful later).
* Annotate all intended fallthoughs.
This commit is contained in:
Martchus 2018-06-02 22:56:08 +02:00
parent 404e4f751f
commit 0a640c9f7f
32 changed files with 342 additions and 236 deletions

View File

@ -211,7 +211,7 @@ string AbstractTrack::description() const
void AbstractTrack::parseHeader(Diagnostics &diag)
{
m_headerValid = false;
m_istream->seekg(m_startOffset, ios_base::beg);
m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg);
try {
internalParseHeader(diag);
m_headerValid = true;

View File

@ -17,6 +17,8 @@ namespace TagParser {
void AdtsStream::internalParseHeader(Diagnostics &diag)
{
VAR_UNUSED(diag)
//static const string context("parsing ADTS frame header");
if (!m_istream) {
throw NoDataFoundException();
@ -28,7 +30,7 @@ void AdtsStream::internalParseHeader(Diagnostics &diag)
} else {
m_size = static_cast<uint64>(m_istream->tellg()) + 125u - m_startOffset;
}
m_istream->seekg(m_startOffset, ios_base::beg);
m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg);
// parse frame header
m_firstFrame.parseHeader(m_reader);
m_format = Mpeg4AudioObjectIds::idToMediaFormat(m_firstFrame.mpeg4AudioObjectId());

View File

@ -5,6 +5,8 @@
#include <c++utilities/io/binaryreader.h>
#include <limits>
using namespace std;
using namespace IoUtilities;
@ -42,7 +44,7 @@ void AvcConfiguration::parse(BinaryReader &reader, uint64 maxSize)
}
spsInfos.emplace_back();
try {
spsInfos.back().parse(reader, maxSize);
spsInfos.back().parse(reader, maxSize > numeric_limits<uint32>::max() ? numeric_limits<uint32>::max() : static_cast<uint32>(maxSize));
} catch (const TruncatedDataException &) {
// TODO: log parsing error
if (spsInfos.back().size > maxSize - 2) {
@ -65,7 +67,7 @@ void AvcConfiguration::parse(BinaryReader &reader, uint64 maxSize)
}
ppsInfos.emplace_back();
try {
ppsInfos.back().parse(reader, maxSize);
ppsInfos.back().parse(reader, maxSize > numeric_limits<uint32>::max() ? numeric_limits<uint32>::max() : static_cast<uint32>(maxSize));
} catch (const TruncatedDataException &) {
// TODO: log parsing error
if (ppsInfos.back().size > maxSize - 2) {

View File

@ -108,29 +108,39 @@ void FlacMetaDataBlockPicture::parse(istream &inputStream, uint32 maxSize)
/*!
* \brief Returns the number of bytes make() will write.
* \remarks Any changes to the object will invalidate this value.
* \throws Throws an InvalidDataException() if the assigned data is too big.
*/
uint32 FlacMetaDataBlockPicture::requiredSize() const
{
return 32 + m_value.mimeType().size() + m_value.description().size() + m_value.dataSize();
const auto requiredSize(32 + m_value.mimeType().size() + m_value.description().size() + m_value.dataSize());
if (requiredSize > numeric_limits<uint32>::max()) {
throw InvalidDataException();
}
return static_cast<uint32>(requiredSize);
}
/*!
* \brief Makes the FLAC "METADATA_BLOCK_PICTURE".
* \throws Throws an InvalidDataException() if the assigned data can not be serialized into a "METADATA_BLOCK_PICTURE" structure.
*/
void FlacMetaDataBlockPicture::make(ostream &outputStream)
{
if (m_value.mimeType().size() > numeric_limits<uint32>::max() || m_value.description().size() > numeric_limits<uint32>::max()
|| m_value.dataSize() > numeric_limits<uint32>::max()) {
throw InvalidDataException();
}
BinaryWriter writer(&outputStream);
writer.writeUInt32BE(pictureType());
writer.writeUInt32BE(m_value.mimeType().size());
writer.writeUInt32BE(static_cast<uint32>(m_value.mimeType().size()));
writer.writeString(m_value.mimeType());
writer.writeUInt32BE(m_value.description().size());
writer.writeUInt32BE(static_cast<uint32>(m_value.description().size()));
writer.writeString(m_value.description());
writer.writeUInt32BE(0); // skip width
writer.writeUInt32BE(0); // skip height
writer.writeUInt32BE(0); // skip color depth
writer.writeUInt32BE(0); // skip number of colors used
writer.writeUInt32BE(m_value.dataSize());
writer.write(value().dataPointer(), m_value.dataSize());
writer.writeUInt32BE(static_cast<uint32>(m_value.dataSize()));
writer.write(value().dataPointer(), static_cast<streamoff>(m_value.dataSize()));
}
} // namespace TagParser

View File

@ -71,7 +71,7 @@ void FlacStream::internalParseHeader(Diagnostics &diag)
throw NoDataFoundException();
}
m_istream->seekg(m_startOffset, ios_base::beg);
m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg);
char buffer[0x22];
// check signature
@ -159,7 +159,7 @@ void FlacStream::internalParseHeader(Diagnostics &diag)
// TODO: check first FLAC frame
}
m_streamOffset = m_istream->tellg();
m_streamOffset = static_cast<uint32>(m_istream->tellg());
}
/*!
@ -177,7 +177,7 @@ void FlacStream::internalParseHeader(Diagnostics &diag)
uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag)
{
istream &originalStream = m_mediaFileInfo.stream();
originalStream.seekg(m_startOffset + 4);
originalStream.seekg(static_cast<streamoff>(m_startOffset + 4));
CopyHelper<512> copy;
// write signature
@ -247,6 +247,7 @@ uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag)
outputStream.seekp(lastStartOffset);
header.makeHeader(outputStream);
outputStream.seekp(static_cast<streamoff>(dataSize), ios_base::cur);
lastActuallyWrittenHeader = header;
// write cover fields separately as "METADATA_BLOCK_PICTURE"
if (header.isLast()) {
@ -255,13 +256,37 @@ uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag)
header.setType(FlacMetaDataBlockType::Picture);
const auto coverFields = m_vorbisComment->fields().equal_range(coverId);
for (auto i = coverFields.first; i != coverFields.second;) {
lastStartOffset = outputStream.tellp();
FlacMetaDataBlockPicture pictureBlock(i->second.value());
pictureBlock.setPictureType(i->second.typeInfo());
header.setDataSize(pictureBlock.requiredSize());
header.setLast(++i == coverFields.second);
header.makeHeader(outputStream);
pictureBlock.make(outputStream);
const auto lastCoverStartOffset = outputStream.tellp();
try {
// write the structure
FlacMetaDataBlockPicture pictureBlock(i->second.value());
pictureBlock.setPictureType(i->second.typeInfo());
header.setDataSize(pictureBlock.requiredSize());
header.setLast(++i == coverFields.second);
header.makeHeader(outputStream);
pictureBlock.make(outputStream);
// update variables to handle the "isLast" flag
lastStartOffset = lastCoverStartOffset;
lastActuallyWrittenHeader = header;
} catch (const Failure &) {
// we can expect nothing is written in the error case except the FLAC header, so
// -> just add an error message
diag.emplace_back(DiagLevel::Critical, "Unable to serialize \"METADATA_BLOCK_PICTURE\" from assigned value.",
"write \"METADATA_BLOCK_PICTURE\" to FLAC stream");
// -> and to recover, go back to where we were before
outputStream.seekp(lastCoverStartOffset);
}
}
// adjust "isLast" flag if neccassary
if (!lastActuallyWrittenHeader.isLast()) {
outputStream.seekp(lastStartOffset);
lastActuallyWrittenHeader.setLast(true);
lastActuallyWrittenHeader.makeHeader(outputStream);
outputStream.seekp(lastActuallyWrittenHeader.dataSize());
}
return static_cast<uint32>(lastStartOffset);

View File

@ -40,7 +40,7 @@ const char **Id3Genres::genreNames()
*/
int Id3Genres::indexFromString(const string &genre)
{
const char **ptr = genreNames();
const char *const *ptr = genreNames();
for (int index = 0; index < genreCount(); ++ptr, ++index) {
if (genre == *ptr) {
return index;

View File

@ -25,6 +25,9 @@ namespace Id3v2TextEncodingBytes {
enum Id3v2TextEncodingByte : byte { Ascii, Utf16WithBom, Utf16BigEndianWithoutBom, Utf8 };
}
/// \brief The maximum (supported) size of an ID3v2Frame.
constexpr auto maxId3v2FrameDataSize(numeric_limits<uint32>::max() - 15);
/*!
* \class Media::Id3v2Frame
* \brief The Id3v2Frame class is used by Id3v2Tag to store the fields.
@ -213,7 +216,11 @@ void Id3v2Frame::parse(BinaryReader &reader, uint32 version, uint32 maximalSize,
diag.emplace_back(DiagLevel::Critical, "Decompressing failed (unknown reason).", context);
throw InvalidDataException();
}
m_dataSize = decompressedSize;
if (decompressedSize > maxId3v2FrameDataSize) {
diag.emplace_back(DiagLevel::Critical, "The decompressed data exceeds the maximum supported frame size.", context);
throw InvalidDataException();
}
m_dataSize = static_cast<uint32>(decompressedSize);
} else {
buffer = make_unique<char[]>(m_dataSize);
reader.read(buffer.get(), m_dataSize);
@ -222,7 +229,7 @@ void Id3v2Frame::parse(BinaryReader &reader, uint32 version, uint32 maximalSize,
// -> get tag value depending of field type
if (Id3v2FrameIds::isTextFrame(id())) {
// frame contains text
TagTextEncoding dataEncoding = parseTextEncodingByte(*buffer.get(), diag); // the first byte stores the encoding
TagTextEncoding dataEncoding = parseTextEncodingByte(static_cast<byte>(*buffer.get()), diag); // the first byte stores the encoding
if ((version >= 3 && (id() == Id3v2FrameIds::lTrackPosition || id() == Id3v2FrameIds::lDiskPosition))
|| (version < 3 && id() == Id3v2FrameIds::sTrackPosition)) {
// the track number or the disk number frame
@ -464,7 +471,11 @@ Id3v2FrameMaker::Id3v2FrameMaker(Id3v2Frame &frame, byte version, Diagnostics &d
} else {
// make unknown frame
m_data = make_unique<char[]>(m_decompressedSize = value.dataSize());
if (value.dataSize() > maxId3v2FrameDataSize) {
diag.emplace_back(DiagLevel::Critical, "Assigned value exceeds maximum size.", context);
throw InvalidDataException();
}
m_data = make_unique<char[]>(m_decompressedSize = static_cast<uint32>(value.dataSize()));
copy(value.dataPointer(), value.dataPointer() + m_decompressedSize, m_data.get());
}
} catch (const ConversionException &) {
@ -479,9 +490,9 @@ Id3v2FrameMaker::Id3v2FrameMaker(Id3v2Frame &frame, byte version, Diagnostics &d
// apply compression if frame should be compressed
if (version >= 3 && m_frame.isCompressed()) {
m_dataSize = compressBound(m_decompressedSize);
auto compressedData = make_unique<char[]>(m_decompressedSize);
switch (compress(reinterpret_cast<Bytef *>(compressedData.get()), reinterpret_cast<uLongf *>(&m_dataSize),
auto compressedSize = compressBound(m_decompressedSize);
auto compressedData = make_unique<char[]>(compressedSize);
switch (compress(reinterpret_cast<Bytef *>(compressedData.get()), reinterpret_cast<uLongf *>(&compressedSize),
reinterpret_cast<Bytef *>(m_data.get()), m_decompressedSize)) {
case Z_MEM_ERROR:
diag.emplace_back(DiagLevel::Critical, "Decompressing failed. The source buffer was too small.", context);
@ -491,7 +502,12 @@ Id3v2FrameMaker::Id3v2FrameMaker(Id3v2Frame &frame, byte version, Diagnostics &d
throw InvalidDataException();
case Z_OK:;
}
if (compressedSize > maxId3v2FrameDataSize) {
diag.emplace_back(DiagLevel::Critical, "Compressed size exceeds maximum data size.", context);
throw InvalidDataException();
}
m_data.swap(compressedData);
m_dataSize = static_cast<uint32>(compressedSize);
} else {
m_dataSize = m_decompressedSize;
}
@ -744,15 +760,15 @@ void Id3v2Frame::parseLegacyPicture(const char *buffer, std::size_t maxSize, Tag
throw TruncatedDataException();
}
const char *end = buffer + maxSize;
auto dataEncoding = parseTextEncodingByte(*buffer, diag); // the first byte stores the encoding
auto dataEncoding = parseTextEncodingByte(static_cast<byte>(*buffer), diag); // the first byte stores the encoding
typeInfo = static_cast<unsigned char>(*(buffer + 4));
auto substr = parseSubstring(buffer + 5, end - 5 - buffer, dataEncoding, true, diag);
auto substr = parseSubstring(buffer + 5, static_cast<size_t>(end - 5 - buffer), dataEncoding, true, diag);
tagValue.setDescription(string(get<0>(substr), get<1>(substr)), dataEncoding);
if (get<2>(substr) >= end) {
diag.emplace_back(DiagLevel::Critical, "Picture frame is incomplete (actual data is missing).", context);
throw TruncatedDataException();
}
tagValue.assignData(get<2>(substr), end - get<2>(substr), TagDataType::Picture, dataEncoding);
tagValue.assignData(get<2>(substr), static_cast<size_t>(end - get<2>(substr)), TagDataType::Picture, dataEncoding);
}
/*!
@ -766,7 +782,7 @@ void Id3v2Frame::parsePicture(const char *buffer, std::size_t maxSize, TagValue
{
static const string context("parsing ID3v2.3 picture frame");
const char *end = buffer + maxSize;
auto dataEncoding = parseTextEncodingByte(*buffer, diag); // the first byte stores the encoding
auto dataEncoding = parseTextEncodingByte(static_cast<byte>(*buffer), diag); // the first byte stores the encoding
auto mimeTypeEncoding = TagTextEncoding::Latin1;
auto substr = parseSubstring(buffer + 1, maxSize - 1, mimeTypeEncoding, true, diag);
if (get<1>(substr)) {
@ -781,13 +797,13 @@ void Id3v2Frame::parsePicture(const char *buffer, std::size_t maxSize, TagValue
diag.emplace_back(DiagLevel::Critical, "Picture frame is incomplete (description and actual data are missing).", context);
throw TruncatedDataException();
}
substr = parseSubstring(get<2>(substr), end - get<2>(substr), dataEncoding, true, diag);
substr = parseSubstring(get<2>(substr), static_cast<size_t>(end - get<2>(substr)), dataEncoding, true, diag);
tagValue.setDescription(string(get<0>(substr), get<1>(substr)), dataEncoding);
if (get<2>(substr) >= end) {
diag.emplace_back(DiagLevel::Critical, "Picture frame is incomplete (actual data is missing).", context);
throw TruncatedDataException();
}
tagValue.assignData(get<2>(substr), end - get<2>(substr), TagDataType::Picture, dataEncoding);
tagValue.assignData(get<2>(substr), static_cast<size_t>(end - get<2>(substr)), TagDataType::Picture, dataEncoding);
}
/*!
@ -804,7 +820,7 @@ void Id3v2Frame::parseComment(const char *buffer, std::size_t dataSize, TagValue
diag.emplace_back(DiagLevel::Critical, "Comment frame is incomplete.", context);
throw TruncatedDataException();
}
TagTextEncoding dataEncoding = parseTextEncodingByte(*buffer, diag);
TagTextEncoding dataEncoding = parseTextEncodingByte(static_cast<byte>(*buffer), diag);
if (*(++buffer)) {
tagValue.setLanguage(string(buffer, 3));
}
@ -814,7 +830,7 @@ void Id3v2Frame::parseComment(const char *buffer, std::size_t dataSize, TagValue
diag.emplace_back(DiagLevel::Critical, "Comment frame is incomplete (description not terminated?).", context);
throw TruncatedDataException();
}
substr = parseSubstring(get<2>(substr), end - get<2>(substr), dataEncoding, false, diag);
substr = parseSubstring(get<2>(substr), static_cast<size_t>(end - get<2>(substr)), dataEncoding, false, diag);
tagValue.assignData(get<0>(substr), get<1>(substr), TagDataType::Text, dataEncoding);
}
@ -852,14 +868,14 @@ void Id3v2Frame::makeEncodingAndData(
case TagTextEncoding::Unspecified: // assumption
// allocate buffer
buffer = make_unique<char[]>(bufferSize = 1 + dataSize + 1);
buffer[0] = makeTextEncodingByte(encoding); // set text encoding byte
buffer[0] = static_cast<char>(makeTextEncodingByte(encoding)); // set text encoding byte
bufferDataAddress = buffer.get() + 1;
break;
case TagTextEncoding::Utf16LittleEndian:
case TagTextEncoding::Utf16BigEndian:
// allocate buffer
buffer = make_unique<char[]>(bufferSize = 1 + 2 + dataSize + 2);
buffer[0] = makeTextEncodingByte(encoding); // set text encoding byte
buffer[0] = static_cast<char>(makeTextEncodingByte(encoding)); // set text encoding byte
ConversionUtilities::LE::getBytes(
encoding == TagTextEncoding::Utf16LittleEndian ? static_cast<uint16>(0xFEFF) : static_cast<uint16>(0xFFFE), buffer.get() + 1);
bufferDataAddress = buffer.get() + 3;
@ -919,7 +935,7 @@ void Id3v2Frame::makeLegacyPicture(unique_ptr<char[]> &buffer, uint32 &bufferSiz
// note: encoding byte + image format + picture type byte + description size + 1 or 2 null bytes (depends on encoding) + data size
char *offset = buffer.get();
// write encoding byte
*offset = makeTextEncodingByte(descriptionEncoding);
*offset = static_cast<char>(makeTextEncodingByte(descriptionEncoding));
// write mime type
const char *imageFormat;
if (picture.mimeType() == "image/jpeg") {
@ -935,7 +951,7 @@ void Id3v2Frame::makeLegacyPicture(unique_ptr<char[]> &buffer, uint32 &bufferSiz
}
strncpy(++offset, imageFormat, 3);
// write picture type
*(offset += 3) = typeInfo;
*(offset += 3) = static_cast<char>(typeInfo);
// write description
offset += makeBom(offset + 1, descriptionEncoding);
if (convertedDescription.first) {
@ -988,12 +1004,12 @@ void Id3v2Frame::makePicture(std::unique_ptr<char[]> &buffer, uint32 &bufferSize
// note: encoding byte + mime type size + 0 byte + picture type byte + description size + 1 or 4 null bytes (depends on encoding) + data size
char *offset = buffer.get();
// write encoding byte
*offset = makeTextEncodingByte(descriptionEncoding);
*offset = static_cast<char>(makeTextEncodingByte(descriptionEncoding));
// write mime type
picture.mimeType().copy(++offset, mimeTypeSize);
*(offset += mimeTypeSize) = 0x00; // terminate mime type
// write picture type
*(++offset) = typeInfo;
*(++offset) = static_cast<char>(typeInfo);
// write description
offset += makeBom(offset + 1, descriptionEncoding);
if (convertedDescription.first) {
@ -1045,7 +1061,7 @@ void Id3v2Frame::makeComment(unique_ptr<char[]> &buffer, uint32 &bufferSize, con
// note: encoding byte + language + description size + actual data size + BOMs and termination
char *offset = buffer.get();
// write encoding
*offset = makeTextEncodingByte(encoding);
*offset = static_cast<char>(makeTextEncodingByte(encoding));
// write language
for (unsigned int i = 0; i < 3; ++i) {
*(++offset) = (lng.length() > i) ? lng[i] : 0x00;

View File

@ -496,6 +496,8 @@ Id3v2TagMaker::Id3v2TagMaker(Id3v2Tag &tag, Diagnostics &diag)
*/
void Id3v2TagMaker::make(std::ostream &stream, uint32 padding, Diagnostics &diag)
{
VAR_UNUSED(diag)
BinaryWriter writer(&stream);
// write header

View File

@ -77,7 +77,7 @@ void EbmlElement::internalParse(Diagnostics &diag)
diag.emplace_back(DiagLevel::Critical, argsToString("The EBML element at ", startOffset(), " is truncated or does not exist."), context);
throw TruncatedDataException();
}
stream().seekg(startOffset());
stream().seekg(static_cast<streamoff>(startOffset()));
// read ID
char buf[maximumIdLengthSupported() > maximumSizeLengthSupported() ? maximumIdLengthSupported() : maximumSizeLengthSupported()] = { 0 };
@ -144,7 +144,8 @@ void EbmlElement::internalParse(Diagnostics &diag)
}
// read size
beg = static_cast<byte>(stream().peek()), mask = 0x80;
beg = static_cast<byte>(stream().peek());
mask = 0x80;
m_sizeLength = 1;
if ((m_sizeUnknown = (beg == 0xFF))) {
// this indicates that the element size is unknown
@ -225,7 +226,7 @@ void EbmlElement::internalParse(Diagnostics &diag)
*/
std::string EbmlElement::readString()
{
stream().seekg(dataOffset());
stream().seekg(static_cast<streamoff>(dataOffset()));
return reader().readString(dataSize());
}
@ -237,13 +238,11 @@ std::string EbmlElement::readString()
*/
uint64 EbmlElement::readUInteger()
{
char buff[sizeof(uint64)] = { 0 };
int i = static_cast<int>(sizeof(buff)) - dataSize();
if (i < 0) {
i = 0;
}
stream().seekg(dataOffset(), ios_base::beg);
stream().read(buff + i, sizeof(buff) - i);
constexpr DataSizeType maxBytesToRead = 8;
char buff[maxBytesToRead] = { 0 };
const auto bytesToSkip = maxBytesToRead - min(dataSize(), maxBytesToRead);
stream().seekg(static_cast<streamoff>(dataOffset()), ios_base::beg);
stream().read(buff + bytesToSkip, static_cast<streamoff>(sizeof(buff) - bytesToSkip));
return BE::toUInt64(buff);
}
@ -253,10 +252,10 @@ uint64 EbmlElement::readUInteger()
*/
float64 EbmlElement::readFloat()
{
stream().seekg(dataOffset());
stream().seekg(static_cast<streamoff>(dataOffset()));
switch (dataSize()) {
case sizeof(float32):
return reader().readFloat32BE();
return static_cast<float64>(reader().readFloat32BE());
case sizeof(float64):
return reader().readFloat64BE();
default:
@ -319,7 +318,7 @@ byte EbmlElement::calculateSizeDenotationLength(uint64 size)
byte EbmlElement::makeId(GenericFileElement::IdentifierType id, char *buff)
{
if (id <= 0xFF) {
*buff = static_cast<byte>(id);
*buff = static_cast<char>(id);
return 1;
} else if (id <= 0x7FFF) {
BE::getBytes(static_cast<uint16>(id), buff);
@ -345,7 +344,7 @@ byte EbmlElement::makeId(GenericFileElement::IdentifierType id, char *buff)
byte EbmlElement::makeSizeDenotation(uint64 size, char *buff)
{
if (size < 126) {
*buff = static_cast<byte>(size | 0x80);
*buff = static_cast<char>(size | 0x80);
return 1;
} else if (size <= 16382ul) {
BE::getBytes(static_cast<uint16>(size | 0x4000), buff);
@ -383,7 +382,7 @@ byte EbmlElement::makeSizeDenotation(uint64 size, char *buff)
byte EbmlElement::makeSizeDenotation(uint64 size, char *buff, byte minBytes)
{
if (minBytes <= 1 && size < 126) {
*buff = static_cast<byte>(size | 0x80);
*buff = static_cast<char>(size | 0x80);
return 1;
} else if (minBytes <= 2 && size <= 16382ul) {
BE::getBytes(static_cast<uint16>(size | 0x4000), buff);
@ -474,6 +473,8 @@ byte EbmlElement::makeUInteger(uint64 value, char *buff)
* \param value Specifies the value to be written.
* \param buff Specifies the buffer to write to.
* \param minBytes Specifies the minimum number of bytes to use.
* \remarks Regardless of \a minBytes, this function will never make
* more than 8 bytes.
*/
byte EbmlElement::makeUInteger(uint64 value, char *buff, byte minBytes)
{

View File

@ -173,7 +173,7 @@ void MatroskaAttachmentMaker::make(ostream &stream, Diagnostics &diag) const
if (attachment().data() && attachment().data()->size()) {
BE::getBytes(static_cast<uint16>(MatroskaIds::FileData), buff);
stream.write(buff, 2);
len = EbmlElement::makeSizeDenotation(attachment().data()->size(), buff);
len = EbmlElement::makeSizeDenotation(static_cast<uint64>(attachment().data()->size()), buff);
stream.write(buff, len);
attachment().data()->copyTo(stream);
}

View File

@ -1579,13 +1579,13 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee
outputWriter.writeUInt32BE(MatroskaIds::Segment);
sizeLength = EbmlElement::makeSizeDenotation(segment.totalDataSize, buff);
outputStream.write(buff, sizeLength);
segment.newDataOffset = offset = outputStream.tellp(); // store segment data offset here
segment.newDataOffset = offset = static_cast<uint64>(outputStream.tellp()); // store segment data offset here
// write CRC-32 element ...
if (segment.hasCrc32) {
// ... if the original element had a CRC-32 element
*buff = EbmlIds::Crc32;
*(buff + 1) = 0x84; // length denotation: 4 byte
*buff = static_cast<char>(EbmlIds::Crc32);
*(buff + 1) = static_cast<char>(0x84); // length denotation: 4 byte
// set the value after writing the element
crc32Offsets.emplace_back(outputStream.tellp(), segment.totalDataSize);
outputStream.write(buff, 6);
@ -1736,16 +1736,16 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee
switch (level2Element->id()) {
case MatroskaIds::Position:
// calculate new position
sizeLength = EbmlElement::makeUInteger(
level1Element->startOffset() - segmentData.front().newDataOffset, buff, level2Element->dataSize());
sizeLength = EbmlElement::makeUInteger(level1Element->startOffset() - segmentData.front().newDataOffset, buff,
level2Element->dataSize() > 8 ? 8 : static_cast<byte>(level2Element->dataSize()));
// new position can only applied if it doesn't need more bytes than the previous position
if (level2Element->dataSize() < sizeLength) {
// can't update position -> void position elements ("Position"-elements seem a bit useless anyways)
outputStream.seekp(level2Element->startOffset());
outputStream.seekp(static_cast<streamoff>(level2Element->startOffset()));
outputStream.put(static_cast<char>(EbmlIds::Void));
} else {
// update position
outputStream.seekp(level2Element->dataOffset());
outputStream.seekp(static_cast<streamoff>(level2Element->dataOffset()));
outputStream.write(buff, sizeLength);
}
break;
@ -1754,7 +1754,7 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee
}
}
// skip existing "Cluster"-elements
outputStream.seekp(segment.clusterEndOffset);
outputStream.seekp(static_cast<streamoff>(segment.clusterEndOffset));
}
progress.updateStep("Writing segment tail ...");
@ -1847,8 +1847,8 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee
if (!crc32Offsets.empty()) {
progress.updateStep("Updating CRC-32 checksums ...");
for (const auto &crc32Offset : crc32Offsets) {
outputStream.seekg(get<0>(crc32Offset) + 6);
outputStream.seekp(get<0>(crc32Offset) + 2);
outputStream.seekg(static_cast<streamoff>(get<0>(crc32Offset) + 6));
outputStream.seekp(static_cast<streamoff>(get<0>(crc32Offset) + 2));
writer().writeUInt32LE(reader().readCrc32(get<1>(crc32Offset) - 6));
}
}

View File

@ -265,7 +265,7 @@ void MatroskaCuePositionUpdater::make(ostream &stream, Diagnostics &diag)
break;
case MatroskaIds::CuePoint:
// write "CuePoint"-element
stream.put(MatroskaIds::CuePoint);
stream.put(static_cast<char>(MatroskaIds::CuePoint));
len = EbmlElement::makeSizeDenotation(m_sizes[cuePointElement], buff);
stream.write(buff, len);
for (EbmlElement *cuePointChild = cuePointElement->firstChild(); cuePointChild; cuePointChild = cuePointChild->nextSibling()) {
@ -282,7 +282,7 @@ void MatroskaCuePositionUpdater::make(ostream &stream, Diagnostics &diag)
break;
case MatroskaIds::CueTrackPositions:
// write "CueTrackPositions"-element
stream.put(MatroskaIds::CueTrackPositions);
stream.put(static_cast<char>(MatroskaIds::CueTrackPositions));
len = EbmlElement::makeSizeDenotation(m_sizes[cuePointChild], buff);
stream.write(buff, len);
for (EbmlElement *cueTrackPositionsChild = cuePointChild->firstChild(); cueTrackPositionsChild;
@ -314,7 +314,7 @@ void MatroskaCuePositionUpdater::make(ostream &stream, Diagnostics &diag)
break;
case MatroskaIds::CueReference:
// write "CueReference"-element
stream.put(MatroskaIds::CueRefTime);
stream.put(static_cast<char>(MatroskaIds::CueRefTime));
len = EbmlElement::makeSizeDenotation(m_sizes[cueTrackPositionsChild], buff);
stream.write(buff, len);
for (EbmlElement *cueReferenceChild = cueTrackPositionsChild->firstChild(); cueReferenceChild;

View File

@ -26,7 +26,11 @@ void MatroskaSeekInfo::shift(uint64 start, int64 amount)
{
for (auto &info : m_info) {
if (get<1>(info) >= start) {
get<1>(info) += amount;
if (amount > 0) {
get<1>(info) += static_cast<uint64>(amount);
} else {
get<1>(info) -= static_cast<uint64>(-amount);
}
}
}
}
@ -106,6 +110,8 @@ void MatroskaSeekInfo::parse(EbmlElement *seekHeadElement, Diagnostics &diag)
*/
void MatroskaSeekInfo::make(ostream &stream, Diagnostics &diag)
{
VAR_UNUSED(diag)
uint64 totalSize = 0;
char buff0[8];
char buff1[8];
@ -129,16 +135,16 @@ void MatroskaSeekInfo::make(ostream &stream, Diagnostics &diag)
// "Seek" header
BE::getBytes(static_cast<uint16>(MatroskaIds::Seek), buff2);
stream.write(buff2, 2);
stream.put(0x80 | (2 + 1 + sizeLength0 + 2 + 1 + sizeLength1));
stream.put(static_cast<char>(0x80 | (2 + 1 + sizeLength0 + 2 + 1 + sizeLength1)));
// "SeekID" element
BE::getBytes(static_cast<uint16>(MatroskaIds::SeekID), buff2);
stream.write(buff2, 2);
stream.put(0x80 | sizeLength0);
stream.put(static_cast<char>(0x80 | sizeLength0));
stream.write(buff0, sizeLength0);
// "SeekPosition" element
BE::getBytes(static_cast<uint16>(MatroskaIds::SeekPosition), buff2);
stream.write(buff2, 2);
stream.put(0x80 | sizeLength1);
stream.put(static_cast<char>(0x80 | sizeLength1));
stream.write(buff1, sizeLength1);
}
}

View File

@ -111,7 +111,12 @@ void MatroskaTag::parse(EbmlElement &tagElement, Diagnostics &diag)
{
static const string context("parsing Matroska tag");
tagElement.parse(diag);
m_size = tagElement.totalSize();
if (tagElement.totalSize() > numeric_limits<uint32>::max()) {
// FIXME: Support this? Likely not very useful in practise.
diag.emplace_back(DiagLevel::Critical, "Matroska tag is too big.", context);
throw NotImplementedException();
}
m_size = static_cast<uint32>(tagElement.totalSize());
for (EbmlElement *child = tagElement.firstChild(); child; child = child->nextSibling()) {
child->parse(diag);
switch (child->id()) {
@ -292,7 +297,7 @@ void MatroskaTagMaker::make(ostream &stream) const
BE::getBytes(static_cast<uint16>(MatroskaIds::TargetTypeValue), buff);
stream.write(buff, 2);
len = EbmlElement::makeUInteger(t.level(), buff);
stream.put(0x80 | len);
stream.put(static_cast<char>(0x80 | len));
stream.write(buff, len);
}
if (!t.levelName().empty()) {
@ -311,7 +316,7 @@ void MatroskaTagMaker::make(ostream &stream) const
BE::getBytes(pair.first, buff);
for (auto uid : pair.second) {
len = EbmlElement::makeUInteger(uid, buff + 3);
*(buff + 2) = 0x80 | len;
*(buff + 2) = static_cast<char>(0x80 | len);
stream.write(buff, 3 + len);
}
}

View File

@ -70,8 +70,8 @@ void MatroskaTagField::reparse(EbmlElement &simpleTagElement, Diagnostics &diag,
case MatroskaIds::TagBinary:
if (value().isEmpty()) {
unique_ptr<char[]> buffer = make_unique<char[]>(child->dataSize());
child->stream().seekg(child->dataOffset());
child->stream().read(buffer.get(), child->dataSize());
child->stream().seekg(static_cast<streamoff>(child->dataOffset()));
child->stream().read(buffer.get(), static_cast<streamoff>(child->dataSize()));
switch (child->id()) {
case MatroskaIds::TagString:
value().assignData(move(buffer), child->dataSize(), TagDataType::Text, TagTextEncoding::Utf8);

View File

@ -442,13 +442,13 @@ void MatroskaTrack::internalParseHeader(Diagnostics &diag)
}
// read further information from the CodecPrivate element for some codecs
EbmlElement *codecPrivateElement;
switch (m_format.general) {
EbmlElement *codecPrivateElement;
case GeneralMediaFormat::MicrosoftVideoCodecManager:
if ((codecPrivateElement = m_trackElement->childById(MatroskaIds::CodecPrivate, diag))) {
// parse bitmap info header to determine actual format
if (codecPrivateElement->dataSize() >= 0x28) {
m_istream->seekg(codecPrivateElement->dataOffset());
m_istream->seekg(static_cast<streamoff>(codecPrivateElement->dataOffset()));
BitmapInfoHeader bitmapInfoHeader;
bitmapInfoHeader.parse(reader());
m_formatId.reserve(m_formatId.size() + 7);
@ -465,7 +465,7 @@ void MatroskaTrack::internalParseHeader(Diagnostics &diag)
if ((codecPrivateElement = m_trackElement->childById(MatroskaIds::CodecPrivate, diag))) {
// parse WAVE header to determine actual format
if (codecPrivateElement->dataSize() >= 16) {
m_istream->seekg(codecPrivateElement->dataOffset());
m_istream->seekg(static_cast<streamoff>(codecPrivateElement->dataOffset()));
WaveFormatHeader waveFormatHeader;
waveFormatHeader.parse(reader());
WaveAudioStream::addInfo(waveFormatHeader, *this);
@ -502,7 +502,7 @@ void MatroskaTrack::internalParseHeader(Diagnostics &diag)
if ((codecPrivateElement = m_trackElement->childById(MatroskaIds::CodecPrivate, diag))) {
auto avcConfig = make_unique<TagParser::AvcConfiguration>();
try {
m_istream->seekg(codecPrivateElement->dataOffset());
m_istream->seekg(static_cast<streamoff>(codecPrivateElement->dataOffset()));
avcConfig->parse(m_reader, codecPrivateElement->dataSize());
Mp4Track::addInfo(*avcConfig, *this);
} catch (const TruncatedDataException &) {

View File

@ -1005,9 +1005,8 @@ const char *mediaTypeName(MediaType mediaType)
return "Control";
case MediaType::Unknown:
return "Other";
default:
return "";
}
return "";
}
} // namespace TagParser

View File

@ -68,7 +68,7 @@ void Mp4Atom::internalParse(Diagnostics &diag)
context);
throw TruncatedDataException();
}
stream().seekg(startOffset());
stream().seekg(static_cast<streamoff>(startOffset()));
m_dataSize = reader().readUInt32BE();
if (m_dataSize == 0) {
// atom size extends to rest of the file/enclosing container
@ -122,6 +122,11 @@ void Mp4Atom::internalParse(Diagnostics &diag)
* \brief This function helps to write the atom size after writing an atom to a stream.
* \param stream Specifies the stream.
* \param startOffset Specifies the start offset of the atom.
* \remarks The caller must ensure that no seek before \a startOffset happended.
* \throw The caller has to be sure, that the number of written bytes does not exceed
* maximum of an 32-bit unsigned integer. Otherwise the function will throw
* Failure and Mp4Atom::seekBackAndWriteAtomSize64 should be used instead.
* \todo Add a version which creates a diag message (in addition to throwing an exception).
*
* This function seeks back to the start offset and writes the difference between the
* previous offset and the start offset as 32-bit unsigned integer to the \a stream.
@ -130,9 +135,13 @@ void Mp4Atom::internalParse(Diagnostics &diag)
void Mp4Atom::seekBackAndWriteAtomSize(std::ostream &stream, const ostream::pos_type &startOffset)
{
ostream::pos_type currentOffset = stream.tellp();
const auto atomSize(currentOffset - startOffset);
if (atomSize > numeric_limits<uint32>::max()) {
throw Failure();
}
stream.seekp(startOffset);
BinaryWriter writer(&stream);
writer.writeUInt32BE(currentOffset - startOffset);
writer.writeUInt32BE(static_cast<uint32>(atomSize));
stream.seekp(currentOffset);
}
@ -140,6 +149,7 @@ void Mp4Atom::seekBackAndWriteAtomSize(std::ostream &stream, const ostream::pos_
* \brief This function helps to write the atom size after writing an atom to a stream.
* \param stream Specifies the stream.
* \param startOffset Specifies the start offset of the atom.
* \remarks The caller must ensure that no seek before \a startOffset happended.
*
* This function seeks back to the start offset and writes the difference between the
* previous offset and the start offset as 64-bit unsigned integer to the \a stream.
@ -152,7 +162,7 @@ void Mp4Atom::seekBackAndWriteAtomSize64(std::ostream &stream, const ostream::po
BinaryWriter writer(&stream);
writer.writeUInt32BE(1);
stream.seekp(4, ios_base::cur);
writer.writeUInt64BE(currentOffset - startOffset);
writer.writeUInt64BE(static_cast<uint64>(currentOffset - startOffset));
stream.seekp(currentOffset);
}

View File

@ -644,8 +644,8 @@ calculatePadding:
// write padding
if (newPadding) {
// write free atom header
if (newPadding < 0xFFFFFFFF) {
outputWriter.writeUInt32BE(newPadding);
if (newPadding < numeric_limits<uint32>::max()) {
outputWriter.writeUInt32BE(static_cast<uint32>(newPadding));
outputWriter.writeUInt32BE(Mp4AtomIds::Free);
newPadding -= 8;
} else {
@ -678,7 +678,7 @@ calculatePadding:
break;
} else {
// store media data offsets when not writing chunk-by-chunk to be able to update chunk offset table
origMediaDataOffsets.push_back(level0Atom->startOffset());
origMediaDataOffsets.push_back(static_cast<int64>(level0Atom->startOffset()));
newMediaDataOffsets.push_back(outputStream.tellp());
}
FALLTHROUGH;
@ -741,8 +741,8 @@ calculatePadding:
// still chunks to be copied (of this track)?
if (chunkIndexWithinTrack < chunkOffsetTable.size() && chunkIndexWithinTrack < chunkSizesTable.size()) {
// copy chunk, update entry in chunk offset table
sourceStream.seekg(chunkOffsetTable[chunkIndexWithinTrack]);
chunkOffsetTable[chunkIndexWithinTrack] = outputStream.tellp();
sourceStream.seekg(static_cast<streamoff>(chunkOffsetTable[chunkIndexWithinTrack]));
chunkOffsetTable[chunkIndexWithinTrack] = static_cast<uint64>(outputStream.tellp());
copyHelper.copy(sourceStream, outputStream, chunkSizesTable[chunkIndexWithinTrack]);
// update counter / status
@ -916,12 +916,13 @@ void Mp4Container::updateOffsets(const std::vector<int64> &oldMdatOffsets, const
uint64 off = reader().readUInt64BE();
for (auto iOld = oldMdatOffsets.cbegin(), iNew = newMdatOffsets.cbegin(), end = oldMdatOffsets.cend(); iOld != end;
++iOld, ++iNew) {
if (off >= static_cast<uint64>(*iOld)) {
off += (*iNew - *iOld);
stream().seekp(static_cast<iostream::off_type>(tfhdAtom->dataOffset()) + 8);
writer().writeUInt64BE(off);
break;
if (off < static_cast<uint64>(*iOld)) {
continue;
}
off += static_cast<uint64>(*iNew - *iOld);
stream().seekp(static_cast<iostream::off_type>(tfhdAtom->dataOffset()) + 8);
writer().writeUInt64BE(off);
break;
}
}
switch (tfhdAtomCount) {

View File

@ -27,10 +27,12 @@ Mp4ExtendedFieldId::Mp4ExtendedFieldId(KnownField field)
{
switch (field) {
case KnownField::EncoderSettings:
mean = Mp4TagExtendedMeanIds::iTunes, name = Mp4TagExtendedNameIds::cdec;
mean = Mp4TagExtendedMeanIds::iTunes;
name = Mp4TagExtendedNameIds::cdec;
break;
case KnownField::RecordLabel:
mean = Mp4TagExtendedMeanIds::iTunes, name = Mp4TagExtendedNameIds::label;
mean = Mp4TagExtendedMeanIds::iTunes;
name = Mp4TagExtendedNameIds::label;
updateOnly = true; // set record label via extended field only if extended field is already present
break;
default:
@ -319,7 +321,11 @@ void Mp4Tag::parse(Mp4Atom &metaAtom, Diagnostics &diag)
static const string context("parsing MP4 tag");
istream &stream = metaAtom.container().stream();
BinaryReader &reader = metaAtom.container().reader();
m_size = metaAtom.totalSize();
if (metaAtom.totalSize() > numeric_limits<uint32>::max()) {
diag.emplace_back(DiagLevel::Critical, "Can't handle such big \"meta\" atoms.", context);
throw NotImplementedException();
}
m_size = static_cast<uint32>(metaAtom.totalSize());
Mp4Atom *subAtom = nullptr;
try {
metaAtom.childById(Mp4AtomIds::HandlerReference, diag);
@ -327,7 +333,7 @@ void Mp4Tag::parse(Mp4Atom &metaAtom, Diagnostics &diag)
diag.emplace_back(DiagLevel::Critical, "Unable to parse child atoms of meta atom (stores hdlr and ilst atoms).", context);
}
if (subAtom) {
stream.seekg(subAtom->startOffset() + subAtom->headerSize());
stream.seekg(static_cast<streamoff>(subAtom->startOffset() + subAtom->headerSize()));
int versionByte = reader.readByte();
if (versionByte != 0) {
diag.emplace_back(DiagLevel::Warning, "Version is unknown.", context);
@ -351,20 +357,19 @@ void Mp4Tag::parse(Mp4Atom &metaAtom, Diagnostics &diag)
} catch (const Failure &) {
diag.emplace_back(DiagLevel::Critical, "Unable to parse child atoms of meta atom (stores hdlr and ilst atoms).", context);
}
if (subAtom) {
for (auto *child = subAtom->firstChild(); child; child = child->nextSibling()) {
Mp4TagField tagField;
try {
child->parse(diag);
tagField.reparse(*child, diag);
fields().emplace(child->id(), move(tagField));
} catch (const Failure &) {
}
}
} else {
if (!subAtom) {
diag.emplace_back(DiagLevel::Warning, "No ilst atom found (stores attached meta information).", context);
throw NoDataFoundException();
}
for (auto *child = subAtom->firstChild(); child; child = child->nextSibling()) {
Mp4TagField tagField;
try {
child->parse(diag);
tagField.reparse(*child, diag);
fields().emplace(child->id(), move(tagField));
} catch (const Failure &) {
}
}
}
/*!
@ -429,6 +434,10 @@ Mp4TagMaker::Mp4TagMaker(Mp4Tag &tag, Diagnostics &diag)
if (m_ilstSize != 8) {
m_metaSize += m_ilstSize;
}
if (m_metaSize >= numeric_limits<uint32>::max()) {
diag.emplace_back(DiagLevel::Critical, "Making such big tags is not implemented.", "making MP4 tag");
throw NotImplementedException();
}
}
/*!
@ -442,7 +451,7 @@ void Mp4TagMaker::make(ostream &stream, Diagnostics &diag)
{
// write meta head
BinaryWriter writer(&stream);
writer.writeUInt32BE(m_metaSize);
writer.writeUInt32BE(static_cast<uint32>(m_metaSize));
writer.writeUInt32BE(Mp4AtomIds::Meta);
// write hdlr atom
static const byte hdlrData[37] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x68, 0x64, 0x6C, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -450,7 +459,7 @@ void Mp4TagMaker::make(ostream &stream, Diagnostics &diag)
stream.write(reinterpret_cast<const char *>(hdlrData), sizeof(hdlrData));
if (m_ilstSize != 8) {
// write ilst head
writer.writeUInt32BE(m_ilstSize);
writer.writeUInt32BE(static_cast<uint32>(m_ilstSize));
writer.writeUInt32BE(Mp4AtomIds::ItunesList);
// write fields
for (auto &maker : m_maker) {

View File

@ -98,7 +98,7 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
}
continue;
}
stream.seekg(dataAtom->dataOffset());
stream.seekg(static_cast<streamoff>(dataAtom->dataOffset()));
if (reader.readByte() != 0) {
diag.emplace_back(DiagLevel::Warning,
"The version indicator byte is not zero, the tag atom might be unsupported and hence not be parsed correctly.", context);
@ -117,7 +117,7 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
switch (m_parsedRawDataType) {
case RawDataType::Utf8:
case RawDataType::Utf16:
stream.seekg(dataAtom->dataOffset() + 8);
stream.seekg(static_cast<streamoff>(dataAtom->dataOffset() + 8));
value().assignText(reader.readString(dataAtom->dataSize() - 8),
(m_parsedRawDataType == RawDataType::Utf16) ? TagTextEncoding::Utf16BigEndian : TagTextEncoding::Utf8);
break;
@ -140,10 +140,10 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
break;
default:;
}
const streamsize coverSize = dataAtom->dataSize() - 8;
unique_ptr<char[]> coverData = make_unique<char[]>(coverSize);
const auto coverSize = static_cast<streamoff>(dataAtom->dataSize() - 8);
auto coverData = make_unique<char[]>(static_cast<size_t>(coverSize));
stream.read(coverData.get(), coverSize);
value().assignData(move(coverData), coverSize, TagDataType::Picture);
value().assignData(move(coverData), static_cast<size_t>(coverSize), TagDataType::Picture);
break;
}
case RawDataType::BeSignedInt: {
@ -215,13 +215,13 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
}
break;
default: // no supported data type, read raw data
streamsize dataSize = dataAtom->dataSize() - 8;
unique_ptr<char[]> data = make_unique<char[]>(dataSize);
const auto dataSize = static_cast<streamsize>(dataAtom->dataSize() - 8);
auto data = make_unique<char[]>(static_cast<size_t>(dataSize));
stream.read(data.get(), dataSize);
if (ilstChild.id() == Mp4TagAtomIds::Cover) {
value().assignData(move(data), dataSize, TagDataType::Picture);
value().assignData(move(data), static_cast<size_t>(dataSize), TagDataType::Picture);
} else {
value().assignData(move(data), dataSize, TagDataType::Undefined);
value().assignData(move(data), static_cast<size_t>(dataSize), TagDataType::Undefined);
}
}
}
@ -237,7 +237,7 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
}
continue;
}
stream.seekg(dataAtom->dataOffset() + 4);
stream.seekg(static_cast<streamoff>(dataAtom->dataOffset() + 4));
m_mean = reader.readString(dataAtom->dataSize() - 4);
} else if (dataAtom->id() == Mp4AtomIds::Name) {
if (dataAtom->dataSize() < 4) {
@ -251,7 +251,7 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
}
continue;
}
stream.seekg(dataAtom->dataOffset() + 4);
stream.seekg(static_cast<streamoff>(dataAtom->dataOffset() + 4));
m_name = reader.readString(dataAtom->dataSize() - 4);
} else {
diag.emplace_back(DiagLevel::Warning,
@ -501,10 +501,10 @@ Mp4TagFieldMaker::Mp4TagFieldMaker(Mp4TagField &field, Diagnostics &diag)
if (number <= numeric_limits<uint16>::max() && number >= numeric_limits<uint16>::min()) {
m_writer.writeUInt16BE(static_cast<uint16>(number));
} else if (number > 0) {
m_writer.writeUInt32BE(number);
m_writer.writeUInt32BE(static_cast<uint32>(number));
} else {
throw ConversionException(
"Negative integer can not be assigned to the field with the id \"" % interpretIntegerAsString<uint32>(m_field.id()) + "\".");
"Negative integer can not be assigned to the field with the ID \"" % interpretIntegerAsString<uint32>(m_field.id()) + "\".");
}
break;
}
@ -531,7 +531,7 @@ Mp4TagFieldMaker::Mp4TagFieldMaker(Mp4TagField &field, Diagnostics &diag)
break;
}
case Mp4TagAtomIds::PreDefinedGenre:
m_writer.writeUInt16BE(m_field.value().toStandardGenreIndex());
m_writer.writeUInt16BE(static_cast<uint16>(m_field.value().toStandardGenreIndex()));
break;
default:; // leave converted data empty to write original data later
}
@ -553,6 +553,10 @@ Mp4TagFieldMaker::Mp4TagFieldMaker(Mp4TagField &field, Diagnostics &diag)
m_totalSize = 8 // calculate entire size
+ (m_field.name().empty() ? 0 : (12 + m_field.name().length())) + (m_field.mean().empty() ? 0 : (12 + m_field.mean().length()))
+ (m_dataSize ? (16 + m_dataSize) : 0);
if (m_totalSize > numeric_limits<uint32>::max()) {
diag.emplace_back(DiagLevel::Critical, "Making a such big MP4 tag field is not supported.", context);
throw NotImplementedException();
}
}
/*!
@ -566,25 +570,25 @@ void Mp4TagFieldMaker::make(ostream &stream)
{
m_writer.setStream(&stream);
// size of entire tag atom
m_writer.writeUInt32BE(m_totalSize);
m_writer.writeUInt32BE(static_cast<uint32>(m_totalSize));
// id of tag atom
m_writer.writeUInt32BE(m_field.id());
if (!m_field.mean().empty()) {
// write "mean"
m_writer.writeUInt32BE(12 + m_field.mean().size());
m_writer.writeUInt32BE(static_cast<uint32>(12 + m_field.mean().size()));
m_writer.writeUInt32BE(Mp4AtomIds::Mean);
m_writer.writeUInt32BE(0);
m_writer.writeString(m_field.mean());
}
if (!m_field.name().empty()) {
// write "name"
m_writer.writeUInt32BE(12 + m_field.name().length());
m_writer.writeUInt32BE(static_cast<uint32>(12 + m_field.name().length()));
m_writer.writeUInt32BE(Mp4AtomIds::Name);
m_writer.writeUInt32BE(0);
m_writer.writeString(m_field.name());
}
if (!m_field.value().isEmpty()) { // write data
m_writer.writeUInt32BE(16 + m_dataSize); // size of data atom
m_writer.writeUInt32BE(static_cast<uint32>(16 + m_dataSize)); // size of data atom
m_writer.writeUInt32BE(Mp4AtomIds::Data); // id of data atom
m_writer.writeByte(0); // version
m_writer.writeUInt24BE(m_rawDataType);
@ -595,7 +599,7 @@ void Mp4TagFieldMaker::make(ostream &stream)
stream << m_convertedData.rdbuf();
} else {
// no conversion was needed, write data directly from tag value
stream.write(m_field.value().dataPointer(), m_field.value().dataSize());
stream.write(m_field.value().dataPointer(), static_cast<streamoff>(m_field.value().dataSize()));
}
}
}

View File

@ -1219,8 +1219,8 @@ void Mp4Track::makeTrackHeader(Diagnostics &diag)
// make further values, either from existing tkhd atom or just some defaults
if (info.canUseExisting) {
// write all bytes after the previously determined additionalDataOffset
m_ostream->write(
m_tkhdAtom->buffer().get() + m_tkhdAtom->headerSize() + info.additionalDataOffset, m_tkhdAtom->dataSize() - info.additionalDataOffset);
m_ostream->write(m_tkhdAtom->buffer().get() + m_tkhdAtom->headerSize() + info.additionalDataOffset,
static_cast<streamoff>(m_tkhdAtom->dataSize() - info.additionalDataOffset));
// discard the buffer again if it wasn't present before
if (info.discardBuffer) {
m_tkhdAtom->discardBuffer();

View File

@ -62,7 +62,7 @@ void Mpeg4Descriptor::internalParse(Diagnostics &diag)
"parsing MPEG-4 descriptor");
throw TruncatedDataException();
}
stream().seekg(startOffset());
stream().seekg(static_cast<streamoff>(startOffset()));
// read ID
m_idLength = m_sizeLength = 1;
m_id = reader().readByte();
@ -76,18 +76,20 @@ void Mpeg4Descriptor::internalParse(Diagnostics &diag)
// check whether the denoted data size exceeds the available data size
if (maxTotalSize() < totalSize()) {
diag.emplace_back(DiagLevel::Warning, "The descriptor seems to be truncated; unable to parse siblings of that ", parsingContext());
m_dataSize = maxTotalSize(); // using max size instead
m_dataSize = static_cast<uint32>(maxTotalSize()); // using max size instead
}
m_firstChild.reset();
Mpeg4Descriptor *sibling = nullptr;
if (totalSize() < maxTotalSize()) {
if (parent()) {
sibling = new Mpeg4Descriptor(*(parent()), startOffset() + totalSize());
} else {
sibling = new Mpeg4Descriptor(container(), startOffset() + totalSize(), maxTotalSize() - totalSize());
}
// check for siblings
if (totalSize() >= maxTotalSize()) {
m_nextSibling.reset();
return;
}
if (parent()) {
m_nextSibling.reset(new Mpeg4Descriptor(*(parent()), startOffset() + totalSize()));
} else {
m_nextSibling.reset(new Mpeg4Descriptor(container(), startOffset() + totalSize(), maxTotalSize() - totalSize()));
}
m_nextSibling.reset(sibling);
}
} // namespace TagParser

View File

@ -23,7 +23,7 @@ namespace TagParser {
void MpegAudioFrameStream::addInfo(const MpegAudioFrame &frame, AbstractTrack &track)
{
track.m_version = frame.mpegVersion();
track.m_format = MediaFormat(GeneralMediaFormat::Mpeg1Audio, frame.layer());
track.m_format = MediaFormat(GeneralMediaFormat::Mpeg1Audio, static_cast<unsigned char>(frame.layer()));
track.m_channelCount = frame.channelMode() == MpegChannelMode::SingleChannel ? 1 : 2;
track.m_channelConfig = static_cast<byte>(frame.channelMode());
track.m_samplingFrequency = frame.samplingFrequency();
@ -42,7 +42,7 @@ void MpegAudioFrameStream::internalParseHeader(Diagnostics &diag)
} else {
m_size = static_cast<uint64>(m_istream->tellg()) + 125u - m_startOffset;
}
m_istream->seekg(m_startOffset, ios_base::beg);
m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg);
// parse frame header
m_frames.emplace_back();
MpegAudioFrame &frame = m_frames.back();
@ -60,7 +60,7 @@ void MpegAudioFrameStream::internalParseHeader(Diagnostics &diag)
? ((static_cast<double>(m_size) * 8.0)
/ (static_cast<double>(frame.xingFrameCount() * frame.sampleCount()) / static_cast<double>(frame.samplingFrequency())) / 1024.0)
: frame.bitrate();
m_duration = TimeSpan::fromSeconds(static_cast<double>(m_size) / (m_bytesPerSecond = m_bitrate * 125));
m_duration = TimeSpan::fromSeconds(static_cast<double>(m_size) / (m_bytesPerSecond = static_cast<uint32>(m_bitrate * 125)));
}
} // namespace TagParser

View File

@ -112,6 +112,7 @@ OggVorbisComment *OggContainer::createTag(const TagTarget &target)
} else {
// TODO: error handling?
}
break;
default:;
}
// TODO: allow adding tags to FLAC tracks (not really important, because a tag should always be present)
@ -349,7 +350,7 @@ void OggContainer::makeVorbisCommentSegment(stringstream &buffer, CopyHelper<653
comment->make(buffer, VorbisCommentFlags::NoSignature | VorbisCommentFlags::NoFramingByte, diag);
// finally make the header
header.setDataSize(buffer.tellp() - offset - 4);
header.setDataSize(static_cast<uint32>(buffer.tellp() - offset - 4));
if (header.dataSize() > 0xFFFFFF) {
diag.emplace_back(
DiagLevel::Critical, "Size of Vorbis comment exceeds size limit for FLAC \"METADATA_BLOCK_HEADER\".", "making Vorbis Comment");
@ -361,7 +362,7 @@ void OggContainer::makeVorbisCommentSegment(stringstream &buffer, CopyHelper<653
}
default:;
}
newSegmentSizes.push_back(buffer.tellp() - offset);
newSegmentSizes.push_back(static_cast<uint32>(buffer.tellp() - offset));
}
void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback &progress)
@ -430,51 +431,52 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
uint64 segmentOffset = m_iterator.currentSegmentOffset();
vector<uint32>::size_type segmentIndex = 0;
for (const auto segmentSize : currentPage.segmentSizes()) {
if (segmentSize) {
// check whether this segment contains the Vorbis Comment
if ((m_iterator.currentPageIndex() >= currentParams->firstPageIndex && segmentIndex >= currentParams->firstSegmentIndex)
&& (m_iterator.currentPageIndex() <= currentParams->lastPageIndex && segmentIndex <= currentParams->lastSegmentIndex)) {
// prevent making the comment twice if it spreads over multiple pages/segments
if (!currentParams->removed
&& ((m_iterator.currentPageIndex() == currentParams->firstPageIndex
&& m_iterator.currentSegmentIndex() == currentParams->firstSegmentIndex))) {
makeVorbisCommentSegment(buffer, copyHelper, newSegmentSizes, currentComment, currentParams, diag);
}
if (!segmentSize) {
++segmentIndex;
continue;
}
// check whether this segment contains the Vorbis Comment
if ((m_iterator.currentPageIndex() >= currentParams->firstPageIndex && segmentIndex >= currentParams->firstSegmentIndex)
&& (m_iterator.currentPageIndex() <= currentParams->lastPageIndex && segmentIndex <= currentParams->lastSegmentIndex)) {
// prevent making the comment twice if it spreads over multiple pages/segments
if (!currentParams->removed
&& ((m_iterator.currentPageIndex() == currentParams->firstPageIndex
&& m_iterator.currentSegmentIndex() == currentParams->firstSegmentIndex))) {
makeVorbisCommentSegment(buffer, copyHelper, newSegmentSizes, currentComment, currentParams, diag);
}
// proceed with next comment?
if (m_iterator.currentPageIndex() > currentParams->lastPageIndex
|| (m_iterator.currentPageIndex() == currentParams->lastPageIndex
&& segmentIndex > currentParams->lastSegmentIndex)) {
if (++tagIterator != tagEnd) {
currentParams = &(currentComment = tagIterator->get())->oggParams();
} else {
currentComment = nullptr;
currentParams = nullptr;
}
}
} else {
// copy other segments unchanged
backupStream.seekg(segmentOffset);
copyHelper.copy(backupStream, buffer, segmentSize);
newSegmentSizes.push_back(segmentSize);
// check whether there is a new comment to be inserted into the current page
if (m_iterator.currentPageIndex() == currentParams->lastPageIndex
&& currentParams->firstSegmentIndex == numeric_limits<size_t>::max()) {
if (!currentParams->removed) {
makeVorbisCommentSegment(buffer, copyHelper, newSegmentSizes, currentComment, currentParams, diag);
}
// proceed with next comment
if (++tagIterator != tagEnd) {
currentParams = &(currentComment = tagIterator->get())->oggParams();
} else {
currentComment = nullptr;
currentParams = nullptr;
}
// proceed with next comment?
if (m_iterator.currentPageIndex() > currentParams->lastPageIndex
|| (m_iterator.currentPageIndex() == currentParams->lastPageIndex && segmentIndex > currentParams->lastSegmentIndex)) {
if (++tagIterator != tagEnd) {
currentParams = &(currentComment = tagIterator->get())->oggParams();
} else {
currentComment = nullptr;
currentParams = nullptr;
}
}
} else {
// copy other segments unchanged
backupStream.seekg(static_cast<streamoff>(segmentOffset));
copyHelper.copy(backupStream, buffer, segmentSize);
newSegmentSizes.push_back(segmentSize);
// check whether there is a new comment to be inserted into the current page
if (m_iterator.currentPageIndex() == currentParams->lastPageIndex
&& currentParams->firstSegmentIndex == numeric_limits<size_t>::max()) {
if (!currentParams->removed) {
makeVorbisCommentSegment(buffer, copyHelper, newSegmentSizes, currentComment, currentParams, diag);
}
// proceed with next comment
if (++tagIterator != tagEnd) {
currentParams = &(currentComment = tagIterator->get())->oggParams();
} else {
currentComment = nullptr;
currentParams = nullptr;
}
}
segmentOffset += segmentSize;
}
segmentOffset += segmentSize;
++segmentIndex;
}
@ -486,12 +488,12 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
// write pages until all data in the buffer is written
while (newSegmentSizesIterator != newSegmentSizesEnd) {
// write header
backupStream.seekg(currentPage.startOffset());
updatedPageOffsets.push_back(stream().tellp()); // memorize offset to update checksum later
backupStream.seekg(static_cast<streamoff>(currentPage.startOffset()));
updatedPageOffsets.push_back(static_cast<uint64>(stream().tellp())); // memorize offset to update checksum later
copyHelper.copy(backupStream, stream(), 27); // just copy header from original file
// set continue flag
stream().seekp(-22, ios_base::cur);
stream().put(currentPage.headerTypeFlag() & (continuePreviousSegment ? 0xFF : 0xFE));
stream().put(static_cast<char>(currentPage.headerTypeFlag() & (continuePreviousSegment ? 0xFF : 0xFE)));
continuePreviousSegment = true;
// adjust page sequence number
stream().seekp(12, ios_base::cur);
@ -503,14 +505,14 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
uint32 currentSize = 0;
while (bytesLeft && segmentSizesWritten < 0xFF) {
while (bytesLeft >= 0xFF && segmentSizesWritten < 0xFF) {
stream().put(0xFF);
stream().put(static_cast<char>(0xFF));
currentSize += 0xFF;
bytesLeft -= 0xFF;
++segmentSizesWritten;
}
if (bytesLeft && segmentSizesWritten < 0xFF) {
// bytes left is here < 0xFF
stream().put(bytesLeft);
stream().put(static_cast<char>(bytesLeft));
currentSize += bytesLeft;
bytesLeft = 0;
++segmentSizesWritten;
@ -534,7 +536,7 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
// -> write segment table size (segmentSizesWritten) and segment data
// -> seek back and write updated page segment number
stream().seekp(-1 - segmentSizesWritten, ios_base::cur);
stream().put(segmentSizesWritten);
stream().put(static_cast<char>(segmentSizesWritten));
stream().seekp(segmentSizesWritten, ios_base::cur);
// -> write actual page data
copyHelper.copy(buffer, stream(), currentSize);
@ -546,8 +548,8 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
} else {
if (pageSequenceNumber != m_iterator.currentPageIndex()) {
// just update page sequence number
backupStream.seekg(currentPage.startOffset());
updatedPageOffsets.push_back(stream().tellp()); // memorize offset to update checksum later
backupStream.seekg(static_cast<streamoff>(currentPage.startOffset()));
updatedPageOffsets.push_back(static_cast<uint64>(stream().tellp())); // memorize offset to update checksum later
copyHelper.copy(backupStream, stream(), 27);
stream().seekp(-9, ios_base::cur);
writer().writeUInt32LE(pageSequenceNumber);
@ -555,7 +557,7 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
copyHelper.copy(backupStream, stream(), pageSize - 27);
} else {
// copy page unchanged
backupStream.seekg(currentPage.startOffset());
backupStream.seekg(static_cast<streamoff>(currentPage.startOffset()));
copyHelper.copy(backupStream, stream(), pageSize);
}
++pageSequenceNumber;
@ -563,7 +565,7 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
}
// report new size
fileInfo().reportSizeChanged(stream().tellp());
fileInfo().reportSizeChanged(static_cast<uint64>(stream().tellp()));
// "save as path" is now the regular path
if (!fileInfo().saveFilePath().empty()) {

View File

@ -136,9 +136,9 @@ void OggIterator::read(char *buffer, size_t count)
size_t bytesRead = 0;
while (*this && count) {
const uint32 available = currentSegmentSize() - m_bytesRead;
stream().seekg(currentCharacterOffset());
stream().seekg(static_cast<streamoff>(currentCharacterOffset()));
if (count <= available) {
stream().read(buffer + bytesRead, count);
stream().read(buffer + bytesRead, static_cast<streamoff>(count));
m_bytesRead += count;
return;
} else {
@ -171,9 +171,9 @@ size_t OggIterator::readAll(char *buffer, size_t max)
size_t bytesRead = 0;
while (*this && max) {
const uint32 available = currentSegmentSize() - m_bytesRead;
stream().seekg(currentCharacterOffset());
stream().seekg(static_cast<streamoff>(currentCharacterOffset()));
if (max <= available) {
stream().read(buffer + bytesRead, max);
stream().read(buffer + bytesRead, static_cast<streamoff>(max));
m_bytesRead += max;
return bytesRead + max;
} else {
@ -243,7 +243,7 @@ bool OggIterator::resyncAt(uint64 offset)
}
// find capture pattern 'OggS'
stream().seekg(offset);
stream().seekg(static_cast<streamoff>(offset));
byte lettersFound = 0;
for (uint64 bytesAvailable = max<uint64>(streamSize() - offset, 65307ul); bytesAvailable >= 27; --bytesAvailable) {
switch (static_cast<char>(stream().get())) {

View File

@ -25,7 +25,7 @@ namespace TagParser {
void OggPage::parseHeader(istream &stream, uint64 startOffset, int32 maxSize)
{
// prepare reading
stream.seekg(startOffset);
stream.seekg(static_cast<streamoff>(startOffset));
BinaryReader reader(&stream);
if (maxSize < 27) {
throw TruncatedDataException();
@ -74,7 +74,7 @@ void OggPage::parseHeader(istream &stream, uint64 startOffset, int32 maxSize)
*/
uint32 OggPage::computeChecksum(istream &stream, uint64 startOffset)
{
stream.seekg(startOffset);
stream.seekg(static_cast<streamoff>(startOffset));
uint32 crc = 0x0;
byte value, segmentTableSize = 0, segmentTableIndex = 0;
for (uint32 i = 0, segmentLength = 27; i != segmentLength; ++i) {
@ -82,6 +82,7 @@ uint32 OggPage::computeChecksum(istream &stream, uint64 startOffset)
case 22:
// bytes 22, 23, 24, 25 hold denoted checksum and must be set to zero
stream.seekg(4, ios_base::cur);
FALLTHROUGH;
case 23:
case 24:
case 25:
@ -89,10 +90,10 @@ uint32 OggPage::computeChecksum(istream &stream, uint64 startOffset)
break;
case 26:
// byte 26 holds the number of segment sizes
segmentLength += (segmentTableSize = (value = stream.get()));
segmentLength += (segmentTableSize = (value = static_cast<byte>(stream.get())));
break;
default:
value = stream.get();
value = static_cast<byte>(stream.get());
if (i > 26 && segmentTableIndex < segmentTableSize) {
// bytes 27 to (27 + segment size count) hold page size
segmentLength += value;
@ -112,7 +113,7 @@ void OggPage::updateChecksum(iostream &stream, uint64 startOffset)
{
char buff[4];
LE::getBytes(computeChecksum(stream, startOffset), buff);
stream.seekp(startOffset + 22);
stream.seekp(static_cast<streamoff>(startOffset + 22));
stream.write(buff, sizeof(buff));
}
@ -124,11 +125,11 @@ uint32 OggPage::makeSegmentSizeDenotation(ostream &stream, uint32 size)
{
uint32 bytesWritten = 1;
while (size >= 0xff) {
stream.put(0xff);
stream.put(static_cast<char>(0xff));
size -= 0xff;
++bytesWritten;
}
stream.put(size);
stream.put(static_cast<char>(size));
return bytesWritten;
}

View File

@ -65,7 +65,7 @@ void OggStream::internalParseHeader(Diagnostics &diag)
const uint32 currentSize = iterator.currentSegmentSize();
if (currentSize >= 8) {
// determine stream format
inputStream().seekg(iterator.currentSegmentOffset());
inputStream().seekg(static_cast<streamoff>(iterator.currentSegmentOffset()));
const uint64 sig = reader().readUInt64BE();
if ((sig & 0x00ffffffffffff00u) == 0x00766F7262697300u) {

View File

@ -77,21 +77,22 @@ TagValue::TagValue(const TagValue &other)
*/
TagValue &TagValue::operator=(const TagValue &other)
{
if (this != &other) {
m_size = other.m_size;
m_type = other.m_type;
m_desc = other.m_desc;
m_mimeType = other.m_mimeType;
m_language = other.m_language;
m_labeledAsReadonly = other.m_labeledAsReadonly;
m_encoding = other.m_encoding;
m_descEncoding = other.m_descEncoding;
if (other.isEmpty()) {
m_ptr.reset();
} else {
m_ptr = make_unique<char[]>(m_size);
std::copy(other.m_ptr.get(), other.m_ptr.get() + other.m_size, m_ptr.get());
}
if (this == &other) {
return *this;
}
m_size = other.m_size;
m_type = other.m_type;
m_desc = other.m_desc;
m_mimeType = other.m_mimeType;
m_language = other.m_language;
m_labeledAsReadonly = other.m_labeledAsReadonly;
m_encoding = other.m_encoding;
m_descEncoding = other.m_descEncoding;
if (other.isEmpty()) {
m_ptr.reset();
} else {
m_ptr = make_unique<char[]>(m_size);
std::copy(other.m_ptr.get(), other.m_ptr.get() + other.m_size, m_ptr.get());
}
return *this;
}

View File

@ -396,7 +396,7 @@ inline void TagValue::clearDataAndMetadata()
* \brief Returns the size of the assigned value in bytes.
* \remarks Meta data such as description and MIME type is not considered as part of the assigned value.
*/
inline size_t TagValue::dataSize() const
inline std::size_t TagValue::dataSize() const
{
return m_size;
}

View File

@ -191,6 +191,9 @@ bool VorbisCommentField::make(BinaryWriter &writer, VorbisCommentFlags flags, Di
pictureBlock.make(bufferStream);
valueString = encodeBase64(reinterpret_cast<byte *>(buffer.get()), requiredSize);
} catch (const Failure &) {
diag.emplace_back(DiagLevel::Critical, "Unable to make METADATA_BLOCK_PICTURE struct from the assigned value.", context);
throw;
} catch (...) {
catchIoFailure();
diag.emplace_back(DiagLevel::Critical, "An IO error occured when writing the METADATA_BLOCK_PICTURE struct.", context);
@ -200,7 +203,12 @@ bool VorbisCommentField::make(BinaryWriter &writer, VorbisCommentFlags flags, Di
// make normal string value
valueString = value().toString();
}
writer.writeUInt32LE(id().size() + 1 + valueString.size());
const auto size(valueString.size() + id().size() + 1);
if (size > numeric_limits<uint32>::max()) {
diag.emplace_back(DiagLevel::Critical, "Assigned value exceeds the maximum size.", context);
throw InvalidDataException();
}
writer.writeUInt32LE(static_cast<uint32>(size));
writer.writeString(id());
writer.writeChar('=');
writer.writeString(valueString);

View File

@ -114,7 +114,7 @@ void WaveAudioStream::internalParseHeader(Diagnostics &diag)
if (m_reader.readUInt32BE() != 0x52494646u) {
throw NoDataFoundException();
}
m_istream->seekg(m_startOffset + 8);
m_istream->seekg(static_cast<streamoff>(m_startOffset + 8));
if (m_reader.readUInt32BE() != 0x57415645u) {
throw NoDataFoundException();
}
@ -133,7 +133,7 @@ void WaveAudioStream::internalParseHeader(Diagnostics &diag)
}
break;
case 0x64617461u:
m_dataOffset = m_istream->tellg();
m_dataOffset = static_cast<uint64>(m_istream->tellg());
m_size = restHeaderLen;
m_sampleCount = m_size / m_chunkSize;
m_duration = TimeSpan::fromSeconds(static_cast<double>(m_sampleCount) / static_cast<double>(m_samplingFrequency));
@ -145,7 +145,7 @@ void WaveAudioStream::internalParseHeader(Diagnostics &diag)
if (m_format.general != GeneralMediaFormat::Mpeg1Audio || !m_dataOffset) {
return;
}
m_istream->seekg(m_dataOffset);
m_istream->seekg(static_cast<streamoff>(m_dataOffset));
MpegAudioFrame frame;
frame.parseHeader(m_reader);
MpegAudioFrameStream::addInfo(frame, *this);
@ -153,7 +153,7 @@ void WaveAudioStream::internalParseHeader(Diagnostics &diag)
? ((static_cast<double>(m_size) * 8.0)
/ (static_cast<double>(frame.xingFrameCount() * frame.sampleCount()) / static_cast<double>(frame.samplingFrequency())) / 1024.0)
: frame.bitrate();
m_bytesPerSecond = m_bitrate * 125;
m_bytesPerSecond = static_cast<uint32>(m_bitrate * 125);
m_duration = TimeSpan::fromSeconds(static_cast<double>(m_size) / (m_bitrate * 128.0));
}