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., 51 Franklin Street, Fifth Floor, Boston, MA *
19 * 02110-1301 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#ifndef TAGLIB_ID3V2FRAME_H
27#define TAGLIB_ID3V2FRAME_H
28
29#include "tstring.h"
30#include "tbytevector.h"
31#include "taglib_export.h"
32
33namespace TagLib {
34
35 class StringList;
36 class PropertyMap;
37
38 namespace ID3v2 {
39
40 class Tag;
41 class FrameFactory;
42
43 //! ID3v2 frame implementation
44
45 /*!
46 * This class is the main ID3v2 frame implementation. In ID3v2, a tag is
47 * split between a collection of frames (which are in turn split into fields
48 * (Structure, <a href="id3v2-structure.html#4">4</a>)
49 * (<a href="id3v2-frames.html">Frames</a>). This class provides an API for
50 * gathering information about and modifying ID3v2 frames. Funtionallity
51 * specific to a given frame type is handed in one of the many subclasses.
52 */
53
54 class TAGLIB_EXPORT Frame
55 {
56 friend class Tag;
57 friend class FrameFactory;
58
59 public:
60
61 /*!
62 * Creates a textual frame which corresponds to a single key in the PropertyMap
63 * interface. These are all (User)TextIdentificationFrames except TIPL and TMCL,
64 * all (User)URLLinkFrames, CommentsFrames, and UnsynchronizedLyricsFrame.
65 */
66 static Frame *createTextualFrame(const String &key, const StringList &values);
67
68 /*!
69 * Destroys this Frame instance.
70 */
71 virtual ~Frame();
72
73 /*!
74 * Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
75 * (Frames, <a href="id3v2-frames.html#4">4</a>)
76 */
77 ByteVector frameID() const;
78
79 /*!
80 * Returns the size of the frame.
81 */
82 unsigned int size() const;
83
84 /*!
85 * Returns the size of the frame header
86 *
87 * \deprecated This is only accurate for ID3v2.3 or ID3v2.4. Please use
88 * the call below which accepts an ID3v2 version number. In the next
89 * non-binary compatible release this will be made into a non-static
90 * member that checks the internal ID3v2 version.
91 */
92 static unsigned int headerSize(); // BIC: remove and make non-static
93
94 /*!
95 * Returns the size of the frame header for the given ID3v2 version.
96 *
97 * \deprecated Please see the explanation above.
98 */
99 static unsigned int headerSize(unsigned int version); // BIC: remove and make non-static
100
101 /*!
102 * Sets the data that will be used as the frame. Since the length is not
103 * known before the frame has been parsed, this should just be a pointer to
104 * the first byte of the frame. It will determine the length internally
105 * and make that available through size().
106 */
107 void setData(const ByteVector &data);
108
109 /*!
110 * Set the text of frame in the sanest way possible. This should only be
111 * reimplemented in frames where there is some logical mapping to text.
112 *
113 * \note If the frame type supports multiple text encodings, this will not
114 * change the text encoding of the frame; the string will be converted to
115 * that frame's encoding. Please use the specific APIs of the frame types
116 * to set the encoding if that is desired.
117 */
118 virtual void setText(const String &text);
119
120 /*!
121 * This returns the textual representation of the data in the frame.
122 * Subclasses must reimplement this method to provide a string
123 * representation of the frame's data.
124 */
125 virtual String toString() const = 0;
126
127 /*!
128 * Render the frame back to its binary format in a ByteVector.
129 */
130 ByteVector render() const;
131
132 /*!
133 * Returns the text delimiter that is used between fields for the string
134 * type \a t.
135 */
136 static ByteVector textDelimiter(String::Type t);
137
138 /*!
139 * The string with which an instrument name is prefixed to build a key in a PropertyMap;
140 * used to translate PropertyMaps to TMCL frames. In the current implementation, this
141 * is "PERFORMER:".
142 */
143 static const String instrumentPrefix;
144 /*!
145 * The PropertyMap key prefix which triggers the use of a COMM frame instead of a TXXX
146 * frame for a non-standard key. In the current implementation, this is "COMMENT:".
147 */
148 static const String commentPrefix;
149 /*!
150 * The PropertyMap key prefix which triggers the use of a USLT frame instead of a TXXX
151 * frame for a non-standard key. In the current implementation, this is "LYRICS:".
152 */
153 static const String lyricsPrefix;
154 /*!
155 * The PropertyMap key prefix which triggers the use of a WXXX frame instead of a TXX
156 * frame for a non-standard key. In the current implementation, this is "URL:".
157 */
158 static const String urlPrefix;
159
160 protected:
161 class Header;
162
163 /*!
164 * Constructs an ID3v2 frame using \a data to read the header information.
165 * All other processing of \a data should be handled in a subclass.
166 *
167 * \note This need not contain anything more than a frame ID, but
168 * \e must contain at least that.
169 */
170 explicit Frame(const ByteVector &data);
171
172 /*!
173 * This creates an Frame using the header \a h.
174 *
175 * The ownership of this header will be assigned to the frame and the
176 * header will be deleted when the frame is destroyed.
177 */
178 Frame(Header *h);
179
180 /*!
181 * Returns a pointer to the frame header.
182 */
183 Header *header() const;
184
185 /*!
186 * Sets the header to \a h. If \a deleteCurrent is true, this will free
187 * the memory of the current header.
188 *
189 * The ownership of this header will be assigned to the frame and the
190 * header will be deleted when the frame is destroyed.
191 */
192 void setHeader(Header *h, bool deleteCurrent = true);
193
194 /*!
195 * Called by setData() to parse the frame data. It makes this information
196 * available through the public API.
197 */
198 void parse(const ByteVector &data);
199
200 /*!
201 * Called by parse() to parse the field data. It makes this information
202 * available through the public API. This must be overridden by the
203 * subclasses.
204 */
205 virtual void parseFields(const ByteVector &data) = 0;
206
207 /*!
208 * Render the field data back to a binary format in a ByteVector. This
209 * must be overridden by subclasses.
210 */
211 virtual ByteVector renderFields() const = 0;
212
213 /*!
214 * Returns a ByteVector containing the field data given the frame data.
215 * This correctly adjusts for the header size plus any additional frame
216 * data that's specified in the frame header flags.
217 */
218 ByteVector fieldData(const ByteVector &frameData) const;
219
220 /*!
221 * Reads a String of type \a encoding from the ByteVector \a data. If \a
222 * position is passed in it is used both as the starting point and is
223 * updated to return the position just after the string that has been read.
224 * This is useful for reading strings sequentially.
225 */
226 String readStringField(const ByteVector &data, String::Type encoding,
227 int *positon = 0);
228
229 /*!
230 * Checks a the list of string values to see if they can be used with the
231 * specified encoding and returns the recommended encoding.
232 */
233 // BIC: remove and make non-static
234 static String::Type checkEncoding(const StringList &fields,
235 String::Type encoding);
236
237 /*!
238 * Checks a the list of string values to see if they can be used with the
239 * specified encoding and returns the recommended encoding. This method
240 * also checks the ID3v2 version and makes sure the encoding can be used
241 * in the specified version.
242 */
243 // BIC: remove and make non-static
244 static String::Type checkEncoding(const StringList &fields,
245 String::Type encoding, unsigned int version);
246
247 /*!
248 * Checks a the list of string values to see if they can be used with the
249 * specified encoding and returns the recommended encoding. This method
250 * also checks the ID3v2 version and makes sure the encoding can be used
251 * in the version specified by the frame's header.
252 */
253 String::Type checkTextEncoding(const StringList &fields,
254 String::Type encoding) const;
255
256
257 /*!
258 * Parses the contents of this frame as PropertyMap. If that fails, the returend
259 * PropertyMap will be empty, and its unsupportedData() will contain this frame's
260 * ID.
261 * BIC: Will be a virtual function in future releases.
262 */
263 PropertyMap asProperties() const;
264
265 /*!
266 * Returns an appropriate ID3 frame ID for the given free-form tag key. This method
267 * will return an empty ByteVector if no specialized translation is found.
268 */
269 static ByteVector keyToFrameID(const String &);
270
271 /*!
272 * Returns a free-form tag name for the given ID3 frame ID. Note that this does not work
273 * for general frame IDs such as TXXX or WXXX; in such a case an empty string is returned.
274 */
275 static String frameIDToKey(const ByteVector &);
276
277 /*!
278 * Returns an appropriate TXXX frame description for the given free-form tag key.
279 */
280 static String keyToTXXX(const String &);
281
282 /*!
283 * Returns a free-form tag name for the given ID3 frame description.
284 */
285 static String txxxToKey(const String &);
286
287 /*!
288 * This helper function splits the PropertyMap \a original into three ProperytMaps
289 * \a singleFrameProperties, \a tiplProperties, and \a tmclProperties, such that:
290 * - \a singleFrameProperties contains only of keys which can be represented with
291 * exactly one ID3 frame per key. In the current implementation
292 * this is everything except for the fixed "involved people" keys and keys of the
293 * form "TextIdentificationFrame::instrumentPrefix" + "instrument", which are
294 * mapped to a TMCL frame.
295 * - \a tiplProperties will consist of those keys that are present in
296 * TextIdentificationFrame::involvedPeopleMap()
297 * - \a tmclProperties contains the "musician credits" keys which should be mapped
298 * to a TMCL frame
299 */
300 static void splitProperties(const PropertyMap &original, PropertyMap &singleFrameProperties,
301 PropertyMap &tiplProperties, PropertyMap &tmclProperties);
302
303 private:
304 Frame(const Frame &);
305 Frame &operator=(const Frame &);
306
307 class FramePrivate;
308 friend class FramePrivate;
309 FramePrivate *d;
310 };
311
312 //! ID3v2 frame header implementation
313
314 /*!
315 * The ID3v2 Frame Header (Structure, <a href="id3v2-structure.html#4">4</a>)
316 *
317 * Every ID3v2::Frame has an associated header that gives some general
318 * properties of the frame and also makes it possible to identify the frame
319 * type.
320 *
321 * As such when reading an ID3v2 tag ID3v2::FrameFactory first creates the
322 * frame headers and then creates the appropriate Frame subclass based on
323 * the type and attaches the header.
324 */
325
326 class TAGLIB_EXPORT Frame::Header
327 {
328 public:
329 /*!
330 * Construct a Frame Header based on \a data. \a data must at least
331 * contain a 4 byte frame ID, and optionally can contain flag data and the
332 * frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
333 *
334 * \deprecated Please use the constructor below that accepts a version
335 * number.
336 */
337 Header(const ByteVector &data, bool synchSafeInts);
338
339 /*!
340 * Construct a Frame Header based on \a data. \a data must at least
341 * contain a 4 byte frame ID, and optionally can contain flag data and the
342 * frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
343 *
344 * \a version should be the ID3v2 version of the tag.
345 */
346 explicit Header(const ByteVector &data, unsigned int version = 4);
347
348 /*!
349 * Destroys this Header instance.
350 */
351 virtual ~Header();
352
353 /*!
354 * Sets the data for the Header.
355 *
356 * \deprecated Please use the version below that accepts an ID3v2 version
357 * number.
358 */
359 void setData(const ByteVector &data, bool synchSafeInts);
360
361 /*!
362 * Sets the data for the Header. \a version should indicate the ID3v2
363 * version number of the tag that this frame is contained in.
364 */
365 void setData(const ByteVector &data, unsigned int version = 4);
366
367 /*!
368 * Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
369 * (Frames, <a href="id3v2-frames.html#4">4</a>)
370 */
371 ByteVector frameID() const;
372
373 /*!
374 * Sets the frame's ID to \a id. Only the first four bytes of \a id will
375 * be used.
376 *
377 * \warning This method should in general be avoided. It exists simply to
378 * provide a mechanism for transforming frames from a deprecated frame type
379 * to a newer one -- i.e. TYER to TDRC from ID3v2.3 to ID3v2.4.
380 */
381 void setFrameID(const ByteVector &id);
382
383 /*!
384 * Returns the size of the frame data portion, as set when setData() was
385 * called or set explicitly via setFrameSize().
386 */
387 unsigned int frameSize() const;
388
389 /*!
390 * Sets the size of the frame data portion.
391 */
392 void setFrameSize(unsigned int size);
393
394 /*!
395 * Returns the ID3v2 version of the header, as passed in from the
396 * construction of the header or set via setVersion().
397 */
398 unsigned int version() const;
399
400 /*!
401 * Sets the ID3v2 version of the header, changing has impact on the
402 * correct parsing/rendering of frame data.
403 */
404 void setVersion(unsigned int version);
405
406 /*!
407 * Returns the size of the frame header in bytes.
408 *
409 * \deprecated Please use the version of this method that accepts a
410 * version. This is only accurate for ID3v2.3 and ID3v2.4. This will be
411 * removed in the next binary incompatible release (2.0) and will be
412 * replaced with a non-static method that checks the frame version.
413 */
414 static unsigned int size();
415
416 /*!
417 * Returns the size of the frame header in bytes for the ID3v2 version
418 * that's given.
419 *
420 * \deprecated Please see the explanation in the version above.
421 */
422 static unsigned int size(unsigned int version);
423
424 /*!
425 * Returns true if the flag for tag alter preservation is set.
426 *
427 * The semantics are a little backwards from what would seem natural
428 * (setting the preservation flag to throw away the frame), but this
429 * follows the ID3v2 standard.
430 *
431 * \see setTagAlterPreservation()
432 */
433 bool tagAlterPreservation() const;
434
435 /*!
436 * Sets the flag for preservation of this frame if the tag is set. If
437 * this is set to true the frame will not be written when the tag is
438 * saved.
439 *
440 * The semantics are a little backwards from what would seem natural
441 * (setting the preservation flag to throw away the frame), but this
442 * follows the ID3v2 standard.
443 *
444 * \see tagAlterPreservation()
445 */
446 void setTagAlterPreservation(bool discard);
447
448 /*!
449 * Returns true if the flag for file alter preservation is set.
450 *
451 * \note This flag is currently ignored internally in TagLib.
452 */
453 bool fileAlterPreservation() const;
454
455 /*!
456 * Returns true if the frame is meant to be read only.
457 *
458 * \note This flag is currently ignored internally in TagLib.
459 */
460 bool readOnly() const;
461
462 /*!
463 * Returns true if the flag for the grouping identity is set.
464 *
465 * \note This flag is currently ignored internally in TagLib.
466 */
467 bool groupingIdentity() const;
468
469 /*!
470 * Returns true if compression is enabled for this frame.
471 *
472 * \note This flag is currently ignored internally in TagLib.
473 */
474 bool compression() const;
475
476 /*!
477 * Returns true if encryption is enabled for this frame.
478 *
479 * \note This flag is currently ignored internally in TagLib.
480 */
481 bool encryption() const;
482
483#ifndef DO_NOT_DOCUMENT
484 bool unsycronisation() const;
485#endif
486
487 /*!
488 * Returns true if unsynchronisation is enabled for this frame.
489 */
490 bool unsynchronisation() const;
491
492 /*!
493 * Returns true if the flag for a data length indicator is set.
494 */
495 bool dataLengthIndicator() const;
496
497 /*!
498 * Render the Header back to binary format in a ByteVector.
499 */
500 ByteVector render() const;
501
502 /*!
503 * \deprecated
504 */
505 bool frameAlterPreservation() const;
506
507 private:
508 Header(const Header &);
509 Header &operator=(const Header &);
510
511 class HeaderPrivate;
512 HeaderPrivate *d;
513 };
514
515 }
516}
517
518#endif
519