1 /***************************************************************************
2     copyright            : (C) 2002 - 2008 by Scott Wheeler
3     email                : wheeler@kde.org
4 
5     copyright            : (C) 2006 by Aaron VonderHaar
6     email                : avh4@users.sourceforge.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *   This library is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU Lesser General Public License version   *
12  *   2.1 as published by the Free Software Foundation.                     *
13  *                                                                         *
14  *   This library is distributed in the hope that it will be useful, but   *
15  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
17  *   Lesser General Public License for more details.                       *
18  *                                                                         *
19  *   You should have received a copy of the GNU Lesser General Public      *
20  *   License along with this library; if not, write to the Free Software   *
21  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
22  *   02110-1301  USA                                                       *
23  *                                                                         *
24  *   Alternatively, this file is available under the Mozilla Public        *
25  *   License Version 1.1.  You may obtain a copy of the License at         *
26  *   http://www.mozilla.org/MPL/                                           *
27  ***************************************************************************/
28 
29 #include <tdebug.h>
30 #include <tstringlist.h>
31 
32 #include "generalencapsulatedobjectframe.h"
33 
34 using namespace TagLib;
35 using namespace ID3v2;
36 
37 class GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFramePrivate
38 {
39 public:
GeneralEncapsulatedObjectFramePrivate()40   GeneralEncapsulatedObjectFramePrivate() : textEncoding(String::Latin1) {}
41 
42   String::Type textEncoding;
43   String mimeType;
44   String fileName;
45   String description;
46   ByteVector data;
47 };
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 // public members
51 ////////////////////////////////////////////////////////////////////////////////
52 
GeneralEncapsulatedObjectFrame()53 GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame() :
54   Frame("GEOB"),
55   d(new GeneralEncapsulatedObjectFramePrivate())
56 {
57 }
58 
GeneralEncapsulatedObjectFrame(const ByteVector & data)59 GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame(const ByteVector &data) :
60   Frame(data),
61   d(new GeneralEncapsulatedObjectFramePrivate())
62 {
63   setData(data);
64 }
65 
~GeneralEncapsulatedObjectFrame()66 GeneralEncapsulatedObjectFrame::~GeneralEncapsulatedObjectFrame()
67 {
68   delete d;
69 }
70 
toString() const71 String GeneralEncapsulatedObjectFrame::toString() const
72 {
73   String text = "[" + d->mimeType + "]";
74 
75   if(!d->fileName.isEmpty())
76     text += " " + d->fileName;
77 
78   if(!d->description.isEmpty())
79     text += " \"" + d->description + "\"";
80 
81   return text;
82 }
83 
textEncoding() const84 String::Type GeneralEncapsulatedObjectFrame::textEncoding() const
85 {
86   return d->textEncoding;
87 }
88 
setTextEncoding(String::Type encoding)89 void GeneralEncapsulatedObjectFrame::setTextEncoding(String::Type encoding)
90 {
91   d->textEncoding = encoding;
92 }
93 
mimeType() const94 String GeneralEncapsulatedObjectFrame::mimeType() const
95 {
96   return d->mimeType;
97 }
98 
setMimeType(const String & type)99 void GeneralEncapsulatedObjectFrame::setMimeType(const String &type)
100 {
101   d->mimeType = type;
102 }
103 
fileName() const104 String GeneralEncapsulatedObjectFrame::fileName() const
105 {
106   return d->fileName;
107 }
108 
setFileName(const String & name)109 void GeneralEncapsulatedObjectFrame::setFileName(const String &name)
110 {
111   d->fileName = name;
112 }
113 
description() const114 String GeneralEncapsulatedObjectFrame::description() const
115 {
116   return d->description;
117 }
118 
setDescription(const String & desc)119 void GeneralEncapsulatedObjectFrame::setDescription(const String &desc)
120 {
121   d->description = desc;
122 }
123 
object() const124 ByteVector GeneralEncapsulatedObjectFrame::object() const
125 {
126   return d->data;
127 }
128 
setObject(const ByteVector & data)129 void GeneralEncapsulatedObjectFrame::setObject(const ByteVector &data)
130 {
131   d->data = data;
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 // protected members
136 ////////////////////////////////////////////////////////////////////////////////
137 
parseFields(const ByteVector & data)138 void GeneralEncapsulatedObjectFrame::parseFields(const ByteVector &data)
139 {
140   if(data.size() < 4) {
141     debug("An object frame must contain at least 4 bytes.");
142     return;
143   }
144 
145   d->textEncoding = String::Type(data[0]);
146 
147   int pos = 1;
148 
149   d->mimeType = readStringField(data, String::Latin1, &pos);
150   d->fileName = readStringField(data, d->textEncoding, &pos);
151   d->description = readStringField(data, d->textEncoding, &pos);
152 
153   d->data = data.mid(pos);
154 }
155 
renderFields() const156 ByteVector GeneralEncapsulatedObjectFrame::renderFields() const
157 {
158   StringList sl;
159   sl.append(d->fileName);
160   sl.append(d->description);
161 
162   const String::Type encoding = checkTextEncoding(sl, d->textEncoding);
163 
164   ByteVector data;
165 
166   data.append(char(encoding));
167   data.append(d->mimeType.data(String::Latin1));
168   data.append(textDelimiter(String::Latin1));
169   data.append(d->fileName.data(encoding));
170   data.append(textDelimiter(encoding));
171   data.append(d->description.data(encoding));
172   data.append(textDelimiter(encoding));
173   data.append(d->data);
174 
175   return data;
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 // private members
180 ////////////////////////////////////////////////////////////////////////////////
181 
GeneralEncapsulatedObjectFrame(const ByteVector & data,Header * h)182 GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame(const ByteVector &data, Header *h) :
183   Frame(h),
184   d(new GeneralEncapsulatedObjectFramePrivate())
185 {
186   parseFields(fieldData(data));
187 }
188