Large update:

* Give access to APEv2 features like lists and read-only fields (not enforced by TagLib).
* Support one common mistake: ID3v1 tags placed after an APE-tag. In this case both tags are now read and maintained. APE-tags after an ID3v1 tag is not supported.


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@332903 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
Allan Sandfeld Jensen
2004-07-26 12:58:59 +00:00
parent 62ca49decb
commit 2025c4e9e5
5 changed files with 487 additions and 170 deletions

View File

@ -27,6 +27,7 @@
#include "id3v1tag.h"
#include "id3v2header.h"
#include "apetag.h"
#include "mpctag.h"
using namespace TagLib;
@ -43,6 +44,7 @@ public:
ID3v2Header(0),
ID3v2Location(-1),
ID3v2Size(0),
tag(0),
properties(0),
scanned(false),
hasAPE(false),
@ -95,16 +97,7 @@ MPC::File::~File()
TagLib::Tag *MPC::File::tag() const
{
if(d->APETag)
return d->APETag;
else {
if(d->ID3v1Tag)
return d->ID3v1Tag;
else {
d->APETag = new APE::Tag;
return d->APETag;
}
}
return d->tag;
}
MPC::Properties *MPC::File::audioProperties() const
@ -114,27 +107,92 @@ MPC::Properties *MPC::File::audioProperties() const
bool MPC::File::save()
{
// Update APE tag
if(d->hasAPE && d->APETag)
insert(d->APETag->render(), d->APELocation, d->APESize);
else {
// Update ID3v1 tag
// Update ID3v1 tag
if(d->hasID3v1 && d->ID3v1Tag) {
seek(-128, End);
writeBlock(d->ID3v1Tag->render());
if(d->ID3v1Tag)
{
if(d->hasID3v1)
{
seek(-128, End);
writeBlock(d->ID3v1Tag->render());
}
else
{
seek(0, End);
writeBlock(d->ID3v1Tag->render());
}
}
// Update APE tag
if(d->APETag)
{
if(d->hasAPE)
{
insert(d->APETag->render(), d->APELocation, d->APESize);
}
else
if (d->hasID3v1)
{
seek(-128, End);
insert(d->APETag->render(), tell(), 0);
}
else
{
seek(0, End);
writeBlock(d->APETag->render());
}
}
return true;
}
ID3v1::Tag *MPC::File::ID3v1Tag(bool create)
{
if(!create || d->ID3v1Tag)
return d->ID3v1Tag;
// no ID3v1 tag exists and we've been asked to create one
d->ID3v1Tag = new ID3v1::Tag;
if (d->APETag)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
d->tag = d->ID3v1Tag;
return d->ID3v1Tag;
}
APE::Tag *MPC::File::APETag(bool create)
{
if(!create || d->APETag)
return d->APETag;
// no APE tag exists and we've been asked to create one
d->APETag = new APE::Tag;
if (d->ID3v1Tag)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
d->tag = d->APETag;
return d->APETag;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
{
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for an APE tag
findAPE();
@ -144,16 +202,16 @@ void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesSty
d->hasAPE = true;
}
// Look for an ID3v1 tag
if(!d->hasAPE) {
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
}
if (d->hasID3v1 && d->hasAPE)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
if (d->hasID3v1)
d->tag = d->ID3v1Tag;
else
if (d->hasAPE)
d->tag = d->APETag;
else
d->tag = d->APETag = new APE::Tag();
// Look for and skip an ID3v2 tag
@ -184,7 +242,10 @@ bool MPC::File::findAPE()
if(!isValid())
return false;
seek(-32, End);
if (d->hasID3v1)
seek(-160, End);
else
seek(-32, End);
long p = tell();
ByteVector footer = readBlock(32);