mirror of
https://github.com/taglib/taglib.git
synced 2025-06-04 01:28:21 -04:00
Merge pull request #207 from TsudaKageyu/anonymous
Moved somethings from global to anonymous namespace.
This commit is contained in:
commit
a23d41c509
@ -175,14 +175,17 @@ void APE::Tag::setTrack(uint i)
|
||||
addValue("TRACK", String::number(i), true);
|
||||
}
|
||||
|
||||
// conversions of tag keys between what we use in PropertyMap and what's usual
|
||||
// for APE tags
|
||||
static const TagLib::uint keyConversionsSize = 5; //usual, APE
|
||||
static const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" },
|
||||
{"DATE", "YEAR" },
|
||||
{"ALBUMARTIST", "ALBUM ARTIST"},
|
||||
{"DISCNUMBER", "DISC" },
|
||||
{"REMIXER", "MIXARTIST" }};
|
||||
namespace
|
||||
{
|
||||
// conversions of tag keys between what we use in PropertyMap and what's usual
|
||||
// for APE tags
|
||||
static const TagLib::uint keyConversionsSize = 5; //usual, APE
|
||||
static const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" },
|
||||
{"DATE", "YEAR" },
|
||||
{"ALBUMARTIST", "ALBUM ARTIST"},
|
||||
{"DISCNUMBER", "DISC" },
|
||||
{"REMIXER", "MIXARTIST" }};
|
||||
}
|
||||
|
||||
PropertyMap APE::Tag::properties() const
|
||||
{
|
||||
|
@ -56,17 +56,20 @@ public:
|
||||
ASF::File::MetadataLibraryObject *metadataLibraryObject;
|
||||
};
|
||||
|
||||
static const ByteVector headerGuid("\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
|
||||
static const ByteVector filePropertiesGuid("\xA1\xDC\xAB\x8C\x47\xA9\xCF\x11\x8E\xE4\x00\xC0\x0C\x20\x53\x65", 16);
|
||||
static const ByteVector streamPropertiesGuid("\x91\x07\xDC\xB7\xB7\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65", 16);
|
||||
static const ByteVector contentDescriptionGuid("\x33\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
|
||||
static const ByteVector extendedContentDescriptionGuid("\x40\xA4\xD0\xD2\x07\xE3\xD2\x11\x97\xF0\x00\xA0\xC9\x5E\xA8\x50", 16);
|
||||
static const ByteVector headerExtensionGuid("\xb5\x03\xbf_.\xa9\xcf\x11\x8e\xe3\x00\xc0\x0c Se", 16);
|
||||
static const ByteVector metadataGuid("\xEA\xCB\xF8\xC5\xAF[wH\204g\xAA\214D\xFAL\xCA", 16);
|
||||
static const ByteVector metadataLibraryGuid("\224\034#D\230\224\321I\241A\x1d\x13NEpT", 16);
|
||||
static const ByteVector contentEncryptionGuid("\xFB\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E", 16);
|
||||
static const ByteVector extendedContentEncryptionGuid("\x14\xE6\x8A\x29\x22\x26 \x17\x4C\xB9\x35\xDA\xE0\x7E\xE9\x28\x9C", 16);
|
||||
static const ByteVector advancedContentEncryptionGuid("\xB6\x9B\x07\x7A\xA4\xDA\x12\x4E\xA5\xCA\x91\xD3\x8D\xC1\x1A\x8D", 16);
|
||||
namespace
|
||||
{
|
||||
const ByteVector headerGuid("\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
|
||||
const ByteVector filePropertiesGuid("\xA1\xDC\xAB\x8C\x47\xA9\xCF\x11\x8E\xE4\x00\xC0\x0C\x20\x53\x65", 16);
|
||||
const ByteVector streamPropertiesGuid("\x91\x07\xDC\xB7\xB7\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65", 16);
|
||||
const ByteVector contentDescriptionGuid("\x33\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
|
||||
const ByteVector extendedContentDescriptionGuid("\x40\xA4\xD0\xD2\x07\xE3\xD2\x11\x97\xF0\x00\xA0\xC9\x5E\xA8\x50", 16);
|
||||
const ByteVector headerExtensionGuid("\xb5\x03\xbf_.\xa9\xcf\x11\x8e\xe3\x00\xc0\x0c Se", 16);
|
||||
const ByteVector metadataGuid("\xEA\xCB\xF8\xC5\xAF[wH\204g\xAA\214D\xFAL\xCA", 16);
|
||||
const ByteVector metadataLibraryGuid("\224\034#D\230\224\321I\241A\x1d\x13NEpT", 16);
|
||||
const ByteVector contentEncryptionGuid("\xFB\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E", 16);
|
||||
const ByteVector extendedContentEncryptionGuid("\x14\xE6\x8A\x29\x22\x26 \x17\x4C\xB9\x35\xDA\xE0\x7E\xE9\x28\x9C", 16);
|
||||
const ByteVector advancedContentEncryptionGuid("\xB6\x9B\x07\x7A\xA4\xDA\x12\x4E\xA5\xCA\x91\xD3\x8D\xC1\x1A\x8D", 16);
|
||||
}
|
||||
|
||||
class ASF::File::BaseObject
|
||||
{
|
||||
|
@ -194,46 +194,49 @@ bool ASF::Tag::isEmpty() const
|
||||
d->attributeListMap.isEmpty();
|
||||
}
|
||||
|
||||
static const char *keyTranslation[][2] = {
|
||||
{ "WM/AlbumTitle", "ALBUM" },
|
||||
{ "WM/Composer", "COMPOSER" },
|
||||
{ "WM/Writer", "WRITER" },
|
||||
{ "WM/Conductor", "CONDUCTOR" },
|
||||
{ "WM/ModifiedBy", "REMIXER" },
|
||||
{ "WM/Year", "DATE" },
|
||||
{ "WM/OriginalReleaseYear", "ORIGINALDATE" },
|
||||
{ "WM/Producer", "PRODUCER" },
|
||||
{ "WM/ContentGroupDescription", "GROUPING" },
|
||||
{ "WM/SubTitle", "SUBTITLE" },
|
||||
{ "WM/SetSubTitle", "DISCSUBTITLE" },
|
||||
{ "WM/TrackNumber", "TRACKNUMBER" },
|
||||
{ "WM/PartOfSet", "DISCNUMBER" },
|
||||
{ "WM/Genre", "GENRE" },
|
||||
{ "WM/BeatsPerMinute", "BPM" },
|
||||
{ "WM/Mood", "MOOD" },
|
||||
{ "WM/ISRC", "ISRC" },
|
||||
{ "WM/Lyrics", "LYRICS" },
|
||||
{ "WM/Media", "MEDIA" },
|
||||
{ "WM/Publisher", "LABEL" },
|
||||
{ "WM/CatalogNo", "CATALOGNUMBER" },
|
||||
{ "WM/Barcode", "BARCODE" },
|
||||
{ "WM/EncodedBy", "ENCODEDBY" },
|
||||
{ "WM/AlbumSortOrder", "ALBUMSORT" },
|
||||
{ "WM/AlbumArtistSortOrder", "ALBUMARTISTSORT" },
|
||||
{ "WM/ArtistSortOrder", "ARTISTSORT" },
|
||||
{ "WM/TitleSortOrder", "TITLESORT" },
|
||||
{ "WM/Script", "SCRIPT" },
|
||||
{ "WM/Language", "LANGUAGE" },
|
||||
{ "MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID" },
|
||||
{ "MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MusicBrainz/Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "MusicIP/PUID", "MUSICIP_PUID" },
|
||||
{ "Acoustid/Id", "ACOUSTID_ID" },
|
||||
{ "Acoustid/Fingerprint", "ACOUSTID_FINGERPRINT" },
|
||||
};
|
||||
namespace
|
||||
{
|
||||
const char *keyTranslation[][2] = {
|
||||
{ "WM/AlbumTitle", "ALBUM" },
|
||||
{ "WM/Composer", "COMPOSER" },
|
||||
{ "WM/Writer", "WRITER" },
|
||||
{ "WM/Conductor", "CONDUCTOR" },
|
||||
{ "WM/ModifiedBy", "REMIXER" },
|
||||
{ "WM/Year", "DATE" },
|
||||
{ "WM/OriginalReleaseYear", "ORIGINALDATE" },
|
||||
{ "WM/Producer", "PRODUCER" },
|
||||
{ "WM/ContentGroupDescription", "GROUPING" },
|
||||
{ "WM/SubTitle", "SUBTITLE" },
|
||||
{ "WM/SetSubTitle", "DISCSUBTITLE" },
|
||||
{ "WM/TrackNumber", "TRACKNUMBER" },
|
||||
{ "WM/PartOfSet", "DISCNUMBER" },
|
||||
{ "WM/Genre", "GENRE" },
|
||||
{ "WM/BeatsPerMinute", "BPM" },
|
||||
{ "WM/Mood", "MOOD" },
|
||||
{ "WM/ISRC", "ISRC" },
|
||||
{ "WM/Lyrics", "LYRICS" },
|
||||
{ "WM/Media", "MEDIA" },
|
||||
{ "WM/Publisher", "LABEL" },
|
||||
{ "WM/CatalogNo", "CATALOGNUMBER" },
|
||||
{ "WM/Barcode", "BARCODE" },
|
||||
{ "WM/EncodedBy", "ENCODEDBY" },
|
||||
{ "WM/AlbumSortOrder", "ALBUMSORT" },
|
||||
{ "WM/AlbumArtistSortOrder", "ALBUMARTISTSORT" },
|
||||
{ "WM/ArtistSortOrder", "ARTISTSORT" },
|
||||
{ "WM/TitleSortOrder", "TITLESORT" },
|
||||
{ "WM/Script", "SCRIPT" },
|
||||
{ "WM/Language", "LANGUAGE" },
|
||||
{ "MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID" },
|
||||
{ "MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MusicBrainz/Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "MusicIP/PUID", "MUSICIP_PUID" },
|
||||
{ "Acoustid/Id", "ACOUSTID_ID" },
|
||||
{ "Acoustid/Fingerprint", "ACOUSTID_FINGERPRINT" },
|
||||
};
|
||||
}
|
||||
|
||||
PropertyMap ASF::Tag::properties() const
|
||||
{
|
||||
|
@ -767,54 +767,57 @@ MP4::Tag::toString() const
|
||||
return desc.toString("\n");
|
||||
}
|
||||
|
||||
static const char *keyTranslation[][2] = {
|
||||
{ "\251nam", "TITLE" },
|
||||
{ "\251ART", "ARTIST" },
|
||||
{ "\251alb", "ALBUM" },
|
||||
{ "\251cmt", "COMMENT" },
|
||||
{ "\251gen", "GENRE" },
|
||||
{ "\251day", "DATE" },
|
||||
{ "\251wrt", "COMPOSER" },
|
||||
{ "\251grp", "GROUPING" },
|
||||
{ "trkn", "TRACKNUMBER" },
|
||||
{ "disk", "DISCNUMBER" },
|
||||
{ "cpil", "COMPILATION" },
|
||||
{ "tmpo", "BPM" },
|
||||
{ "cprt", "COPYRIGHT" },
|
||||
{ "\251lyr", "LYRICS" },
|
||||
{ "\251too", "ENCODEDBY" },
|
||||
{ "soal", "ALBUMSORT" },
|
||||
{ "soaa", "ALBUMARTISTSORT" },
|
||||
{ "soar", "ARTISTSORT" },
|
||||
{ "sonm", "TITLESORT" },
|
||||
{ "soco", "COMPOSERSORT" },
|
||||
{ "sosn", "SHOWSORT" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Track Id", "MUSICBRAINZ_TRACKID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "----:com.apple.iTunes:ASIN", "ASIN" },
|
||||
{ "----:com.apple.iTunes:LABEL", "LABEL" },
|
||||
{ "----:com.apple.iTunes:LYRICIST", "LYRICIST" },
|
||||
{ "----:com.apple.iTunes:CONDUCTOR", "CONDUCTOR" },
|
||||
{ "----:com.apple.iTunes:REMIXER", "REMIXER" },
|
||||
{ "----:com.apple.iTunes:ENGINEER", "ENGINEER" },
|
||||
{ "----:com.apple.iTunes:PRODUCER", "PRODUCER" },
|
||||
{ "----:com.apple.iTunes:DJMIXER", "DJMIXER" },
|
||||
{ "----:com.apple.iTunes:MIXER", "MIXER" },
|
||||
{ "----:com.apple.iTunes:SUBTITLE", "SUBTITLE" },
|
||||
{ "----:com.apple.iTunes:DISCSUBTITLE", "DISCSUBTITLE" },
|
||||
{ "----:com.apple.iTunes:MOOD", "MOOD" },
|
||||
{ "----:com.apple.iTunes:ISRC", "ISRC" },
|
||||
{ "----:com.apple.iTunes:CATALOGNUMBER", "CATALOGNUMBER" },
|
||||
{ "----:com.apple.iTunes:BARCODE", "BARCODE" },
|
||||
{ "----:com.apple.iTunes:SCRIPT", "SCRIPT" },
|
||||
{ "----:com.apple.iTunes:LANGUAGE", "LANGUAGE" },
|
||||
{ "----:com.apple.iTunes:LICENSE", "LICENSE" },
|
||||
{ "----:com.apple.iTunes:MEDIA", "MEDIA" },
|
||||
};
|
||||
namespace
|
||||
{
|
||||
const char *keyTranslation[][2] = {
|
||||
{ "\251nam", "TITLE" },
|
||||
{ "\251ART", "ARTIST" },
|
||||
{ "\251alb", "ALBUM" },
|
||||
{ "\251cmt", "COMMENT" },
|
||||
{ "\251gen", "GENRE" },
|
||||
{ "\251day", "DATE" },
|
||||
{ "\251wrt", "COMPOSER" },
|
||||
{ "\251grp", "GROUPING" },
|
||||
{ "trkn", "TRACKNUMBER" },
|
||||
{ "disk", "DISCNUMBER" },
|
||||
{ "cpil", "COMPILATION" },
|
||||
{ "tmpo", "BPM" },
|
||||
{ "cprt", "COPYRIGHT" },
|
||||
{ "\251lyr", "LYRICS" },
|
||||
{ "\251too", "ENCODEDBY" },
|
||||
{ "soal", "ALBUMSORT" },
|
||||
{ "soaa", "ALBUMARTISTSORT" },
|
||||
{ "soar", "ARTISTSORT" },
|
||||
{ "sonm", "TITLESORT" },
|
||||
{ "soco", "COMPOSERSORT" },
|
||||
{ "sosn", "SHOWSORT" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Track Id", "MUSICBRAINZ_TRACKID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "----:com.apple.iTunes:ASIN", "ASIN" },
|
||||
{ "----:com.apple.iTunes:LABEL", "LABEL" },
|
||||
{ "----:com.apple.iTunes:LYRICIST", "LYRICIST" },
|
||||
{ "----:com.apple.iTunes:CONDUCTOR", "CONDUCTOR" },
|
||||
{ "----:com.apple.iTunes:REMIXER", "REMIXER" },
|
||||
{ "----:com.apple.iTunes:ENGINEER", "ENGINEER" },
|
||||
{ "----:com.apple.iTunes:PRODUCER", "PRODUCER" },
|
||||
{ "----:com.apple.iTunes:DJMIXER", "DJMIXER" },
|
||||
{ "----:com.apple.iTunes:MIXER", "MIXER" },
|
||||
{ "----:com.apple.iTunes:SUBTITLE", "SUBTITLE" },
|
||||
{ "----:com.apple.iTunes:DISCSUBTITLE", "DISCSUBTITLE" },
|
||||
{ "----:com.apple.iTunes:MOOD", "MOOD" },
|
||||
{ "----:com.apple.iTunes:ISRC", "ISRC" },
|
||||
{ "----:com.apple.iTunes:CATALOGNUMBER", "CATALOGNUMBER" },
|
||||
{ "----:com.apple.iTunes:BARCODE", "BARCODE" },
|
||||
{ "----:com.apple.iTunes:SCRIPT", "SCRIPT" },
|
||||
{ "----:com.apple.iTunes:LANGUAGE", "LANGUAGE" },
|
||||
{ "----:com.apple.iTunes:LICENSE", "LICENSE" },
|
||||
{ "----:com.apple.iTunes:MEDIA", "MEDIA" },
|
||||
};
|
||||
}
|
||||
|
||||
PropertyMap MP4::Tag::properties() const
|
||||
{
|
||||
|
@ -157,36 +157,39 @@ int MPC::AudioProperties::albumPeak() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned long readSize(File *file, size_t &sizelength)
|
||||
namespace
|
||||
{
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
unsigned long readSize(File *file, size_t &sizelength)
|
||||
{
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
|
||||
do {
|
||||
ByteVector b = file->readBlock(1);
|
||||
tmp = b[0];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
sizelength++;
|
||||
} while((tmp & 0x80));
|
||||
return size;
|
||||
do {
|
||||
ByteVector b = file->readBlock(1);
|
||||
tmp = b[0];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
sizelength++;
|
||||
} while((tmp & 0x80));
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned long readSize(const ByteVector &data, size_t &sizelength)
|
||||
{
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
unsigned long pos = 0;
|
||||
|
||||
do {
|
||||
tmp = data[pos++];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
sizelength++;
|
||||
} while((tmp & 0x80) && (pos < data.size()));
|
||||
return size;
|
||||
}
|
||||
|
||||
static const unsigned short sftable [4] = { 44100, 48000, 37800, 32000 };
|
||||
}
|
||||
|
||||
unsigned long readSize(const ByteVector &data, size_t &sizelength)
|
||||
{
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
unsigned long pos = 0;
|
||||
|
||||
do {
|
||||
tmp = data[pos++];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
sizelength++;
|
||||
} while((tmp & 0x80) && (pos < data.size()));
|
||||
return size;
|
||||
}
|
||||
|
||||
static const unsigned short sftable [4] = { 44100, 48000, 37800, 32000 };
|
||||
|
||||
void MPC::AudioProperties::readSV8(File *file)
|
||||
{
|
||||
bool readSH = false, readRG = false;
|
||||
|
@ -51,7 +51,11 @@ public:
|
||||
static const TagLib::StringHandler *stringHandler;
|
||||
};
|
||||
|
||||
static const ID3v1::StringHandler defaultStringHandler;
|
||||
namespace
|
||||
{
|
||||
const ID3v1::StringHandler defaultStringHandler;
|
||||
}
|
||||
|
||||
const TagLib::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = &defaultStringHandler;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -31,20 +31,23 @@
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
||||
static inline int bitsToBytes(int i)
|
||||
namespace
|
||||
{
|
||||
return i % 8 == 0 ? i / 8 : (i - i % 8) / 8 + 1;
|
||||
static inline int bitsToBytes(int i)
|
||||
{
|
||||
return i % 8 == 0 ? i / 8 : (i - i % 8) / 8 + 1;
|
||||
}
|
||||
|
||||
struct ChannelData
|
||||
{
|
||||
ChannelData() : channelType(RelativeVolumeFrame::Other), volumeAdjustment(0) {}
|
||||
|
||||
RelativeVolumeFrame::ChannelType channelType;
|
||||
short volumeAdjustment;
|
||||
RelativeVolumeFrame::PeakVolume peakVolume;
|
||||
};
|
||||
}
|
||||
|
||||
struct ChannelData
|
||||
{
|
||||
ChannelData() : channelType(RelativeVolumeFrame::Other), volumeAdjustment(0) {}
|
||||
|
||||
RelativeVolumeFrame::ChannelType channelType;
|
||||
short volumeAdjustment;
|
||||
RelativeVolumeFrame::PeakVolume peakVolume;
|
||||
};
|
||||
|
||||
class RelativeVolumeFrame::RelativeVolumeFramePrivate
|
||||
{
|
||||
public:
|
||||
|
@ -119,15 +119,18 @@ void TextIdentificationFrame::setTextEncoding(String::Type encoding)
|
||||
d->textEncoding = encoding;
|
||||
}
|
||||
|
||||
// array of allowed TIPL prefixes and their corresponding key value
|
||||
static const TagLib::uint involvedPeopleSize = 5;
|
||||
static const char* involvedPeople[][2] = {
|
||||
{"ARRANGER", "ARRANGER"},
|
||||
{"ENGINEER", "ENGINEER"},
|
||||
{"PRODUCER", "PRODUCER"},
|
||||
{"DJ-MIX", "DJMIXER"},
|
||||
{"MIX", "MIXER"},
|
||||
};
|
||||
namespace
|
||||
{
|
||||
// array of allowed TIPL prefixes and their corresponding key value
|
||||
static const TagLib::uint involvedPeopleSize = 5;
|
||||
static const char* involvedPeople[][2] = {
|
||||
{"ARRANGER", "ARRANGER"},
|
||||
{"ENGINEER", "ENGINEER"},
|
||||
{"PRODUCER", "PRODUCER"},
|
||||
{"DJ-MIX", "DJMIXER"},
|
||||
{"MIX", "MIXER"},
|
||||
};
|
||||
}
|
||||
|
||||
const KeyConversionMap &TextIdentificationFrame::involvedPeopleMap() // static
|
||||
{
|
||||
|
@ -319,121 +319,125 @@ String::Type Frame::checkTextEncoding(const StringList &fields, String::Type enc
|
||||
return checkEncoding(fields, encoding, header()->version());
|
||||
}
|
||||
|
||||
static const TagLib::uint frameTranslationSize = 51;
|
||||
static const char *frameTranslation[][2] = {
|
||||
// Text information frames
|
||||
{ "TALB", "ALBUM"},
|
||||
{ "TBPM", "BPM" },
|
||||
{ "TCOM", "COMPOSER" },
|
||||
{ "TCON", "GENRE" },
|
||||
{ "TCOP", "COPYRIGHT" },
|
||||
{ "TDEN", "ENCODINGTIME" },
|
||||
{ "TDLY", "PLAYLISTDELAY" },
|
||||
{ "TDOR", "ORIGINALDATE" },
|
||||
{ "TDRC", "DATE" },
|
||||
// { "TRDA", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TDAT", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TYER", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TIME", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
{ "TDRL", "RELEASEDATE" },
|
||||
{ "TDTG", "TAGGINGDATE" },
|
||||
{ "TENC", "ENCODEDBY" },
|
||||
{ "TEXT", "LYRICIST" },
|
||||
{ "TFLT", "FILETYPE" },
|
||||
//{ "TIPL", "INVOLVEDPEOPLE" }, handled separately
|
||||
{ "TIT1", "CONTENTGROUP" },
|
||||
{ "TIT2", "TITLE"},
|
||||
{ "TIT3", "SUBTITLE" },
|
||||
{ "TKEY", "INITIALKEY" },
|
||||
{ "TLAN", "LANGUAGE" },
|
||||
{ "TLEN", "LENGTH" },
|
||||
//{ "TMCL", "MUSICIANCREDITS" }, handled separately
|
||||
{ "TMED", "MEDIA" },
|
||||
{ "TMOO", "MOOD" },
|
||||
{ "TOAL", "ORIGINALALBUM" },
|
||||
{ "TOFN", "ORIGINALFILENAME" },
|
||||
{ "TOLY", "ORIGINALLYRICIST" },
|
||||
{ "TOPE", "ORIGINALARTIST" },
|
||||
{ "TOWN", "OWNER" },
|
||||
{ "TPE1", "ARTIST"},
|
||||
{ "TPE2", "ALBUMARTIST" }, // id3's spec says 'PERFORMER', but most programs use 'ALBUMARTIST'
|
||||
{ "TPE3", "CONDUCTOR" },
|
||||
{ "TPE4", "REMIXER" }, // could also be ARRANGER
|
||||
{ "TPOS", "DISCNUMBER" },
|
||||
{ "TPRO", "PRODUCEDNOTICE" },
|
||||
{ "TPUB", "LABEL" },
|
||||
{ "TRCK", "TRACKNUMBER" },
|
||||
{ "TRSN", "RADIOSTATION" },
|
||||
{ "TRSO", "RADIOSTATIONOWNER" },
|
||||
{ "TSOA", "ALBUMSORT" },
|
||||
{ "TSOP", "ARTISTSORT" },
|
||||
{ "TSOT", "TITLESORT" },
|
||||
{ "TSO2", "ALBUMARTISTSORT" }, // non-standard, used by iTunes
|
||||
{ "TSRC", "ISRC" },
|
||||
{ "TSSE", "ENCODING" },
|
||||
// URL frames
|
||||
{ "WCOP", "COPYRIGHTURL" },
|
||||
{ "WOAF", "FILEWEBPAGE" },
|
||||
{ "WOAR", "ARTISTWEBPAGE" },
|
||||
{ "WOAS", "AUDIOSOURCEWEBPAGE" },
|
||||
{ "WORS", "RADIOSTATIONWEBPAGE" },
|
||||
{ "WPAY", "PAYMENTWEBPAGE" },
|
||||
{ "WPUB", "PUBLISHERWEBPAGE" },
|
||||
//{ "WXXX", "URL"}, handled specially
|
||||
// Other frames
|
||||
{ "COMM", "COMMENT" },
|
||||
//{ "USLT", "LYRICS" }, handled specially
|
||||
};
|
||||
|
||||
static const TagLib::uint txxxFrameTranslationSize = 7;
|
||||
static const char *txxxFrameTranslation[][2] = {
|
||||
{ "MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "Acoustid Id", "ACOUSTID_ID" },
|
||||
{ "Acoustid Fingerprint", "ACOUSTID_FINGERPRINT" },
|
||||
{ "MusicIP PUID", "MUSICIP_PUID" },
|
||||
};
|
||||
|
||||
Map<ByteVector, String> &idMap()
|
||||
namespace
|
||||
{
|
||||
static Map<ByteVector, String> m;
|
||||
if(m.isEmpty())
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i)
|
||||
m[frameTranslation[i][0]] = frameTranslation[i][1];
|
||||
return m;
|
||||
}
|
||||
static const TagLib::uint frameTranslationSize = 51;
|
||||
static const char *frameTranslation[][2] = {
|
||||
// Text information frames
|
||||
{ "TALB", "ALBUM"},
|
||||
{ "TBPM", "BPM" },
|
||||
{ "TCOM", "COMPOSER" },
|
||||
{ "TCON", "GENRE" },
|
||||
{ "TCOP", "COPYRIGHT" },
|
||||
{ "TDEN", "ENCODINGTIME" },
|
||||
{ "TDLY", "PLAYLISTDELAY" },
|
||||
{ "TDOR", "ORIGINALDATE" },
|
||||
{ "TDRC", "DATE" },
|
||||
// { "TRDA", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TDAT", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TYER", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TIME", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
{ "TDRL", "RELEASEDATE" },
|
||||
{ "TDTG", "TAGGINGDATE" },
|
||||
{ "TENC", "ENCODEDBY" },
|
||||
{ "TEXT", "LYRICIST" },
|
||||
{ "TFLT", "FILETYPE" },
|
||||
//{ "TIPL", "INVOLVEDPEOPLE" }, handled separately
|
||||
{ "TIT1", "CONTENTGROUP" },
|
||||
{ "TIT2", "TITLE"},
|
||||
{ "TIT3", "SUBTITLE" },
|
||||
{ "TKEY", "INITIALKEY" },
|
||||
{ "TLAN", "LANGUAGE" },
|
||||
{ "TLEN", "LENGTH" },
|
||||
//{ "TMCL", "MUSICIANCREDITS" }, handled separately
|
||||
{ "TMED", "MEDIA" },
|
||||
{ "TMOO", "MOOD" },
|
||||
{ "TOAL", "ORIGINALALBUM" },
|
||||
{ "TOFN", "ORIGINALFILENAME" },
|
||||
{ "TOLY", "ORIGINALLYRICIST" },
|
||||
{ "TOPE", "ORIGINALARTIST" },
|
||||
{ "TOWN", "OWNER" },
|
||||
{ "TPE1", "ARTIST"},
|
||||
{ "TPE2", "ALBUMARTIST" }, // id3's spec says 'PERFORMER', but most programs use 'ALBUMARTIST'
|
||||
{ "TPE3", "CONDUCTOR" },
|
||||
{ "TPE4", "REMIXER" }, // could also be ARRANGER
|
||||
{ "TPOS", "DISCNUMBER" },
|
||||
{ "TPRO", "PRODUCEDNOTICE" },
|
||||
{ "TPUB", "LABEL" },
|
||||
{ "TRCK", "TRACKNUMBER" },
|
||||
{ "TRSN", "RADIOSTATION" },
|
||||
{ "TRSO", "RADIOSTATIONOWNER" },
|
||||
{ "TSOA", "ALBUMSORT" },
|
||||
{ "TSOP", "ARTISTSORT" },
|
||||
{ "TSOT", "TITLESORT" },
|
||||
{ "TSO2", "ALBUMARTISTSORT" }, // non-standard, used by iTunes
|
||||
{ "TSRC", "ISRC" },
|
||||
{ "TSSE", "ENCODING" },
|
||||
// URL frames
|
||||
{ "WCOP", "COPYRIGHTURL" },
|
||||
{ "WOAF", "FILEWEBPAGE" },
|
||||
{ "WOAR", "ARTISTWEBPAGE" },
|
||||
{ "WOAS", "AUDIOSOURCEWEBPAGE" },
|
||||
{ "WORS", "RADIOSTATIONWEBPAGE" },
|
||||
{ "WPAY", "PAYMENTWEBPAGE" },
|
||||
{ "WPUB", "PUBLISHERWEBPAGE" },
|
||||
//{ "WXXX", "URL"}, handled specially
|
||||
// Other frames
|
||||
{ "COMM", "COMMENT" },
|
||||
//{ "USLT", "LYRICS" }, handled specially
|
||||
};
|
||||
|
||||
Map<String, String> &txxxMap()
|
||||
{
|
||||
static Map<String, String> m;
|
||||
if(m.isEmpty()) {
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i) {
|
||||
String key = String(txxxFrameTranslation[i][0]).upper();
|
||||
m[key] = txxxFrameTranslation[i][1];
|
||||
}
|
||||
static const TagLib::uint txxxFrameTranslationSize = 7;
|
||||
static const char *txxxFrameTranslation[][2] = {
|
||||
{ "MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "Acoustid Id", "ACOUSTID_ID" },
|
||||
{ "Acoustid Fingerprint", "ACOUSTID_FINGERPRINT" },
|
||||
{ "MusicIP PUID", "MUSICIP_PUID" },
|
||||
};
|
||||
|
||||
Map<ByteVector, String> &idMap()
|
||||
{
|
||||
static Map<ByteVector, String> m;
|
||||
if(m.isEmpty())
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i)
|
||||
m[frameTranslation[i][0]] = frameTranslation[i][1];
|
||||
return m;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
// list of deprecated frames and their successors
|
||||
static const TagLib::uint deprecatedFramesSize = 4;
|
||||
static const char *deprecatedFrames[][2] = {
|
||||
{"TRDA", "TDRC"}, // 2.3 -> 2.4 (http://en.wikipedia.org/wiki/ID3)
|
||||
{"TDAT", "TDRC"}, // 2.3 -> 2.4
|
||||
{"TYER", "TDRC"}, // 2.3 -> 2.4
|
||||
{"TIME", "TDRC"}, // 2.3 -> 2.4
|
||||
};
|
||||
Map<String, String> &txxxMap()
|
||||
{
|
||||
static Map<String, String> m;
|
||||
if(m.isEmpty()) {
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i) {
|
||||
String key = String(txxxFrameTranslation[i][0]).upper();
|
||||
m[key] = txxxFrameTranslation[i][1];
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
Map<ByteVector,ByteVector> &deprecationMap()
|
||||
{
|
||||
static Map<ByteVector,ByteVector> depMap;
|
||||
if(depMap.isEmpty())
|
||||
for(TagLib::uint i = 0; i < deprecatedFramesSize; ++i)
|
||||
depMap[deprecatedFrames[i][0]] = deprecatedFrames[i][1];
|
||||
return depMap;
|
||||
// list of deprecated frames and their successors
|
||||
static const TagLib::uint deprecatedFramesSize = 4;
|
||||
static const char *deprecatedFrames[][2] = {
|
||||
{"TRDA", "TDRC"}, // 2.3 -> 2.4 (http://en.wikipedia.org/wiki/ID3)
|
||||
{"TDAT", "TDRC"}, // 2.3 -> 2.4
|
||||
{"TYER", "TDRC"}, // 2.3 -> 2.4
|
||||
{"TIME", "TDRC"}, // 2.3 -> 2.4
|
||||
};
|
||||
|
||||
|
||||
Map<ByteVector,ByteVector> &deprecationMap()
|
||||
{
|
||||
static Map<ByteVector,ByteVector> depMap;
|
||||
if(depMap.isEmpty())
|
||||
for(TagLib::uint i = 0; i < deprecatedFramesSize; ++i)
|
||||
depMap[deprecatedFrames[i][0]] = deprecatedFrames[i][1];
|
||||
return depMap;
|
||||
}
|
||||
}
|
||||
|
||||
String Frame::frameIDToKey(const ByteVector &id)
|
||||
|
@ -74,7 +74,11 @@ public:
|
||||
static const TagLib::StringHandler *stringHandler;
|
||||
};
|
||||
|
||||
static const ID3v2::Latin1StringHandler defaultStringHandler;
|
||||
namespace
|
||||
{
|
||||
const ID3v2::Latin1StringHandler defaultStringHandler;
|
||||
}
|
||||
|
||||
const TagLib::StringHandler *ID3v2::Tag::TagPrivate::stringHandler = &defaultStringHandler;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -32,13 +32,16 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
struct Chunk
|
||||
namespace
|
||||
{
|
||||
ByteVector name;
|
||||
offset_t offset;
|
||||
TagLib::uint size;
|
||||
char padding;
|
||||
};
|
||||
struct Chunk
|
||||
{
|
||||
ByteVector name;
|
||||
offset_t offset;
|
||||
TagLib::uint size;
|
||||
char padding;
|
||||
};
|
||||
}
|
||||
|
||||
class RIFF::File::FilePrivate
|
||||
{
|
||||
@ -250,17 +253,20 @@ void RIFF::File::removeChunk(const ByteVector &name)
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool isValidChunkID(const ByteVector &name)
|
||||
namespace
|
||||
{
|
||||
if(name.size() != 4) {
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(name[i] < 32 || name[i] > 127) {
|
||||
bool isValidChunkID(const ByteVector &name)
|
||||
{
|
||||
if(name.size() != 4) {
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(name[i] < 32 || name[i] > 127) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RIFF::File::read()
|
||||
|
@ -57,7 +57,11 @@ public:
|
||||
static const TagLib::StringHandler *stringHandler;
|
||||
};
|
||||
|
||||
static const RIFF::Info::StringHandler defaultStringHandler;
|
||||
namespace
|
||||
{
|
||||
const RIFF::Info::StringHandler defaultStringHandler;
|
||||
}
|
||||
|
||||
const TagLib::StringHandler *RIFF::Info::Tag::TagPrivate::stringHandler = &defaultStringHandler;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -27,11 +27,6 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class ByteVectorListPrivate
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -120,8 +120,11 @@ TagLib::uint WavPack::AudioProperties::sampleFrames() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const unsigned int sample_rates[] = { 6000, 8000, 9600, 11025, 12000,
|
||||
namespace
|
||||
{
|
||||
const unsigned int sample_rates[] = { 6000, 8000, 9600, 11025, 12000,
|
||||
16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 };
|
||||
}
|
||||
|
||||
#define BYTES_STORED 3
|
||||
#define MONO_FLAG 4
|
||||
|
@ -62,294 +62,298 @@ using TagLib::ushort;
|
||||
* Maybe if this is useful to other formats these classes can be moved to
|
||||
* their own public files.
|
||||
*/
|
||||
class Reader
|
||||
|
||||
namespace
|
||||
{
|
||||
public:
|
||||
virtual ~Reader()
|
||||
class Reader
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Reads associated values from \a file, but never reads more
|
||||
* then \a limit bytes.
|
||||
*/
|
||||
virtual uint read(TagLib::File &file, uint limit) = 0;
|
||||
|
||||
/*!
|
||||
* Returns the number of bytes this reader would like to read.
|
||||
*/
|
||||
virtual uint size() const = 0;
|
||||
};
|
||||
|
||||
class SkipReader : public Reader
|
||||
{
|
||||
public:
|
||||
SkipReader(uint size) : m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
uint count = std::min(m_size, limit);
|
||||
file.seek(count, TagLib::File::Current);
|
||||
return count;
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
uint m_size;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ValueReader : public Reader
|
||||
{
|
||||
public:
|
||||
ValueReader(T &value) : value(value)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
T &value;
|
||||
};
|
||||
|
||||
class StringReader : public ValueReader<String>
|
||||
{
|
||||
public:
|
||||
StringReader(String &string, uint size) :
|
||||
ValueReader<String>(string), m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(m_size, limit));
|
||||
size_t count = data.size();
|
||||
const size_t index = data.find((char) 0);
|
||||
if(index != ByteVector::npos) {
|
||||
data.resize(index);
|
||||
public:
|
||||
virtual ~Reader()
|
||||
{
|
||||
}
|
||||
data.replace((char) 0xff, ' ');
|
||||
value = data;
|
||||
return static_cast<uint>(count);
|
||||
}
|
||||
|
||||
uint size() const
|
||||
/*!
|
||||
* Reads associated values from \a file, but never reads more
|
||||
* then \a limit bytes.
|
||||
*/
|
||||
virtual uint read(TagLib::File &file, uint limit) = 0;
|
||||
|
||||
/*!
|
||||
* Returns the number of bytes this reader would like to read.
|
||||
*/
|
||||
virtual uint size() const = 0;
|
||||
};
|
||||
|
||||
class SkipReader : public Reader
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
uint m_size;
|
||||
};
|
||||
|
||||
class ByteReader : public ValueReader<uchar>
|
||||
{
|
||||
public:
|
||||
ByteReader(uchar &byte) : ValueReader<uchar>(byte) {}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(1U,limit));
|
||||
if(data.size() > 0) {
|
||||
value = data[0];
|
||||
public:
|
||||
SkipReader(uint size) : m_size(size)
|
||||
{
|
||||
}
|
||||
return static_cast<uint>(data.size());
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class NumberReader : public ValueReader<T>
|
||||
{
|
||||
public:
|
||||
NumberReader(T &value, bool bigEndian) :
|
||||
ValueReader<T>(value), bigEndian(bigEndian)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
bool bigEndian;
|
||||
};
|
||||
|
||||
class U16Reader : public NumberReader<ushort>
|
||||
{
|
||||
public:
|
||||
U16Reader(ushort &value, bool bigEndian)
|
||||
: NumberReader<ushort>(value, bigEndian) {}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(2U,limit));
|
||||
|
||||
if(bigEndian)
|
||||
value = data.toUInt16BE(0);
|
||||
else
|
||||
value = data.toUInt16LE(0);
|
||||
|
||||
return static_cast<uint>(data.size());
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
|
||||
class U32Reader : public NumberReader<uint>
|
||||
{
|
||||
public:
|
||||
U32Reader(uint &value, bool bigEndian = true) :
|
||||
NumberReader<uint>(value, bigEndian)
|
||||
{
|
||||
}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(4U,limit));
|
||||
|
||||
if(bigEndian)
|
||||
value = data.toUInt32BE(0);
|
||||
else
|
||||
value = data.toUInt32LE(0);
|
||||
|
||||
return static_cast<uint>(data.size());
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
|
||||
class StructReader : public Reader
|
||||
{
|
||||
public:
|
||||
StructReader()
|
||||
{
|
||||
m_readers.setAutoDelete(true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a nested reader. This reader takes ownership.
|
||||
*/
|
||||
StructReader &reader(Reader *reader)
|
||||
{
|
||||
m_readers.append(reader);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Don't read anything but skip \a size bytes.
|
||||
*/
|
||||
StructReader &skip(uint size)
|
||||
{
|
||||
m_readers.append(new SkipReader(size));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a string of \a size characters (bytes) into \a string.
|
||||
*/
|
||||
StructReader &string(String &string, uint size)
|
||||
{
|
||||
m_readers.append(new StringReader(string, size));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a byte into \a byte.
|
||||
*/
|
||||
StructReader &byte(uchar &byte)
|
||||
{
|
||||
m_readers.append(new ByteReader(byte));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 16 Bit integer into \a number. The byte order
|
||||
* is controlled by \a bigEndian.
|
||||
*/
|
||||
StructReader &u16(ushort &number, bool bigEndian)
|
||||
{
|
||||
m_readers.append(new U16Reader(number, bigEndian));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 16 Bit little endian integer into \a number.
|
||||
*/
|
||||
StructReader &u16L(ushort &number)
|
||||
{
|
||||
return u16(number, false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 16 Bit big endian integer into \a number.
|
||||
*/
|
||||
StructReader &u16B(ushort &number)
|
||||
{
|
||||
return u16(number, true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 32 Bit integer into \a number. The byte order
|
||||
* is controlled by \a bigEndian.
|
||||
*/
|
||||
StructReader &u32(uint &number, bool bigEndian)
|
||||
{
|
||||
m_readers.append(new U32Reader(number, bigEndian));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 32 Bit little endian integer into \a number.
|
||||
*/
|
||||
StructReader &u32L(uint &number)
|
||||
{
|
||||
return u32(number, false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 32 Bit big endian integer into \a number.
|
||||
*/
|
||||
StructReader &u32B(uint &number)
|
||||
{
|
||||
return u32(number, true);
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
uint size = 0;
|
||||
for(List<Reader*>::ConstIterator i = m_readers.begin();
|
||||
i != m_readers.end(); ++ i) {
|
||||
size += (*i)->size();
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
uint count = std::min(m_size, limit);
|
||||
file.seek(count, TagLib::File::Current);
|
||||
return count;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
uint sumcount = 0;
|
||||
for(List<Reader*>::Iterator i = m_readers.begin();
|
||||
limit > 0 && i != m_readers.end(); ++ i) {
|
||||
uint count = (*i)->read(file, limit);
|
||||
limit -= count;
|
||||
sumcount += count;
|
||||
uint size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
return sumcount;
|
||||
}
|
||||
|
||||
private:
|
||||
List<Reader*> m_readers;
|
||||
};
|
||||
private:
|
||||
uint m_size;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ValueReader : public Reader
|
||||
{
|
||||
public:
|
||||
ValueReader(T &value) : value(value)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
T &value;
|
||||
};
|
||||
|
||||
class StringReader : public ValueReader<String>
|
||||
{
|
||||
public:
|
||||
StringReader(String &string, uint size) :
|
||||
ValueReader<String>(string), m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(m_size, limit));
|
||||
size_t count = data.size();
|
||||
const size_t index = data.find((char) 0);
|
||||
if(index != ByteVector::npos) {
|
||||
data.resize(index);
|
||||
}
|
||||
data.replace((char) 0xff, ' ');
|
||||
value = data;
|
||||
return static_cast<uint>(count);
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
uint m_size;
|
||||
};
|
||||
|
||||
class ByteReader : public ValueReader<uchar>
|
||||
{
|
||||
public:
|
||||
ByteReader(uchar &byte) : ValueReader<uchar>(byte) {}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(1U,limit));
|
||||
if(data.size() > 0) {
|
||||
value = data[0];
|
||||
}
|
||||
return static_cast<uint>(data.size());
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class NumberReader : public ValueReader<T>
|
||||
{
|
||||
public:
|
||||
NumberReader(T &value, bool bigEndian) :
|
||||
ValueReader<T>(value), bigEndian(bigEndian)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
bool bigEndian;
|
||||
};
|
||||
|
||||
class U16Reader : public NumberReader<ushort>
|
||||
{
|
||||
public:
|
||||
U16Reader(ushort &value, bool bigEndian)
|
||||
: NumberReader<ushort>(value, bigEndian) {}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(2U,limit));
|
||||
|
||||
if(bigEndian)
|
||||
value = data.toUInt16BE(0);
|
||||
else
|
||||
value = data.toUInt16LE(0);
|
||||
|
||||
return static_cast<uint>(data.size());
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
|
||||
class U32Reader : public NumberReader<uint>
|
||||
{
|
||||
public:
|
||||
U32Reader(uint &value, bool bigEndian = true) :
|
||||
NumberReader<uint>(value, bigEndian)
|
||||
{
|
||||
}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
ByteVector data = file.readBlock(std::min(4U,limit));
|
||||
|
||||
if(bigEndian)
|
||||
value = data.toUInt32BE(0);
|
||||
else
|
||||
value = data.toUInt32LE(0);
|
||||
|
||||
return static_cast<uint>(data.size());
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
|
||||
class StructReader : public Reader
|
||||
{
|
||||
public:
|
||||
StructReader()
|
||||
{
|
||||
m_readers.setAutoDelete(true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a nested reader. This reader takes ownership.
|
||||
*/
|
||||
StructReader &reader(Reader *reader)
|
||||
{
|
||||
m_readers.append(reader);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Don't read anything but skip \a size bytes.
|
||||
*/
|
||||
StructReader &skip(uint size)
|
||||
{
|
||||
m_readers.append(new SkipReader(size));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a string of \a size characters (bytes) into \a string.
|
||||
*/
|
||||
StructReader &string(String &string, uint size)
|
||||
{
|
||||
m_readers.append(new StringReader(string, size));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a byte into \a byte.
|
||||
*/
|
||||
StructReader &byte(uchar &byte)
|
||||
{
|
||||
m_readers.append(new ByteReader(byte));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 16 Bit integer into \a number. The byte order
|
||||
* is controlled by \a bigEndian.
|
||||
*/
|
||||
StructReader &u16(ushort &number, bool bigEndian)
|
||||
{
|
||||
m_readers.append(new U16Reader(number, bigEndian));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 16 Bit little endian integer into \a number.
|
||||
*/
|
||||
StructReader &u16L(ushort &number)
|
||||
{
|
||||
return u16(number, false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 16 Bit big endian integer into \a number.
|
||||
*/
|
||||
StructReader &u16B(ushort &number)
|
||||
{
|
||||
return u16(number, true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 32 Bit integer into \a number. The byte order
|
||||
* is controlled by \a bigEndian.
|
||||
*/
|
||||
StructReader &u32(uint &number, bool bigEndian)
|
||||
{
|
||||
m_readers.append(new U32Reader(number, bigEndian));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 32 Bit little endian integer into \a number.
|
||||
*/
|
||||
StructReader &u32L(uint &number)
|
||||
{
|
||||
return u32(number, false);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Read a unsigned 32 Bit big endian integer into \a number.
|
||||
*/
|
||||
StructReader &u32B(uint &number)
|
||||
{
|
||||
return u32(number, true);
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
uint size = 0;
|
||||
for(List<Reader*>::ConstIterator i = m_readers.begin();
|
||||
i != m_readers.end(); ++ i) {
|
||||
size += (*i)->size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
uint read(TagLib::File &file, uint limit)
|
||||
{
|
||||
uint sumcount = 0;
|
||||
for(List<Reader*>::Iterator i = m_readers.begin();
|
||||
limit > 0 && i != m_readers.end(); ++ i) {
|
||||
uint count = (*i)->read(file, limit);
|
||||
limit -= count;
|
||||
sumcount += count;
|
||||
}
|
||||
return sumcount;
|
||||
}
|
||||
|
||||
private:
|
||||
List<Reader*> m_readers;
|
||||
};
|
||||
}
|
||||
|
||||
class XM::File::FilePrivate
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user