Implemented dict interface for more formats.

Now supported: MOD files (IT, MOD, S3M, XM), RIFF files
(AIFF, WAV), TrueAudio, WavPack.
This commit is contained in:
Michael Helmling
2011-11-02 21:02:35 +01:00
parent 292a377d1e
commit 0eaf3a3fbd
20 changed files with 315 additions and 29 deletions

View File

@ -65,6 +65,16 @@ Mod::Tag *IT::File::tag() const
return &d->tag;
}
TagDict IT::File::toDict() const
{
return d->tag.toDict();
}
void IT::File::fromDict(const TagDict &tagDict)
{
d->tag.fromDict(tagDict);
}
IT::Properties *IT::File::audioProperties() const
{
return &d->properties;

View File

@ -60,6 +60,18 @@ namespace TagLib {
Mod::Tag *tag() const;
/*!
* Implements the unified tag dictionary interface -- export function.
* Forwards to Mod::Tag::toDict().
*/
TagDict toDict() const;
/*!
* Implements the unified tag dictionary interface -- import function.
* Forwards to Mod::Tag::fromDict().
*/
void fromDict(const TagDict &);
/*!
* Returns the IT::Properties for this file. If no audio properties
* were read then this will return a null pointer.
@ -74,6 +86,7 @@ namespace TagLib {
*/
bool save();
private:
File(const File &);
File &operator=(const File &);

View File

@ -70,6 +70,16 @@ Mod::Properties *Mod::File::audioProperties() const
return &d->properties;
}
TagDict Mod::File::toDict() const
{
return d->tag.toDict();
}
void Mod::File::fromDict(const TagDict &tagDict)
{
d->tag.fromDict(tagDict);
}
bool Mod::File::save()
{
if(readOnly()) {

View File

@ -61,6 +61,17 @@ namespace TagLib {
Mod::Tag *tag() const;
/*!
* Implements the unified tag dictionary interface -- export function.
* Forwards to Mod::Tag::toDict().
*/
TagDict toDict() const;
/*!
* Implements the unified tag dictionary interface -- import function.
* Forwards to Mod::Tag::fromDict().
*/
void fromDict(const TagDict &);
/*!
* Returns the Mod::Properties for this file. If no audio properties
* were read then this will return a null pointer.

View File

@ -20,7 +20,7 @@
***************************************************************************/
#include "modtag.h"
#include "tstringlist.h"
using namespace TagLib;
using namespace Mod;
@ -120,3 +120,31 @@ void Mod::Tag::setTrackerName(const String &trackerName)
{
d->trackerName = trackerName;
}
TagDict Mod::Tag::toDict() const
{
TagDict dict;
dict["TITLE"] = d->title;
dict["COMMENT"] = d->comment;
if (!(d->trackerName == String::null))
dict["TRACKERNAME"] = d->trackerName;
return dict;
}
void Mod::Tag::fromDict(const TagDict &tagDict)
{
if (tagDict.contains("TITLE") && !tagDict["TITILE"].isEmpty())
d->title = tagDict["TITLE"][0];
else
d->title = String::null;
if (tagDict.contains("COMMENT") && !tagDict["COMMENT"].isEmpty())
d->comment = tagDict["COMMENT"][0];
else
d->comment = String::null;
if (tagDict.contains("TRACKERNAME") && !tagDict["TRACKERNAME"].isEmpty())
d->trackerName = tagDict["TRACKERNAME"][0];
else
d->trackerName = String::null;
}

View File

@ -159,6 +159,21 @@ namespace TagLib {
*/
void setTrackerName(const String &trackerName);
/*!
* Implements the unified tag dictionary interface -- export function.
* Since the module tag is very limited, the exported dict is as well.
*/
TagDict toDict() const;
/*!
* Implements the unified tag dictionary interface -- import function.
* Because of the limitations of the module file tag, any tags besides
* COMMENT, TITLE and, if it is an XM file, TRACKERNAME, will be
* ignored. Additionally, if the dict contains tags with multiple values,
* all but the first will be ignored.
*/
void fromDict(const TagDict &);
private:
Tag(const Tag &);
Tag &operator=(const Tag &);

View File

@ -26,6 +26,7 @@
#include <tbytevector.h>
#include <tdebug.h>
#include <id3v2tag.h>
#include <tstringlist.h>
#include "aifffile.h"
@ -83,6 +84,18 @@ ID3v2::Tag *RIFF::AIFF::File::tag() const
return d->tag;
}
TagLib::TagDict RIFF::AIFF::File::toDict(void) const
{
return d->tag->toDict();
}
void RIFF::AIFF::File::fromDict(const TagDict &dict)
{
d->tag->fromDict(dict);
}
RIFF::AIFF::Properties *RIFF::AIFF::File::audioProperties() const
{
return d->properties;

View File

@ -83,6 +83,18 @@ namespace TagLib {
*/
virtual ID3v2::Tag *tag() const;
/*!
* Implements the unified tag dictionary interface -- export function.
* This method forwards to ID3v2::Tag::toDict.
*/
TagDict toDict() const;
/*!
* Implements the unified tag dictionary interface -- import function.
* This method forwards to ID3v2::Tag::fromDict.
*/
void fromDict(const TagDict &);
/*!
* Returns the AIFF::Properties for this file. If no audio properties
* were read then this will return a null pointer.

View File

@ -26,6 +26,7 @@
#include <tbytevector.h>
#include <tdebug.h>
#include <id3v2tag.h>
#include <tstringlist.h>
#include "wavfile.h"
@ -83,6 +84,17 @@ ID3v2::Tag *RIFF::WAV::File::tag() const
return d->tag;
}
TagLib::TagDict RIFF::WAV::File::toDict(void) const
{
return d->tag->toDict();
}
void RIFF::WAV::File::fromDict(const TagDict &dict)
{
d->tag->fromDict(dict);
}
RIFF::WAV::Properties *RIFF::WAV::File::audioProperties() const
{
return d->properties;

View File

@ -83,6 +83,18 @@ namespace TagLib {
*/
virtual ID3v2::Tag *tag() const;
/*!
* Implements the unified tag dictionary interface -- export function.
* This method forwards to ID3v2::Tag::toDict.
*/
TagDict toDict() const;
/*!
* Implements the unified tag dictionary interface -- import function.
* This method forwards to ID3v2::Tag::fromDict.
*/
void fromDict(const TagDict &);
/*!
* Returns the WAV::Properties for this file. If no audio properties
* were read then this will return a null pointer.

View File

@ -67,6 +67,16 @@ Mod::Tag *S3M::File::tag() const
return &d->tag;
}
TagDict S3M::File::toDict() const
{
return d->tag.toDict();
}
void S3M::File::fromDict(const TagDict &tagDict)
{
d->tag.fromDict(tagDict);
}
S3M::Properties *S3M::File::audioProperties() const
{
return &d->properties;

View File

@ -60,6 +60,18 @@ namespace TagLib {
Mod::Tag *tag() const;
/*!
* Implements the unified tag dictionary interface -- export function.
* Forwards to Mod::Tag::toDict().
*/
TagDict toDict() const;
/*!
* Implements the unified tag dictionary interface -- import function.
* Forwards to Mod::Tag::fromDict().
*/
void fromDict(const TagDict &);
/*!
* Returns the S3M::Properties for this file. If no audio properties
* were read then this will return a null pointer.

View File

@ -75,32 +75,32 @@ TagDict Tag::toDict() const
void Tag::fromDict(const TagDict &dict)
{
if (dict.contains("TITLE") and dict["TITLE"].size() >= 1)
if (dict.contains("TITLE") && dict["TITLE"].size() >= 1)
setTitle(dict["TITLE"].front());
else
setTitle(String::null);
if (dict.contains("ARTIST") and dict["ARTIST"].size() >= 1)
if (dict.contains("ARTIST") && !dict["ARTIST"].isEmpty())
setArtist(dict["ARTIST"].front());
else
setArtist(String::null);
if (dict.contains("ALBUM") and dict["ALBUM"].size() >= 1)
if (dict.contains("ALBUM") && !dict["ALBUM"].isEmpty())
setAlbum(dict["ALBUM"].front());
else
setAlbum(String::null);
if (dict.contains("COMMENT") and dict["COMMENT"].size() >= 1)
if (dict.contains("COMMENT") && !dict["COMMENT"].isEmpty())
setComment(dict["COMMENT"].front());
else
setComment(String::null);
if (dict.contains("GENRE") and dict["GENRE"].size() >=1)
if (dict.contains("GENRE") && !dict["GENRE"].isEmpty())
setGenre(dict["GENRE"].front());
else
setGenre(String::null);
if (dict.contains("DATE") and dict["DATE"].size() >= 1) {
if (dict.contains("DATE") && !dict["DATE"].isEmpty()) {
bool ok;
int date = dict["DATE"].front().toInt(&ok);
if (ok)
@ -111,7 +111,7 @@ void Tag::fromDict(const TagDict &dict)
else
setYear(0);
if (dict.contains("TRACKNUMBER") and dict["TRACKNUMBER"].size() >= 1) {
if (dict.contains("TRACKNUMBER") && !dict["TRACKNUMBER"].isEmpty()) {
bool ok;
int track = dict["TRACKNUMBER"].front().toInt(&ok);
if (ok)

View File

@ -66,7 +66,7 @@
#include "modfile.h"
#include "s3mfile.h"
#include "itfile.h"
#include "xmfile.h" \
#include "xmfile.h"
using namespace TagLib;
@ -117,39 +117,76 @@ TagDict File::toDict() const
{
// ugly workaround until this method is virtual
if (dynamic_cast<const APE::File* >(this))
return dynamic_cast<const APE::File* >(this)->toDict();
return dynamic_cast<const APE::File* >(this)->toDict();
if (dynamic_cast<const FLAC::File* >(this))
return dynamic_cast<const FLAC::File* >(this)->toDict();
return dynamic_cast<const FLAC::File* >(this)->toDict();
if (dynamic_cast<const IT::File* >(this))
return dynamic_cast<const IT::File* >(this)->toDict();
if (dynamic_cast<const Mod::File* >(this))
return dynamic_cast<const Mod::File* >(this)->toDict();
if (dynamic_cast<const MPC::File* >(this))
return dynamic_cast<const MPC::File* >(this)->toDict();
return dynamic_cast<const MPC::File* >(this)->toDict();
if (dynamic_cast<const MPEG::File* >(this))
return dynamic_cast<const MPEG::File* >(this)->toDict();
return dynamic_cast<const MPEG::File* >(this)->toDict();
if (dynamic_cast<const Ogg::FLAC::File* >(this))
return dynamic_cast<const Ogg::FLAC::File* >(this)->toDict();
if (dynamic_cast<const Ogg::Speex::File* >(this))
return dynamic_cast<const Ogg::Speex::File* >(this)->toDict();
return dynamic_cast<const Ogg::Speex::File* >(this)->toDict();
if (dynamic_cast<const Ogg::Vorbis::File* >(this))
return dynamic_cast<const Ogg::Vorbis::File* >(this)->toDict();
return dynamic_cast<const Ogg::Vorbis::File* >(this)->toDict();
if (dynamic_cast<const RIFF::AIFF::File* >(this))
return dynamic_cast<const RIFF::AIFF::File* >(this)->toDict();
if (dynamic_cast<const RIFF::WAV::File* >(this))
return dynamic_cast<const RIFF::WAV::File* >(this)->toDict();
if (dynamic_cast<const S3M::File* >(this))
return dynamic_cast<const S3M::File* >(this)->toDict();
if (dynamic_cast<const TrueAudio::File* >(this))
return dynamic_cast<const TrueAudio::File* >(this)->toDict();
if (dynamic_cast<const WavPack::File* >(this))
return dynamic_cast<const WavPack::File* >(this)->toDict();
if (dynamic_cast<const XM::File* >(this))
return dynamic_cast<const XM::File* >(this)->toDict();
// no specialized implementation available -> use generic one
// - ASF: ugly format, largely undocumented, not worth implementing
// dict interface ...
// - MP4: taglib's MP4::Tag does not really support anything beyond
// the basic implementation, therefor we use just the default Tag
// interface
return tag()->toDict();
}
void File::fromDict(const TagDict &dict)
{
if (dynamic_cast<const APE::File* >(this))
dynamic_cast< APE::File* >(this)->fromDict(dict);
else if (dynamic_cast<const FLAC::File* >(this))
dynamic_cast< FLAC::File* >(this)->fromDict(dict);
else if (dynamic_cast<const MPC::File* >(this))
dynamic_cast< MPC::File* >(this)->fromDict(dict);
else if (dynamic_cast<const MPEG::File* >(this))
dynamic_cast< MPEG::File* >(this)->fromDict(dict);
else if (dynamic_cast<const Ogg::FLAC::File* >(this))
dynamic_cast< Ogg::FLAC::File* >(this)->fromDict(dict);
else if (dynamic_cast<const Ogg::Speex::File* >(this))
dynamic_cast< Ogg::Speex::File* >(this)->fromDict(dict);
else if (dynamic_cast<const Ogg::Vorbis::File* >(this))
dynamic_cast< Ogg::Vorbis::File* >(this)->fromDict(dict);
if (dynamic_cast<APE::File* >(this))
dynamic_cast<APE::File* >(this)->fromDict(dict);
else if (dynamic_cast<FLAC::File* >(this))
dynamic_cast<FLAC::File* >(this)->fromDict(dict);
else if (dynamic_cast<IT::File* >(this))
dynamic_cast<IT::File* >(this)->fromDict(dict);
else if (dynamic_cast<Mod::File* >(this))
dynamic_cast<Mod::File* >(this)->fromDict(dict);
else if (dynamic_cast<MPC::File* >(this))
dynamic_cast<MPC::File* >(this)->fromDict(dict);
else if (dynamic_cast<MPEG::File* >(this))
dynamic_cast<MPEG::File* >(this)->fromDict(dict);
else if (dynamic_cast<Ogg::FLAC::File* >(this))
dynamic_cast<Ogg::FLAC::File* >(this)->fromDict(dict);
else if (dynamic_cast<Ogg::Speex::File* >(this))
dynamic_cast<Ogg::Speex::File* >(this)->fromDict(dict);
else if (dynamic_cast<Ogg::Vorbis::File* >(this))
dynamic_cast<Ogg::Vorbis::File* >(this)->fromDict(dict);
else if (dynamic_cast<RIFF::AIFF::File* >(this))
dynamic_cast<RIFF::AIFF::File* >(this)->fromDict(dict);
else if (dynamic_cast<RIFF::WAV::File* >(this))
dynamic_cast<RIFF::WAV::File* >(this)->fromDict(dict);
else if (dynamic_cast<S3M::File* >(this))
dynamic_cast<S3M::File* >(this)->fromDict(dict);
else if (dynamic_cast<TrueAudio::File* >(this))
dynamic_cast<TrueAudio::File* >(this)->fromDict(dict);
else if (dynamic_cast<WavPack::File* >(this))
dynamic_cast<WavPack::File* >(this)->fromDict(dict);
else if (dynamic_cast<XM::File* >(this))
dynamic_cast<XM::File* >(this)->fromDict(dict);
else
tag()->fromDict(dict);

View File

@ -31,6 +31,7 @@
#include <tstring.h>
#include <tdebug.h>
#include <tagunion.h>
#include <tstringlist.h>
#include "trueaudiofile.h"
#include "id3v1tag.h"
@ -126,6 +127,27 @@ TagLib::Tag *TrueAudio::File::tag() const
return &d->tag;
}
TagLib::TagDict TrueAudio::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<ID3v2::Tag>(ID3v2Index, false)->toDict();
if (d->hasID3v1)
return d->tag.access<ID3v1::Tag>(ID3v1Index, false)->toDict();
return TagLib::TagDict();
}
void TrueAudio::File::fromDict(const TagDict &dict)
{
if (d->hasID3v2)
d->tag.access<ID3v2::Tag>(ID3v2Index, false)->fromDict(dict);
else if (d->hasID3v1)
d->tag.access<ID3v1::Tag>(ID3v1Index, false)->fromDict(dict);
else
d->tag.access<ID3v2::Tag>(ID3v2Index, true)->fromDict(dict);
}
TrueAudio::Properties *TrueAudio::File::audioProperties() const
{
return d->properties;

View File

@ -124,6 +124,20 @@ namespace TagLib {
*/
virtual TagLib::Tag *tag() const;
/*!
* Implements the unified tag dictionary interface -- export function.
* If the file contains both ID3v1 and v2 tags, only ID3v2 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 TrueAudio::Properties for this file. If no audio properties
* were read then this will return a null pointer.

View File

@ -105,6 +105,25 @@ TagLib::Tag *WavPack::File::tag() const
return &d->tag;
}
TagLib::TagDict WavPack::File::toDict(void) const
{
if (d->hasAPE)
return d->tag.access<APE::Tag>(APEIndex, false)->toDict();
if (d->hasID3v1)
return d->tag.access<ID3v1::Tag>(ID3v1Index, false)->toDict();
return TagLib::TagDict();
}
void WavPack::File::fromDict(const TagDict &dict)
{
if (d->hasAPE)
d->tag.access<APE::Tag>(APEIndex, false)->fromDict(dict);
else if (d->hasID3v1)
d->tag.access<ID3v1::Tag>(ID3v1Index, false)->fromDict(dict);
else
d->tag.access<APE::Tag>(APE, true)->fromDict(dict);
}
WavPack::Properties *WavPack::File::audioProperties() const
{
return d->properties;

View File

@ -106,6 +106,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 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 MPC::Properties for this file. If no audio properties
* were read then this will return a null pointer.

View File

@ -379,6 +379,16 @@ Mod::Tag *XM::File::tag() const
return &d->tag;
}
TagDict XM::File::toDict() const
{
return d->tag.toDict();
}
void XM::File::fromDict(const TagDict &tagDict)
{
d->tag.fromDict(tagDict);
}
XM::Properties *XM::File::audioProperties() const
{
return &d->properties;

View File

@ -60,6 +60,18 @@ namespace TagLib {
Mod::Tag *tag() const;
/*!
* Implements the unified tag dictionary interface -- export function.
* Forwards to Mod::Tag::toDict().
*/
TagDict toDict() const;
/*!
* Implements the unified tag dictionary interface -- import function.
* Forwards to Mod::Tag::fromDict().
*/
void fromDict(const TagDict &);
/*!
* Returns the XM::Properties for this file. If no audio properties
* were read then this will return a null pointer.