]> granicus.if.org Git - taglib/blob - taglib/mpeg/id3v2/id3v2tag.h
Add docs for this method
[taglib] / taglib / mpeg / id3v2 / id3v2tag.h
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_ID3V2TAG_H
27 #define TAGLIB_ID3V2TAG_H
28
29 #include "tag.h"
30 #include "tbytevector.h"
31 #include "tstring.h"
32 #include "tlist.h"
33 #include "tmap.h"
34 #include "taglib_export.h"
35
36 #include "id3v2framefactory.h"
37
38 namespace TagLib {
39
40   class File;
41
42   //! An ID3v2 implementation
43
44   /*!
45    * This is a relatively complete and flexible framework for working with ID3v2
46    * tags.
47    *
48    * \see ID3v2::Tag
49    */
50
51   namespace ID3v2 {
52
53     class Header;
54     class ExtendedHeader;
55     class Footer;
56
57     typedef List<Frame *> FrameList;
58     typedef Map<ByteVector, FrameList> FrameListMap;
59
60     //! An abstraction for the ISO-8859-1 string to data encoding in ID3v2 tags.
61
62     /*!
63      * ID3v2 tag can store strings in ISO-8859-1 (Latin1), and TagLib only
64      * supports genuine ISO-8859-1 by default.  However, in practice, non
65      * ISO-8859-1 encodings are often used instead of ISO-8859-1, such as
66      * Windows-1252 for western languages, Shift_JIS for Japanese and so on.
67      *
68      * Here is an option to read such tags by subclassing this class,
69      * reimplementing parse() and setting your reimplementation as the default
70      * with ID3v2::Tag::setStringHandler().
71      *
72      * \note Writing non-ISO-8859-1 tags is not implemented intentionally.
73      * Use UTF-16 or UTF-8 instead.
74      *
75      * \see ID3v2::Tag::setStringHandler()
76      */
77     class TAGLIB_EXPORT Latin1StringHandler
78     {
79     public:
80       Latin1StringHandler();
81       virtual ~Latin1StringHandler();
82
83       /*!
84        * Decode a string from \a data.  The default implementation assumes that
85        * \a data is an ISO-8859-1 (Latin1) character array.
86        */
87       virtual String parse(const ByteVector &data) const;
88     };
89
90     //! The main class in the ID3v2 implementation
91
92     /*!
93      * This is the main class in the ID3v2 implementation.  It serves two
94      * functions.  This first, as is obvious from the public API, is to provide a
95      * container for the other ID3v2 related classes.  In addition, through the
96      * read() and parse() protected methods, it provides the most basic level of
97      * parsing.  In these methods the ID3v2 tag is extracted from the file and
98      * split into data components.
99      *
100      * ID3v2 tags have several parts, TagLib attempts to provide an interface
101      * for them all.  header(), footer() and extendedHeader() correspond to those
102      * data structures in the ID3v2 standard and the APIs for the classes that
103      * they return attempt to reflect this.
104      *
105      * Also ID3v2 tags are built up from a list of frames, which are in turn
106      * have a header and a list of fields.  TagLib provides two ways of accessing
107      * the list of frames that are in a given ID3v2 tag.  The first is simply
108      * via the frameList() method.  This is just a list of pointers to the frames.
109      * The second is a map from the frame type -- i.e. "COMM" for comments -- and
110      * a list of frames of that type.  (In some cases ID3v2 allows for multiple
111      * frames of the same type, hence this being a map to a list rather than just
112      * a map to an individual frame.)
113      *
114      * More information on the structure of frames can be found in the ID3v2::Frame
115      * class.
116      *
117      * read() and parse() pass binary data to the other ID3v2 class structures,
118      * they do not handle parsing of flags or fields, for instance.  Those are
119      * handled by similar functions within those classes.
120      *
121      * \note All pointers to data structures within the tag will become invalid
122      * when the tag is destroyed.
123      *
124      * \warning Dealing with the nasty details of ID3v2 is not for the faint of
125      * heart and should not be done without much meditation on the spec.  It's
126      * rather long, but if you're planning on messing with this class and others
127      * that deal with the details of ID3v2 (rather than the nice, safe, abstract
128      * TagLib::Tag and friends), it's worth your time to familiarize yourself
129      * with said spec (which is distributed with the TagLib sources).  TagLib
130      * tries to do most of the work, but with a little luck, you can still
131      * convince it to generate invalid ID3v2 tags.  The APIs for ID3v2 assume a
132      * working knowledge of ID3v2 structure.  You're been warned.
133      */
134
135     class TAGLIB_EXPORT Tag : public TagLib::Tag
136     {
137     public:
138       /*!
139        * Constructs an empty ID3v2 tag.
140        *
141        * \note You must create at least one frame for this tag to be valid.
142        */
143       Tag();
144
145       /*!
146        * Constructs an ID3v2 tag read from \a file starting at \a tagOffset.
147        * \a factory specifies which FrameFactory will be used for the
148        * construction of new frames.
149        *
150        * \note You should be able to ignore the \a factory parameter in almost
151        * all situations.  You would want to specify your own FrameFactory
152        * subclass in the case that you are extending TagLib to support additional
153        * frame types, which would be incorporated into your factory.
154        *
155        * \see FrameFactory
156        */
157       Tag(File *file, long tagOffset,
158           const FrameFactory *factory = FrameFactory::instance());
159
160       /*!
161        * Destroys this Tag instance.
162        */
163       virtual ~Tag();
164
165       // Reimplementations.
166
167       virtual String title() const;
168       virtual String artist() const;
169       virtual String album() const;
170       virtual String comment() const;
171       virtual String genre() const;
172       virtual unsigned int year() const;
173       virtual unsigned int track() const;
174
175       virtual void setTitle(const String &s);
176       virtual void setArtist(const String &s);
177       virtual void setAlbum(const String &s);
178       virtual void setComment(const String &s);
179       virtual void setGenre(const String &s);
180       virtual void setYear(unsigned int i);
181       virtual void setTrack(unsigned int i);
182
183       virtual bool isEmpty() const;
184
185       /*!
186        * Returns a pointer to the tag's header.
187        */
188       Header *header() const;
189
190       /*!
191        * Returns a pointer to the tag's extended header or null if there is no
192        * extended header.
193        */
194       ExtendedHeader *extendedHeader() const;
195
196       /*!
197        * Returns a pointer to the tag's footer or null if there is no footer.
198        *
199        * \deprecated I don't see any reason to keep this around since there's
200        * nothing useful to be retrieved from the footer, but well, again, I'm
201        * prone to change my mind, so this gets to stay around until near a
202        * release.
203        */
204       Footer *footer() const;
205
206       /*!
207        * Returns a reference to the frame list map.  This is an FrameListMap of
208        * all of the frames in the tag.
209        *
210        * This is the most convenient structure for accessing the tag's frames.
211        * Many frame types allow multiple instances of the same frame type so this
212        * is a map of lists.  In most cases however there will only be a single
213        * frame of a certain type.
214        *
215        * Let's say for instance that you wanted to access the frame for total
216        * beats per minute -- the TBPM frame.
217        *
218        * \code
219        * TagLib::MPEG::File f("foo.mp3");
220        *
221        * // Check to make sure that it has an ID3v2 tag
222        *
223        * if(f.ID3v2Tag()) {
224        *
225        *   // Get the list of frames for a specific frame type
226        *
227        *   TagLib::ID3v2::FrameList l = f.ID3v2Tag()->frameListMap()["TBPM"];
228        *
229        *   if(!l.isEmpty())
230        *     std::cout << l.front()->toString() << std::endl;
231        * }
232        *
233        * \endcode
234        *
235        * \warning You should not modify this data structure directly, instead
236        * use addFrame() and removeFrame().
237        *
238        * \see frameList()
239        */
240       const FrameListMap &frameListMap() const;
241
242       /*!
243        * Returns a reference to the frame list.  This is an FrameList of all of
244        * the frames in the tag in the order that they were parsed.
245        *
246        * This can be useful if for example you want iterate over the tag's frames
247        * in the order that they occur in the tag.
248        *
249        * \warning You should not modify this data structure directly, instead
250        * use addFrame() and removeFrame().
251        */
252       const FrameList &frameList() const;
253
254       /*!
255        * Returns the frame list for frames with the id \a frameID or an empty
256        * list if there are no frames of that type.  This is just a convenience
257        * and is equivalent to:
258        *
259        * \code
260        * frameListMap()[frameID];
261        * \endcode
262        *
263        * \see frameListMap()
264        */
265       const FrameList &frameList(const ByteVector &frameID) const;
266
267       /*!
268        * Add a frame to the tag.  At this point the tag takes ownership of
269        * the frame and will handle freeing its memory.
270        *
271        * \note Using this method will invalidate any pointers on the list
272        * returned by frameList()
273        */
274       void addFrame(Frame *frame);
275
276       /*!
277        * Remove a frame from the tag.  If \a del is true the frame's memory
278        * will be freed; if it is false, it must be deleted by the user.
279        *
280        * \note Using this method will invalidate any pointers on the list
281        * returned by frameList()
282        */
283       void removeFrame(Frame *frame, bool del = true);
284
285       /*!
286        * Remove all frames of type \a id from the tag and free their memory.
287        *
288        * \note Using this method will invalidate any pointers on the list
289        * returned by frameList()
290        */
291       void removeFrames(const ByteVector &id);
292
293       /*!
294        * Implements the unified property interface -- export function.
295        * This function does some work to translate the hard-specified ID3v2
296        * frame types into a free-form string-to-stringlist PropertyMap:
297        *  - if ID3v2 frame ID is known by Frame::frameIDToKey(), the returned
298        *    key is used
299        *  - if the frame ID is "TXXX" (user text frame), the description() is
300        *    used as key
301        *  - if the frame ID is "WXXX" (user url frame),
302        *    - if the description is empty or "URL", the key "URL" is used
303        *    - otherwise, the key "URL:<description>" is used;
304        *  - if the frame ID is "COMM" (comments frame),
305        *    - if the description is empty or "COMMENT", the key "COMMENT"
306        *      is used
307        *    - otherwise, the key "COMMENT:<description>" is used;
308        *  - if the frame ID is "USLT" (unsynchronized lyrics),
309        *    - if the description is empty or "LYRICS", the key "LYRICS" is used
310        *    - otherwise, the key "LYRICS:<description>" is used;
311        *  - if the frame ID is "TIPL" (involved peoples list), and if all the
312        *    roles defined in the frame are known in TextIdentificationFrame::involvedPeopleMap(),
313        *    then "<role>=<name>" will be contained in the returned object for each
314        *  - if the frame ID is "TMCL" (musician credit list), then
315        *    "PERFORMER:<instrument>=<name>" will be contained in the returned
316        *    PropertyMap for each defined musician
317        *  In any other case, the unsupportedData() of the returned object will contain
318        *  the frame's ID and, in case of a frame ID which is allowed to appear more than
319        *  once, the description, separated by a "/".
320        *
321        */
322       PropertyMap properties() const;
323
324       /*!
325        * Removes unsupported frames given by \a properties. The elements of
326        * \a properties must be taken from properties().unsupportedData(); they
327        * are of one of the following forms:
328        *  - a four-character frame ID, if the ID3 specification allows only one
329        *    frame with that ID (thus, the frame is uniquely determined)
330        *  - frameID + "/" + description(), when the ID is one of "TXXX", "WXXX",
331        *    "COMM", or "USLT",
332        *  - "UNKNOWN/" + frameID, for frames that could not be parsed by TagLib.
333        *    In that case, *all* unknown frames with the given ID will be removed.
334        */
335       void removeUnsupportedProperties(const StringList &properties);
336
337       /*!
338        * Implements the unified property interface -- import function.
339        * See the comments in properties().
340        */
341       PropertyMap setProperties(const PropertyMap &);
342
343       /*!
344        * Render the tag back to binary data, suitable to be written to disk.
345        */
346       ByteVector render() const;
347
348       /*!
349        * Render the tag back to binary data, suitable to be written to disk.
350        *
351        * The \a version parameter specifies the version of the rendered
352        * ID3v2 tag. It can be either 4 or 3.
353        */
354       // BIC: combine with the above method
355       ByteVector render(int version) const;
356
357       /*!
358        * Gets the current string handler that decides how the "Latin-1" data
359        * will be converted to and from binary data.
360        *
361        * \see Latin1StringHandler
362        */
363       static Latin1StringHandler const *latin1StringHandler();
364
365       /*!
366        * Sets the string handler that decides how the "Latin-1" data will be
367        * converted to and from binary data.
368        * If the parameter \a handler is null, the previous handler is
369        * released and default ISO-8859-1 handler is restored.
370        *
371        * \note The caller is responsible for deleting the previous handler
372        * as needed after it is released.
373        *
374        * \see Latin1StringHandler
375        */
376       static void setLatin1StringHandler(const Latin1StringHandler *handler);
377
378     protected:
379       /*!
380        * Reads data from the file specified in the constructor.  It does basic
381        * parsing of the data in the largest chunks.  It partitions the tag into
382        * the Header, the body of the tag  (which contains the ExtendedHeader and
383        * frames) and Footer.
384        */
385       void read();
386
387       /*!
388        * This is called by read to parse the body of the tag.  It determines if an
389        * extended header exists and adds frames to the FrameListMap.
390        */
391       void parse(const ByteVector &data);
392
393       /*!
394        * Sets the value of the text frame with the Frame ID \a id to \a value.
395        * If the frame does not exist, it is created.
396        */
397       void setTextFrame(const ByteVector &id, const String &value);
398
399       /*!
400        * Dowgrade frames from ID3v2.4 (used internally and by default) to ID3v2.3
401        */
402       void downgradeFrames(FrameList *existingFrames, FrameList *newFrames) const;
403
404     private:
405       Tag(const Tag &);
406       Tag &operator=(const Tag &);
407
408       class TagPrivate;
409       TagPrivate *d;
410     };
411
412   }
413 }
414
415 #endif