// Read the version number
- d->version = data.mid(8, 4).toUInt(false);
+ d->version = data.toUInt(8, false);
// Read the tag size
- d->tagSize = data.mid(12, 4).toUInt(false);
+ d->tagSize = data.toUInt(12, false);
// Read the item count
- d->itemCount = data.mid(16, 4).toUInt(false);
+ d->itemCount = data.toUInt(16, false);
// Read the flags
- std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.mid(20, 4).toUInt(false)));
+ std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.toUInt(20, false)));
d->headerPresent = flags[31];
d->footerPresent = !flags[30];
return;
}
- uint valueLength = data.mid(0, 4).toUInt(false);
- uint flags = data.mid(4, 4).toUInt(false);
+ const uint valueLength = data.toUInt(0, false);
+ const uint flags = data.toUInt(4, false);
d->key = String(data.mid(8), String::UTF8);
// Then we read the header common for all versions of APE
d->file->seek(offset);
- ByteVector commonHeader=d->file->readBlock(6);
+ ByteVector commonHeader = d->file->readBlock(6);
if(!commonHeader.startsWith("MAC "))
return;
- d->version = commonHeader.mid(4).toUInt(false);
+ d->version = commonHeader.toUShort(4, false);
if(d->version >= 3980) {
analyzeCurrent();
// Read the descriptor
d->file->seek(2, File::Current);
ByteVector descriptor = d->file->readBlock(44);
- uint descriptorBytes = descriptor.mid(0,4).toUInt(false);
+ const uint descriptorBytes = descriptor.toUInt(0, false);
if ((descriptorBytes - 52) > 0)
d->file->seek(descriptorBytes - 52, File::Current);
ByteVector header = d->file->readBlock(24);
// Get the APE info
- d->channels = header.mid(18, 2).toShort(false);
- d->sampleRate = header.mid(20, 4).toUInt(false);
- d->bitsPerSample = header.mid(16, 2).toShort(false);
+ d->channels = header.toShort(18, false);
+ d->sampleRate = header.toUInt(20, false);
+ d->bitsPerSample = header.toShort(16, false);
//d->compressionLevel =
- uint totalFrames = header.mid(12, 4).toUInt(false);
- uint blocksPerFrame = header.mid(4, 4).toUInt(false);
- uint finalFrameBlocks = header.mid(8, 4).toUInt(false);
+ const uint totalFrames = header.toUInt(12, false);
+ const uint blocksPerFrame = header.toUInt(4, false);
+ const uint finalFrameBlocks = header.toUInt(8, false);
d->sampleFrames = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0;
d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0;
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
void APE::Properties::analyzeOld()
{
ByteVector header = d->file->readBlock(26);
- uint totalFrames = header.mid(18, 4).toUInt(false);
+ const uint totalFrames = header.toUInt(18, false);
// Fail on 0 length APE files (catches non-finalized APE files)
if(totalFrames == 0)
return;
- short compressionLevel = header.mid(0, 2).toShort(false);
+ const short compressionLevel = header.toShort(0, false);
uint blocksPerFrame;
if(d->version >= 3950)
blocksPerFrame = 73728 * 4;
blocksPerFrame = 73728;
else
blocksPerFrame = 9216;
- d->channels = header.mid(4, 2).toShort(false);
- d->sampleRate = header.mid(6, 4).toUInt(false);
- uint finalFrameBlocks = header.mid(22, 4).toUInt(false);
- uint totalBlocks = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0;
+ d->channels = header.toShort(4, false);
+ d->sampleRate = header.toUInt(6, false);
+ const uint finalFrameBlocks = header.toUInt(22, false);
+ const uint totalBlocks
+ = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0;
d->length = totalBlocks / d->sampleRate;
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
}
void ASF::File::FilePropertiesObject::parse(ASF::File *file, uint size)
{
BaseObject::parse(file, size);
- file->d->properties->setLength((int)(data.mid(40, 8).toLongLong(false) / 10000000L - data.mid(56, 8).toLongLong(false) / 1000L));
+ file->d->properties->setLength(
+ (int)(data.toLongLong(40, false) / 10000000L - data.toLongLong(56, false) / 1000L));
}
ByteVector ASF::File::StreamPropertiesObject::guid()
void ASF::File::StreamPropertiesObject::parse(ASF::File *file, uint size)
{
BaseObject::parse(file, size);
- file->d->properties->setChannels(data.mid(56, 2).toShort(false));
- file->d->properties->setSampleRate(data.mid(58, 4).toUInt(false));
- file->d->properties->setBitrate(data.mid(62, 4).toUInt(false) * 8 / 1000);
+ file->d->properties->setChannels(data.toShort(56, false));
+ file->d->properties->setSampleRate(data.toUInt(58, false));
+ file->d->properties->setBitrate(data.toUInt(62, false) * 8 / 1000);
}
ByteVector ASF::File::ContentDescriptionObject::guid()
return;
int pos = 0;
d->type = (Type)bytes[0]; ++pos;
- uint dataLen = bytes.mid(pos, 4).toUInt(false); pos+=4;
+ const uint dataLen = bytes.toUInt(pos, false); pos+=4;
const ByteVector nullStringTerminator(2, 0);
char blockType = header[0] & 0x7f;
bool isLastBlock = (header[0] & 0x80) != 0;
- uint length = header.mid(1, 3).toUInt();
+ uint length = header.toUInt(1U, 3U);
// First block should be the stream_info metadata
header = readBlock(4);
blockType = header[0] & 0x7f;
isLastBlock = (header[0] & 0x80) != 0;
- length = header.mid(1, 3).toUInt();
+ length = header.toUInt(1U, 3U);
ByteVector data = readBlock(length);
if(data.size() != length || length == 0) {
return false;
}
- int pos = 0;
- d->type = FLAC::Picture::Type(data.mid(pos, 4).toUInt());
+ uint pos = 0;
+ d->type = FLAC::Picture::Type(data.toUInt(pos));
pos += 4;
- uint mimeTypeLength = data.mid(pos, 4).toUInt();
+ uint mimeTypeLength = data.toUInt(pos);
pos += 4;
if(pos + mimeTypeLength + 24 > data.size()) {
debug("Invalid picture block.");
}
d->mimeType = String(data.mid(pos, mimeTypeLength), String::UTF8);
pos += mimeTypeLength;
- uint descriptionLength = data.mid(pos, 4).toUInt();
+ uint descriptionLength = data.toUInt(pos);
pos += 4;
if(pos + descriptionLength + 20 > data.size()) {
debug("Invalid picture block.");
}
d->description = String(data.mid(pos, descriptionLength), String::UTF8);
pos += descriptionLength;
- d->width = data.mid(pos, 4).toUInt();
+ d->width = data.toUInt(pos);
pos += 4;
- d->height = data.mid(pos, 4).toUInt();
+ d->height = data.toUInt(pos);
pos += 4;
- d->colorDepth = data.mid(pos, 4).toUInt();
+ d->colorDepth = data.toUInt(pos);
pos += 4;
- d->numColors = data.mid(pos, 4).toUInt();
+ d->numColors = data.toUInt(pos);
pos += 4;
- uint dataLength = data.mid(pos, 4).toUInt();
+ uint dataLength = data.toUInt(pos);
pos += 4;
if(pos + dataLength > data.size()) {
debug("Invalid picture block.");
return;
}
- int pos = 0;
+ uint pos = 0;
// Minimum block size (in samples)
pos += 2;
// Maximum frame size (in bytes)
pos += 3;
- uint flags = d->data.mid(pos, 4).toUInt(true);
+ uint flags = d->data.toUInt(pos, true);
pos += 4;
d->sampleRate = flags >> 12;
// stream length in samples. (Audio files measured in days)
unsigned long long hi = flags & 0xf;
- unsigned long long lo = d->data.mid(pos, 4).toUInt(true);
+ unsigned long long lo = d->data.toUInt(pos, true);
pos += 4;
d->sampleFrames = (hi << 32) | lo;
return;
}
- length = header.mid(0, 4).toUInt();
+ length = header.toUInt();
if (length == 1) {
- long long longLength = file->readBlock(8).toLongLong();
+ const long long longLength = file->readBlock(8).toLongLong();
if (longLength >= 8 && longLength <= 0xFFFFFFFF) {
// The atom has a 64-bit length, but it's actually a 32-bit value
length = (long)longLength;
debug("MP4: Atom 'trak.mdia.mdhd' is smaller than expected");
return;
}
- long long unit = data.mid(28, 8).toLongLong();
- long long length = data.mid(36, 8).toLongLong();
+ const long long unit = data.toLongLong(28U);
+ const long long length = data.toLongLong(36U);
d->length = unit ? int(length / unit) : 0;
}
else {
debug("MP4: Atom 'trak.mdia.mdhd' is smaller than expected");
return;
}
- unsigned int unit = data.mid(20, 4).toUInt();
- unsigned int length = data.mid(24, 4).toUInt();
+ const unsigned int unit = data.toUInt(20U);
+ const unsigned int length = data.toUInt(24U);
d->length = unit ? length / unit : 0;
}
file->seek(atom->offset);
data = file->readBlock(atom->length);
if(data.mid(20, 4) == "mp4a") {
- d->channels = data.mid(40, 2).toShort();
- d->bitsPerSample = data.mid(42, 2).toShort();
- d->sampleRate = data.mid(46, 4).toUInt();
+ d->channels = data.toShort(40U);
+ d->bitsPerSample = data.toShort(42U);
+ d->sampleRate = data.toUInt(46U);
if(data.mid(56, 4) == "esds" && data[64] == 0x03) {
- long pos = 65;
+ uint pos = 65;
if(data.mid(pos, 3) == "\x80\x80\x80") {
pos += 3;
}
pos += 3;
}
pos += 10;
- d->bitrate = (data.mid(pos, 4).toUInt() + 500) / 1000;
+ d->bitrate = (data.toUInt(pos) + 500) / 1000;
}
}
}
else if (data.mid(20, 4) == "alac") {
if (atom->length == 88 && data.mid(56, 4) == "alac") {
d->bitsPerSample = data.at(69);
- d->channels = data.at(73);
- d->bitrate = data.mid(80, 4).toUInt() / 1000;
- d->sampleRate = data.mid(84, 4).toUInt();
+ d->channels = data.at(73);
+ d->bitrate = data.toUInt(80U) / 1000;
+ d->sampleRate = data.toUInt(84U);
}
}
int i = 0;
unsigned int pos = 0;
while(pos < data.size()) {
- int length = data.mid(pos, 4).toUInt();
+ const int length = static_cast<int>(data.toUInt(pos));
ByteVector name = data.mid(pos + 4, 4);
- int flags = data.mid(pos + 8, 4).toUInt();
+ const int flags = static_cast<int>(data.toUInt(pos + 8));
if(freeForm && i < 2) {
if(i == 0 && name != "mean") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"mean\"");
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
- int a = data[0].mid(2, 2).toShort();
- int b = data[0].mid(4, 2).toShort();
+ const int a = data[0].toShort(2U);
+ const int b = data[0].toShort(4U);
addItem(atom->name, MP4::Item(a, b));
}
}
ByteVector data = file->readBlock(atom->length - 8);
unsigned int pos = 0;
while(pos < data.size()) {
- int length = data.mid(pos, 4).toUInt();
+ const int length = static_cast<int>(data.toUInt(pos));
ByteVector name = data.mid(pos + 4, 4);
- int flags = data.mid(pos + 8, 4).toUInt();
+ const int flags = static_cast<int>(data.toUInt(pos + 8));
if(name != "data") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\"");
break;
}
d->file->seek(atom->offset + 12);
ByteVector data = d->file->readBlock(atom->length - 12);
- unsigned int count = data.mid(0, 4).toUInt();
+ unsigned int count = data.toUInt();
d->file->seek(atom->offset + 16);
- int pos = 4;
+ uint pos = 4;
while(count--) {
- long o = data.mid(pos, 4).toUInt();
+ long o = static_cast<long>(data.toUInt(pos));
if(o > offset) {
o += delta;
}
}
d->file->seek(atom->offset + 12);
ByteVector data = d->file->readBlock(atom->length - 12);
- unsigned int count = data.mid(0, 4).toUInt();
+ unsigned int count = data.toUInt();
d->file->seek(atom->offset + 16);
- int pos = 4;
+ uint pos = 4;
while(count--) {
- long long o = data.mid(pos, 8).toLongLong();
+ long long o = data.toLongLong(pos);
if(o > offset) {
o += delta;
}
}
d->file->seek(atom->offset + 9);
ByteVector data = d->file->readBlock(atom->length - 9);
- unsigned int flags = (ByteVector(1, '\0') + data.mid(0, 3)).toUInt();
+ const unsigned int flags = data.toUInt(0, 3, true);
if(flags & 1) {
- long long o = data.mid(7, 8).toLongLong();
+ long long o = data.toLongLong(7U);
if(o > offset) {
o += delta;
}
d->sampleFrames = readSize(data.mid(pos), pos);
ulong begSilence = readSize(data.mid(pos), pos);
- std::bitset<16> flags(TAGLIB_CONSTRUCT_BITSET(data.mid(pos, 2).toUShort(true)));
+ std::bitset<16> flags(TAGLIB_CONSTRUCT_BITSET(data.toUShort(pos, true)));
pos += 2;
d->sampleRate = sftable[flags[15] * 4 + flags[14] * 2 + flags[13]];
int replayGainVersion = data[0];
if(replayGainVersion == 1) {
- d->trackGain = data.mid(1, 2).toUInt(true);
- d->trackPeak = data.mid(3, 2).toUInt(true);
- d->albumGain = data.mid(5, 2).toUInt(true);
- d->albumPeak = data.mid(7, 2).toUInt(true);
+ d->trackGain = data.toShort(1, true);
+ d->trackPeak = data.toShort(3, true);
+ d->albumGain = data.toShort(5, true);
+ d->albumPeak = data.toShort(7, true);
}
}
if(d->version < 7)
return;
- d->totalFrames = data.mid(4, 4).toUInt(false);
+ d->totalFrames = data.toUInt(4, false);
- std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.mid(8, 4).toUInt(false)));
+ std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.toUInt(8, false)));
d->sampleRate = sftable[flags[17] * 2 + flags[16]];
d->channels = 2;
- uint gapless = data.mid(5, 4).toUInt(false);
+ uint gapless = data.toUInt(5, false);
- d->trackGain = data.mid(14,2).toShort(false);
- d->trackPeak = data.mid(12,2).toUInt(false);
- d->albumGain = data.mid(18,2).toShort(false);
- d->albumPeak = data.mid(16,2).toUInt(false);
+ d->trackGain = data.toShort(14, false);
+ d->trackPeak = data.toShort(12, false);
+ d->albumGain = data.toShort(18, false);
+ d->albumPeak = data.toShort(16, false);
// convert gain info
if(d->trackGain != 0) {
d->sampleFrames = d->totalFrames * 1152 - 576;
}
else {
- uint headerData = data.mid(0, 4).toUInt(false);
+ uint headerData = data.toUInt(0, false);
d->bitrate = (headerData >> 23) & 0x01ff;
d->version = (headerData >> 11) & 0x03ff;
d->channels = 2;
if(d->version >= 5)
- d->totalFrames = data.mid(4, 4).toUInt(false);
+ d->totalFrames = data.toUInt(4, false);
else
- d->totalFrames = data.mid(6, 2).toUInt(false);
+ d->totalFrames = data.toUShort(6, false);
d->sampleFrames = d->totalFrames * 1152 - 576;
}
if(pos < size) {
d->rating = (unsigned char)(data[pos++]);
if(pos < size) {
- d->counter = data.mid(pos, 4).toUInt();
+ d->counter = data.toUInt(static_cast<uint>(pos));
}
}
}
ChannelData &channel = d->channels[type];
- channel.volumeAdjustment = data.mid(pos, 2).toShort();
+ channel.volumeAdjustment = data.toShort(static_cast<uint>(pos));
pos += 2;
channel.peakVolume.bitsRepresentingPeak = data[pos];
return;
}
- d->frameSize = data.mid(3, 3).toUInt();
+ d->frameSize = data.toUInt(3, 3, true);
break;
}
// Set the size -- the frame size is the four bytes starting at byte four in
// the frame header (structure 4)
- d->frameSize = data.mid(4, 4).toUInt();
+ d->frameSize = data.toUInt(4U);
{ // read the first byte of flags
std::bitset<8> flags(data[8]);
// iTunes writes v2.4 tags with v2.3-like frame sizes
if(d->frameSize > 127) {
if(!isValidFrameID(data.mid(d->frameSize + 10, 4))) {
- unsigned int uintSize = data.mid(4, 4).toUInt();
+ unsigned int uintSize = data.toUInt(4U);
if(isValidFrameID(data.mid(uintSize + 10, 4))) {
d->frameSize = uintSize;
}
// Invalid data; assume this was created by some buggy software that just
// put normal integers here rather than syncsafe ones, and try it that
// way.
- sum = (data.size() > 4) ? data.mid(0, 4).toUInt() : data.toUInt();
+ sum = data.toUInt();
}
return sum;
return;
}
- d->frames = data.mid(8, 4).toUInt();
- d->size = data.mid(12, 4).toUInt();
+ d->frames = data.toUInt(8U);
+ d->size = data.toUInt(12U);
d->valid = true;
}
char blockType = header[0] & 0x7f;
bool lastBlock = (header[0] & 0x80) != 0;
- uint length = header.mid(1, 3).toUInt();
+ uint length = header.toUInt(1, 3, true);
overhead += length;
// Sanity: First block should be the stream_info metadata
return;
}
- d->streamInfoData = metadataHeader.mid(4,length);
+ d->streamInfoData = metadataHeader.mid(4, length);
// Search through the remaining metadata
header = metadataHeader.mid(0, 4);
blockType = header[0] & 0x7f;
lastBlock = (header[0] & 0x80) != 0;
- length = header.mid(1, 3).toUInt();
+ length = header.toUInt(1, 3, true);
overhead += length;
if(blockType == 1) {
d->firstPageOfStream = flags.test(1);
d->lastPageOfStream = flags.test(2);
- d->absoluteGranularPosition = data.mid(6, 8).toLongLong(false);
- d->streamSerialNumber = data.mid(14, 4).toUInt(false);
- d->pageSequenceNumber = data.mid(18, 4).toUInt(false);
+ d->absoluteGranularPosition = data.toLongLong(6, false);
+ d->streamSerialNumber = data.toUInt(14, false);
+ d->pageSequenceNumber = data.toUInt(18, false);
// Byte number 27 is the number of page segments, which is the only variable
// length portion of the page header. After reading the number of page
ByteVector data = d->file->packet(0);
// *Magic Signature*
- int pos = 8;
+ uint pos = 8;
// *Version* (8 bits, unsigned)
d->opusVersion = uchar(data.at(pos));
pos += 1;
// *Pre-skip* (16 bits, unsigned, little endian)
- ushort preSkip = data.mid(pos, 2).toUShort(false);
+ const ushort preSkip = data.toUShort(pos, false);
pos += 2;
// *Input Sample Rate* (32 bits, unsigned, little endian)
- d->inputSampleRate = data.mid(pos, 4).toUInt(false);
+ d->inputSampleRate = data.toUInt(pos, false);
pos += 4;
// *Output Gain* (16 bits, signed, little endian)
ByteVector data = d->file->packet(0);
- int pos = 28;
+ uint pos = 28;
// speex_version_id; /**< Version for Speex (for checking compatibility) */
- d->speexVersion = data.mid(pos, 4).toUInt(false);
+ d->speexVersion = data.toUInt(pos, false);
pos += 4;
// header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */
pos += 4;
// rate; /**< Sampling rate used */
- d->sampleRate = data.mid(pos, 4).toUInt(false);
+ d->sampleRate = data.toUInt(pos, false);
pos += 4;
// mode; /**< Mode used (0 for narrowband, 1 for wideband) */
- d->mode = data.mid(pos, 4).toUInt(false);
+ d->mode = data.toUInt(pos, false);
pos += 4;
// mode_bitstream_version; /**< Version ID of the bit-stream */
pos += 4;
// nb_channels; /**< Number of channels encoded */
- d->channels = data.mid(pos, 4).toUInt(false);
+ d->channels = data.toUInt(pos, false);
pos += 4;
// bitrate; /**< Bit-rate used */
- d->bitrate = data.mid(pos, 4).toUInt(false);
+ d->bitrate = data.toUInt(pos, false);
pos += 4;
// frame_size; /**< Size of frames */
pos += 4;
// vbr; /**< 1 for a VBR encoding, 0 otherwise */
- d->vbr = data.mid(pos, 4).toUInt(false) == 1;
+ d->vbr = data.toUInt(pos, false) == 1;
pos += 4;
// frames_per_packet; /**< Number of frames stored per Ogg packet */
ByteVector data = d->file->packet(0);
- int pos = 0;
+ uint pos = 0;
if(data.mid(pos, 7) != vorbisSetupHeaderID) {
debug("Vorbis::Properties::read() -- invalid Vorbis identification header");
pos += 7;
- d->vorbisVersion = data.mid(pos, 4).toUInt(false);
+ d->vorbisVersion = data.toUInt(pos, false);
pos += 4;
d->channels = uchar(data[pos]);
pos += 1;
- d->sampleRate = data.mid(pos, 4).toUInt(false);
+ d->sampleRate = data.toUInt(pos, false);
pos += 4;
- d->bitrateMaximum = data.mid(pos, 4).toUInt(false);
+ d->bitrateMaximum = data.toUInt(pos, false);
pos += 4;
- d->bitrateNominal = data.mid(pos, 4).toUInt(false);
+ d->bitrateNominal = data.toUInt(pos, false);
pos += 4;
- d->bitrateMinimum = data.mid(pos, 4).toUInt(false);
+ d->bitrateMinimum = data.toUInt(pos, false);
// TODO: Later this should be only the "fast" mode.
d->bitrate = d->bitrateNominal;
uint pos = 0;
- uint vendorLength = data.mid(0, 4).toUInt(false);
+ const uint vendorLength = data.toUInt(0, false);
pos += 4;
d->vendorID = String(data.mid(pos, vendorLength), String::UTF8);
// Next the number of fields in the comment vector.
- uint commentFields = data.mid(pos, 4).toUInt(false);
+ const uint commentFields = data.toUInt(pos, false);
pos += 4;
if(commentFields > (data.size() - 8) / 4) {
// Each comment field is in the format "KEY=value" in a UTF8 string and has
// 4 bytes before the text starts that gives the length.
- uint commentLength = data.mid(pos, 4).toUInt(false);
+ const uint commentLength = data.toUInt(pos, false);
pos += 4;
String comment = String(data.mid(pos, commentLength), String::UTF8);
void RIFF::AIFF::Properties::read(const ByteVector &data)
{
- d->channels = data.mid(0, 2).toShort();
- d->sampleFrames = data.mid(2, 4).toUInt();
- d->sampleWidth = data.mid(6, 2).toShort();
+ d->channels = data.toShort(0U);
+ d->sampleFrames = data.toUInt(2U);
+ d->sampleWidth = data.toShort(6U);
double sampleRate = ConvertFromIeeeExtended(reinterpret_cast<unsigned char *>(data.mid(8, 10).data()));
d->sampleRate = (int)sampleRate;
d->bitrate = (int)((sampleRate * d->sampleWidth * d->channels) / 1000.0);
{
uint p = 4;
while(p < data.size()) {
- uint size = data.mid(p + 4, 4).toUInt(false);
+ const uint size = data.toUInt(p + 4, false);
d->fieldListMap[data.mid(p, 4)] = TagPrivate::stringHandler->parse(data.mid(p + 8, size));
p += ((size + 1) & ~1) + 8;
void RIFF::WAV::Properties::read(const ByteVector &data)
{
- d->format = data.mid(0, 2).toShort(false);
- d->channels = data.mid(2, 2).toShort(false);
- d->sampleRate = data.mid(4, 4).toUInt(false);
- d->sampleWidth = data.mid(14, 2).toShort(false);
+ d->format = data.toShort(0, false);
+ d->channels = data.toShort(2, false);
+ d->sampleRate = data.toUInt(4, false);
+ d->sampleWidth = data.toShort(14, false);
- uint byteRate = data.mid(8, 4).toUInt(false);
+ const uint byteRate = data.toUInt(8, false);
d->bitrate = byteRate * 8 / 1000;
d->length = byteRate > 0 ? d->streamLength / byteRate : 0;
#else
- const bool isLittleEndianSystem = isLittleEndianSystem();
+ const bool isLittleEndianSystem = isLittleEndian();
#endif
}
***************************************************************************/
#include <iostream>
+#include <cstdio>
+#include <cstring>
#include <tstring.h>
#include <tdebug.h>
-#include <string.h>
#include "tbytevector.h"
#include "tbyteswap.h"
}
template <class T>
-T toNumber(const ByteVector &v, bool mostSignificantByteFirst)
+T toNumber(const ByteVector &v, size_t offset, bool mostSignificantByteFirst)
{
- if(v.isEmpty()) {
- debug("toNumber<T>() -- data is empty, returning 0");
+ if(offset + sizeof(T) > v.size()) {
+ debug("toNumber<T>() -- offset is out of range. Returning 0.");
return 0;
}
- if(v.size() >= sizeof(T)) {
- if(isLittleEndianSystem == mostSignificantByteFirst)
- return byteSwap<T>(*reinterpret_cast<const T*>(v.data()));
- else
- return *reinterpret_cast<const T*>(v.data());
+ if(isLittleEndianSystem == mostSignificantByteFirst)
+ return byteSwap<T>(*reinterpret_cast<const T*>(v.data() + offset));
+ else
+ return *reinterpret_cast<const T*>(v.data() + offset);
+}
+
+template <class T>
+T toNumber(const ByteVector &v, size_t offset, size_t length, bool mostSignificantByteFirst)
+{
+ if(offset + length > v.size()) {
+ debug("toNumber<T>() -- offset and/or length is out of range. Returning 0.");
+ return 0;
+ }
+
+ if(length >= sizeof(T)) {
+ return toNumber<T>(v, offset, mostSignificantByteFirst);
}
else {
T sum = 0;
- for(size_t i = 0; i < v.size(); i++) {
- const size_t shift = (mostSignificantByteFirst ? v.size() - 1 - i : i) * 8;
- sum |= static_cast<T>(static_cast<uchar>(v[i]) << shift);
+ for(size_t i = 0; i < length; i++) {
+ const size_t shift = (mostSignificantByteFirst ? length - 1 - i : i) * 8;
+ sum |= static_cast<T>(static_cast<uchar>(v[offset + i]) << shift);
}
return sum;
ByteVector ByteVector::mid(uint index, uint length) const
{
- if(index > size())
- index = size();
-
- if(length > size() - index)
- length = size() - index;
+ index = std::min(index, size());
+ length = std::min(length, size() - index);
return ByteVector(*this, index, length);
}
TagLib::uint ByteVector::toUInt(bool mostSignificantByteFirst) const
{
- return toNumber<uint>(*this, mostSignificantByteFirst);
+ return toNumber<uint>(*this, 0, mostSignificantByteFirst);
+}
+
+TagLib::uint ByteVector::toUInt(uint offset, bool mostSignificantByteFirst) const
+{
+ return toNumber<uint>(*this, offset, mostSignificantByteFirst);
+}
+
+TagLib::uint ByteVector::toUInt(uint offset, uint length, bool mostSignificantByteFirst) const
+{
+ return toNumber<uint>(*this, offset, length, mostSignificantByteFirst);
}
short ByteVector::toShort(bool mostSignificantByteFirst) const
{
- return toNumber<unsigned short>(*this, mostSignificantByteFirst);
+ return toNumber<unsigned short>(*this, 0, mostSignificantByteFirst);
+}
+
+short ByteVector::toShort(uint offset, bool mostSignificantByteFirst) const
+{
+ return toNumber<unsigned short>(*this, offset, mostSignificantByteFirst);
}
unsigned short ByteVector::toUShort(bool mostSignificantByteFirst) const
{
- return toNumber<unsigned short>(*this, mostSignificantByteFirst);
+ return toNumber<unsigned short>(*this, 0, mostSignificantByteFirst);
+}
+
+unsigned short ByteVector::toUShort(uint offset, bool mostSignificantByteFirst) const
+{
+ return toNumber<unsigned short>(*this, offset, mostSignificantByteFirst);
}
long long ByteVector::toLongLong(bool mostSignificantByteFirst) const
{
- return toNumber<unsigned long long>(*this, mostSignificantByteFirst);
+ return toNumber<unsigned long long>(*this, 0, mostSignificantByteFirst);
+}
+
+long long ByteVector::toLongLong(uint offset, bool mostSignificantByteFirst) const
+{
+ return toNumber<unsigned long long>(*this, offset, mostSignificantByteFirst);
}
const char &ByteVector::operator[](int index) const
uint toUInt(bool mostSignificantByteFirst = true) const;
/*!
- * Converts the first 2 bytes of the vector to a short.
+ * Converts the 4 bytes at \a offset of the vector to an unsigned integer.
+ *
+ * If \a mostSignificantByteFirst is true this will operate left to right
+ * evaluating the integer. For example if \a mostSignificantByteFirst is
+ * true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 ==
+ * 0x01000000 == 1.
+ *
+ * \see fromUInt()
+ */
+ uint toUInt(uint offset, bool mostSignificantByteFirst = true) const;
+
+ /*!
+ * Converts the \a length bytes at \a offset of the vector to an unsigned
+ * integer. If \a length is larger than 4, the excess is ignored.
+ *
+ * If \a mostSignificantByteFirst is true this will operate left to right
+ * evaluating the integer. For example if \a mostSignificantByteFirst is
+ * true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 ==
+ * 0x01000000 == 1.
+ *
+ * \see fromUInt()
+ */
+ uint toUInt(uint offset, uint length, bool mostSignificantByteFirst = true) const;
+
+ /*!
+ * Converts the first 2 bytes of the vector to a (signed) short.
*
* If \a mostSignificantByteFirst is true this will operate left to right
* evaluating the integer. For example if \a mostSignificantByteFirst is
*/
short toShort(bool mostSignificantByteFirst = true) const;
+ /*!
+ * Converts the 2 bytes at \a offset of the vector to a (signed) short.
+ *
+ * If \a mostSignificantByteFirst is true this will operate left to right
+ * evaluating the integer. For example if \a mostSignificantByteFirst is
+ * true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1.
+ *
+ * \see fromShort()
+ */
+ short toShort(uint offset, bool mostSignificantByteFirst = true) const;
+
/*!
* Converts the first 2 bytes of the vector to a unsigned short.
*
*/
unsigned short toUShort(bool mostSignificantByteFirst = true) const;
+ /*!
+ * Converts the 2 bytes at \a offset of the vector to a unsigned short.
+ *
+ * If \a mostSignificantByteFirst is true this will operate left to right
+ * evaluating the integer. For example if \a mostSignificantByteFirst is
+ * true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1.
+ *
+ * \see fromShort()
+ */
+ unsigned short toUShort(uint offset, bool mostSignificantByteFirst = true) const;
+
/*!
* Converts the first 8 bytes of the vector to a (signed) long long.
*
*/
long long toLongLong(bool mostSignificantByteFirst = true) const;
+ /*!
+ * Converts the 8 bytes at \a offset of the vector to a (signed) long long.
+ *
+ * If \a mostSignificantByteFirst is true this will operate left to right
+ * evaluating the integer. For example if \a mostSignificantByteFirst is
+ * true then $00 00 00 00 00 00 00 01 == 0x0000000000000001 == 1,
+ * if false, $01 00 00 00 00 00 00 00 == 0x0100000000000000 == 1.
+ *
+ * \see fromUInt()
+ */
+ long long toLongLong(uint offset, bool mostSignificantByteFirst = true) const;
+
/*!
* Creates a 4 byte ByteVector based on \a value. If
* \a mostSignificantByteFirst is true, then this will operate left to right
// Skip the audio format
pos += 2;
- d->channels = d->data.mid(pos, 2).toShort(false);
+ d->channels = d->data.toShort(pos, false);
pos += 2;
- d->bitsPerSample = d->data.mid(pos, 2).toShort(false);
+ d->bitsPerSample = d->data.toShort(pos, false);
pos += 2;
- d->sampleRate = d->data.mid(pos, 4).toUInt(false);
+ d->sampleRate = d->data.toUInt(pos, false);
pos += 4;
- d->sampleFrames = d->data.mid(pos, 4).toUInt(false);
+ d->sampleFrames = d->data.toUInt(pos, false);
d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0;
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
if(!d->data.startsWith("wvpk"))
return;
- d->version = d->data.mid(8, 2).toShort(false);
+ d->version = d->data.toShort(8, false);
if(d->version < MIN_STREAM_VERS || d->version > MAX_STREAM_VERS)
return;
- unsigned int flags = d->data.mid(24, 4).toUInt(false);
+ const unsigned int flags = d->data.toUInt(24, false);
d->bitsPerSample = ((flags & BYTES_STORED) + 1) * 8 -
((flags & SHIFT_MASK) >> SHIFT_LSB);
d->sampleRate = sample_rates[(flags & SRATE_MASK) >> SRATE_LSB];
d->channels = (flags & MONO_FLAG) ? 1 : 2;
- unsigned int samples = d->data.mid(12, 4).toUInt(false);
+ unsigned int samples = d->data.toUInt(12, false);
if(samples == ~0u) {
if(d->file && d->style != Fast) {
samples = seekFinalIndex();
ByteVector data = d->file->readBlock(32);
if(data.size() != 32)
return 0;
- int version = data.mid(8, 2).toShort(false);
+ const int version = data.toShort(8, false);
if(version < MIN_STREAM_VERS || version > MAX_STREAM_VERS)
continue;
- unsigned int flags = data.mid(24, 4).toUInt(false);
+ const unsigned int flags = data.toUInt(24, false);
if(!(flags & FINAL_BLOCK))
return 0;
- unsigned int blockIndex = data.mid(16, 4).toUInt(false);
- unsigned int blockSamples = data.mid(20, 4).toUInt(false);
+ const unsigned int blockIndex = data.toUInt(16, false);
+ const unsigned int blockSamples = data.toUInt(20, false);
return blockIndex + blockSamples;
}