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