From: Michael Helmling Date: Sun, 28 Aug 2011 20:58:40 +0000 (+0200) Subject: Made im/export functions nonvirtual. Added similar functions to File and X-Git-Tag: v1.8beta~24^2~40 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5647b2e2935d6e4a06f9fe8b449055772e31c097;p=taglib Made im/export functions nonvirtual. Added similar functions to File and its subclasses. TagLib::File contains a bunch of dynamic_casts to call the correct specializations. --- diff --git a/taglib/ape/apefile.cpp b/taglib/ape/apefile.cpp index 2973a476..7c63412e 100644 --- a/taglib/ape/apefile.cpp +++ b/taglib/ape/apefile.cpp @@ -109,6 +109,25 @@ TagLib::Tag *APE::File::tag() const return &d->tag; } +TagLib::TagDict APE::File::toDict(void) const +{ + if (d->hasAPE) + return d->tag.access(APEIndex, false)->toDict(); + if (d->hasID3v1) + return d->tag.access(ID3v1Index, false)->toDict(); + return TagLib::TagDict(); +} + +void APE::File::fromDict(const TagDict &dict) +{ + if (d->hasAPE) + d->tag.access(APEIndex, false)->fromDict(dict); + else if (d->hasID3v1) + d->tag.access(ID3v1Index, false)->fromDict(dict); + else + d->tag.access(APE, true)->fromDict(dict); +} + APE::Properties *APE::File::audioProperties() const { return d->properties; diff --git a/taglib/ape/apefile.h b/taglib/ape/apefile.h index 2f22fdde..ab290b83 100644 --- a/taglib/ape/apefile.h +++ b/taglib/ape/apefile.h @@ -110,6 +110,19 @@ namespace TagLib { */ virtual TagLib::Tag *tag() const; + /*! + * Implements the unified tag dictionary interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only APE + * will be converted to the TagDict. + */ + TagDict toDict() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * As for the export, only one tag is taken into account. If the file + * has no tag at all, APE will be created. + */ + void fromDict(const TagDict &); /*! * Returns the APE::Properties for this file. If no audio properties * were read then this will return a null pointer. diff --git a/taglib/ape/apetag.h b/taglib/ape/apetag.h index b48d9291..089420ea 100644 --- a/taglib/ape/apetag.h +++ b/taglib/ape/apetag.h @@ -114,13 +114,13 @@ namespace TagLib { * TRACK to TRACKNUMBER and YEAR to DATE, respectively, in order to be compliant * with the names used in other formats. */ - virtual TagDict toDict() const; + TagDict toDict() const; /*! * Implements the unified tag dictionary interface -- import function. The same * comments as for the export function apply. */ - virtual void fromDict(const TagDict &); + void fromDict(const TagDict &); /*! * Returns a pointer to the tag's footer. diff --git a/taglib/flac/flacfile.cpp b/taglib/flac/flacfile.cpp index 5065cd29..ec925d0f 100644 --- a/taglib/flac/flacfile.cpp +++ b/taglib/flac/flacfile.cpp @@ -138,6 +138,31 @@ TagLib::Tag *FLAC::File::tag() const return &d->tag; } +TagLib::TagDict FLAC::File::toDict(void) const +{ + // once Tag::toDict() is virtual, this case distinction could actually be done + // within TagUnion. + if (d->hasXiphComment) + return d->tag.access(XiphIndex, false)->toDict(); + if (d->hasID3v2) + return d->tag.access(ID3v2Index, false)->toDict(); + if (d->hasID3v1) + return d->tag.access(ID3v1Index, false)->toDict(); + return TagLib::TagDict(); +} + +void FLAC::File::fromDict(const TagDict &dict) +{ + if (d->hasXiphComment) + d->tag.access(XiphIndex, false)->fromDict(dict); + else if (d->hasID3v2) + d->tag.access(ID3v2Index, false)->fromDict(dict); + else if (d->hasID3v1) + d->tag.access(ID3v1Index, false)->fromDict(dict); + else + d->tag.access(XiphIndex, true)->fromDict(dict); +} + FLAC::Properties *FLAC::File::audioProperties() const { return d->properties; diff --git a/taglib/flac/flacfile.h b/taglib/flac/flacfile.h index 01466a2d..9fdc1c2e 100644 --- a/taglib/flac/flacfile.h +++ b/taglib/flac/flacfile.h @@ -29,6 +29,7 @@ #include "taglib_export.h" #include "tfile.h" #include "tlist.h" +#include "tag.h" #include "flacpicture.h" #include "flacproperties.h" @@ -36,7 +37,6 @@ namespace TagLib { class Tag; - namespace ID3v2 { class FrameFactory; class Tag; } namespace ID3v1 { class Tag; } namespace Ogg { class XiphComment; } @@ -118,6 +118,21 @@ namespace TagLib { */ virtual TagLib::Tag *tag() const; + /*! + * Implements the unified tag dictionary interface -- export function. + * If the file contains more than one tag (e.g. XiphComment and ID3v1), + * only the first one (in the order XiphComment, ID3v2, ID3v1) will be + * converted to the TagDict. + */ + TagDict toDict() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * As with the export, only one tag is taken into account. If the file + * has no tag at all, a XiphComment will be created. + */ + void fromDict(const TagDict &); + /*! * Returns the FLAC::Properties for this file. If no audio properties * were read then this will return a null pointer. diff --git a/taglib/mpc/mpcfile.cpp b/taglib/mpc/mpcfile.cpp index 216c1b3b..2482a90c 100644 --- a/taglib/mpc/mpcfile.cpp +++ b/taglib/mpc/mpcfile.cpp @@ -113,6 +113,27 @@ TagLib::Tag *MPC::File::tag() const return &d->tag; } +TagLib::TagDict MPC::File::toDict(void) const +{ + // once Tag::toDict() is virtual, this case distinction could actually be done + // within TagUnion. + if (d->hasAPE) + return d->tag.access(APEIndex, false)->toDict(); + if (d->hasID3v1) + return d->tag.access(ID3v1Index, false)->toDict(); + return TagLib::TagDict(); +} + +void MPC::File::fromDict(const TagDict &dict) +{ + if (d->hasAPE) + d->tag.access(APEIndex, false)->fromDict(dict); + else if (d->hasID3v1) + d->tag.access(ID3v1Index, false)->fromDict(dict); + else + d->tag.access(APEIndex, true)->fromDict(dict); +} + MPC::Properties *MPC::File::audioProperties() const { return d->properties; diff --git a/taglib/mpc/mpcfile.h b/taglib/mpc/mpcfile.h index 93471cf1..6ff91e71 100644 --- a/taglib/mpc/mpcfile.h +++ b/taglib/mpc/mpcfile.h @@ -28,6 +28,7 @@ #include "taglib_export.h" #include "tfile.h" +#include "tag.h" #include "mpcproperties.h" @@ -107,6 +108,20 @@ namespace TagLib { */ virtual TagLib::Tag *tag() const; + /*! + * Implements the unified tag dictionary interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only the APE + * tag will be converted to the TagDict. + */ + TagDict toDict() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * As with the export, only one tag is taken into account. If the file + * has no tag at all, APE will be created. + */ + void fromDict(const TagDict &); + /*! * Returns the MPC::Properties for this file. If no audio properties * were read then this will return a null pointer. diff --git a/taglib/mpeg/id3v2/id3v2tag.h b/taglib/mpeg/id3v2/id3v2tag.h index f67a71e7..3f731282 100644 --- a/taglib/mpeg/id3v2/id3v2tag.h +++ b/taglib/mpeg/id3v2/id3v2tag.h @@ -265,13 +265,13 @@ namespace TagLib { * This function does some work to translate the hard-specified ID3v2 * frame types into a free-form string-to-stringlist dictionary. */ - virtual TagDict toDict() const; + TagDict toDict() const; /*! * Implements the unified tag dictionary interface -- import function. * See the comments in toDict(). */ - virtual void fromDict(const TagDict &); + void fromDict(const TagDict &); /*! * Render the tag back to binary data, suitable to be written to disk. diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp index a3bad823..645409fa 100644 --- a/taglib/mpeg/mpegfile.cpp +++ b/taglib/mpeg/mpegfile.cpp @@ -133,6 +133,31 @@ TagLib::Tag *MPEG::File::tag() const return &d->tag; } +TagLib::TagDict MPEG::File::toDict(void) const +{ + // once Tag::toDict() is virtual, this case distinction could actually be done + // within TagUnion. + if (d->hasID3v2) + return d->tag.access(ID3v2Index, false)->toDict(); + if (d->hasAPE) + return d->tag.access(APEIndex, false)->toDict(); + if (d->hasID3v1) + return d->tag.access(ID3v1Index, false)->toDict(); + return TagLib::TagDict(); +} + +void MPEG::File::fromDict(const TagDict &dict) +{ + if (d->hasID3v2) + d->tag.access(ID3v2Index, false)->fromDict(dict); + else if (d->hasAPE) + d->tag.access(APEIndex, false)->fromDict(dict); + else if (d->hasID3v1) + d->tag.access(ID3v1Index, false)->fromDict(dict); + else + d->tag.access(ID3v2Index, true)->fromDict(dict); +} + MPEG::Properties *MPEG::File::audioProperties() const { return d->properties; diff --git a/taglib/mpeg/mpegfile.h b/taglib/mpeg/mpegfile.h index cff5469d..75da7b0a 100644 --- a/taglib/mpeg/mpegfile.h +++ b/taglib/mpeg/mpegfile.h @@ -28,6 +28,7 @@ #include "taglib_export.h" #include "tfile.h" +#include "tag.h" #include "mpegproperties.h" @@ -128,6 +129,21 @@ namespace TagLib { */ virtual Tag *tag() const; + /*! + * Implements the unified tag dictionary interface -- export function. + * If the file contains more than one tag (e.g. ID3v2 and v1), only the + * first one (in the order ID3v2, APE, ID3v1) will be converted to the + * TagDict. + */ + TagDict toDict() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * As with the export, only one tag is taken into account. If the file + * has no tag at all, ID3v2 will be created. + */ + void fromDict(const TagDict &); + /*! * Returns the MPEG::Properties for this file. If no audio properties * were read then this will return a null pointer. diff --git a/taglib/ogg/flac/oggflacfile.cpp b/taglib/ogg/flac/oggflacfile.cpp index 3addbffa..437dabf0 100644 --- a/taglib/ogg/flac/oggflacfile.cpp +++ b/taglib/ogg/flac/oggflacfile.cpp @@ -92,6 +92,16 @@ Ogg::XiphComment *Ogg::FLAC::File::tag() const return d->comment; } +TagLib::TagDict Ogg::FLAC::File::toDict(void) const +{ + return d->comment->toDict(); +} + +void Ogg::FLAC::File::fromDict(const TagDict &dict) +{ + d->comment->fromDict(dict); +} + Properties *Ogg::FLAC::File::audioProperties() const { return d->properties; diff --git a/taglib/ogg/flac/oggflacfile.h b/taglib/ogg/flac/oggflacfile.h index d4373795..e39ac2cc 100644 --- a/taglib/ogg/flac/oggflacfile.h +++ b/taglib/ogg/flac/oggflacfile.h @@ -89,6 +89,18 @@ namespace TagLib { */ virtual XiphComment *tag() const; + /*! + * Implements the unified tag dictionary interface -- export function. + * Returns the contents of the Ogg::XiphComment as TagDict. + */ + TagDict toDict() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Matches the TagDict's contents to the XiphComment of the file. + */ + void fromDict(const TagDict &); + /*! * Returns the FLAC::Properties for this file. If no audio properties * were read then this will return a null pointer. diff --git a/taglib/ogg/speex/speexfile.cpp b/taglib/ogg/speex/speexfile.cpp index 3a4940a2..d602bcc8 100644 --- a/taglib/ogg/speex/speexfile.cpp +++ b/taglib/ogg/speex/speexfile.cpp @@ -82,6 +82,16 @@ Ogg::XiphComment *Speex::File::tag() const return d->comment; } +TagLib::TagDict Ogg::Speex::File::toDict(void) const +{ + return d->comment->toDict(); +} + +void Ogg::Speex::File::fromDict(const TagDict &dict) +{ + d->comment->fromDict(dict); +} + Speex::Properties *Speex::File::audioProperties() const { return d->properties; diff --git a/taglib/ogg/speex/speexfile.h b/taglib/ogg/speex/speexfile.h index c14cf2aa..2af6cd82 100644 --- a/taglib/ogg/speex/speexfile.h +++ b/taglib/ogg/speex/speexfile.h @@ -82,6 +82,17 @@ namespace TagLib { * TagLib::File::tag(). */ virtual Ogg::XiphComment *tag() const; + /*! + * Implements the unified tag dictionary interface -- export function. + * Returns the contents of the Ogg::XiphComment as TagDict. + */ + TagDict toDict() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Matches the TagDict's contents to the XiphComment of the file. + */ + void fromDict(const TagDict &); /*! * Returns the Speex::Properties for this file. If no audio properties diff --git a/taglib/ogg/vorbis/vorbisfile.cpp b/taglib/ogg/vorbis/vorbisfile.cpp index 60056f83..fe50d6d0 100644 --- a/taglib/ogg/vorbis/vorbisfile.cpp +++ b/taglib/ogg/vorbis/vorbisfile.cpp @@ -85,6 +85,16 @@ Ogg::XiphComment *Vorbis::File::tag() const return d->comment; } +TagLib::TagDict Ogg::Vorbis::File::toDict(void) const +{ + return d->comment->toDict(); +} + +void Ogg::Vorbis::File::fromDict(const TagDict &dict) +{ + d->comment->fromDict(dict); +} + Vorbis::Properties *Vorbis::File::audioProperties() const { return d->properties; diff --git a/taglib/ogg/vorbis/vorbisfile.h b/taglib/ogg/vorbis/vorbisfile.h index 299d9c2d..989eac3d 100644 --- a/taglib/ogg/vorbis/vorbisfile.h +++ b/taglib/ogg/vorbis/vorbisfile.h @@ -90,6 +90,17 @@ namespace TagLib { */ virtual Ogg::XiphComment *tag() const; + /*! + * Implements the unified tag dictionary interface -- export function. + * Returns the contents of the Ogg::XiphComment as TagDict. + */ + TagDict toDict() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Matches the TagDict's contents to the XiphComment of the file. + */ + void fromDict(const TagDict &); /*! * Returns the Vorbis::Properties for this file. If no audio properties * were read then this will return a null pointer. diff --git a/taglib/ogg/xiphcomment.h b/taglib/ogg/xiphcomment.h index 6ad23c6a..f9f23d54 100644 --- a/taglib/ogg/xiphcomment.h +++ b/taglib/ogg/xiphcomment.h @@ -147,13 +147,13 @@ namespace TagLib { * comment is nothing more than a map from tag names to list of values, * as is the dict interface). */ - virtual TagDict toDict() const; + TagDict toDict() const; /*! * Implements the unified tag dictionary interface -- import function. * The tags from the given dict will be stored one-to-one in the file. */ - virtual void fromDict(const TagDict &); + void fromDict(const TagDict &); /*! * Returns the vendor ID of the Ogg Vorbis encoder. libvorbis 1.0 as the diff --git a/taglib/tag.h b/taglib/tag.h index 45caf083..728c3980 100644 --- a/taglib/tag.h +++ b/taglib/tag.h @@ -63,7 +63,7 @@ namespace TagLib { * of the specific metadata format into a "human-readable" map of strings * to lists of strings, being as precise as possible. */ - virtual TagDict toDict() const; + TagDict toDict() const; /*! * Unified tag dictionary interface -- import function. Converts a map @@ -72,7 +72,7 @@ namespace TagLib { * be lost by this operation. Especially the default implementation handles * only single values of the default tags specified in this class. */ - virtual void fromDict(const TagDict &); + void fromDict(const TagDict &); /*! * Returns the track name; if no track name is present in the tag diff --git a/taglib/toolkit/tfile.cpp b/taglib/toolkit/tfile.cpp index ae3eec1d..9ac5f9bb 100644 --- a/taglib/toolkit/tfile.cpp +++ b/taglib/toolkit/tfile.cpp @@ -50,6 +50,24 @@ # define W_OK 2 #endif +#include "asffile.h" +#include "mpegfile.h" +#include "vorbisfile.h" +#include "flacfile.h" +#include "oggflacfile.h" +#include "mpcfile.h" +#include "mp4file.h" +#include "wavpackfile.h" +#include "speexfile.h" +#include "trueaudiofile.h" +#include "aifffile.h" +#include "wavfile.h" +#include "apefile.h" +#include "modfile.h" +#include "s3mfile.h" +#include "itfile.h" +#include "xmfile.h" \ + using namespace TagLib; class File::FilePrivate @@ -95,6 +113,48 @@ FileName File::name() const return d->stream->name(); } +TagDict File::toDict() const +{ + // ugly workaround until this method is virtual + if (dynamic_cast(this)) + return dynamic_cast(this)->toDict(); + if (dynamic_cast(this)) + return dynamic_cast(this)->toDict(); + if (dynamic_cast(this)) + return dynamic_cast(this)->toDict(); + if (dynamic_cast(this)) + return dynamic_cast(this)->toDict(); + if (dynamic_cast(this)) + return dynamic_cast(this)->toDict(); + if (dynamic_cast(this)) + return dynamic_cast(this)->toDict(); + if (dynamic_cast(this)) + return dynamic_cast(this)->toDict(); + // no specialized implementation available -> use generic one + return tag()->toDict(); +} + +void File::fromDict(const TagDict &dict) +{ + if (dynamic_cast(this)) + dynamic_cast< APE::File* >(this)->fromDict(dict); + else if (dynamic_cast(this)) + dynamic_cast< FLAC::File* >(this)->fromDict(dict); + else if (dynamic_cast(this)) + dynamic_cast< MPC::File* >(this)->fromDict(dict); + else if (dynamic_cast(this)) + dynamic_cast< MPEG::File* >(this)->fromDict(dict); + else if (dynamic_cast(this)) + dynamic_cast< Ogg::FLAC::File* >(this)->fromDict(dict); + else if (dynamic_cast(this)) + dynamic_cast< Ogg::Speex::File* >(this)->fromDict(dict); + else if (dynamic_cast(this)) + dynamic_cast< Ogg::Vorbis::File* >(this)->fromDict(dict); + else + tag()->fromDict(dict); + +} + ByteVector File::readBlock(ulong length) { return d->stream->readBlock(length); diff --git a/taglib/toolkit/tfile.h b/taglib/toolkit/tfile.h index ee6f0488..75faf8a8 100644 --- a/taglib/toolkit/tfile.h +++ b/taglib/toolkit/tfile.h @@ -28,6 +28,7 @@ #include "taglib_export.h" #include "taglib.h" +#include "tag.h" #include "tbytevector.h" #include "tiostream.h" @@ -76,6 +77,20 @@ namespace TagLib { */ virtual Tag *tag() const = 0; + /*! + * Exports the tags of the file as dictionary mapping (human readable) tag + * names (Strings) to StringLists of tag values. Calls the according specialization + * in the File subclasses. + * Will be made virtual in future releases. + */ + TagDict toDict() const; + + /*! + * Sets the tags of this File to those specified by the given TagDict. Calls the + * according specialization method in the subclasses of File to do the translation + * into the format-specific details. + */ + void fromDict(const TagDict &); /*! * Returns a pointer to this file's audio properties. This should be * reimplemented in the concrete subclasses. If no audio properties were