Added TagLib (with AUTORS and COPYING files)
[someplayer] / src / taglib / mpeg / id3v2 / frames / commentsframe.cpp
1 /***************************************************************************
2     copyright            : (C) 2002 - 2008 by Scott Wheeler
3     email                : wheeler@kde.org
4  ***************************************************************************/
5
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.                     *
10  *                                                                         *
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.                       *
15  *                                                                         *
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  *
19  *   USA                                                                   *
20  *                                                                         *
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  ***************************************************************************/
25
26 #include <tbytevectorlist.h>
27 #include <id3v2tag.h>
28 #include <tdebug.h>
29 #include <tstringlist.h>
30
31 #include "commentsframe.h"
32
33 using namespace TagLib;
34 using namespace ID3v2;
35
36 class CommentsFrame::CommentsFramePrivate
37 {
38 public:
39   CommentsFramePrivate() : textEncoding(String::Latin1) {}
40   String::Type textEncoding;
41   ByteVector language;
42   String description;
43   String text;
44 };
45
46 ////////////////////////////////////////////////////////////////////////////////
47 // public members
48 ////////////////////////////////////////////////////////////////////////////////
49
50 CommentsFrame::CommentsFrame(String::Type encoding) : Frame("COMM")
51 {
52   d = new CommentsFramePrivate;
53   d->textEncoding = encoding;
54 }
55
56 CommentsFrame::CommentsFrame(const ByteVector &data) : Frame(data)
57 {
58   d = new CommentsFramePrivate;
59   setData(data);
60 }
61
62 CommentsFrame::~CommentsFrame()
63 {
64   delete d;
65 }
66
67 String CommentsFrame::toString() const
68 {
69   return d->text;
70 }
71
72 ByteVector CommentsFrame::language() const
73 {
74   return d->language;
75 }
76
77 String CommentsFrame::description() const
78 {
79   return d->description;
80 }
81
82 String CommentsFrame::text() const
83 {
84   return d->text;
85 }
86
87 void CommentsFrame::setLanguage(const ByteVector &languageEncoding)
88 {
89   d->language = languageEncoding.mid(0, 3);
90 }
91
92 void CommentsFrame::setDescription(const String &s)
93 {
94   d->description = s;
95 }
96
97 void CommentsFrame::setText(const String &s)
98 {
99   d->text = s;
100 }
101
102 String::Type CommentsFrame::textEncoding() const
103 {
104   return d->textEncoding;
105 }
106
107 void CommentsFrame::setTextEncoding(String::Type encoding)
108 {
109   d->textEncoding = encoding;
110 }
111
112 CommentsFrame *CommentsFrame::findByDescription(const ID3v2::Tag *tag, const String &d) // static
113 {
114   ID3v2::FrameList comments = tag->frameList("COMM");
115
116   for(ID3v2::FrameList::ConstIterator it = comments.begin();
117       it != comments.end();
118       ++it)
119   {
120     CommentsFrame *frame = dynamic_cast<CommentsFrame *>(*it);
121     if(frame && frame->description() == d)
122       return frame;
123   }
124
125   return 0;
126 }
127
128 ////////////////////////////////////////////////////////////////////////////////
129 // protected members
130 ////////////////////////////////////////////////////////////////////////////////
131
132 void CommentsFrame::parseFields(const ByteVector &data)
133 {
134   if(data.size() < 5) {
135     debug("A comment frame must contain at least 5 bytes.");
136     return;
137   }
138
139   d->textEncoding = String::Type(data[0]);
140   d->language = data.mid(1, 3);
141
142   int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
143
144   ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
145
146   if(l.size() == 2) {
147     d->description = String(l.front(), d->textEncoding);
148     d->text = String(l.back(), d->textEncoding);
149   }
150 }
151
152 ByteVector CommentsFrame::renderFields() const
153 {
154   ByteVector v;
155
156   String::Type encoding = d->textEncoding;
157
158   encoding = checkEncoding(d->description, encoding);
159   encoding = checkEncoding(d->text, encoding);
160
161   v.append(char(encoding));
162   v.append(d->language.size() == 3 ? d->language : "XXX");
163   v.append(d->description.data(encoding));
164   v.append(textDelimiter(encoding));
165   v.append(d->text.data(encoding));
166
167   return v;
168 }
169
170 ////////////////////////////////////////////////////////////////////////////////
171 // private members
172 ////////////////////////////////////////////////////////////////////////////////
173
174 CommentsFrame::CommentsFrame(const ByteVector &data, Header *h) : Frame(h)
175 {
176   d = new CommentsFramePrivate();
177   parseFields(fieldData(data));
178 }