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_VORBISCOMMENT_H
27 #define TAGLIB_VORBISCOMMENT_H
28 
29 #include "tag.h"
30 #include "tlist.h"
31 #include "tmap.h"
32 #include "tstring.h"
33 #include "tstringlist.h"
34 #include "tbytevector.h"
35 #include "flacpicture.h"
36 #include "taglib_export.h"
37 
38 namespace TagLib {
39 
40   namespace Ogg {
41 
42     /*!
43      * A mapping between a list of field names, or keys, and a list of values
44      * associated with that field.
45      *
46      * \see XiphComment::fieldListMap()
47      */
48     typedef Map<String, StringList> FieldListMap;
49 
50     //! Ogg Vorbis comment implementation
51 
52     /*!
53      * This class is an implementation of the Ogg Vorbis comment specification,
54      * to be found in section 5 of the Ogg Vorbis specification.  Because this
55      * format is also used in other (currently unsupported) Xiph.org formats, it
56      * has been made part of a generic implementation rather than being limited
57      * to strictly Vorbis.
58      *
59      * Vorbis comments are a simple vector of keys and values, called fields.
60      * Multiple values for a given key are supported.
61      *
62      * \see fieldListMap()
63      */
64 
65     class TAGLIB_EXPORT XiphComment : public TagLib::Tag
66     {
67     public:
68       /*!
69        * Constructs an empty Vorbis comment.
70        */
71       XiphComment();
72 
73       /*!
74        * Constructs a Vorbis comment from \a data.
75        */
76       XiphComment(const ByteVector &data);
77 
78       /*!
79        * Destroys this instance of the XiphComment.
80        */
81       virtual ~XiphComment();
82 
83       virtual String title() const;
84       virtual String artist() const;
85       virtual String album() const;
86       virtual String comment() const;
87       virtual String genre() const;
88       virtual unsigned int year() const;
89       virtual unsigned int track() const;
90 
91       virtual void setTitle(const String &s);
92       virtual void setArtist(const String &s);
93       virtual void setAlbum(const String &s);
94       virtual void setComment(const String &s);
95       virtual void setGenre(const String &s);
96       virtual void setYear(unsigned int i);
97       virtual void setTrack(unsigned int i);
98 
99       virtual bool isEmpty() const;
100 
101       /*!
102        * Returns the number of fields present in the comment.
103        */
104       unsigned int fieldCount() const;
105 
106       /*!
107        * Returns a reference to the map of field lists.  Because Xiph comments
108        * support multiple fields with the same key, a pure Map would not work.
109        * As such this is a Map of string lists, keyed on the comment field name.
110        *
111        * The standard set of Xiph/Vorbis fields (which may or may not be
112        * contained in any specific comment) is:
113        *
114        * <ul>
115        *   <li>TITLE</li>
116        *   <li>VERSION</li>
117        *   <li>ALBUM</li>
118        *   <li>ARTIST</li>
119        *   <li>PERFORMER</li>
120        *   <li>COPYRIGHT</li>
121        *   <li>ORGANIZATION</li>
122        *   <li>DESCRIPTION</li>
123        *   <li>GENRE</li>
124        *   <li>DATE</li>
125        *   <li>LOCATION</li>
126        *   <li>CONTACT</li>
127        *   <li>ISRC</li>
128        * </ul>
129        *
130        * For a more detailed description of these fields, please see the Ogg
131        * Vorbis specification, section 5.2.2.1.
132        *
133        * \note The Ogg Vorbis comment specification does allow these key values
134        * to be either upper or lower case.  However, it is conventional for them
135        * to be upper case.  As such, TagLib, when parsing a Xiph/Vorbis comment,
136        * converts all fields to uppercase.  When you are using this data
137        * structure, you will need to specify the field name in upper case.
138        *
139        * \warning You should not modify this data structure directly, instead
140        * use addField() and removeField().
141        */
142       const FieldListMap &fieldListMap() const;
143 
144       /*!
145        * Implements the unified property interface -- export function.
146        * The result is a one-to-one match of the Xiph comment, since it is
147        * completely compatible with the property interface (in fact, a Xiph
148        * comment is nothing more than a map from tag names to list of values,
149        * as is the dict interface).
150        */
151       PropertyMap properties() const;
152 
153       /*!
154        * Implements the unified property interface -- import function.
155        * The tags from the given map will be stored one-to-one in the file,
156        * except for invalid keys (less than one character, non-ASCII, or
157        * containing '=' or '~') in which case the according values will
158        * be contained in the returned PropertyMap.
159        */
160       PropertyMap setProperties(const PropertyMap&);
161 
162       /*!
163        * Check if the given String is a valid Xiph comment key.
164        */
165       static bool checkKey(const String&);
166 
167       /*!
168        * Returns the vendor ID of the Ogg Vorbis encoder.  libvorbis 1.0 as the
169        * most common case always returns "Xiph.Org libVorbis I 20020717".
170        */
171       String vendorID() const;
172 
173       /*!
174        * Add the field specified by \a key with the data \a value.  If \a replace
175        * is true, then all of the other fields with the same key will be removed
176        * first.
177        *
178        * If the field value is empty, the field will be removed.
179        */
180       void addField(const String &key, const String &value, bool replace = true);
181 
182       /*!
183        * Remove the field specified by \a key with the data \a value.  If
184        * \a value is null, all of the fields with the given key will be removed.
185        *
186        * \deprecated Using this method may lead to a linkage error.
187        */
188       // BIC: remove and merge with below
189       void removeField(const String &key, const String &value = String::null);
190 
191       /*!
192        * Remove all the fields specified by \a key.
193        *
194        * \see removeAllFields()
195        */
196       void removeFields(const String &key);
197 
198       /*!
199        * Remove all the fields specified by \a key with the data \a value.
200        *
201        * \see removeAllFields()
202        */
203       void removeFields(const String &key, const String &value);
204 
205       /*!
206        * Remove all the fields in the comment.
207        *
208        * \see removeFields()
209        */
210       void removeAllFields();
211 
212       /*!
213        * Returns true if the field is contained within the comment.
214        *
215        * \note This is safer than checking for membership in the FieldListMap.
216        */
217       bool contains(const String &key) const;
218 
219       /*!
220        * Renders the comment to a ByteVector suitable for inserting into a file.
221        */
222       ByteVector render() const; // BIC: remove and merge with below
223 
224       /*!
225        * Renders the comment to a ByteVector suitable for inserting into a file.
226        *
227        * If \a addFramingBit is true the standard Vorbis comment framing bit will
228        * be appended.  However some formats (notably FLAC) do not work with this
229        * in place.
230        */
231       ByteVector render(bool addFramingBit) const;
232 
233 
234       /*!
235        * Returns a list of pictures attached to the xiph comment.
236        */
237       List<FLAC::Picture *> pictureList();
238 
239       /*!
240        * Removes an picture. If \a del is true the picture's memory
241        * will be freed; if it is false, it must be deleted by the user.
242        */
243       void removePicture(FLAC::Picture *picture, bool del = true);
244 
245       /*!
246        * Remove all pictures.
247        */
248       void removeAllPictures();
249 
250       /*!
251        * Add a new picture to the comment block. The comment block takes ownership of the
252        * picture and will handle freeing its memory.
253        *
254        * \note The file will be saved only after calling save().
255        */
256       void addPicture(FLAC::Picture *picture);
257 
258     protected:
259       /*!
260        * Reads the tag from the file specified in the constructor and fills the
261        * FieldListMap.
262        */
263       void parse(const ByteVector &data);
264 
265     private:
266       XiphComment(const XiphComment &);
267       XiphComment &operator=(const XiphComment &);
268 
269       class XiphCommentPrivate;
270       XiphCommentPrivate *d;
271     };
272   }
273 }
274 
275 #endif
276