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