From 37e2d6293f6312fb1fa7383d42726dc10e733a27 Mon Sep 17 00:00:00 2001 From: Scott Wheeler Date: Thu, 31 Jan 2008 05:46:13 +0000 Subject: [PATCH] Ok, think I've got this all sorted out a bit. Code is much simpler now, though much of this could be moved into the base class as there's a lot of copy-paste action going on. git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@768992 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- taglib/flac/flacfile.cpp | 24 ++-- taglib/mpc/combinedtag.h | 175 ----------------------------- taglib/mpc/mpcfile.cpp | 109 ++++++------------ taglib/mpeg/mpegfile.cpp | 58 +++------- taglib/tagunion.cpp | 44 ++++---- taglib/tagunion.h | 25 ++--- taglib/trueaudio/trueaudiofile.cpp | 99 +++++----------- taglib/wavpack/wavpackfile.cpp | 115 ++++++------------- 8 files changed, 152 insertions(+), 497 deletions(-) delete mode 100644 taglib/mpc/combinedtag.h diff --git a/taglib/flac/flacfile.cpp b/taglib/flac/flacfile.cpp index 6d3d6cf2..2cf35ad2 100644 --- a/taglib/flac/flacfile.cpp +++ b/taglib/flac/flacfile.cpp @@ -227,26 +227,18 @@ ID3v2::Tag *FLAC::File::ID3v2Tag(bool create) if(!create || d->tag[ID3v2Index]) return static_cast(d->tag[ID3v2Index]); - d->tag.setTag(ID3v2Index, new ID3v2::Tag); + d->tag.set(ID3v2Index, new ID3v2::Tag); return static_cast(d->tag[ID3v2Index]); } ID3v1::Tag *FLAC::File::ID3v1Tag(bool create) { - if(!create || d->tag[ID3v1Index]) - return static_cast(d->tag[ID3v1Index]); - - d->tag.setTag(ID3v1Index, new ID3v1::Tag); - return static_cast(d->tag[ID3v1Index]); + return d->tag.access(ID3v1Index, create); } Ogg::XiphComment *FLAC::File::xiphComment(bool create) { - if(!create || d->tag[XiphIndex]) - return static_cast(d->tag[XiphIndex]); - - d->tag.setTag(XiphIndex, new Ogg::XiphComment); - return static_cast(d->tag[XiphIndex]); + return d->tag.access(XiphIndex, create); } void FLAC::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory) @@ -267,12 +259,12 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle if(d->ID3v2Location >= 0) { - d->tag.setTag(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); + d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); d->ID3v2OriginalSize = ID3v2Tag()->header()->completeTagSize(); if(ID3v2Tag()->header()->tagSize() <= 0) - d->tag.setTag(ID3v2Index, 0); + d->tag.set(ID3v2Index, 0); else d->hasID3v2 = true; } @@ -282,7 +274,7 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->tag.setTag(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); + d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -294,9 +286,9 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle return; if(d->hasXiphComment) - d->tag.setTag(XiphIndex, new Ogg::XiphComment(xiphCommentData())); + d->tag.set(XiphIndex, new Ogg::XiphComment(xiphCommentData())); else - d->tag.setTag(XiphIndex, new Ogg::XiphComment); + d->tag.set(XiphIndex, new Ogg::XiphComment); if(readProperties) d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle); diff --git a/taglib/mpc/combinedtag.h b/taglib/mpc/combinedtag.h deleted file mode 100644 index 03df6152..00000000 --- a/taglib/mpc/combinedtag.h +++ /dev/null @@ -1,175 +0,0 @@ -/*************************************************************************** - copyright : (C) 2004 by Allan Sandfeld Jensen - email : kde@carewolf.org - ***************************************************************************/ - -/*************************************************************************** - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License version * - * 2.1 as published by the Free Software Foundation. * - * * - * This library is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * - * USA * - * * - * Alternatively, this file is available under the Mozilla Public * - * License Version 1.1. You may obtain a copy of the License at * - * http://www.mozilla.org/MPL/ * - ***************************************************************************/ - -#ifndef DO_NOT_DOCUMENT // Tell Doxygen not to document this header - -#ifndef TAGLIB_COMBINEDTAG_H -#define TAGLIB_COMBINEDTAG_H - -//////////////////////////////////////////////////////////////////////////////// -// Note that this header is not installed. -//////////////////////////////////////////////////////////////////////////////// - -#include - -namespace TagLib { - - /*! - * A union of two TagLib::Tags. - */ - class CombinedTag : public TagLib::Tag - { - public: - CombinedTag(Tag *tag1 = 0, Tag *tag2 = 0) - : TagLib::Tag(), - tag1(tag1), tag2(tag2) {} - - virtual String title() const { - if(tag1 && !tag1->title().isEmpty()) - return tag1->title(); - - if(tag2) - return tag2->title(); - - return String::null; - } - - virtual String artist() const { - if(tag1 && !tag1->artist().isEmpty()) - return tag1->artist(); - - if(tag2) - return tag2->artist(); - - return String::null; - } - - virtual String album() const { - if(tag1 && !tag1->album().isEmpty()) - return tag1->album(); - - if(tag2) - return tag2->album(); - - return String::null; - } - - virtual String comment() const { - if(tag1 && !tag1->comment().isEmpty()) - return tag1->comment(); - - if(tag2) - return tag2->comment(); - - return String::null; - } - - virtual String genre() const { - if(tag1 && !tag1->genre().isEmpty()) - return tag1->genre(); - - if(tag2) - return tag2->genre(); - - return String::null; - } - - virtual uint year() const { - if(tag1 && tag1->year() > 0) - return tag1->year(); - - if(tag2) - return tag2->year(); - - return 0; - } - - virtual uint track() const { - if(tag1 && tag1->track() > 0) - return tag1->track(); - - if(tag2) - return tag2->track(); - - return 0; - } - - virtual void setTitle(const String &s) { - if(tag1) - tag1->setTitle(s); - if(tag2) - tag2->setTitle(s); - } - - virtual void setArtist(const String &s) { - if(tag1) - tag1->setArtist(s); - if(tag2) - tag2->setArtist(s); - } - - virtual void setAlbum(const String &s) { - if(tag1) - tag1->setAlbum(s); - if(tag2) - tag2->setAlbum(s); - } - - virtual void setComment(const String &s) { - if(tag1) - tag1->setComment(s); - if(tag2) - tag2->setComment(s); - } - - virtual void setGenre(const String &s) { - if(tag1) - tag1->setGenre(s); - if(tag2) - tag2->setGenre(s); - } - - virtual void setYear(uint i) { - if(tag1) - tag1->setYear(i); - if(tag2) - tag2->setYear(i); - } - - virtual void setTrack(uint i) { - if(tag1) - tag1->setTrack(i); - if(tag2) - tag2->setTrack(i); - } - - private: - Tag *tag1; - Tag *tag2; - }; -} - -#endif -#endif diff --git a/taglib/mpc/mpcfile.cpp b/taglib/mpc/mpcfile.cpp index 0d9fe636..922bf838 100644 --- a/taglib/mpc/mpcfile.cpp +++ b/taglib/mpc/mpcfile.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include "mpcfile.h" @@ -32,23 +33,24 @@ #include "id3v2header.h" #include "apetag.h" #include "apefooter.h" -#include "combinedtag.h" using namespace TagLib; +namespace +{ + enum { APEIndex, ID3v1Index }; +} + class MPC::File::FilePrivate { public: FilePrivate() : - APETag(0), APELocation(-1), APESize(0), - ID3v1Tag(0), ID3v1Location(-1), ID3v2Header(0), ID3v2Location(-1), ID3v2Size(0), - tag(0), properties(0), scanned(false), hasAPE(false), @@ -57,26 +59,20 @@ public: ~FilePrivate() { - if (tag != ID3v1Tag && tag != APETag) delete tag; - delete ID3v1Tag; - delete APETag; delete ID3v2Header; delete properties; } - APE::Tag *APETag; - // long APEFooter; long APELocation; uint APESize; - ID3v1::Tag *ID3v1Tag; long ID3v1Location; ID3v2::Header *ID3v2Header; long ID3v2Location; uint ID3v2Size; - Tag *tag; + TagUnion tag; Properties *properties; bool scanned; @@ -107,7 +103,7 @@ MPC::File::~File() TagLib::Tag *MPC::File::tag() const { - return d->tag; + return &d->tag; } MPC::Properties *MPC::File::audioProperties() const @@ -135,15 +131,15 @@ bool MPC::File::save() // Update ID3v1 tag - if(d->ID3v1Tag) { + if(ID3v1Tag()) { if(d->hasID3v1) { seek(d->ID3v1Location); - writeBlock(d->ID3v1Tag->render()); + writeBlock(ID3v1Tag()->render()); } else { seek(0, End); d->ID3v1Location = tell(); - writeBlock(d->ID3v1Tag->render()); + writeBlock(ID3v1Tag()->render()); d->hasID3v1 = true; } } else @@ -158,13 +154,13 @@ bool MPC::File::save() // Update APE tag - if(d->APETag) { + if(APETag()) { if(d->hasAPE) - insert(d->APETag->render(), d->APELocation, d->APESize); + insert(APETag()->render(), d->APELocation, d->APESize); else { if(d->hasID3v1) { - insert(d->APETag->render(), d->ID3v1Location, 0); - d->APESize = d->APETag->footer()->completeTagSize(); + insert(APETag()->render(), d->ID3v1Location, 0); + d->APESize = APETag()->footer()->completeTagSize(); d->hasAPE = true; d->APELocation = d->ID3v1Location; d->ID3v1Location += d->APESize; @@ -172,8 +168,8 @@ bool MPC::File::save() else { seek(0, End); d->APELocation = tell(); - writeBlock(d->APETag->render()); - d->APESize = d->APETag->footer()->completeTagSize(); + writeBlock(APETag()->render()); + d->APESize = APETag()->footer()->completeTagSize(); d->hasAPE = true; } } @@ -183,7 +179,7 @@ bool MPC::File::save() removeBlock(d->APELocation, d->APESize); d->hasAPE = false; if(d->hasID3v1) { - if (d->ID3v1Location > d->APELocation) + if(d->ID3v1Location > d->APELocation) d->ID3v1Location -= d->APESize; } } @@ -193,48 +189,19 @@ bool MPC::File::save() 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; + return d->tag.access(ID3v1Index, create); } 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; + return d->tag.access(APEIndex, create); } void MPC::File::strip(int tags) { if(tags & ID3v1) { - delete d->ID3v1Tag; - d->ID3v1Tag = 0; - - if(d->APETag) - d->tag = d->APETag; - else - d->tag = d->APETag = new APE::Tag; + d->tag.set(ID3v1Index, 0); + APETag(true); } if(tags & ID3v2) { @@ -243,13 +210,10 @@ void MPC::File::strip(int tags) } if(tags & APE) { - delete d->APETag; - d->APETag = 0; + d->tag.set(APEIndex, 0); - if(d->ID3v1Tag) - d->tag = d->ID3v1Tag; - else - d->tag = d->APETag = new APE::Tag; + if(!ID3v1Tag()) + APETag(true); } } @@ -270,7 +234,7 @@ void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesSty d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location); + d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -281,24 +245,15 @@ void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesSty d->APELocation = findAPE(); if(d->APELocation >= 0) { - d->APETag = new APE::Tag(this, d->APELocation); - d->APESize = d->APETag->footer()->completeTagSize(); - d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APESize; + d->tag.set(APEIndex, new APE::Tag(this, d->APELocation)); + + d->APESize = APETag()->footer()->completeTagSize(); + d->APELocation = d->APELocation + APETag()->footer()->size() - d->APESize; d->hasAPE = 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; - } - } + if(!d->hasID3v1) + APETag(true); // Look for and skip an ID3v2 tag diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp index 58622d62..18dc75c0 100644 --- a/taglib/mpeg/mpegfile.cpp +++ b/taglib/mpeg/mpegfile.cpp @@ -41,27 +41,6 @@ using namespace TagLib; namespace { enum { ID3v2Index = 0, APEIndex = 1, ID3v1Index = 2 }; - - class MPEGTag : public TagUnion - { - public: - virtual Tag *tag(int index, AccessType type) const - { - if(type == Write) - { - if(index == ID3v2Index && !(*this)[ID3v2Index]) - { - const_cast(this)->setTag(ID3v2Index, new ID3v2::Tag); - } - else if(index == ID3v1Index && !(*this)[ID3v1Index]) - { - const_cast(this)->setTag(ID3v1Index, new ID3v1::Tag); - } - } - - return TagUnion::tag(index); - } - }; } class MPEG::File::FilePrivate @@ -97,7 +76,7 @@ public: long ID3v1Location; - MPEGTag tag; + TagUnion tag; // These indicate whether the file *on disk* has these tags, not if // this data structure does. This is used in computing offsets. @@ -257,25 +236,17 @@ bool MPEG::File::save(int tags, bool stripOthers) ID3v2::Tag *MPEG::File::ID3v2Tag(bool create) { - return static_cast( - d->tag.tag(ID3v2Index, create ? MPEGTag::Write : MPEGTag::Read)); + return d->tag.access(ID3v2Index, create); } ID3v1::Tag *MPEG::File::ID3v1Tag(bool create) { - return static_cast( - d->tag.tag(ID3v1Index, create ? MPEGTag::Write : MPEGTag::Read)); + return d->tag.access(ID3v1Index, create); } APE::Tag *MPEG::File::APETag(bool create) { - if(!create || d->tag[APEIndex]) - return static_cast(d->tag[APEIndex]); - - debug("Creating APE Tag."); - - d->tag.setTag(APEIndex, new APE::Tag); - return static_cast(d->tag[APEIndex]); + return d->tag.access(APEIndex, create); } bool MPEG::File::strip(int tags) @@ -297,7 +268,7 @@ bool MPEG::File::strip(int tags, bool freeMemory) d->hasID3v2 = false; if(freeMemory) - d->tag.setTag(ID3v2Index, 0); + d->tag.set(ID3v2Index, 0); // v1 tag location has changed, update if it exists @@ -316,7 +287,7 @@ bool MPEG::File::strip(int tags, bool freeMemory) d->hasID3v1 = false; if(freeMemory) - d->tag.setTag(ID3v1Index, 0); + d->tag.set(ID3v1Index, 0); } if((tags & APE) && d->hasAPE) { @@ -329,7 +300,7 @@ bool MPEG::File::strip(int tags, bool freeMemory) } if(freeMemory) - d->tag.setTag(APEIndex, 0); + d->tag.set(APEIndex, 0); } return true; @@ -411,12 +382,12 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle if(d->ID3v2Location >= 0) { - d->tag.setTag(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); + d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); d->ID3v2OriginalSize = ID3v2Tag()->header()->completeTagSize(); if(ID3v2Tag()->header()->tagSize() <= 0) - d->tag.setTag(ID3v2Index, 0); + d->tag.set(ID3v2Index, 0); else d->hasID3v2 = true; } @@ -426,7 +397,7 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->tag.setTag(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); + d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -436,9 +407,7 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle if(d->APELocation >= 0) { - debug("Found APE"); - - d->tag.setTag(APEIndex, new APE::Tag(this, d->APELocation)); + d->tag.set(APEIndex, new APE::Tag(this, d->APELocation)); d->APEOriginalSize = APETag()->footer()->completeTagSize(); @@ -449,6 +418,11 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle if(readProperties) d->properties = new Properties(this, propertiesStyle); + + // Make sure that we have our default tag types available. + + ID3v2Tag(true); + ID3v1Tag(true); } long MPEG::File::findID3v2() diff --git a/taglib/tagunion.cpp b/taglib/tagunion.cpp index b29bb1f0..ae181eb8 100644 --- a/taglib/tagunion.cpp +++ b/taglib/tagunion.cpp @@ -28,30 +28,30 @@ using namespace TagLib; #define stringUnion(method) \ - if(tag(0, Read) && !tag(0, Read)->method().isEmpty()) \ - return tag(0, Read)->method(); \ - if(tag(1, Read) && !tag(1, Read)->method().isEmpty()) \ - return tag(1, Read)->method(); \ - if(tag(2, Read) && !tag(2, Read)->method().isEmpty()) \ - return tag(2, Read)->method(); \ + if(tag(0) && !tag(0)->method().isEmpty()) \ + return tag(0)->method(); \ + if(tag(1) && !tag(1)->method().isEmpty()) \ + return tag(1)->method(); \ + if(tag(2) && !tag(2)->method().isEmpty()) \ + return tag(2)->method(); \ return String::null \ #define numberUnion(method) \ - if(tag(0, Read) && tag(0, Read)->method() > 0) \ - return tag(0, Read)->method(); \ - if(tag(1, Read) && tag(1, Read)->method() > 0) \ - return tag(1, Read)->method(); \ - if(tag(2, Read) && tag(2, Read)->method() > 0) \ - return tag(2, Read)->method(); \ + if(tag(0) && tag(0)->method() > 0) \ + return tag(0)->method(); \ + if(tag(1) && tag(1)->method() > 0) \ + return tag(1)->method(); \ + if(tag(2) && tag(2)->method() > 0) \ + return tag(2)->method(); \ return 0 #define setUnion(method, value) \ - if(tag(0, Write)) \ - tag(0, Write)->set##method(value); \ - if(tag(1, Write)) \ - tag(1, Write)->set##method(value); \ - if(tag(2, Write)) \ - tag(2, Write)->set##method(value); \ + if(tag(0)) \ + tag(0)->set##method(value); \ + if(tag(1)) \ + tag(1)->set##method(value); \ + if(tag(2)) \ + tag(2)->set##method(value); \ class TagUnion::TagUnionPrivate { @@ -87,15 +87,15 @@ TagUnion::~TagUnion() Tag *TagUnion::operator[](int index) const { - return d->tags[index]; + return tag(index); } -Tag *TagUnion::tag(int index, AccessType) const +Tag *TagUnion::tag(int index) const { - return (*this)[index]; + return d->tags[index]; } -void TagUnion::setTag(int index, Tag *tag) +void TagUnion::set(int index, Tag *tag) { delete d->tags[index]; d->tags[index] = tag; diff --git a/taglib/tagunion.h b/taglib/tagunion.h index 7ccf5fb3..80d996db 100644 --- a/taglib/tagunion.h +++ b/taglib/tagunion.h @@ -49,22 +49,10 @@ namespace TagLib { virtual ~TagUnion(); - /*! - * Simply returns the value for the the tag at \a index. - * - * \note This does not call tag() - * - * \see tag() - */ Tag *operator[](int index) const; + Tag *tag(int index) const; - /*! - * By default just a call to operator[], but may be overridden if, for - * instance, it is desirable to create frames on write. - */ - virtual Tag *tag(int index, AccessType type = Read) const; - - void setTag(int index, Tag *tag); + void set(int index, Tag *tag); virtual String title() const; virtual String artist() const; @@ -83,6 +71,15 @@ namespace TagLib { virtual void setTrack(uint i); virtual bool isEmpty() const; + template T *access(int index, bool create) + { + if(!create || tag(index)) + return static_cast(tag(index)); + + set(index, new T); + return static_cast(tag(index)); + } + private: TagUnion(const Tag &); TagUnion &operator=(const Tag &); diff --git a/taglib/trueaudio/trueaudiofile.cpp b/taglib/trueaudio/trueaudiofile.cpp index c5bee76b..c5979ecf 100644 --- a/taglib/trueaudio/trueaudiofile.cpp +++ b/taglib/trueaudio/trueaudiofile.cpp @@ -30,26 +30,28 @@ #include #include #include +#include #include "trueaudiofile.h" #include "id3v1tag.h" #include "id3v2tag.h" #include "id3v2header.h" -#include "combinedtag.h" using namespace TagLib; +namespace +{ + enum { ID3v2Index = 0, ID3v1Index = 1 }; +} + class TrueAudio::File::FilePrivate { public: FilePrivate(const ID3v2::FrameFactory *frameFactory = ID3v2::FrameFactory::instance()) : ID3v2FrameFactory(frameFactory), - ID3v2Tag(0), ID3v2Location(-1), ID3v2OriginalSize(0), - ID3v1Tag(0), ID3v1Location(-1), - tag(0), properties(0), scanned(false), hasID3v1(false), @@ -57,21 +59,16 @@ public: ~FilePrivate() { - if (tag != ID3v1Tag && tag != ID3v2Tag) delete tag; - delete ID3v1Tag; - delete ID3v2Tag; delete properties; } const ID3v2::FrameFactory *ID3v2FrameFactory; - ID3v2::Tag *ID3v2Tag; long ID3v2Location; uint ID3v2OriginalSize; - ID3v1::Tag *ID3v1Tag; long ID3v1Location; - Tag *tag; + TagUnion tag; Properties *properties; bool scanned; @@ -111,7 +108,7 @@ TrueAudio::File::~File() TagLib::Tag *TrueAudio::File::tag() const { - return d->tag; + return &d->tag; } TrueAudio::Properties *TrueAudio::File::audioProperties() const @@ -133,12 +130,12 @@ bool TrueAudio::File::save() // Update ID3v2 tag - if(d->ID3v2Tag && !d->ID3v2Tag->isEmpty()) { + if(ID3v2Tag() && !ID3v2Tag()->isEmpty()) { if(!d->hasID3v2) { d->ID3v2Location = 0; d->ID3v2OriginalSize = 0; } - ByteVector data = d->ID3v2Tag->render(); + ByteVector data = ID3v2Tag()->render(); insert(data, d->ID3v2Location, d->ID3v2OriginalSize); d->ID3v1Location -= d->ID3v2OriginalSize - data.size(); d->ID3v2OriginalSize = data.size(); @@ -154,14 +151,14 @@ bool TrueAudio::File::save() // Update ID3v1 tag - if(d->ID3v1Tag && !d->ID3v1Tag->isEmpty()) { + if(ID3v1Tag() && !ID3v1Tag()->isEmpty()) { if(!d->hasID3v1) { seek(0, End); d->ID3v1Location = tell(); } else seek(d->ID3v1Location); - writeBlock(d->ID3v1Tag->render()); + writeBlock(ID3v1Tag()->render()); d->hasID3v1 = true; } else if(d->hasID3v1) { @@ -175,58 +172,26 @@ bool TrueAudio::File::save() ID3v1::Tag *TrueAudio::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->ID3v2Tag) - d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag); - else - d->tag = d->ID3v1Tag; - - return d->ID3v1Tag; + return d->tag.access(ID3v1Index, create); } ID3v2::Tag *TrueAudio::File::ID3v2Tag(bool create) { - if(!create || d->ID3v2Tag) - return d->ID3v2Tag; - - // no ID3v2 tag exists and we've been asked to create one - - d->ID3v2Tag = new ID3v2::Tag; - - if(d->ID3v1Tag) - d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag); - else - d->tag = d->ID3v2Tag; - - return d->ID3v2Tag; + return d->tag.access(ID3v2Index, create); } void TrueAudio::File::strip(int tags) { if(tags & ID3v1) { - delete d->ID3v1Tag; - d->ID3v1Tag = 0; - - if(d->ID3v2Tag) - d->tag = d->ID3v2Tag; - else - d->tag = d->ID3v2Tag = new ID3v2::Tag; + d->tag.set(ID3v1Index, 0); + ID3v2Tag(true); } if(tags & ID3v2) { - delete d->ID3v2Tag; - d->ID3v2Tag = 0; + d->tag.set(ID3v2Index, 0); - if(d->ID3v1Tag) - d->tag = d->ID3v1Tag; - else - d->tag = d->ID3v2Tag = new ID3v2::Tag; + if(!ID3v1Tag()) + ID3v2Tag(true); } } @@ -243,14 +208,12 @@ void TrueAudio::File::read(bool readProperties, Properties::ReadStyle /* propert if(d->ID3v2Location >= 0) { - d->ID3v2Tag = new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory); + d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); - d->ID3v2OriginalSize = d->ID3v2Tag->header()->completeTagSize(); + d->ID3v2OriginalSize = ID3v2Tag()->header()->completeTagSize(); - if(d->ID3v2Tag->header()->tagSize() <= 0) { - delete d->ID3v2Tag; - d->ID3v2Tag = 0; - } + if(ID3v2Tag()->header()->tagSize() <= 0) + d->tag.set(ID3v2Index, 0); else d->hasID3v2 = true; } @@ -260,22 +223,12 @@ void TrueAudio::File::read(bool readProperties, Properties::ReadStyle /* propert d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location); + d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } - if(d->hasID3v1 && d->hasID3v2) - d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag); - else { - if(d->hasID3v1) - d->tag = d->ID3v1Tag; - else { - if(d->hasID3v2) - d->tag = d->ID3v2Tag; - else - d->tag = d->ID3v2Tag = new ID3v2::Tag; - } - } + if(!d->hasID3v1) + ID3v2Tag(true); // Look for TrueAudio metadata diff --git a/taglib/wavpack/wavpackfile.cpp b/taglib/wavpack/wavpackfile.cpp index 37ea42e7..e0360253 100644 --- a/taglib/wavpack/wavpackfile.cpp +++ b/taglib/wavpack/wavpackfile.cpp @@ -30,26 +30,28 @@ #include #include #include +#include #include "wavpackfile.h" #include "id3v1tag.h" #include "id3v2header.h" #include "apetag.h" #include "apefooter.h" -#include "combinedtag.h" using namespace TagLib; +namespace +{ + enum { APEIndex, ID3v1Index }; +} + class WavPack::File::FilePrivate { public: FilePrivate() : - APETag(0), APELocation(-1), APESize(0), - ID3v1Tag(0), ID3v1Location(-1), - tag(0), properties(0), scanned(false), hasAPE(false), @@ -57,20 +59,15 @@ public: ~FilePrivate() { - if (tag != ID3v1Tag && tag != APETag) delete tag; - delete ID3v1Tag; - delete APETag; delete properties; } - APE::Tag *APETag; long APELocation; uint APESize; - ID3v1::Tag *ID3v1Tag; long ID3v1Location; - Tag *tag; + TagUnion tag; Properties *properties; bool scanned; @@ -100,7 +97,7 @@ WavPack::File::~File() TagLib::Tag *WavPack::File::tag() const { - return d->tag; + return &d->tag; } WavPack::Properties *WavPack::File::audioProperties() const @@ -117,18 +114,19 @@ bool WavPack::File::save() // Update ID3v1 tag - if(d->ID3v1Tag) { + if(ID3v1Tag()) { if(d->hasID3v1) { seek(d->ID3v1Location); - writeBlock(d->ID3v1Tag->render()); + writeBlock(ID3v1Tag()->render()); } else { seek(0, End); d->ID3v1Location = tell(); - writeBlock(d->ID3v1Tag->render()); + writeBlock(ID3v1Tag()->render()); d->hasID3v1 = true; } - } else + } + else { if(d->hasID3v1) { removeBlock(d->ID3v1Location, 128); d->hasID3v1 = false; @@ -137,16 +135,17 @@ bool WavPack::File::save() d->APELocation -= 128; } } + } // Update APE tag - if(d->APETag) { + if(APETag()) { if(d->hasAPE) - insert(d->APETag->render(), d->APELocation, d->APESize); + insert(APETag()->render(), d->APELocation, d->APESize); else { if(d->hasID3v1) { - insert(d->APETag->render(), d->ID3v1Location, 0); - d->APESize = d->APETag->footer()->completeTagSize(); + insert(APETag()->render(), d->ID3v1Location, 0); + d->APESize = APETag()->footer()->completeTagSize(); d->hasAPE = true; d->APELocation = d->ID3v1Location; d->ID3v1Location += d->APESize; @@ -154,79 +153,49 @@ bool WavPack::File::save() else { seek(0, End); d->APELocation = tell(); - writeBlock(d->APETag->render()); - d->APESize = d->APETag->footer()->completeTagSize(); + writeBlock(APETag()->render()); + d->APESize = APETag()->footer()->completeTagSize(); d->hasAPE = true; } } } - else + else { if(d->hasAPE) { removeBlock(d->APELocation, d->APESize); d->hasAPE = false; if(d->hasID3v1) { - if (d->ID3v1Location > d->APELocation) + if(d->ID3v1Location > d->APELocation) { d->ID3v1Location -= d->APESize; + } } } + } return true; } ID3v1::Tag *WavPack::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; + return d->tag.access(ID3v1Index, create); } APE::Tag *WavPack::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; + return d->tag.access(APEIndex, create); } void WavPack::File::strip(int tags) { if(tags & ID3v1) { - delete d->ID3v1Tag; - d->ID3v1Tag = 0; - - if(d->APETag) - d->tag = d->APETag; - else - d->tag = d->APETag = new APE::Tag; + d->tag.set(ID3v1Index, 0); + APETag(true); } if(tags & APE) { - delete d->APETag; - d->APETag = 0; + d->tag.set(APEIndex, 0); - if(d->ID3v1Tag) - d->tag = d->ID3v1Tag; - else - d->tag = d->APETag = new APE::Tag; + if(!ID3v1Tag()) + APETag(true); } } @@ -241,7 +210,7 @@ void WavPack::File::read(bool readProperties, Properties::ReadStyle /* propertie d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location); + d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -250,24 +219,14 @@ void WavPack::File::read(bool readProperties, Properties::ReadStyle /* propertie d->APELocation = findAPE(); if(d->APELocation >= 0) { - d->APETag = new APE::Tag(this, d->APELocation); - d->APESize = d->APETag->footer()->completeTagSize(); - d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APESize; + d->tag.set(APEIndex, new APE::Tag(this, d->APELocation)); + d->APESize = APETag()->footer()->completeTagSize(); + d->APELocation = d->APELocation + APETag()->footer()->size() - d->APESize; d->hasAPE = 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; - } - } + if(!d->hasID3v1) + APETag(true); // Look for WavPack audio properties -- 2.40.0