std::cout << "******************** Stripping ID3v1 Tag From: \"" << argv[i] << "\"********************" << std::endl;
MPEG::File f(argv[i]);
- f.strip(MPEG::File::ID3v1);
+ f.strip();
}
}
CommentsFrame::CommentsFrame(String::Type encoding) : Frame("COMM")
{
- d = new CommentsFramePrivate();
+ d = new CommentsFramePrivate;
d->textEncoding = encoding;
}
CommentsFrame::CommentsFrame(const ByteVector &data) : Frame(data)
{
- d = new CommentsFramePrivate();
- parseFields(data.mid(Header::size(), size()));
+ d = new CommentsFramePrivate;
+ parseFields(data.mid(Header::size(header()->version()), size()));
}
CommentsFrame::~CommentsFrame()
CommentsFrame::CommentsFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new CommentsFramePrivate();
- parseFields(data.mid(Header::size(), size()));
+ parseFields(data.mid(Header::size(h->version()), size()));
}
TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new TextIdentificationFramePrivate;
- parseFields(data.mid(Header::size(), size()));
+ parseFields(data.mid(Header::size(h->version()), size()));
}
return Header::size();
}
+TagLib::uint Frame::headerSize(uint version)
+{
+ return Header::size(version);
+}
+
ByteVector Frame::textDelimiter(String::Type t)
{
ByteVector d = char(0);
Frame::Frame(const ByteVector &data)
{
- d = new FramePrivate();
+ d = new FramePrivate;
d->header = new Header(data);
}
Frame::Frame(Header *h)
{
- d = new FramePrivate();
+ d = new FramePrivate;
d->header = h;
}
d->header = new Header(data);
// size() is the lenght of the field data
- parseFields(data.mid(Header::size(), size()));
+
+ parseFields(data.mid(Header::size(d->header->version()), size()));
}
////////////////////////////////////////////////////////////////////////////////
class Frame::Header::HeaderPrivate
{
public:
- HeaderPrivate() : frameSize(0) {}
+ HeaderPrivate() : frameSize(0), version(4) {}
ByteVector frameID;
uint frameSize;
- static const unsigned int size = 10;
+ uint version;
};
////////////////////////////////////////////////////////////////////////////////
TagLib::uint Frame::Header::size()
{
- return HeaderPrivate::size;
+ return size(4);
+}
+
+TagLib::uint Frame::Header::size(uint version)
+{
+ switch(version) {
+ case 0:
+ case 1:
+ case 2:
+ return 6;
+ case 3:
+ case 4:
+ default:
+ return 10;
+ }
}
////////////////////////////////////////////////////////////////////////////////
setData(data, synchSafeInts);
}
+Frame::Header::Header(const ByteVector &data, uint version)
+{
+ d = new HeaderPrivate;
+ setData(data, version);
+}
+
Frame::Header::~Header()
{
delete d;
void Frame::Header::setData(const ByteVector &data, bool synchSafeInts)
{
- if(data.size() < 4) {
- debug("You must at least specify a frame ID.");
- return;
- }
+ setData(data, uint(synchSafeInts ? 4 : 3));
+}
+
+void Frame::Header::setData(const ByteVector &data, uint version)
+{
+ d->version = version;
+
+ switch(version) {
+ case 0:
+ case 1:
+ case 2:
+ {
- // set the frame ID -- the first four bytes
+ // ID3v2.2
- d->frameID = data.mid(0, 4);
+ if(data.size() < 3) {
+ debug("You must at least specify a frame ID.");
+ return;
+ }
- // If the full header information was not passed in, do not continue to the
- // steps to parse the frame size and flags.
+ // Set the frame ID -- the first three bytes
- if(data.size() < 10) {
- d->frameSize = 0;
- return;
+ d->frameID = data.mid(0, 3);
+
+ // If the full header information was not passed in, do not continue to the
+ // steps to parse the frame size and flags.
+
+ if(data.size() < 6) {
+ d->frameSize = 0;
+ return;
+ }
+
+ d->frameSize = data.mid(3, 3).toUInt();
+
+ break;
}
+ case 3:
+ case 4:
+ default:
+ {
+ // ID3v2.3 / ID3v2.4
- // Set the size -- the frame size is the four bytes starting at byte four in
- // the frame header (structure 4)
+ if(data.size() < 4) {
+ debug("You must at least specify a frame ID.");
+ return;
+ }
- if(synchSafeInts)
- d->frameSize = SynchData::toUInt(data.mid(4, 4));
- else
- d->frameSize = data.mid(4, 4).toUInt();
+ // Set the frame ID -- the first four bytes
+
+ d->frameID = data.mid(0, 4);
+
+ // If the full header information was not passed in, do not continue to the
+ // steps to parse the frame size and flags.
+
+ if(data.size() < 10) {
+ d->frameSize = 0;
+ return;
+ }
- // read flags
- // ...
+ // Set the size -- the frame size is the four bytes starting at byte four in
+ // the frame header (structure 4)
+
+ if(version >= 4)
+ d->frameSize = SynchData::toUInt(data.mid(4, 4));
+ else
+ d->frameSize = data.mid(4, 4).toUInt();
+
+ // TODO: read flags
+
+ break;
+ }
+ }
}
ByteVector Frame::Header::frameID() const
d->frameSize = size;
}
+TagLib::uint Frame::Header::version() const
+{
+ return d->version;
+}
+
ByteVector Frame::Header::render() const
{
ByteVector flags(2, char(0)); // just blank for the moment
/*!
* Returns the size of the frame header
+ *
+ * \deprecated This is only accurate for ID3v2.3 or ID3v2.4. Please use
+ * the call below which accepts an ID3v2 version number. In the next
+ * non-binary compatible release this will be made into a non-static
+ * member that checks the internal ID3v2 version.
*/
- static uint headerSize();
+ static uint headerSize(); // BIC: remove and make non-static
+
+ /*!
+ * Returns the size of the frame header for the given ID3v2 version.
+ *
+ * \deprecated Please see the explanation above.
+ */
+ static uint headerSize(uint version); // BIC: remove and make non-static
/*!
* Sets the data that will be used as the frame. Since the length is not
* Construct a Frame Header based on \a data. \a data must at least
* contain a 4 byte frame ID, and optionally can contain flag data and the
* frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
+ *
+ * \deprecated Please use the constructor below that accepts a version
+ * number.
+ */
+ explicit Header(const ByteVector &data, bool synchSafeInts);
+
+ /*!
+ * Construct a Frame Header based on \a data. \a data must at least
+ * contain a 4 byte frame ID, and optionally can contain flag data and the
+ * frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
+ *
+ * \a version should be the ID3v2 version of the tag.
*/
- explicit Header(const ByteVector &data, bool synchSafeInts = true);
+ explicit Header(const ByteVector &data, uint version = 4);
/*!
* Destroys this Header instance.
/*!
* Sets the data for the Header.
+ *
+ * \deprecated Please use the version below that accepts an ID3v2 version
+ * number.
+ */
+ void setData(const ByteVector &data, bool synchSafeInts);
+
+ /*!
+ * Sets the data for the Header. \a version should indicate the ID3v2
+ * version number of the tag that this frame is contained in.
*/
- void setData(const ByteVector &data, bool synchSafeInts = true);
+ void setData(const ByteVector &data, uint version = 4);
/*!
* Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
void setFrameSize(uint size);
/*!
- * Returns the size of the frame header in bytes. Currently this is
- * always 10.
+ * Returns the ID3v2 version of the header (as passed in from the
+ * construction of the header).
+ */
+ uint version() const;
+
+ /*!
+ * Returns the size of the frame header in bytes.
+ *
+ * \deprecated Please use the version of this method that accepts a
+ * version. This is only accurate for ID3v2.3 and ID3v2.4. This will be
+ * removed in the next binary incompatible release (2.0) and will be
+ * replaced with a non-static method that checks the frame version.
*/
static uint size();
+ /*!
+ * Returns the size of the frame header in bytes for the ID3v2 version
+ * that's given.
+ *
+ * \deprecated Please see the explanation in the version above.
+ */
+ static uint size(uint version);
+
/*!
* Render the Header back to binary format in a ByteVector.
*/
Frame *FrameFactory::createFrame(const ByteVector &data, bool synchSafeInts) const
{
- Frame::Header *header = new Frame::Header(data, synchSafeInts);
+ return createFrame(data, uint(synchSafeInts ? 4 : 3));
+}
+
+Frame *FrameFactory::createFrame(const ByteVector &data, uint version) const
+{
+ Frame::Header *header = new Frame::Header(data, version);
TagLib::ByteVector frameID = header->frameID();
// A quick sanity check -- make sure that the frameID is 4 uppercase Latin1
// characters. Also make sure that there is data in the frame.
- if(!frameID.size() == 4 || header->frameSize() <= 0)
- return 0;
+ if(!frameID.size() == (version < 3 ? 3 : 4) || header->frameSize() <= 0)
+ return 0;
for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) {
if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) {
-/***************************************************************************
+ /***************************************************************************
copyright : (C) 2002, 2003 by Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
* Create a frame based on \a data. \a synchSafeInts should only be set
* false if we are parsing an old tag (v2.3 or older) that does not support
* synchsafe ints.
+ *
+ * \deprecated Please use the method below that accepts an ID3 version
+ * number in new code.
+ */
+ Frame *createFrame(const ByteVector &data, bool synchSafeInts) const;
+
+ /*!
+ * Create a frame based on \a data. \a version should indicate the ID3v2
+ * version of the tag. As ID3v2.4 is the most current version of the
+ * standard 4 is the default.
*/
- Frame *createFrame(const ByteVector &data, bool synchSafeInts = true) const;
+ Frame *createFrame(const ByteVector &data, uint version = 4) const;
/*!
* Returns the default text encoding for text frames. If setTextEncoding()
Header::Header()
{
- d = new HeaderPrivate();
+ d = new HeaderPrivate;
}
Header::Header(const ByteVector &data)
{
- d = new HeaderPrivate();
+ d = new HeaderPrivate;
parse(data);
}
// Make sure that there is at least enough room in the remaining frame data for
// a frame header.
- while(frameDataPosition < frameDataLength - Frame::headerSize()) {
+ while(frameDataPosition < frameDataLength - Frame::headerSize(d->header.majorVersion())) {
// If the next data is position is 0, assume that we've hit the padding
// portion of the frame data.
return;
}
- bool synchSafeInts = d->header.majorVersion() >= 4;
-
Frame *frame = d->factory->createFrame(data.mid(frameDataOffset + frameDataPosition),
- synchSafeInts);
+ d->header.majorVersion());
if(!frame)
return;
return;
}
- frameDataPosition += frame->size() + Frame::headerSize();
+ frameDataPosition += frame->size() + Frame::headerSize(d->header.majorVersion());
addFrame(frame);
}
}