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]);