Adapt most changes from taglib2

This commit is contained in:
Jonas Kvinge
2020-06-26 23:30:30 +02:00
parent 08882639e0
commit 5f71a558b9
374 changed files with 13708 additions and 4418 deletions

View File

@@ -23,8 +23,9 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include <tfile.h>
#include "tdebug.h"
#include "tfile.h"
#include "tpicturemap.h"
#include "id3v1tag.h"
#include "id3v1genres.h"
@@ -33,8 +34,24 @@ using namespace Strawberry_TagLib::TagLib;
using namespace ID3v1;
namespace {
const ID3v1::StringHandler defaultStringHandler;
const ID3v1::StringHandler *stringHandler = &defaultStringHandler;
class DefaultStringHandler : public Strawberry_TagLib::TagLib::StringHandler {
public:
explicit DefaultStringHandler() : Strawberry_TagLib::TagLib::StringHandler() {}
String parse(const ByteVector &data) const override {
return String(data, String::Latin1).stripWhiteSpace();
}
ByteVector render(const String &s) const override {
if (s.isLatin1())
return s.data(String::Latin1);
else
return ByteVector();
}
};
const DefaultStringHandler defaultStringHandler;
const Strawberry_TagLib::TagLib::StringHandler *stringHandler = &defaultStringHandler;
} // namespace
class ID3v1::Tag::TagPrivate {
@@ -45,7 +62,7 @@ class ID3v1::Tag::TagPrivate {
genre(255) {}
File *file;
long tagOffset;
long long tagOffset;
String title;
String artist;
@@ -56,32 +73,13 @@ class ID3v1::Tag::TagPrivate {
unsigned char genre;
};
////////////////////////////////////////////////////////////////////////////////
// StringHandler implementation
////////////////////////////////////////////////////////////////////////////////
StringHandler::StringHandler() {}
String ID3v1::StringHandler::parse(const ByteVector &data) const {
return String(data, String::Latin1).stripWhiteSpace();
}
ByteVector ID3v1::StringHandler::render(const String &s) const {
if (s.isLatin1())
return s.data(String::Latin1);
else
return ByteVector();
}
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
ID3v1::Tag::Tag() : d(new TagPrivate()) {}
ID3v1::Tag::Tag(File *file, long tagOffset) : d(new TagPrivate()) {
ID3v1::Tag::Tag(File *file, long long tagOffset) : d(new TagPrivate()) {
d->file = file;
d->tagOffset = tagOffset;
@@ -143,6 +141,10 @@ unsigned int ID3v1::Tag::track() const {
return d->track;
}
Strawberry_TagLib::TagLib::PictureMap ID3v1::Tag::pictures() const {
return PictureMap();
}
void ID3v1::Tag::setTitle(const String &s) {
d->title = s;
}
@@ -171,6 +173,8 @@ void ID3v1::Tag::setTrack(unsigned int i) {
d->track = i < 256 ? i : 0;
}
void ID3v1::Tag::setPictures(const PictureMap&) {}
unsigned int ID3v1::Tag::genreNumber() const {
return d->genre;
}
@@ -179,7 +183,7 @@ void ID3v1::Tag::setGenreNumber(unsigned int i) {
d->genre = i < 256 ? i : 255;
}
void ID3v1::Tag::setStringHandler(const StringHandler *handler) {
void ID3v1::Tag::setStringHandler(const Strawberry_TagLib::TagLib::StringHandler *handler) {
if (handler)
stringHandler = handler;
else

View File

@@ -28,6 +28,7 @@
#include "tag.h"
#include "tbytevector.h"
#include "tstringhandler.h"
#include "taglib_export.h"
namespace Strawberry_TagLib {
@@ -39,44 +40,6 @@ class File;
namespace ID3v1 {
//! A abstraction for the string to data encoding in ID3v1 tags.
/*!
* ID3v1 should in theory always contain ISO-8859-1 (Latin1) data. In practice it does not.
* TagLib by default only supports ISO-8859-1 data in ID3v1 tags.
*
* However by subclassing this class and reimplementing parse() and render() and setting your reimplementation as the default with
* ID3v1::Tag::setStringHandler() you can define how you would like these transformations to be done.
*
* \warning It is advisable <b>not</b> to write non-ISO-8859-1 data to ID3v1 tags.
* Please consider disabling the writing of ID3v1 tags in the case that the data is not ISO-8859-1.
*
* \see ID3v1::Tag::setStringHandler()
*/
class TAGLIB_EXPORT StringHandler {
public:
explicit StringHandler();
virtual ~StringHandler() = default;
/*!
* Decode a string from \a data.
* The default implementation assumes that \a data is an ISO-8859-1 (Latin1) character array.
*/
virtual String parse(const ByteVector &data) const;
/*!
* Encode a ByteVector with the data from \a s.
* The default implementation assumes that \a s is an ISO-8859-1 (Latin1) string.
* If the string is does not conform to ISO-8859-1, no value is written.
*
* \warning It is recommended that you <b>not</b> override this method, but
* instead do not write an ID3v1 tag in the case that the data is not ISO-8859-1.
*/
virtual ByteVector render(const String &s) const;
};
//! The main class in the ID3v1 implementation
/*!
@@ -106,12 +69,12 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
/*!
* Create an ID3v1 tag and parse the data in \a file starting at \a tagOffset.
*/
explicit Tag(File *file, long tagOffset);
explicit Tag(File *file, long long tagOffset);
/*!
* Destroys this Tag instance.
*/
virtual ~Tag();
~Tag() override;
/*!
* Renders the in memory values to a ByteVector suitable for writing to the file.
@@ -125,21 +88,23 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
// Reimplementations.
virtual String title() const;
virtual String artist() const;
virtual String album() const;
virtual String comment() const;
virtual String genre() const;
virtual unsigned int year() const;
virtual unsigned int track() const;
String title() const override;
String artist() const override;
String album() const override;
String comment() const override;
String genre() const override;
unsigned int year() const override;
unsigned int track() const override;
PictureMap pictures() const override;
virtual void setTitle(const String &s);
virtual void setArtist(const String &s);
virtual void setAlbum(const String &s);
virtual void setComment(const String &s);
virtual void setGenre(const String &s);
virtual void setYear(unsigned int i);
virtual void setTrack(unsigned int i);
void setTitle(const String &s) override;
void setArtist(const String &s) override;
void setAlbum(const String &s) override;
void setComment(const String &s) override;
void setGenre(const String &s) override;
void setYear(unsigned int i) override;
void setTrack(unsigned int i) override;
void setPictures(const PictureMap&) override;
/*!
* Returns the genre in number.
@@ -161,9 +126,8 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
*
* \note The caller is responsible for deleting the previous handler as needed after it is released.
*
* \see StringHandler
*/
static void setStringHandler(const StringHandler *handler);
static void setStringHandler(const Strawberry_TagLib::TagLib::StringHandler *handler);
protected:
/*!
@@ -176,7 +140,7 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
void parse(const ByteVector &data);
private:
explicit Tag(const Tag&);
Tag(const Tag&);
Tag &operator=(const Tag&);
class TagPrivate;

View File

@@ -25,15 +25,15 @@
#include "attachedpictureframe.h"
#include <tstringlist.h>
#include <tdebug.h>
#include "tstringlist.h"
#include "tdebug.h"
using namespace Strawberry_TagLib::TagLib;
using namespace ID3v2;
class AttachedPictureFrame::AttachedPictureFramePrivate {
public:
AttachedPictureFramePrivate() : textEncoding(String::Latin1), type(AttachedPictureFrame::Other) {}
explicit AttachedPictureFramePrivate() : textEncoding(String::Latin1), type(AttachedPictureFrame::Other) {}
String::Type textEncoding;
String mimeType;
@@ -114,17 +114,17 @@ void AttachedPictureFrame::parseFields(const ByteVector &data) {
d->textEncoding = String::Type(data[0]);
int pos = 1;
size_t pos = 1;
d->mimeType = readStringField(data, String::Latin1, &pos);
d->mimeType = readStringField(data, String::Latin1, pos);
/* Now we need at least two more bytes available */
if (static_cast<unsigned int>(pos) + 1 >= data.size()) {
if (pos + 1 >= data.size()) {
debug("Truncated picture frame.");
return;
}
d->type = static_cast<ID3v2::AttachedPictureFrame::Type>(data[pos++]);
d->description = readStringField(data, d->textEncoding, &pos);
d->description = readStringField(data, d->textEncoding, pos);
d->data = data.mid(pos);
@@ -169,7 +169,7 @@ void AttachedPictureFrameV22::parseFields(const ByteVector &data) {
d->textEncoding = String::Type(data[0]);
int pos = 1;
size_t pos = 1;
String fixedString = String(data.mid(pos, 3), String::Latin1);
pos += 3;
@@ -186,7 +186,7 @@ void AttachedPictureFrameV22::parseFields(const ByteVector &data) {
}
d->type = static_cast<ID3v2::AttachedPictureFrame::Type>(data[pos++]);
d->description = readStringField(data, d->textEncoding, &pos);
d->description = readStringField(data, d->textEncoding, pos);
d->data = data.mid(pos);

View File

@@ -108,12 +108,12 @@ class TAGLIB_EXPORT AttachedPictureFrame : public Frame {
/*!
* Destroys the AttahcedPictureFrame instance.
*/
virtual ~AttachedPictureFrame();
~AttachedPictureFrame() override;
/*!
* Returns a string containing the description and mime-type
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the text encoding used for the description.
@@ -198,13 +198,13 @@ class TAGLIB_EXPORT AttachedPictureFrame : public Frame {
void setPicture(const ByteVector &p);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
class AttachedPictureFramePrivate;
AttachedPictureFramePrivate *d;
private:
explicit AttachedPictureFrame(const AttachedPictureFrame&);
AttachedPictureFrame(const AttachedPictureFrame&);
AttachedPictureFrame &operator=(const AttachedPictureFrame&);
explicit AttachedPictureFrame(const ByteVector &data, Header *h);
};
@@ -212,7 +212,7 @@ class TAGLIB_EXPORT AttachedPictureFrame : public Frame {
//! support for ID3v2.2 PIC frames
class TAGLIB_EXPORT AttachedPictureFrameV22 : public AttachedPictureFrame {
protected:
virtual void parseFields(const ByteVector &data);
void parseFields(const ByteVector &data) override;
private:
explicit AttachedPictureFrameV22(const ByteVector &data, Header *h);

View File

@@ -25,9 +25,9 @@
#include <cstdio>
#include <tbytevectorlist.h>
#include <tpropertymap.h>
#include <tdebug.h>
#include "tbytevectorlist.h"
#include "tpropertymap.h"
#include "tdebug.h"
#include "chapterframe.h"
@@ -36,11 +36,11 @@ using namespace ID3v2;
class ChapterFrame::ChapterFramePrivate {
public:
ChapterFramePrivate() : tagHeader(nullptr),
startTime(0),
endTime(0),
startOffset(0),
endOffset(0) {
explicit ChapterFramePrivate() : tagHeader(nullptr),
startTime(0),
endTime(0),
startOffset(0),
endOffset(0) {
embeddedFrameList.setAutoDelete(true);
}
@@ -224,23 +224,23 @@ ChapterFrame *ChapterFrame::findByElementID(const ID3v2::Tag *tag, const ByteVec
void ChapterFrame::parseFields(const ByteVector &data) {
unsigned int size = data.size();
size_t size = data.size();
if (size < 18) {
debug("A CHAP frame must contain at least 18 bytes (1 byte element ID "
"terminated by null and 4x4 bytes for start and end time and offset).");
return;
}
int pos = 0;
unsigned int embPos = 0;
d->elementID = readStringField(data, String::Latin1, &pos).data(String::Latin1);
d->startTime = data.toUInt(pos, true);
size_t pos = 0;
size_t embPos = 0;
d->elementID = readStringField(data, String::Latin1, pos).data(String::Latin1);
d->startTime = data.toUInt32BE(pos);
pos += 4;
d->endTime = data.toUInt(pos, true);
d->endTime = data.toUInt32BE(pos);
pos += 4;
d->startOffset = data.toUInt(pos, true);
d->startOffset = data.toUInt32BE(pos);
pos += 4;
d->endOffset = data.toUInt(pos, true);
d->endOffset = data.toUInt32BE(pos);
pos += 4;
size -= pos;
@@ -273,10 +273,10 @@ ByteVector ChapterFrame::renderFields() const {
data.append(d->elementID);
data.append('\0');
data.append(ByteVector::fromUInt(d->startTime, true));
data.append(ByteVector::fromUInt(d->endTime, true));
data.append(ByteVector::fromUInt(d->startOffset, true));
data.append(ByteVector::fromUInt(d->endOffset, true));
data.append(ByteVector::fromUInt32BE(d->startTime));
data.append(ByteVector::fromUInt32BE(d->endTime));
data.append(ByteVector::fromUInt32BE(d->startOffset));
data.append(ByteVector::fromUInt32BE(d->endOffset));
FrameList l = d->embeddedFrameList;
for (FrameList::ConstIterator it = l.begin(); it != l.end(); ++it)
data.append((*it)->render());

View File

@@ -64,7 +64,7 @@ class TAGLIB_EXPORT ChapterFrame : public ID3v2::Frame {
/*!
* Destroys the frame.
*/
virtual ~ChapterFrame();
~ChapterFrame() override;
/*!
* Returns the element ID of the frame.
@@ -201,7 +201,7 @@ class TAGLIB_EXPORT ChapterFrame : public ID3v2::Frame {
*/
void removeEmbeddedFrames(const ByteVector &id);
virtual String toString() const;
String toString() const override;
PropertyMap asProperties() const;
@@ -214,12 +214,12 @@ class TAGLIB_EXPORT ChapterFrame : public ID3v2::Frame {
static ChapterFrame *findByElementID(const Tag *tag, const ByteVector &eID);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
explicit ChapterFrame(const ID3v2::Header *tagHeader, const ByteVector &data, Header *h);
explicit ChapterFrame(const ChapterFrame&);
ChapterFrame(const ChapterFrame&);
ChapterFrame &operator=(const ChapterFrame&);
class ChapterFramePrivate;

View File

@@ -23,10 +23,10 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include <tdebug.h>
#include <tstringlist.h>
#include "tbytevectorlist.h"
#include "id3v2tag.h"
#include "tdebug.h"
#include "tstringlist.h"
#include "commentsframe.h"
#include "tpropertymap.h"
@@ -36,7 +36,7 @@ using namespace ID3v2;
class CommentsFrame::CommentsFramePrivate {
public:
CommentsFramePrivate() : textEncoding(String::Latin1) {}
explicit CommentsFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
ByteVector language;
String description;

View File

@@ -57,14 +57,14 @@ class TAGLIB_EXPORT CommentsFrame : public Frame {
/*!
* Destroys this CommentFrame instance.
*/
virtual ~CommentsFrame();
~CommentsFrame() override;
/*!
* Returns the text of this comment.
*
* \see text()
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the language encoding as a 3 byte encoding as specified by
@@ -112,7 +112,7 @@ class TAGLIB_EXPORT CommentsFrame : public Frame {
*
* \see text()
*/
virtual void setText(const String &s);
void setText(const String &s) override;
/*!
* Returns the text encoding that will be used in rendering this frame.
@@ -154,15 +154,15 @@ class TAGLIB_EXPORT CommentsFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
* The constructor used by the FrameFactory.
*/
explicit CommentsFrame(const ByteVector &data, Header *h);
explicit CommentsFrame(const CommentsFrame &);
CommentsFrame(const CommentsFrame &);
CommentsFrame &operator=(const CommentsFrame &);
class CommentsFramePrivate;

View File

@@ -24,17 +24,17 @@
***************************************************************************/
#include "eventtimingcodesframe.h"
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include <tdebug.h>
#include <tpropertymap.h>
#include "tbytevectorlist.h"
#include "id3v2tag.h"
#include "tdebug.h"
#include "tpropertymap.h"
using namespace Strawberry_TagLib::TagLib;
using namespace ID3v2;
class EventTimingCodesFrame::EventTimingCodesFramePrivate {
public:
EventTimingCodesFramePrivate() : timestampFormat(EventTimingCodesFrame::AbsoluteMilliseconds) {}
explicit EventTimingCodesFramePrivate() : timestampFormat(EventTimingCodesFrame::AbsoluteMilliseconds) {}
EventTimingCodesFrame::TimestampFormat timestampFormat;
EventTimingCodesFrame::SynchedEventList synchedEvents;
};
@@ -83,7 +83,7 @@ void EventTimingCodesFrame::setSynchedEvents(
void EventTimingCodesFrame::parseFields(const ByteVector &data) {
const int end = data.size();
const size_t end = data.size();
if (end < 1) {
debug("An event timing codes frame must contain at least 1 byte.");
return;
@@ -91,11 +91,11 @@ void EventTimingCodesFrame::parseFields(const ByteVector &data) {
d->timestampFormat = TimestampFormat(data[0]);
int pos = 1;
size_t pos = 1;
d->synchedEvents.clear();
while (pos + 4 < end) {
EventType type = static_cast<EventType>(static_cast<unsigned char>(data[pos++]));
unsigned int time = data.toUInt(pos, true);
unsigned int time = data.toUInt32BE(pos);
pos += 4;
d->synchedEvents.append(SynchedEvent(time, type));
}
@@ -110,7 +110,7 @@ ByteVector EventTimingCodesFrame::renderFields() const {
for (SynchedEventList::ConstIterator it = d->synchedEvents.begin(); it != d->synchedEvents.end(); ++it) {
const SynchedEvent &entry = *it;
v.append(char(entry.type));
v.append(ByteVector::fromUInt(entry.time));
v.append(ByteVector::fromUInt32BE(entry.time));
}
return v;

View File

@@ -129,12 +129,12 @@ class TAGLIB_EXPORT EventTimingCodesFrame : public Frame {
/*!
* Destroys this EventTimingCodesFrame instance.
*/
virtual ~EventTimingCodesFrame();
~EventTimingCodesFrame() override;
/*!
* Returns a null string.
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the timestamp format.
@@ -163,15 +163,15 @@ class TAGLIB_EXPORT EventTimingCodesFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
* The constructor used by the FrameFactory.
*/
explicit EventTimingCodesFrame(const ByteVector &data, Header *h);
explicit EventTimingCodesFrame(const EventTimingCodesFrame&);
EventTimingCodesFrame(const EventTimingCodesFrame&);
EventTimingCodesFrame &operator=(const EventTimingCodesFrame&);
class EventTimingCodesFramePrivate;

View File

@@ -26,8 +26,8 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include <tstringlist.h>
#include "tdebug.h"
#include "tstringlist.h"
#include "generalencapsulatedobjectframe.h"
@@ -36,7 +36,7 @@ using namespace ID3v2;
class GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFramePrivate {
public:
GeneralEncapsulatedObjectFramePrivate() : textEncoding(String::Latin1) {}
explicit GeneralEncapsulatedObjectFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
String mimeType;
@@ -126,11 +126,11 @@ void GeneralEncapsulatedObjectFrame::parseFields(const ByteVector &data) {
d->textEncoding = String::Type(data[0]);
int pos = 1;
size_t pos = 1;
d->mimeType = readStringField(data, String::Latin1, &pos);
d->fileName = readStringField(data, d->textEncoding, &pos);
d->description = readStringField(data, d->textEncoding, &pos);
d->mimeType = readStringField(data, String::Latin1, pos);
d->fileName = readStringField(data, d->textEncoding, pos);
d->description = readStringField(data, d->textEncoding, pos);
d->data = data.mid(pos);

View File

@@ -70,12 +70,12 @@ class TAGLIB_EXPORT GeneralEncapsulatedObjectFrame : public Frame {
/*!
* Destroys the GeneralEncapsulatedObjectFrame instance.
*/
virtual ~GeneralEncapsulatedObjectFrame();
~GeneralEncapsulatedObjectFrame() override;
/*!
* Returns a string containing the description, file name and mime-type
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the text encoding used for the description and file name.
@@ -160,12 +160,12 @@ class TAGLIB_EXPORT GeneralEncapsulatedObjectFrame : public Frame {
void setObject(const ByteVector &data);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
explicit GeneralEncapsulatedObjectFrame(const ByteVector &data, Header *h);
explicit GeneralEncapsulatedObjectFrame(const GeneralEncapsulatedObjectFrame&);
GeneralEncapsulatedObjectFrame(const GeneralEncapsulatedObjectFrame&);
GeneralEncapsulatedObjectFrame &operator=(const GeneralEncapsulatedObjectFrame&);
class GeneralEncapsulatedObjectFramePrivate;

View File

@@ -23,9 +23,9 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include <tstringlist.h>
#include <id3v2tag.h>
#include "tdebug.h"
#include "tstringlist.h"
#include "id3v2tag.h"
#include "ownershipframe.h"
@@ -98,14 +98,14 @@ void OwnershipFrame::setTextEncoding(String::Type encoding) {
void OwnershipFrame::parseFields(const ByteVector &data) {
int pos = 0;
size_t pos = 0;
// Get the text encoding
d->textEncoding = String::Type(data[0]);
pos += 1;
// Read the price paid this is a null terminate string
d->pricePaid = readStringField(data, String::Latin1, &pos);
d->pricePaid = readStringField(data, String::Latin1, pos);
// If we don't have at least 8 bytes left then don't parse the rest of the
// data

View File

@@ -57,14 +57,14 @@ class TAGLIB_EXPORT OwnershipFrame : public Frame {
/*!
* Destroys this OwnershipFrame instance.
*/
virtual ~OwnershipFrame();
~OwnershipFrame() override;
/*!
* Returns the text of this popularimeter.
*
* \see text()
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the date purchased.
@@ -128,15 +128,15 @@ class TAGLIB_EXPORT OwnershipFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
* The constructor used by the FrameFactory.
*/
explicit OwnershipFrame(const ByteVector &data, Header *h);
explicit OwnershipFrame(const OwnershipFrame&);
OwnershipFrame(const OwnershipFrame&);
OwnershipFrame &operator=(const OwnershipFrame &);
class OwnershipFramePrivate;

View File

@@ -49,25 +49,25 @@ class TAGLIB_EXPORT PodcastFrame : public Frame {
/*!
* Destroys this PodcastFrame instance.
*/
virtual ~PodcastFrame();
~PodcastFrame() override;
/*!
* Returns a null string.
*/
virtual String toString() const;
String toString() const override;
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
* The constructor used by the FrameFactory.
*/
explicit PodcastFrame(const ByteVector &data, Header *h);
explicit PodcastFrame(const PodcastFrame &);
PodcastFrame(const PodcastFrame &);
PodcastFrame &operator=(const PodcastFrame &);
class PodcastFramePrivate;

View File

@@ -23,7 +23,7 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include "tdebug.h"
#include "popularimeterframe.h"
@@ -32,7 +32,7 @@ using namespace ID3v2;
class PopularimeterFrame::PopularimeterFramePrivate {
public:
PopularimeterFramePrivate() : rating(0), counter(0) {}
explicit PopularimeterFramePrivate() : rating(0), counter(0) {}
String email;
int rating;
unsigned int counter;
@@ -86,16 +86,17 @@ void PopularimeterFrame::setCounter(unsigned int counter) {
void PopularimeterFrame::parseFields(const ByteVector &data) {
int pos = 0, size = int(data.size());
size_t pos = 0;
const size_t size = data.size();
d->email = readStringField(data, String::Latin1, &pos);
d->email = readStringField(data, String::Latin1, pos);
d->rating = 0;
d->counter = 0;
if (pos < size) {
d->rating = static_cast<unsigned char>(data[pos++]);
if (pos < size) {
d->counter = data.toUInt(static_cast<unsigned int>(pos));
d->counter = data.toUInt32BE(pos);
}
}
@@ -108,7 +109,7 @@ ByteVector PopularimeterFrame::renderFields() const {
data.append(d->email.data(String::Latin1));
data.append(textDelimiter(String::Latin1));
data.append(char(d->rating));
data.append(ByteVector::fromUInt(d->counter));
data.append(ByteVector::fromUInt32BE(d->counter));
return data;

View File

@@ -57,14 +57,14 @@ class TAGLIB_EXPORT PopularimeterFrame : public Frame {
/*!
* Destroys this PopularimeterFrame instance.
*/
virtual ~PopularimeterFrame();
~PopularimeterFrame() override;
/*!
* Returns the text of this popularimeter.
*
* \see text()
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the email.
@@ -111,15 +111,15 @@ class TAGLIB_EXPORT PopularimeterFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
* The constructor used by the FrameFactory.
*/
explicit PopularimeterFrame(const ByteVector &data, Header *h);
explicit PopularimeterFrame(const PopularimeterFrame&);
PopularimeterFrame(const PopularimeterFrame&);
PopularimeterFrame &operator=(const PopularimeterFrame&);
class PopularimeterFramePrivate;

View File

@@ -24,9 +24,9 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include <tdebug.h>
#include "tbytevectorlist.h"
#include "id3v2tag.h"
#include "tdebug.h"
#include "privateframe.h"
@@ -87,8 +87,7 @@ void PrivateFrame::parseFields(const ByteVector &data) {
// Owner identifier is assumed to be Latin1
const int byteAlign = 1;
const int endOfOwner = data.find(textDelimiter(String::Latin1), 0, byteAlign);
const size_t endOfOwner = data.find(textDelimiter(String::Latin1), 0, 1);
d->owner = String(data.mid(0, endOfOwner));
d->data = data.mid(endOfOwner + 1);

View File

@@ -55,14 +55,14 @@ class TAGLIB_EXPORT PrivateFrame : public Frame {
/*!
* Destroys this private frame instance.
*/
virtual ~PrivateFrame();
~PrivateFrame() override;
/*!
* Returns the text of this private frame, currently just the owner.
*
* \see text()
*/
virtual String toString() const;
String toString() const override;
/*!
* \return The owner of the private frame.
@@ -89,8 +89,8 @@ class TAGLIB_EXPORT PrivateFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
@@ -98,7 +98,7 @@ class TAGLIB_EXPORT PrivateFrame : public Frame {
*/
explicit PrivateFrame(const ByteVector &data, Header *h);
explicit PrivateFrame(const PrivateFrame&);
PrivateFrame(const PrivateFrame&);
PrivateFrame &operator=(const PrivateFrame&);
class PrivateFramePrivate;

View File

@@ -23,21 +23,23 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include <tmap.h>
#include "tdebug.h"
#include "tmap.h"
#include "relativevolumeframe.h"
using namespace Strawberry_TagLib::TagLib;
using namespace ID3v2;
namespace {
struct ChannelData {
ChannelData() : channelType(RelativeVolumeFrame::Other), volumeAdjustment(0) {}
explicit ChannelData() : channelType(RelativeVolumeFrame::Other), volumeAdjustment(0) {}
RelativeVolumeFrame::ChannelType channelType;
short volumeAdjustment;
RelativeVolumeFrame::PeakVolume peakVolume;
};
} // namespace
class RelativeVolumeFrame::RelativeVolumeFramePrivate {
public:
@@ -79,50 +81,26 @@ short RelativeVolumeFrame::volumeAdjustmentIndex(ChannelType type) const {
return d->channels.contains(type) ? d->channels[type].volumeAdjustment : 0;
}
short RelativeVolumeFrame::volumeAdjustmentIndex() const {
return volumeAdjustmentIndex(MasterVolume);
}
void RelativeVolumeFrame::setVolumeAdjustmentIndex(short index, ChannelType type) {
d->channels[type].volumeAdjustment = index;
}
void RelativeVolumeFrame::setVolumeAdjustmentIndex(short index) {
setVolumeAdjustmentIndex(index, MasterVolume);
}
float RelativeVolumeFrame::volumeAdjustment(ChannelType type) const {
return d->channels.contains(type) ? float(d->channels[type].volumeAdjustment) / float(512) : 0;
}
float RelativeVolumeFrame::volumeAdjustment() const {
return volumeAdjustment(MasterVolume);
}
void RelativeVolumeFrame::setVolumeAdjustment(float adjustment, ChannelType type) {
d->channels[type].volumeAdjustment = short(adjustment * float(512));
}
void RelativeVolumeFrame::setVolumeAdjustment(float adjustment) {
setVolumeAdjustment(adjustment, MasterVolume);
}
RelativeVolumeFrame::PeakVolume RelativeVolumeFrame::peakVolume(ChannelType type) const {
return d->channels.contains(type) ? d->channels[type].peakVolume : PeakVolume();
}
RelativeVolumeFrame::PeakVolume RelativeVolumeFrame::peakVolume() const {
return peakVolume(MasterVolume);
}
void RelativeVolumeFrame::setPeakVolume(const PeakVolume &peak, ChannelType type) {
d->channels[type].peakVolume = peak;
}
void RelativeVolumeFrame::setPeakVolume(const PeakVolume &peak) {
setPeakVolume(peak, MasterVolume);
}
String RelativeVolumeFrame::identification() const {
return d->identification;
}
@@ -137,19 +115,19 @@ void RelativeVolumeFrame::setIdentification(const String &s) {
void RelativeVolumeFrame::parseFields(const ByteVector &data) {
int pos = 0;
d->identification = readStringField(data, String::Latin1, &pos);
size_t pos = 0;
d->identification = readStringField(data, String::Latin1, pos);
// Each channel is at least 4 bytes.
while (pos <= static_cast<int>(data.size()) - 4) {
while (pos + 4 <= data.size()) {
ChannelType type = ChannelType(data[pos]);
pos += 1;
ChannelData &channel = d->channels[type];
channel.volumeAdjustment = data.toShort(static_cast<unsigned int>(pos));
channel.volumeAdjustment = data.toInt16BE(pos);
pos += 2;
channel.peakVolume.bitsRepresentingPeak = data[pos];
@@ -176,7 +154,7 @@ ByteVector RelativeVolumeFrame::renderFields() const {
const ChannelData &channel = (*it).second;
data.append(char(type));
data.append(ByteVector::fromShort(channel.volumeAdjustment));
data.append(ByteVector::fromUInt16BE(channel.volumeAdjustment));
data.append(char(channel.peakVolume.bitsRepresentingPeak));
data.append(channel.peakVolume.peakVolume);
}

View File

@@ -105,26 +105,20 @@ class TAGLIB_EXPORT RelativeVolumeFrame : public Frame {
/*!
* Destroys the RelativeVolumeFrame instance.
*/
virtual ~RelativeVolumeFrame();
~RelativeVolumeFrame() override;
/*!
* Returns the frame's identification.
*
* \see identification()
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns a list of channels with information currently in the frame.
*/
List<ChannelType> channels() const;
/*
* There was a terrible API goof here, and while this can't be changed to the way it appears below for binary compatibility reasons, let's at least pretend that it looks clean.
*/
#ifdef DOXYGEN
/*!
* Returns the relative volume adjustment "index".
* As indicated by the ID3v2 standard this is a 16-bit signed integer that reflects the decibels of adjustment when divided by 512.
@@ -190,30 +184,6 @@ class TAGLIB_EXPORT RelativeVolumeFrame : public Frame {
*/
void setPeakVolume(const PeakVolume &peak, ChannelType type = MasterVolume);
#else
// BIC: Combine each of the following pairs of functions (or maybe just rework this junk altogether).
short volumeAdjustmentIndex(ChannelType type) const;
short volumeAdjustmentIndex() const;
void setVolumeAdjustmentIndex(short index, ChannelType type);
void setVolumeAdjustmentIndex(short index);
float volumeAdjustment(ChannelType type) const;
float volumeAdjustment() const;
void setVolumeAdjustment(float adjustment, ChannelType type);
void setVolumeAdjustment(float adjustment);
PeakVolume peakVolume(ChannelType type) const;
PeakVolume peakVolume() const;
void setPeakVolume(const PeakVolume &peak, ChannelType type);
void setPeakVolume(const PeakVolume &peak);
#endif
/*!
* Returns the identification for this frame.
*/
@@ -226,12 +196,12 @@ class TAGLIB_EXPORT RelativeVolumeFrame : public Frame {
void setIdentification(const String &s);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
explicit RelativeVolumeFrame(const ByteVector &data, Header *h);
explicit RelativeVolumeFrame(const RelativeVolumeFrame&);
RelativeVolumeFrame(const RelativeVolumeFrame&);
RelativeVolumeFrame &operator=(const RelativeVolumeFrame&);
class RelativeVolumeFramePrivate;

View File

@@ -24,19 +24,19 @@
***************************************************************************/
#include "synchronizedlyricsframe.h"
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include <tdebug.h>
#include <tpropertymap.h>
#include "tbytevectorlist.h"
#include "id3v2tag.h"
#include "tdebug.h"
#include "tpropertymap.h"
using namespace Strawberry_TagLib::TagLib;
using namespace ID3v2;
class SynchronizedLyricsFrame::SynchronizedLyricsFramePrivate {
public:
SynchronizedLyricsFramePrivate() : textEncoding(String::Latin1),
timestampFormat(SynchronizedLyricsFrame::AbsoluteMilliseconds),
type(SynchronizedLyricsFrame::Lyrics) {}
explicit SynchronizedLyricsFramePrivate() : textEncoding(String::Latin1),
timestampFormat(SynchronizedLyricsFrame::AbsoluteMilliseconds),
type(SynchronizedLyricsFrame::Lyrics) {}
String::Type textEncoding;
ByteVector language;
SynchronizedLyricsFrame::TimestampFormat timestampFormat;
@@ -124,7 +124,7 @@ void SynchronizedLyricsFrame::setSynchedText(
void SynchronizedLyricsFrame::parseFields(const ByteVector &data) {
const int end = data.size();
const size_t end = data.size();
if (end < 7) {
debug("A synchronized lyrics frame must contain at least 7 bytes.");
return;
@@ -135,9 +135,9 @@ void SynchronizedLyricsFrame::parseFields(const ByteVector &data) {
d->timestampFormat = TimestampFormat(data[4]);
d->type = Type(data[5]);
int pos = 6;
size_t pos = 6;
d->description = readStringField(data, d->textEncoding, &pos);
d->description = readStringField(data, d->textEncoding, pos);
if (pos == 6)
return;
@@ -150,7 +150,7 @@ void SynchronizedLyricsFrame::parseFields(const ByteVector &data) {
*/
String::Type encWithEndianness = d->textEncoding;
if (d->textEncoding == String::UTF16) {
unsigned short bom = data.toUShort(6, true);
unsigned short bom = data.toUInt16BE(6);
if (bom == 0xfffe) {
encWithEndianness = String::UTF16LE;
}
@@ -164,16 +164,16 @@ void SynchronizedLyricsFrame::parseFields(const ByteVector &data) {
String::Type enc = d->textEncoding;
// If a UTF16 string has no BOM, use the encoding found above.
if (enc == String::UTF16 && pos + 1 < end) {
unsigned short bom = data.toUShort(pos, true);
unsigned short bom = data.toUInt16BE(pos);
if (bom != 0xfffe && bom != 0xfeff) {
enc = encWithEndianness;
}
}
String text = readStringField(data, enc, &pos);
String text = readStringField(data, enc, pos);
if (pos + 4 > end)
return;
unsigned int time = data.toUInt(pos, true);
unsigned int time = data.toUInt32BE(pos);
pos += 4;
d->synchedText.append(SynchedText(time, text));
@@ -206,7 +206,7 @@ ByteVector SynchronizedLyricsFrame::renderFields() const {
const SynchedText &entry = *it;
v.append(entry.text.data(encoding));
v.append(textDelimiter(encoding));
v.append(ByteVector::fromUInt(entry.time));
v.append(ByteVector::fromUInt32BE(entry.time));
}
return v;

View File

@@ -106,14 +106,14 @@ class TAGLIB_EXPORT SynchronizedLyricsFrame : public Frame {
/*!
* Destroys this SynchronizedLyricsFrame instance.
*/
virtual ~SynchronizedLyricsFrame();
~SynchronizedLyricsFrame() override;
/*!
* Returns the description of this synchronized lyrics frame.
*
* \see description()
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the text encoding that will be used in rendering this frame.
@@ -205,15 +205,15 @@ class TAGLIB_EXPORT SynchronizedLyricsFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
* The constructor used by the FrameFactory.
*/
explicit SynchronizedLyricsFrame(const ByteVector &data, Header *h);
explicit SynchronizedLyricsFrame(const SynchronizedLyricsFrame&);
SynchronizedLyricsFrame(const SynchronizedLyricsFrame&);
SynchronizedLyricsFrame &operator=(const SynchronizedLyricsFrame&);
class SynchronizedLyricsFramePrivate;

View File

@@ -23,9 +23,9 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevectorlist.h>
#include <tpropertymap.h>
#include <tdebug.h>
#include "tbytevectorlist.h"
#include "tpropertymap.h"
#include "tdebug.h"
#include "tableofcontentsframe.h"
@@ -34,7 +34,7 @@ using namespace ID3v2;
class TableOfContentsFrame::TableOfContentsFramePrivate {
public:
TableOfContentsFramePrivate() : tagHeader(nullptr), isTopLevel(false), isOrdered(false) {
explicit TableOfContentsFramePrivate() : tagHeader(nullptr), isTopLevel(false), isOrdered(false) {
embeddedFrameList.setAutoDelete(true);
}
@@ -259,7 +259,7 @@ TableOfContentsFrame *TableOfContentsFrame::findTopLevel(const ID3v2::Tag *tag)
void TableOfContentsFrame::parseFields(const ByteVector &data) {
unsigned int size = data.size();
size_t size = data.size();
if (size < 6) {
debug("A CTOC frame must contain at least 6 bytes (1 byte element ID terminated by "
"null, 1 byte flags, 1 byte entry count and 1 byte child element ID terminated "
@@ -267,14 +267,14 @@ void TableOfContentsFrame::parseFields(const ByteVector &data) {
return;
}
int pos = 0;
unsigned int embPos = 0;
d->elementID = readStringField(data, String::Latin1, &pos).data(String::Latin1);
size_t pos = 0;
size_t embPos = 0;
d->elementID = readStringField(data, String::Latin1, pos).data(String::Latin1);
d->isTopLevel = (data.at(pos) & 2) != 0;
d->isOrdered = (data.at(pos++) & 1) != 0;
unsigned int entryCount = static_cast<unsigned char>(data.at(pos++));
for (unsigned int i = 0; i < entryCount; i++) {
ByteVector childElementID = readStringField(data, String::Latin1, &pos).data(String::Latin1);
ByteVector childElementID = readStringField(data, String::Latin1, pos).data(String::Latin1);
d->childElements.append(childElementID);
}

View File

@@ -61,7 +61,7 @@ class TAGLIB_EXPORT TableOfContentsFrame : public ID3v2::Frame {
/*!
* Destroys the frame.
*/
~TableOfContentsFrame();
~TableOfContentsFrame() override;
/*!
* Returns the elementID of the frame.
@@ -200,7 +200,7 @@ class TAGLIB_EXPORT TableOfContentsFrame : public ID3v2::Frame {
*/
void removeEmbeddedFrames(const ByteVector &id);
virtual String toString() const;
String toString() const override;
PropertyMap asProperties() const;
@@ -223,12 +223,12 @@ class TAGLIB_EXPORT TableOfContentsFrame : public ID3v2::Frame {
static TableOfContentsFrame *findTopLevel(const Tag *tag);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
explicit TableOfContentsFrame(const ID3v2::Header *tagHeader, const ByteVector &data, Header *h);
explicit TableOfContentsFrame(const TableOfContentsFrame&);
TableOfContentsFrame(const TableOfContentsFrame&);
TableOfContentsFrame &operator=(const TableOfContentsFrame&);
class TableOfContentsFramePrivate;

View File

@@ -23,8 +23,8 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include "tbytevectorlist.h"
#include "id3v2tag.h"
#include "textidentificationframe.h"
#include "tpropertymap.h"
#include "id3v1genres.h"
@@ -34,7 +34,7 @@ using namespace ID3v2;
class TextIdentificationFrame::TextIdentificationFramePrivate {
public:
TextIdentificationFramePrivate() : textEncoding(String::Latin1) {}
explicit TextIdentificationFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
StringList fieldList;
};
@@ -159,8 +159,8 @@ PropertyMap TextIdentificationFrame::asProperties() const {
for (StringList::Iterator it = values.begin(); it != values.end(); ++it) {
// ID3v2 specifies ISO8601 timestamps which contain a 'T' as separator between date and time.
// Since this is unusual in other formats, the T is removed.
int tpos = it->find("T");
if (tpos != -1)
const size_t tpos = it->find("T");
if (tpos != String::npos())
(*it)[tpos] = ' ';
}
}
@@ -405,7 +405,7 @@ UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data,
void UserTextIdentificationFrame::checkFields() {
int fields = fieldList().size();
const size_t fields = fieldList().size();
if (fields == 0)
setDescription(String());

View File

@@ -136,7 +136,7 @@ class TAGLIB_EXPORT TextIdentificationFrame : public Frame {
/*!
* Destroys this TextIdentificationFrame instance.
*/
virtual ~TextIdentificationFrame();
~TextIdentificationFrame() override;
/*!
* Text identification frames are a list of string fields.
@@ -151,8 +151,8 @@ class TAGLIB_EXPORT TextIdentificationFrame : public Frame {
// Reimplementations.
virtual void setText(const String &s);
virtual String toString() const;
void setText(const String &s) override;
String toString() const override;
/*!
* Returns the text encoding that will be used in rendering this frame.
@@ -190,8 +190,8 @@ class TAGLIB_EXPORT TextIdentificationFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
/*!
* The constructor used by the FrameFactory.
@@ -245,7 +245,7 @@ class TAGLIB_EXPORT UserTextIdentificationFrame : public TextIdentificationFrame
*/
UserTextIdentificationFrame(const String &description, const StringList &values, String::Type encoding = String::UTF8);
virtual String toString() const;
String toString() const override;
/*!
* Returns the description for this frame.
@@ -259,7 +259,7 @@ class TAGLIB_EXPORT UserTextIdentificationFrame : public TextIdentificationFrame
void setDescription(const String &s);
StringList fieldList() const;
void setText(const String &text);
void setText(const String &text) override;
void setText(const StringList &fields);
/*!

View File

@@ -23,9 +23,9 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevectorlist.h>
#include <tpropertymap.h>
#include <tdebug.h>
#include "tbytevectorlist.h"
#include "tpropertymap.h"
#include "tdebug.h"
#include "id3v2tag.h"
#include "uniquefileidentifierframe.h"
@@ -112,8 +112,8 @@ void UniqueFileIdentifierFrame::parseFields(const ByteVector &data) {
return;
}
int pos = 0;
d->owner = readStringField(data, String::Latin1, &pos);
size_t pos = 0;
d->owner = readStringField(data, String::Latin1, pos);
d->identifier = data.mid(pos);
}

View File

@@ -56,7 +56,7 @@ class TAGLIB_EXPORT UniqueFileIdentifierFrame : public ID3v2::Frame {
/*!
* Destroys the frame.
*/
~UniqueFileIdentifierFrame();
~UniqueFileIdentifierFrame() override;
/*!
* Returns the owner for the frame; essentially this is the key for determining which identification scheme this key belongs to.
@@ -87,7 +87,7 @@ class TAGLIB_EXPORT UniqueFileIdentifierFrame : public ID3v2::Frame {
*/
void setIdentifier(const ByteVector &v);
virtual String toString() const;
String toString() const override;
PropertyMap asProperties() const;
@@ -99,11 +99,11 @@ class TAGLIB_EXPORT UniqueFileIdentifierFrame : public ID3v2::Frame {
static UniqueFileIdentifierFrame *findByOwner(const Tag *tag, const String &o);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
explicit UniqueFileIdentifierFrame(const UniqueFileIdentifierFrame&);
UniqueFileIdentifierFrame(const UniqueFileIdentifierFrame&);
UniqueFileIdentifierFrame &operator=(const UniqueFileIdentifierFrame&);
explicit UniqueFileIdentifierFrame(const ByteVector &data, Header *h);

View File

@@ -49,10 +49,10 @@ class TAGLIB_EXPORT UnknownFrame : public Frame {
friend class FrameFactory;
public:
UnknownFrame(const ByteVector &data);
virtual ~UnknownFrame();
explicit UnknownFrame(const ByteVector &data);
~UnknownFrame() override;
virtual String toString() const;
String toString() const override;
/*!
* Returns the field data (everything but the header) for this frame.
@@ -60,12 +60,12 @@ class TAGLIB_EXPORT UnknownFrame : public Frame {
ByteVector data() const;
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
explicit UnknownFrame(const ByteVector &data, Header *h);
explicit UnknownFrame(const UnknownFrame&);
UnknownFrame(const UnknownFrame&);
UnknownFrame &operator=(const UnknownFrame&);
class UnknownFramePrivate;

View File

@@ -27,17 +27,17 @@
***************************************************************************/
#include "unsynchronizedlyricsframe.h"
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include <tdebug.h>
#include <tpropertymap.h>
#include "tbytevectorlist.h"
#include "id3v2tag.h"
#include "tdebug.h"
#include "tpropertymap.h"
using namespace Strawberry_TagLib::TagLib;
using namespace ID3v2;
class UnsynchronizedLyricsFrame::UnsynchronizedLyricsFramePrivate {
public:
UnsynchronizedLyricsFramePrivate() : textEncoding(String::Latin1) {}
explicit UnsynchronizedLyricsFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
ByteVector language;
String description;

View File

@@ -55,14 +55,14 @@ class TAGLIB_EXPORT UnsynchronizedLyricsFrame : public Frame {
/*!
* Destroys this UnsynchronizedLyricsFrame instance.
*/
virtual ~UnsynchronizedLyricsFrame();
~UnsynchronizedLyricsFrame() override;
/*!
* Returns the text of this unsynchronized lyrics frame.
*
* \see text()
*/
virtual String toString() const;
String toString() const override;
/*!
* Returns the language encoding as a 3 byte encoding as specified by
@@ -111,7 +111,7 @@ class TAGLIB_EXPORT UnsynchronizedLyricsFrame : public Frame {
*
* \see text()
*/
virtual void setText(const String &s);
void setText(const String &s) override;
/*!
* Returns the text encoding that will be used in rendering this frame.
@@ -154,15 +154,15 @@ class TAGLIB_EXPORT UnsynchronizedLyricsFrame : public Frame {
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
private:
/*!
* The constructor used by the FrameFactory.
*/
explicit UnsynchronizedLyricsFrame(const ByteVector &data, Header *h);
explicit UnsynchronizedLyricsFrame(const UnsynchronizedLyricsFrame&);
UnsynchronizedLyricsFrame(const UnsynchronizedLyricsFrame&);
UnsynchronizedLyricsFrame &operator=(const UnsynchronizedLyricsFrame&);
class UnsynchronizedLyricsFramePrivate;

View File

@@ -28,9 +28,9 @@
#include "urllinkframe.h"
#include "id3v2tag.h"
#include <tdebug.h>
#include <tstringlist.h>
#include <tpropertymap.h>
#include "tdebug.h"
#include "tstringlist.h"
#include "tpropertymap.h"
using namespace Strawberry_TagLib::TagLib;
using namespace ID3v2;
@@ -42,7 +42,7 @@ class UrlLinkFrame::UrlLinkFramePrivate {
class UserUrlLinkFrame::UserUrlLinkFramePrivate {
public:
UserUrlLinkFramePrivate() : textEncoding(String::Latin1) {}
explicit UserUrlLinkFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
String description;
};
@@ -179,22 +179,22 @@ void UserUrlLinkFrame::parseFields(const ByteVector &data) {
return;
}
int pos = 0;
size_t pos = 0;
d->textEncoding = String::Type(data[0]);
pos += 1;
if (d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8) {
int offset = data.find(textDelimiter(d->textEncoding), pos);
if (offset < pos)
const size_t offset = data.find(textDelimiter(d->textEncoding), pos);
if (offset == ByteVector::npos() || offset < pos)
return;
d->description = String(data.mid(pos, offset - pos), d->textEncoding);
pos = offset + 1;
}
else {
int len = data.mid(pos).find(textDelimiter(d->textEncoding), 0, 2);
if (len < 0)
const size_t len = data.mid(pos).find(textDelimiter(d->textEncoding), 0, 2);
if (len == ByteVector::npos())
return;
d->description = String(data.mid(pos, len), d->textEncoding);

View File

@@ -52,7 +52,7 @@ class TAGLIB_EXPORT UrlLinkFrame : public Frame {
/*!
* Destroys this UrlLinkFrame instance.
*/
virtual ~UrlLinkFrame();
~UrlLinkFrame() override;
/*!
* Returns the URL.
@@ -66,13 +66,13 @@ class TAGLIB_EXPORT UrlLinkFrame : public Frame {
// Reimplementations.
virtual void setText(const String &s);
virtual String toString() const;
void setText(const String &s) override;
String toString() const override;
PropertyMap asProperties() const;
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
/*!
* The constructor used by the FrameFactory.
@@ -114,11 +114,11 @@ class TAGLIB_EXPORT UserUrlLinkFrame : public UrlLinkFrame {
/*!
* Destroys this UserUrlLinkFrame instance.
*/
virtual ~UserUrlLinkFrame();
~UserUrlLinkFrame() override;
// Reimplementations.
virtual String toString() const;
String toString() const override;
/*!
* Returns the text encoding that will be used in rendering this frame.
@@ -164,8 +164,8 @@ class TAGLIB_EXPORT UserUrlLinkFrame : public UrlLinkFrame {
static UserUrlLinkFrame *find(Tag *tag, const String &description);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
void parseFields(const ByteVector &data) override;
ByteVector renderFields() const override;
/*!
* The constructor used by the FrameFactory.
@@ -173,7 +173,7 @@ class TAGLIB_EXPORT UserUrlLinkFrame : public UrlLinkFrame {
UserUrlLinkFrame(const ByteVector &data, Header *h);
private:
explicit UserUrlLinkFrame(const UserUrlLinkFrame&);
UserUrlLinkFrame(const UserUrlLinkFrame&);
UserUrlLinkFrame &operator=(const UserUrlLinkFrame&);
class UserUrlLinkFramePrivate;

View File

@@ -31,7 +31,7 @@ using namespace ID3v2;
class ExtendedHeader::ExtendedHeaderPrivate {
public:
ExtendedHeaderPrivate() : size(0) {}
explicit ExtendedHeaderPrivate() : size(0) {}
unsigned int size;
};

View File

@@ -78,7 +78,7 @@ class TAGLIB_EXPORT ExtendedHeader {
void parse(const ByteVector &data);
private:
explicit ExtendedHeader(const ExtendedHeader&);
ExtendedHeader(const ExtendedHeader&);
ExtendedHeader &operator=(const ExtendedHeader&);
class ExtendedHeaderPrivate;

View File

@@ -68,7 +68,7 @@ class TAGLIB_EXPORT Footer {
ByteVector render(const Header *header) const;
private:
explicit Footer(const Footer&);
Footer(const Footer&);
Footer &operator=(const Footer&);
class FooterPrivate;

View File

@@ -25,9 +25,9 @@
#include <bitset>
#include <tdebug.h>
#include <tstringlist.h>
#include <tzlib.h>
#include "tdebug.h"
#include "tstringlist.h"
#include "tzlib.h"
#include "id3v2tag.h"
#include "id3v2frame.h"
@@ -46,7 +46,7 @@ using namespace ID3v2;
class Frame::FramePrivate {
public:
FramePrivate() : header(nullptr) {}
explicit FramePrivate() : header(nullptr) {}
~FramePrivate() {
delete header;
@@ -222,10 +222,10 @@ void Frame::parse(const ByteVector &data) {
ByteVector Frame::fieldData(const ByteVector &frameData) const {
unsigned int headerSize = Header::size(d->header->version());
const size_t headerSize = Header::size(d->header->version());
unsigned int frameDataOffset = headerSize;
unsigned int frameDataLength = size();
size_t frameDataOffset = headerSize;
size_t frameDataLength = size();
if (d->header->compression() || d->header->dataLengthIndicator()) {
frameDataLength = SynchData::toUInt(frameData.mid(headerSize, 4));
@@ -250,27 +250,22 @@ ByteVector Frame::fieldData(const ByteVector &frameData) const {
}
String Frame::readStringField(const ByteVector &data, String::Type encoding, int *position) {
int start = 0;
if (!position)
position = &start;
String Frame::readStringField(const ByteVector &data, String::Type encoding, size_t &position) {
ByteVector delimiter = textDelimiter(encoding);
int end = data.find(delimiter, *position, delimiter.size());
const size_t end = data.find(delimiter, position, delimiter.size());
if (end < *position)
if (end == ByteVector::npos() || end < position)
return String();
String str;
if (encoding == String::Latin1)
str = Tag::latin1StringHandler()->parse(data.mid(*position, end - *position));
str = Tag::latin1StringHandler()->parse(data.mid(position, end - position));
else
str = String(data.mid(*position, end - *position), encoding);
str = String(data.mid(position, end - position), encoding);
*position = end + delimiter.size();
position = end + delimiter.size();
return str;
@@ -594,7 +589,7 @@ void Frame::Header::setData(const ByteVector &data, unsigned int version) {
return;
}
d->frameSize = data.toUInt(3, 3, true);
d->frameSize = data.toUInt24BE(3);
break;
}
@@ -621,7 +616,7 @@ void Frame::Header::setData(const ByteVector &data, unsigned int version) {
// Set the size -- the frame size is the four bytes starting at byte four in
// the frame header (structure 4)
d->frameSize = data.toUInt(4U);
d->frameSize = data.toUInt32BE(4);
{ // read the first byte of flags
std::bitset<8> flags(data[8]);
@@ -667,7 +662,7 @@ void Frame::Header::setData(const ByteVector &data, unsigned int version) {
// 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.toUInt(4U);
const unsigned int uintSize = data.toUInt32BE(4);
if (isValidFrameID(data.mid(uintSize + 10, 4))) {
d->frameSize = uintSize;
}
@@ -765,7 +760,7 @@ ByteVector Frame::Header::render() const {
ByteVector flags(2, char(0)); // just blank for the moment
ByteVector v = d->frameID +
(d->version == 3 ? ByteVector::fromUInt(d->frameSize) : SynchData::fromUInt(d->frameSize)) +
(d->version == 3 ? ByteVector::fromUInt32BE(d->frameSize) : SynchData::fromUInt(d->frameSize)) +
flags;
return v;

View File

@@ -167,7 +167,7 @@ class TAGLIB_EXPORT Frame {
*
* The ownership of this header will be assigned to the frame and the header will be deleted when the frame is destroyed.
*/
Frame(Header *h);
explicit Frame(Header *h);
/*!
* Returns a pointer to the frame header.
@@ -208,7 +208,7 @@ class TAGLIB_EXPORT Frame {
* If \a position is passed in it is used both as the starting point and is updated to return the position just after the string that has been read.
* This is useful for reading strings sequentially.
*/
String readStringField(const ByteVector &data, String::Type encoding, int *position = 0);
String readStringField(const ByteVector &data, String::Type encoding, size_t &position);
/*!
* Checks a the list of string values to see if they can be used with the specified encoding and returns the recommended encoding.
@@ -271,7 +271,7 @@ class TAGLIB_EXPORT Frame {
static void splitProperties(const PropertyMap &original, PropertyMap &singleFrameProperties, PropertyMap &tiplProperties, PropertyMap &tmclProperties);
private:
explicit Frame(const Frame&);
Frame(const Frame&);
Frame &operator=(const Frame&);
class FramePrivate;
@@ -455,7 +455,7 @@ class TAGLIB_EXPORT Frame::Header {
ByteVector render() const;
private:
explicit Header(const Header&);
Header(const Header&);
Header &operator=(const Header&);
class HeaderPrivate;

View File

@@ -23,8 +23,8 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include <tzlib.h>
#include "tdebug.h"
#include "tzlib.h"
#include "id3v2framefactory.h"
#include "id3v2synchdata.h"
@@ -59,7 +59,7 @@ void updateGenre(TextIdentificationFrame *frame) {
for (StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
String s = *it;
int end = s.find(")");
size_t end = s.find(")");
if (s.startsWith("(") && end > 0) {
// "(12)Genre"
@@ -87,7 +87,7 @@ void updateGenre(TextIdentificationFrame *frame) {
class FrameFactory::FrameFactoryPrivate {
public:
FrameFactoryPrivate() : defaultEncoding(String::Latin1), useDefaultEncoding(false) {}
explicit FrameFactoryPrivate() : defaultEncoding(String::Latin1), useDefaultEncoding(false) {}
String::Type defaultEncoding;
bool useDefaultEncoding;

View File

@@ -114,7 +114,7 @@ class TAGLIB_EXPORT FrameFactory {
virtual bool updateFrame(Frame::Header *header) const;
private:
explicit FrameFactory(const FrameFactory&);
FrameFactory(const FrameFactory&);
FrameFactory &operator=(const FrameFactory&);
static FrameFactory factory;

View File

@@ -26,8 +26,8 @@
#include <iostream>
#include <bitset>
#include <tstring.h>
#include <tdebug.h>
#include "tstring.h"
#include "tdebug.h"
#include "id3v2header.h"
#include "id3v2footer.h"
@@ -38,13 +38,13 @@ using namespace ID3v2;
class Header::HeaderPrivate {
public:
HeaderPrivate() : majorVersion(4),
revisionNumber(0),
unsynchronisation(false),
extendedHeader(false),
experimentalIndicator(false),
footerPresent(false),
tagSize(0) {}
explicit HeaderPrivate() : majorVersion(4),
revisionNumber(0),
unsynchronisation(false),
extendedHeader(false),
experimentalIndicator(false),
footerPresent(false),
tagSize(0) {}
unsigned int majorVersion;
unsigned int revisionNumber;

View File

@@ -151,7 +151,7 @@ class TAGLIB_EXPORT Header {
void parse(const ByteVector &data);
private:
explicit Header(const Header&);
Header(const Header&);
Header &operator=(const Header&);
class HeaderPrivate;

View File

@@ -34,7 +34,7 @@ unsigned int SynchData::toUInt(const ByteVector &data) {
unsigned int sum = 0;
bool notSynchSafe = false;
int last = data.size() > 4 ? 3 : data.size() - 1;
const int last = data.size() > 4 ? 3 : data.size() - 1;
for (int i = 0; i <= last; i++) {
if (data[i] & 0x80) {
@@ -49,12 +49,12 @@ unsigned int SynchData::toUInt(const ByteVector &data) {
// 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.
if (data.size() >= 4) {
sum = data.toUInt(0, true);
sum = data.toUInt32BE(0);
}
else {
ByteVector tmp(data);
tmp.resize(4);
sum = tmp.toUInt(0, true);
sum = tmp.toUInt32BE(0);
}
}

View File

@@ -25,10 +25,11 @@
#include <algorithm>
#include <tfile.h>
#include <tbytevector.h>
#include <tpropertymap.h>
#include <tdebug.h>
#include "tfile.h"
#include "tbytevector.h"
#include "tpropertymap.h"
#include "tpicturemap.h"
#include "tdebug.h"
#include "id3v2tag.h"
#include "id3v2header.h"
@@ -37,6 +38,7 @@
#include "id3v2synchdata.h"
#include "id3v1genres.h"
#include "frames/attachedpictureframe.h"
#include "frames/textidentificationframe.h"
#include "frames/commentsframe.h"
#include "frames/urllinkframe.h"
@@ -48,20 +50,34 @@ using namespace Strawberry_TagLib::TagLib;
using namespace ID3v2;
namespace {
const ID3v2::Latin1StringHandler defaultStringHandler;
const ID3v2::Latin1StringHandler *stringHandler = &defaultStringHandler;
class DefaultStringHandler : public Strawberry_TagLib::TagLib::StringHandler {
public:
explicit DefaultStringHandler() : Strawberry_TagLib::TagLib::StringHandler() {}
const long MinPaddingSize = 1024;
const long MaxPaddingSize = 1024 * 1024;
String parse(const ByteVector &data) const override {
return String(data, String::Latin1);
}
ByteVector render(const String&) const override {
// Not implemented on purpose. This function is never used.
return ByteVector();
}
};
const DefaultStringHandler defaultStringHandler;
const Strawberry_TagLib::TagLib::StringHandler *stringHandler = &defaultStringHandler;
const long long MinPaddingSize = 1024;
const long long MaxPaddingSize = 1024 * 1024;
} // namespace
class ID3v2::Tag::TagPrivate {
public:
TagPrivate() : factory(nullptr),
file(nullptr),
tagOffset(0),
extendedHeader(nullptr),
footer(nullptr) {
explicit TagPrivate() : factory(nullptr),
file(nullptr),
tagOffset(0),
extendedHeader(nullptr),
footer(nullptr) {
frameList.setAutoDelete(true);
}
@@ -73,7 +89,7 @@ class ID3v2::Tag::TagPrivate {
const FrameFactory *factory;
File *file;
long tagOffset;
long long tagOffset;
Header header;
ExtendedHeader *extendedHeader;
@@ -83,18 +99,6 @@ class ID3v2::Tag::TagPrivate {
FrameList frameList;
};
////////////////////////////////////////////////////////////////////////////////
// StringHandler implementation
////////////////////////////////////////////////////////////////////////////////
Latin1StringHandler::Latin1StringHandler() {}
Latin1StringHandler::~Latin1StringHandler() {}
String Latin1StringHandler::parse(const ByteVector &data) const {
return String(data, String::Latin1);
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
@@ -103,7 +107,7 @@ ID3v2::Tag::Tag() : d(new TagPrivate()) {
d->factory = FrameFactory::instance();
}
ID3v2::Tag::Tag(File *file, long tagOffset, const FrameFactory *factory) : d(new TagPrivate()) {
ID3v2::Tag::Tag(File *file, long long tagOffset, const FrameFactory *factory) : d(new TagPrivate()) {
d->factory = factory;
d->file = file;
d->tagOffset = tagOffset;
@@ -206,7 +210,90 @@ unsigned int ID3v2::Tag::track() const {
if (!d->frameListMap["TRCK"].isEmpty())
return d->frameListMap["TRCK"].front()->toString().toInt();
return 0;
}
Strawberry_TagLib::TagLib::PictureMap ID3v2::Tag::pictures() const {
if (!d->frameListMap.contains("APIC"))
return PictureMap();
PictureMap map;
FrameList frameListMap = d->frameListMap["APIC"];
for (FrameList::ConstIterator it = frameListMap.begin(); it != frameListMap.end(); ++it) {
const AttachedPictureFrame *frame = static_cast<AttachedPictureFrame *>(*it);
Picture::Type type;
switch (frame->type()) {
case AttachedPictureFrame::FileIcon:
type = Picture::FileIcon;
break;
case AttachedPictureFrame::OtherFileIcon:
type = Picture::OtherFileIcon;
break;
case AttachedPictureFrame::FrontCover:
type = Picture::FrontCover;
break;
case AttachedPictureFrame::BackCover:
type = Picture::BackCover;
break;
case AttachedPictureFrame::LeafletPage:
type = Picture::LeafletPage;
break;
case AttachedPictureFrame::Media:
type = Picture::Media;
break;
case AttachedPictureFrame::LeadArtist:
type = Picture::LeadArtist;
break;
case AttachedPictureFrame::Artist:
type = Picture::Artist;
break;
case AttachedPictureFrame::Conductor:
type = Picture::Conductor;
break;
case AttachedPictureFrame::Band:
type = Picture::Band;
break;
case AttachedPictureFrame::Composer:
type = Picture::Composer;
break;
case AttachedPictureFrame::Lyricist:
type = Picture::Lyricist;
break;
case AttachedPictureFrame::RecordingLocation:
type = Picture::RecordingLocation;
break;
case AttachedPictureFrame::DuringRecording:
type = Picture::DuringRecording;
break;
case AttachedPictureFrame::DuringPerformance:
type = Picture::DuringPerformance;
break;
case AttachedPictureFrame::MovieScreenCapture:
type = Picture::MovieScreenCapture;
break;
case AttachedPictureFrame::ColouredFish:
type = Picture::ColouredFish;
break;
case AttachedPictureFrame::Illustration:
type = Picture::Illustration;
break;
case AttachedPictureFrame::BandLogo:
type = Picture::BandLogo;
break;
case AttachedPictureFrame::PublisherLogo:
type = Picture::PublisherLogo;
break;
default:
type = Picture::Other;
break;
}
Picture picture(frame->picture(), type, frame->mimeType(), frame->description());
map.insert(picture);
}
return PictureMap(map);
}
@@ -282,6 +369,92 @@ void ID3v2::Tag::setTrack(unsigned int i) {
setTextFrame("TRCK", String::number(i));
}
void ID3v2::Tag::setPictures(const PictureMap &l) {
removeFrames("APIC");
for (PictureMap::ConstIterator it = l.begin(); it != l.end(); ++it) {
PictureList list = it->second;
FrameList framesAdded;
for (PictureList::ConstIterator it2 = list.begin(); it2 != list.end(); ++it2) {
const Picture picture = (*it2);
AttachedPictureFrame *frame = new AttachedPictureFrame();
frame->setPicture(picture.data());
frame->setMimeType(picture.mime());
frame->setDescription(picture.description());
switch (picture.type()) {
case Picture::Other:
frame->setType(AttachedPictureFrame::Other);
break;
case Picture::FileIcon:
frame->setType(AttachedPictureFrame::FileIcon);
break;
case Picture::OtherFileIcon:
frame->setType(AttachedPictureFrame::OtherFileIcon);
break;
case Picture::FrontCover:
frame->setType(AttachedPictureFrame::FrontCover);
break;
case Picture::BackCover:
frame->setType(AttachedPictureFrame::BackCover);
break;
case Picture::LeafletPage:
frame->setType(AttachedPictureFrame::LeafletPage);
break;
case Picture::Media:
frame->setType(AttachedPictureFrame::Media);
break;
case Picture::LeadArtist:
frame->setType(AttachedPictureFrame::LeadArtist);
break;
case Picture::Artist:
frame->setType(AttachedPictureFrame::Artist);
break;
case Picture::Conductor:
frame->setType(AttachedPictureFrame::Conductor);
break;
case Picture::Band:
frame->setType(AttachedPictureFrame::Band);
break;
case Picture::Composer:
frame->setType(AttachedPictureFrame::Composer);
break;
case Picture::Lyricist:
frame->setType(AttachedPictureFrame::Lyricist);
break;
case Picture::RecordingLocation:
frame->setType(AttachedPictureFrame::RecordingLocation);
break;
case Picture::DuringRecording:
frame->setType(AttachedPictureFrame::DuringRecording);
break;
case Picture::DuringPerformance:
frame->setType(AttachedPictureFrame::DuringPerformance);
break;
case Picture::MovieScreenCapture:
frame->setType(AttachedPictureFrame::MovieScreenCapture);
break;
case Picture::ColouredFish:
frame->setType(AttachedPictureFrame::ColouredFish);
break;
case Picture::Illustration:
frame->setType(AttachedPictureFrame::Illustration);
break;
case Picture::BandLogo:
frame->setType(AttachedPictureFrame::BandLogo);
break;
case Picture::PublisherLogo:
frame->setType(AttachedPictureFrame::PublisherLogo);
break;
}
framesAdded.append(frame);
}
for (FrameList::ConstIterator it2 = framesAdded.begin(); it2 != framesAdded.end(); ++it2)
addFrame(*it2);
}
}
bool ID3v2::Tag::isEmpty() const {
return d->frameList.isEmpty();
}
@@ -430,10 +603,6 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps) {
}
ByteVector ID3v2::Tag::render() const {
return render(ID3v2::v4);
}
void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const {
#ifdef NO_ITUNES_HACKS
const char *unsupportedFrames[] = { "ASPI", "EQU2", "RVA2", "SEEK", "SIGN", "TDRL", "TDTG", "TMOO", "TPRO", "TSOA", "TSOT", "TSST", "TSOP", nullptr };
@@ -575,8 +744,8 @@ ByteVector ID3v2::Tag::render(Version version) const {
// Compute the amount of padding, and append that to tagData.
long originalSize = d->header.tagSize();
long paddingSize = originalSize - (tagData.size() - Header::size());
long long originalSize = d->header.tagSize();
long long paddingSize = originalSize - (tagData.size() - Header::size());
if (paddingSize <= 0) {
paddingSize = MinPaddingSize;
@@ -584,7 +753,7 @@ ByteVector ID3v2::Tag::render(Version version) const {
else {
// Padding won't increase beyond 1% of the file size or 1MB.
long threshold = d->file ? d->file->length() / 100 : 0;
long long threshold = d->file ? d->file->length() / 100 : 0;
threshold = std::max(threshold, MinPaddingSize);
threshold = std::min(threshold, MaxPaddingSize);
@@ -606,11 +775,11 @@ ByteVector ID3v2::Tag::render(Version version) const {
}
Latin1StringHandler const *ID3v2::Tag::latin1StringHandler() {
Strawberry_TagLib::TagLib::StringHandler const *ID3v2::Tag::latin1StringHandler() {
return stringHandler;
}
void ID3v2::Tag::setLatin1StringHandler(const Latin1StringHandler *handler) {
void ID3v2::Tag::setLatin1StringHandler(const Strawberry_TagLib::TagLib::StringHandler *handler) {
if (handler)
stringHandler = handler;
else
@@ -671,8 +840,8 @@ void ID3v2::Tag::parse(const ByteVector &origData) {
if (d->header.unsynchronisation() && d->header.majorVersion() <= 3)
data = SynchData::decode(data);
unsigned int frameDataPosition = 0;
unsigned int frameDataLength = data.size();
size_t frameDataPosition = 0;
size_t frameDataLength = data.size();
// check for extended header

View File

@@ -29,6 +29,7 @@
#include "tag.h"
#include "tbytevector.h"
#include "tstring.h"
#include "tstringhandler.h"
#include "tlist.h"
#include "tmap.h"
#include "taglib_export.h"
@@ -50,34 +51,6 @@ class Footer;
typedef List<Frame *> FrameList;
typedef Map<ByteVector, FrameList> FrameListMap;
//! An abstraction for the ISO-8859-1 string to data encoding in ID3v2 tags.
/*!
* ID3v2 tag can store strings in ISO-8859-1 (Latin1), and TagLib only supports genuine ISO-8859-1 by default.
* However, in practice, non ISO-8859-1 encodings are often used instead of ISO-8859-1,
* such as Windows-1252 for western languages, Shift_JIS for Japanese and so on.
*
* Here is an option to read such tags by subclassing this class,
* reimplementing parse() and setting your reimplementation as the default
* with ID3v2::Tag::setStringHandler().
*
* \note Writing non-ISO-8859-1 tags is not implemented intentionally.
* Use UTF-16 or UTF-8 instead.
*
* \see ID3v2::Tag::setStringHandler()
*/
class TAGLIB_EXPORT Latin1StringHandler {
public:
explicit Latin1StringHandler();
virtual ~Latin1StringHandler();
/*!
* Decode a string from \a data. The default implementation assumes that
* \a data is an ISO-8859-1 (Latin1) character array.
*/
virtual String parse(const ByteVector &data) const;
};
//! The main class in the ID3v2 implementation
/*!
@@ -133,32 +106,34 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
*
* \see FrameFactory
*/
explicit Tag(File *file, long tagOffset, const FrameFactory *factory = FrameFactory::instance());
explicit Tag(File *file, long long tagOffset, const FrameFactory *factory = FrameFactory::instance());
/*!
* Destroys this Tag instance.
*/
virtual ~Tag();
~Tag() override;
// Reimplementations.
virtual String title() const;
virtual String artist() const;
virtual String album() const;
virtual String comment() const;
virtual String genre() const;
virtual unsigned int year() const;
virtual unsigned int track() const;
String title() const override;
String artist() const override;
String album() const override;
String comment() const override;
String genre() const override;
unsigned int year() const override;
unsigned int track() const override;
PictureMap pictures() const override;
virtual void setTitle(const String &s);
virtual void setArtist(const String &s);
virtual void setAlbum(const String &s);
virtual void setComment(const String &s);
virtual void setGenre(const String &s);
virtual void setYear(unsigned int i);
virtual void setTrack(unsigned int i);
void setTitle(const String &s) override;
void setArtist(const String &s) override;
void setAlbum(const String &s) override;
void setComment(const String &s) override;
void setGenre(const String &s) override;
void setYear(unsigned int i) override;
void setTrack(unsigned int i) override;
void setPictures(const PictureMap &l) override;
virtual bool isEmpty() const;
bool isEmpty() const override;
/*!
* Returns a pointer to the tag's header.
@@ -271,7 +246,7 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
* once, the description, separated by a "/".
*
*/
PropertyMap properties() const;
PropertyMap properties() const override;
/*!
* Removes unsupported frames given by \a properties. The elements of
@@ -284,32 +259,26 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
* - "UNKNOWN/" + frameID, for frames that could not be parsed by TagLib.
* In that case, *all* unknown frames with the given ID will be removed.
*/
void removeUnsupportedProperties(const StringList &properties);
void removeUnsupportedProperties(const StringList &properties) override;
/*!
* Implements the unified property interface -- import function.
* See the comments in properties().
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Render the tag back to binary data, suitable to be written to disk.
*/
ByteVector render() const;
PropertyMap setProperties(const PropertyMap &) override;
/*!
* Render the tag back to binary data, suitable to be written to disk.
*
* The \a version parameter specifies whether ID3v2.4 (default) or ID3v2.3 should be used.
*/
ByteVector render(Version version) const;
ByteVector render(Version version = ID3v2::v4) const;
/*!
* Gets the current string handler that decides how the "Latin-1" data will be converted to and from binary data.
*
* \see Latin1StringHandler
*/
static Latin1StringHandler const *latin1StringHandler();
static Strawberry_TagLib::TagLib::StringHandler const *latin1StringHandler();
/*!
* Sets the string handler that decides how the "Latin-1" data will be converted to and from binary data.
@@ -319,7 +288,7 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
*
* \see Latin1StringHandler
*/
static void setLatin1StringHandler(const Latin1StringHandler *handler);
static void setLatin1StringHandler(const Strawberry_TagLib::TagLib::StringHandler *handler);
protected:
/*!
@@ -348,7 +317,7 @@ class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
void downgradeFrames(FrameList *existingFrames, FrameList *newFrames) const;
private:
explicit Tag(const Tag&);
Tag(const Tag&);
Tag &operator=(const Tag&);
class TagPrivate;

View File

@@ -23,14 +23,14 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tagunion.h>
#include <tagutils.h>
#include <id3v2tag.h>
#include <id3v2header.h>
#include <id3v1tag.h>
#include <apefooter.h>
#include <apetag.h>
#include <tdebug.h>
#include "tagunion.h"
#include "tagutils.h"
#include "id3v2tag.h"
#include "id3v2header.h"
#include "id3v1tag.h"
#include "apefooter.h"
#include "apetag.h"
#include "tdebug.h"
#include "mpegfile.h"
#include "mpegheader.h"
@@ -63,15 +63,15 @@ class MPEG::File::FilePrivate {
const ID3v2::FrameFactory *ID3v2FrameFactory;
long ID3v2Location;
long ID3v2OriginalSize;
long long ID3v2Location;
long long ID3v2OriginalSize;
long APELocation;
long APEOriginalSize;
long long APELocation;
long long APEOriginalSize;
long ID3v1Location;
long long ID3v1Location;
TagUnion tag;
TripleTagUnion tag;
AudioProperties *properties;
};
@@ -103,13 +103,13 @@ bool MPEG::File::isSupported(IOStream *stream) {
// MPEG frame headers are really confusing with irrelevant binary data.
// So we check if a frame header is really valid.
long headerOffset;
long long headerOffset;
const ByteVector buffer = Utils::readHeader(stream, bufferSize(), true, &headerOffset);
if (buffer.isEmpty())
return false;
const long originalPosition = stream->tell();
const long long originalPosition = stream->tell();
AdapterFile file(stream);
for (unsigned int i = 0; i < buffer.size() - 1; ++i) {
@@ -131,20 +131,25 @@ bool MPEG::File::isSupported(IOStream *stream) {
// public members
////////////////////////////////////////////////////////////////////////////////
MPEG::File::File(FileName file, ID3v2::FrameFactory *frameFactory, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(file), d(new FilePrivate(frameFactory)) {
MPEG::File::File(FileName fileName, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(fileName), d(new FilePrivate()) {
if (isOpen())
read(readProperties);
}
MPEG::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(stream), d(new FilePrivate(frameFactory)) {
MPEG::File::File(FileName fileName, ID3v2::FrameFactory *frameFactory, bool readProperties, AudioProperties::ReadStyle) : Strawberry_TagLib::TagLib::File(fileName), d(new FilePrivate(frameFactory)) {
if (isOpen())
read(readProperties);
}
MPEG::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory, bool readProperties, AudioProperties::ReadStyle) : TagLib::File(stream), d(new FilePrivate(frameFactory)) {
if (isOpen())
read(readProperties);
}
MPEG::File::~File() {
delete d;
}
@@ -153,14 +158,6 @@ Strawberry_TagLib::TagLib::Tag *MPEG::File::tag() const {
return &d->tag;
}
PropertyMap MPEG::File::properties() const {
return d->tag.properties();
}
void MPEG::File::removeUnsupportedProperties(const StringList &properties) {
d->tag.removeUnsupportedProperties(properties);
}
PropertyMap MPEG::File::setProperties(const PropertyMap &properties) {
// update ID3v1 tag if it exists, but ignore the return value
@@ -180,10 +177,6 @@ bool MPEG::File::save() {
return save(AllTags);
}
bool MPEG::File::save(int tags) {
return save(tags, StripOthers);
}
bool MPEG::File::save(int tags, StripTags strip, ID3v2::Version version, DuplicateTags duplicate) {
if (readOnly()) {
@@ -360,7 +353,7 @@ bool MPEG::File::strip(int tags, bool freeMemory) {
}
long MPEG::File::nextFrameOffset(long position) {
long long MPEG::File::nextFrameOffset(long long position) {
ByteVector frameSyncBytes(2, '\0');
@@ -370,7 +363,7 @@ long MPEG::File::nextFrameOffset(long position) {
if (buffer.isEmpty())
return -1;
for (unsigned int i = 0; i < buffer.size(); ++i) {
for (size_t i = 0; i < buffer.size(); ++i) {
frameSyncBytes[0] = frameSyncBytes[1];
frameSyncBytes[1] = buffer[i];
if (isFrameSync(frameSyncBytes)) {
@@ -385,12 +378,12 @@ long MPEG::File::nextFrameOffset(long position) {
}
long MPEG::File::previousFrameOffset(long position) {
long long MPEG::File::previousFrameOffset(long long position) {
ByteVector frameSyncBytes(2, '\0');
while (position > 0) {
const long bufferLength = std::min<long>(position, bufferSize());
const long long bufferLength = std::min<long long>(position, bufferSize());
position -= bufferLength;
seek(position);
@@ -411,9 +404,9 @@ long MPEG::File::previousFrameOffset(long position) {
}
long MPEG::File::firstFrameOffset() {
long long MPEG::File::firstFrameOffset() {
long position = 0;
long long position = 0;
if (hasID3v2Tag())
position = d->ID3v2Location + ID3v2Tag()->header()->completeTagSize();
@@ -422,9 +415,9 @@ long MPEG::File::firstFrameOffset() {
}
long MPEG::File::lastFrameOffset() {
long long MPEG::File::lastFrameOffset() {
long position;
long long position;
if (hasAPETag())
position = d->APELocation - 1;
@@ -491,7 +484,7 @@ void MPEG::File::read(bool readProperties) {
}
long MPEG::File::findID3v2() {
long long MPEG::File::findID3v2() {
if (!isValid())
return -1;
@@ -512,7 +505,7 @@ long MPEG::File::findID3v2() {
ByteVector frameSyncBytes(2, '\0');
ByteVector tagHeaderBytes(3, '\0');
long position = 0;
long long position = 0;
while (true) {
seek(position);
@@ -520,7 +513,7 @@ long MPEG::File::findID3v2() {
if (buffer.isEmpty())
return -1;
for (unsigned int i = 0; i < buffer.size(); ++i) {
for (size_t i = 0; i < buffer.size(); ++i) {
frameSyncBytes[0] = frameSyncBytes[1];
frameSyncBytes[1] = buffer[i];
if (isFrameSync(frameSyncBytes)) {

View File

@@ -78,6 +78,17 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
AllTags = 0xffff
};
/*!
* Constructs an MPEG file from \a file. If \a readProperties is true the
* file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
*
* \deprecated This constructor will be dropped in favor of the one below
* in a future version.
*/
explicit File(FileName file, bool readProperties = true, AudioProperties::ReadStyle propertiesStyle = AudioProperties::Average);
/*!
* Constructs an MPEG file from \a file.
* If \a readProperties is true the file's audio properties will also be read.
@@ -88,7 +99,7 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
* \note In the current implementation, \a propertiesStyle is ignored.
*/
// BIC: merge with the above constructor
explicit File(FileName file, ID3v2::FrameFactory *frameFactory, bool readProperties = true, AudioProperties::ReadStyle propertiesStyle = AudioProperties::Average);
explicit File(FileName fileName, ID3v2::FrameFactory *frameFactory, bool readProperties = true, AudioProperties::ReadStyle propertiesStyle = AudioProperties::Average);
/*!
* Constructs an MPEG file from \a stream.
@@ -105,7 +116,7 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
/*!
* Destroys this instance of the File.
*/
virtual ~File();
~File() override;
/*!
* Returns a pointer to a tag that is the union of the ID3v2 and ID3v1 tags.
@@ -122,16 +133,7 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
* \see ID3v2Tag()
* \see APETag()
*/
virtual Tag *tag() const;
/*!
* Implements the reading part of the unified property interface.
* If the file contains more than one tag,
* only the first one (in the order ID3v2, APE, ID3v1) will be converted to the PropertyMap.
*/
PropertyMap properties() const;
void removeUnsupportedProperties(const StringList &properties);
Tag *tag() const override;
/*!
* Implements the writing part of the unified tag dictionary interface.
@@ -140,13 +142,13 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
* If an ID3v1 tag exists, it will be updated as well, within the limitations of that format.
* The returned PropertyMap refers to the ID3v2 tag only.
*/
PropertyMap setProperties(const PropertyMap &);
PropertyMap setProperties(const PropertyMap&) override;
/*!
* Returns the MPEG::AudioProperties for this file.
* If no audio properties were read then this will return a null pointer.
*/
virtual AudioProperties *audioProperties() const;
AudioProperties *audioProperties() const override;
/*!
* Save the file. If at least one tag -- ID3v1 or ID3v2 -- exists this will duplicate its content into the other tag.
@@ -161,18 +163,7 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
*
* \see save(int tags)
*/
virtual bool save();
/*!
* Save the file.
* This will attempt to save all of the tag types that are specified by OR-ing together TagTypes values.
* The save() method above uses AllTags. This returns true if saving was successful.
*
* This strips all tags not included in the mask, but does not modify them
* in memory, so later calls to save() which make use of these tags will remain valid.
* This also strips empty tags.
*/
bool save(int tags);
bool save() override;
/*!
* Save the file. This will attempt to save all of the tag types that are
@@ -187,7 +178,7 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
* If \a duplicate is set to DuplicateTags and at least one tag -- ID3v1
* or ID3v2 -- exists this will duplicate its content into the other tag.
*/
bool save(int tags, StripTags strip, ID3v2::Version version = ID3v2::v4, DuplicateTags duplicate = Duplicate);
bool save(int tags, StripTags strip = StripOthers, ID3v2::Version version = ID3v2::v4, DuplicateTags duplicate = Duplicate);
/*!
* Returns a pointer to the ID3v2 tag of the file.
@@ -266,22 +257,22 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
/*!
* Returns the position in the file of the first MPEG frame.
*/
long firstFrameOffset();
long long firstFrameOffset();
/*!
* Returns the position in the file of the next MPEG frame, using the current position as start
*/
long nextFrameOffset(long position);
long long nextFrameOffset(long long position);
/*!
* Returns the position in the file of the previous MPEG frame, using the current position as start
*/
long previousFrameOffset(long position);
long long previousFrameOffset(long long position);
/*!
* Returns the position in the file of the last MPEG frame.
*/
long lastFrameOffset();
long long lastFrameOffset();
/*!
* Returns whether or not the file on disk actually has an ID3v1 tag.
@@ -312,11 +303,11 @@ class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
static bool isSupported(IOStream *stream);
private:
explicit File(const File&);
File(const File&);
File &operator=(const File&);
void read(bool readProperties);
long findID3v2();
long long findID3v2();
class FilePrivate;
FilePrivate *d;

View File

@@ -23,121 +23,118 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevector.h>
#include <tstring.h>
#include <tfile.h>
#include <tdebug.h>
#include <trefcounter.h>
#include <memory>
#include "tbytevector.h"
#include "tstring.h"
#include "tfile.h"
#include "tdebug.h"
#include "mpegheader.h"
#include "mpegutils.h"
using namespace Strawberry_TagLib::TagLib;
class MPEG::Header::HeaderPrivate : public RefCounter {
public:
HeaderPrivate() : isValid(false),
version(Version1),
layer(0),
protectionEnabled(false),
bitrate(0),
sampleRate(0),
isPadded(false),
channelMode(Stereo),
isCopyrighted(false),
isOriginal(false),
frameLength(0),
samplesPerFrame(0) {}
namespace {
struct HeaderData {
bool isValid;
Version version;
MPEG::Header::Version version;
int layer;
bool protectionEnabled;
int bitrate;
int sampleRate;
bool isPadded;
ChannelMode channelMode;
MPEG::Header::ChannelMode channelMode;
bool isCopyrighted;
bool isOriginal;
int frameLength;
int samplesPerFrame;
};
} // namespace
class MPEG::Header::HeaderPrivate {
public:
explicit HeaderPrivate() : data(new HeaderData()) {
data->isValid = false;
data->layer = 0;
data->version = Version1;
data->protectionEnabled = false;
data->sampleRate = 0;
data->isPadded = false;
data->channelMode = Stereo;
data->isCopyrighted = false;
data->isOriginal = false;
data->frameLength = 0;
data->samplesPerFrame = 0;
}
std::shared_ptr<HeaderData> data;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
MPEG::Header::Header(File *file, long offset, bool checkLength) : d(new HeaderPrivate()) {
MPEG::Header::Header(File *file, long long offset, bool checkLength) : d(new HeaderPrivate()) {
parse(file, offset, checkLength);
}
MPEG::Header::Header(const Header &h) : d(h.d) {
d->ref();
}
MPEG::Header::Header(const Header &h) : d(new HeaderPrivate(*h.d)) {}
MPEG::Header::~Header() {
if (d->deref())
delete d;
delete d;
}
bool MPEG::Header::isValid() const {
return d->isValid;
return d->data->isValid;
}
MPEG::Header::Version MPEG::Header::version() const {
return d->version;
return d->data->version;
}
int MPEG::Header::layer() const {
return d->layer;
return d->data->layer;
}
bool MPEG::Header::protectionEnabled() const {
return d->protectionEnabled;
return d->data->protectionEnabled;
}
int MPEG::Header::bitrate() const {
return d->bitrate;
return d->data->bitrate;
}
int MPEG::Header::sampleRate() const {
return d->sampleRate;
return d->data->sampleRate;
}
bool MPEG::Header::isPadded() const {
return d->isPadded;
return d->data->isPadded;
}
MPEG::Header::ChannelMode MPEG::Header::channelMode() const {
return d->channelMode;
return d->data->channelMode;
}
bool MPEG::Header::isCopyrighted() const {
return d->isCopyrighted;
return d->data->isCopyrighted;
}
bool MPEG::Header::isOriginal() const {
return d->isOriginal;
return d->data->isOriginal;
}
int MPEG::Header::frameLength() const {
return d->frameLength;
return d->data->frameLength;
}
int MPEG::Header::samplesPerFrame() const {
return d->samplesPerFrame;
return d->data->samplesPerFrame;
}
MPEG::Header &MPEG::Header::operator=(const Header &h) {
if (&h == this)
return *this;
if (d->deref())
delete d;
d = h.d;
d->ref();
*d = *h.d;
return *this;
}
@@ -146,7 +143,7 @@ MPEG::Header &MPEG::Header::operator=(const Header &h) {
// private members
////////////////////////////////////////////////////////////////////////////////
void MPEG::Header::parse(File *file, long offset, bool checkLength) {
void MPEG::Header::parse(File *file, long long offset, bool checkLength) {
file->seek(offset);
const ByteVector data = file->readBlock(4);
@@ -168,11 +165,11 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
const int versionBits = (static_cast<unsigned char>(data[1]) >> 3) & 0x03;
if (versionBits == 0)
d->version = Version2_5;
d->data->version = Version2_5;
else if (versionBits == 2)
d->version = Version2;
d->data->version = Version2;
else if (versionBits == 3)
d->version = Version1;
d->data->version = Version1;
else
return;
@@ -181,15 +178,15 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
const int layerBits = (static_cast<unsigned char>(data[1]) >> 1) & 0x03;
if (layerBits == 1)
d->layer = 3;
d->data->layer = 3;
else if (layerBits == 2)
d->layer = 2;
d->data->layer = 2;
else if (layerBits == 3)
d->layer = 1;
d->data->layer = 1;
else
return;
d->protectionEnabled = (static_cast<unsigned char>(data[1] & 0x01) == 0);
d->data->protectionEnabled = (static_cast<unsigned char>(data[1] & 0x01) == 0);
// Set the bitrate
@@ -208,17 +205,17 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
}
};
const int versionIndex = (d->version == Version1) ? 0 : 1;
const int layerIndex = (d->layer > 0) ? d->layer - 1 : 0;
const int versionIndex = (d->data->version == Version1) ? 0 : 1;
const int layerIndex = (d->data->layer > 0) ? d->data->layer - 1 : 0;
// The bitrate index is encoded as the first 4 bits of the 3rd byte,
// i.e. 1111xxxx
const int bitrateIndex = (static_cast<unsigned char>(data[2]) >> 4) & 0x0F;
d->bitrate = bitrates[versionIndex][layerIndex][bitrateIndex];
d->data->bitrate = bitrates[versionIndex][layerIndex][bitrateIndex];
if (d->bitrate == 0)
if (d->data->bitrate == 0)
return;
// Set the sample rate
@@ -233,22 +230,22 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
const int samplerateIndex = (static_cast<unsigned char>(data[2]) >> 2) & 0x03;
d->sampleRate = sampleRates[d->version][samplerateIndex];
d->data->sampleRate = sampleRates[d->data->version][samplerateIndex];
if (d->sampleRate == 0) {
if (d->data->sampleRate == 0) {
return;
}
// The channel mode is encoded as a 2 bit value at the end of the 3nd byte,
// i.e. xxxxxx11
d->channelMode = static_cast<ChannelMode>((static_cast<unsigned char>(data[3]) >> 6) & 0x03);
d->data->channelMode = static_cast<ChannelMode>((static_cast<unsigned char>(data[3]) >> 6) & 0x03);
// TODO: Add mode extension for completeness
d->isOriginal = ((static_cast<unsigned char>(data[3]) & 0x04) != 0);
d->isCopyrighted = ((static_cast<unsigned char>(data[3]) & 0x08) != 0);
d->isPadded = ((static_cast<unsigned char>(data[2]) & 0x02) != 0);
d->data->isOriginal = ((static_cast<unsigned char>(data[3]) & 0x04) != 0);
d->data->isCopyrighted = ((static_cast<unsigned char>(data[3]) & 0x08) != 0);
d->data->isPadded = ((static_cast<unsigned char>(data[2]) & 0x02) != 0);
// Samples per frame
@@ -259,16 +256,16 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
{ 1152, 576 } // Layer III
};
d->samplesPerFrame = samplesPerFrame[layerIndex][versionIndex];
d->data->samplesPerFrame = samplesPerFrame[layerIndex][versionIndex];
// Calculate the frame length
static const int paddingSize[3] = { 4, 1, 1 };
d->frameLength = d->samplesPerFrame * d->bitrate * 125 / d->sampleRate;
d->data->frameLength = d->data->samplesPerFrame * d->data->bitrate * 125 / d->data->sampleRate;
if (d->isPadded)
d->frameLength += paddingSize[layerIndex];
if (d->data->isPadded)
d->data->frameLength += paddingSize[layerIndex];
if (checkLength) {
@@ -279,7 +276,7 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
// consistent. Otherwise, we assume that either or both of the frames are
// broken.
file->seek(offset + d->frameLength);
file->seek(offset + d->data->frameLength);
const ByteVector nextData = file->readBlock(4);
if (nextData.size() < 4)
@@ -287,8 +284,8 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
const unsigned int HeaderMask = 0xfffe0c00;
const unsigned int header = data.toUInt(0, true) & HeaderMask;
const unsigned int nextHeader = nextData.toUInt(0, true) & HeaderMask;
const unsigned int header = data.toUInt32BE(0) & HeaderMask;
const unsigned int nextHeader = nextData.toUInt32BE(0) & HeaderMask;
if (header != nextHeader)
return;
@@ -296,6 +293,6 @@ void MPEG::Header::parse(File *file, long offset, bool checkLength) {
// Now that we're done parsing, set this to be a valid frame.
d->isValid = true;
d->data->isValid = true;
}

View File

@@ -54,12 +54,12 @@ class TAGLIB_EXPORT Header {
* check if the frame length is parsed and calculated correctly.
* So it's suitable for seeking for the first valid frame.
*/
explicit Header(File *file, long offset, bool checkLength = true);
explicit Header(File *file, long long offset, bool checkLength = true);
/*!
* Does a shallow copy of \a h.
*/
explicit Header(const Header &h);
Header(const Header &h);
/*!
* Destroys this Header instance.
@@ -159,7 +159,7 @@ class TAGLIB_EXPORT Header {
Header &operator=(const Header &h);
private:
void parse(File *file, long offset, bool checkLength);
void parse(File *file, long long offset, bool checkLength);
class HeaderPrivate;
HeaderPrivate *d;

View File

@@ -23,8 +23,10 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include <tstring.h>
#include <memory>
#include "tdebug.h"
#include "tstring.h"
#include "audioproperties.h"
#include "mpegproperties.h"
@@ -37,23 +39,18 @@ using namespace Strawberry_TagLib::TagLib;
class MPEG::AudioProperties::AudioPropertiesPrivate {
public:
AudioPropertiesPrivate() : xingHeader(nullptr),
length(0),
bitrate(0),
sampleRate(0),
channels(0),
layer(0),
version(Header::Version1),
channelMode(Header::Stereo),
protectionEnabled(false),
isCopyrighted(false),
isOriginal(false) {}
explicit AudioPropertiesPrivate() : length(0),
bitrate(0),
sampleRate(0),
channels(0),
layer(0),
version(Header::Version1),
channelMode(Header::Stereo),
protectionEnabled(false),
isCopyrighted(false),
isOriginal(false) {}
~AudioPropertiesPrivate() {
delete xingHeader;
}
XingHeader *xingHeader;
std::unique_ptr<XingHeader> xingHeader;
int length;
int bitrate;
int sampleRate;
@@ -70,7 +67,7 @@ class MPEG::AudioProperties::AudioPropertiesPrivate {
// public members
////////////////////////////////////////////////////////////////////////////////
MPEG::AudioProperties::AudioProperties(File *file, ReadStyle style) : Strawberry_TagLib::TagLib::AudioProperties(style), d(new AudioPropertiesPrivate()) {
MPEG::AudioProperties::AudioProperties(File *file, ReadStyle) : Strawberry_TagLib::TagLib::AudioProperties(), d(new AudioPropertiesPrivate()) {
read(file);
}
@@ -99,7 +96,7 @@ int MPEG::AudioProperties::channels() const {
}
const MPEG::XingHeader *MPEG::AudioProperties::xingHeader() const {
return d->xingHeader;
return d->xingHeader.get();
}
MPEG::Header::Version MPEG::AudioProperties::version() const {
@@ -134,7 +131,7 @@ void MPEG::AudioProperties::read(File *file) {
// Only the first valid frame is required if we have a VBR header.
const long firstFrameOffset = file->firstFrameOffset();
const long long firstFrameOffset = file->firstFrameOffset();
if (firstFrameOffset < 0) {
debug("MPEG::AudioProperties::read() -- Could not find an MPEG frame in the stream.");
return;
@@ -146,11 +143,9 @@ void MPEG::AudioProperties::read(File *file) {
// VBR stream.
file->seek(firstFrameOffset);
d->xingHeader = new XingHeader(file->readBlock(firstHeader.frameLength()));
if (!d->xingHeader->isValid()) {
delete d->xingHeader;
d->xingHeader = nullptr;
}
d->xingHeader.reset(new XingHeader(file->readBlock(firstHeader.frameLength())));
if (!d->xingHeader->isValid())
d->xingHeader.reset();
if (d->xingHeader && firstHeader.samplesPerFrame() > 0 && firstHeader.sampleRate() > 0) {
@@ -174,14 +169,14 @@ void MPEG::AudioProperties::read(File *file) {
// Look for the last MPEG audio frame to calculate the stream length.
const long lastFrameOffset = file->lastFrameOffset();
const long long lastFrameOffset = file->lastFrameOffset();
if (lastFrameOffset < 0) {
debug("MPEG::AudioProperties::read() -- Could not find an MPEG frame in the stream.");
return;
}
const Header lastHeader(file, lastFrameOffset, false);
const long streamLength = lastFrameOffset - firstFrameOffset + lastHeader.frameLength();
const long long streamLength = lastFrameOffset - firstFrameOffset + lastHeader.frameLength();
if (streamLength > 0)
d->length = static_cast<int>(streamLength * 8.0 / d->bitrate + 0.5);
}

View File

@@ -54,36 +54,36 @@ class TAGLIB_EXPORT AudioProperties : public Strawberry_TagLib::TagLib::AudioPro
/*!
* Destroys this MPEG AudioProperties instance.
*/
virtual ~AudioProperties();
~AudioProperties() override;
/*!
* Returns the length of the file in seconds. The length is rounded down to the nearest whole second.
*
* \see lengthInMilliseconds()
*/
virtual int lengthInSeconds() const;
int lengthInSeconds() const override;
/*!
* Returns the length of the file in milliseconds.
*
* \see lengthInSeconds()
*/
virtual int lengthInMilliseconds() const;
int lengthInMilliseconds() const override;
/*!
* Returns the average bit rate of the file in kb/s.
*/
virtual int bitrate() const;
int bitrate() const override;
/*!
* Returns the sample rate in Hz.
*/
virtual int sampleRate() const;
int sampleRate() const override;
/*!
* Returns the number of audio channels.
*/
virtual int channels() const;
int channels() const override;
/*!
* Returns a pointer to the Xing/VBRI header if one exists or null if no Xing/VBRI header was found.
@@ -121,9 +121,6 @@ class TAGLIB_EXPORT AudioProperties : public Strawberry_TagLib::TagLib::AudioPro
bool isOriginal() const;
private:
explicit AudioProperties(const AudioProperties&);
AudioProperties &operator=(const AudioProperties&);
void read(File *file);
class AudioPropertiesPrivate;

View File

@@ -23,9 +23,9 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevector.h>
#include <tstring.h>
#include <tdebug.h>
#include "tbytevector.h"
#include "tstring.h"
#include "tdebug.h"
#include "xingheader.h"
#include "mpegfile.h"
@@ -34,7 +34,7 @@ using namespace Strawberry_TagLib::TagLib;
class MPEG::XingHeader::XingHeaderPrivate {
public:
XingHeaderPrivate() : frames(0), size(0), type(MPEG::XingHeader::Invalid) {}
explicit XingHeaderPrivate() : frames(0), size(0), type(MPEG::XingHeader::Invalid) {}
unsigned int frames;
unsigned int size;
@@ -78,11 +78,11 @@ void MPEG::XingHeader::parse(const ByteVector &data) {
// Look for a Xing header.
long offset = data.find("Xing");
if (offset < 0)
size_t offset = data.find("Xing");
if (offset == ByteVector::npos())
offset = data.find("Info");
if (offset >= 0) {
if (offset != ByteVector::npos()) {
// Xing header found.
@@ -96,8 +96,8 @@ void MPEG::XingHeader::parse(const ByteVector &data) {
return;
}
d->frames = data.toUInt(offset + 8, true);
d->size = data.toUInt(offset + 12, true);
d->frames = data.toUInt32BE(offset + 8);
d->size = data.toUInt32BE(offset + 12);
d->type = Xing;
}
else {
@@ -106,7 +106,7 @@ void MPEG::XingHeader::parse(const ByteVector &data) {
offset = data.find("VBRI");
if (offset >= 0) {
if (offset != ByteVector::npos()) {
// VBRI header found.
@@ -115,8 +115,8 @@ void MPEG::XingHeader::parse(const ByteVector &data) {
return;
}
d->frames = data.toUInt(offset + 14, true);
d->size = data.toUInt(offset + 10, true);
d->frames = data.toUInt32BE(offset + 14);
d->size = data.toUInt32BE(offset + 10);
d->type = VBRI;
}
}

View File

@@ -103,7 +103,7 @@ class TAGLIB_EXPORT XingHeader {
HeaderType type() const;
private:
explicit XingHeader(const XingHeader&);
XingHeader(const XingHeader&);
XingHeader &operator=(const XingHeader&);
void parse(const ByteVector &data);