1
/***************************************************************************
2
copyright : (C) 2002 - 2008 by Scott Wheeler
3
email : wheeler@kde.org
4
***************************************************************************/
6
/***************************************************************************
7
* This library is free software; you can redistribute it and/or modify *
8
* it under the terms of the GNU Lesser General Public License version *
9
* 2.1 as published by the Free Software Foundation. *
11
* This library is distributed in the hope that it will be useful, but *
12
* WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14
* Lesser General Public License for more details. *
16
* You should have received a copy of the GNU Lesser General Public *
17
* License along with this library; if not, write to the Free Software *
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
21
* Alternatively, this file is available under the Mozilla Public *
22
* License Version 1.1. You may obtain a copy of the License at *
23
* http://www.mozilla.org/MPL/ *
24
***************************************************************************/
30
#include "id3v1genres.h"
32
using namespace TagLib;
33
using namespace ID3v1;
35
class ID3v1::Tag::TagPrivate
38
TagPrivate() : file(0), tagOffset(-1), track(0), genre(255) {}
51
static const StringHandler *stringHandler;
54
const ID3v1::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = new StringHandler;
56
////////////////////////////////////////////////////////////////////////////////
57
// StringHandler implementation
58
////////////////////////////////////////////////////////////////////////////////
60
String ID3v1::StringHandler::parse(const ByteVector &data) const
62
return String(data, String::Latin1).stripWhiteSpace();
65
ByteVector ID3v1::StringHandler::render(const String &s) const
72
return s.data(String::Latin1);
75
////////////////////////////////////////////////////////////////////////////////
77
////////////////////////////////////////////////////////////////////////////////
79
ID3v1::Tag::Tag() : TagLib::Tag()
84
ID3v1::Tag::Tag(File *file, long tagOffset) : TagLib::Tag()
88
d->tagOffset = tagOffset;
98
ByteVector ID3v1::Tag::render() const
102
data.append(fileIdentifier());
103
data.append(TagPrivate::stringHandler->render(d->title).resize(30));
104
data.append(TagPrivate::stringHandler->render(d->artist).resize(30));
105
data.append(TagPrivate::stringHandler->render(d->album).resize(30));
106
data.append(TagPrivate::stringHandler->render(d->year).resize(4));
107
data.append(TagPrivate::stringHandler->render(d->comment).resize(28));
108
data.append(char(0));
109
data.append(char(d->track));
110
data.append(char(d->genre));
115
ByteVector ID3v1::Tag::fileIdentifier()
117
return ByteVector::fromCString("TAG");
120
String ID3v1::Tag::title() const
125
String ID3v1::Tag::artist() const
130
String ID3v1::Tag::album() const
135
String ID3v1::Tag::comment() const
140
String ID3v1::Tag::genre() const
142
return ID3v1::genre(d->genre);
145
TagLib::uint ID3v1::Tag::year() const
147
return d->year.toInt();
150
TagLib::uint ID3v1::Tag::track() const
155
void ID3v1::Tag::setTitle(const String &s)
160
void ID3v1::Tag::setArtist(const String &s)
165
void ID3v1::Tag::setAlbum(const String &s)
170
void ID3v1::Tag::setComment(const String &s)
175
void ID3v1::Tag::setGenre(const String &s)
177
d->genre = ID3v1::genreIndex(s);
180
void ID3v1::Tag::setYear(uint i)
182
d->year = i > 0 ? String::number(i) : String::null;
185
void ID3v1::Tag::setTrack(uint i)
187
d->track = i < 256 ? i : 0;
190
void ID3v1::Tag::setStringHandler(const StringHandler *handler)
192
delete TagPrivate::stringHandler;
193
TagPrivate::stringHandler = handler;
196
////////////////////////////////////////////////////////////////////////////////
198
////////////////////////////////////////////////////////////////////////////////
200
void ID3v1::Tag::read()
202
if(d->file && d->file->isValid()) {
203
d->file->seek(d->tagOffset);
204
// read the tag -- always 128 bytes
205
ByteVector data = d->file->readBlock(128);
207
// some initial sanity checking
208
if(data.size() == 128 && data.startsWith("TAG"))
211
debug("ID3v1 tag is not valid or could not be read at the specified offset.");
215
void ID3v1::Tag::parse(const ByteVector &data)
219
d->title = TagPrivate::stringHandler->parse(data.mid(offset, 30));
222
d->artist = TagPrivate::stringHandler->parse(data.mid(offset, 30));
225
d->album = TagPrivate::stringHandler->parse(data.mid(offset, 30));
228
d->year = TagPrivate::stringHandler->parse(data.mid(offset, 4));
231
// Check for ID3v1.1 -- Note that ID3v1 *does not* support "track zero" -- this
232
// is not a bug in TagLib. Since a zeroed byte is what we would expect to
233
// indicate the end of a C-String, specifically the comment string, a value of
234
// zero must be assumed to be just that.
236
if(data[offset + 28] == 0 && data[offset + 29] != 0) {
239
d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 28));
240
d->track = uchar(data[offset + 29]);
243
d->comment = data.mid(offset, 30);
247
d->genre = uchar(data[offset]);