1 /* libFLAC++ - Free Lossless Audio Codec library 2 * Copyright (C) 2002-2009 Josh Coalson 3 * Copyright (C) 2011-2016 Xiph.Org Foundation 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of the Xiph.org Foundation nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef FLACPP__METADATA_H 34 #define FLACPP__METADATA_H 35 36 #include "export.h" 37 38 #include "FLAC/metadata.h" 39 40 // =============================================================== 41 // 42 // Full documentation for the metadata interface can be found 43 // in the C layer in include/FLAC/metadata.h 44 // 45 // =============================================================== 46 47 /** \file include/FLAC++/metadata.h 48 * 49 * \brief 50 * This module provides classes for creating and manipulating FLAC 51 * metadata blocks in memory, and three progressively more powerful 52 * interfaces for traversing and editing metadata in FLAC files. 53 * 54 * See the detailed documentation for each interface in the 55 * \link flacpp_metadata metadata \endlink module. 56 */ 57 58 /** \defgroup flacpp_metadata FLAC++/metadata.h: metadata interfaces 59 * \ingroup flacpp 60 * 61 * \brief 62 * This module provides classes for creating and manipulating FLAC 63 * metadata blocks in memory, and three progressively more powerful 64 * interfaces for traversing and editing metadata in FLAC files. 65 * 66 * The behavior closely mimics the C layer interface; be sure to read 67 * the detailed description of the 68 * \link flac_metadata C metadata module \endlink. Note that like the 69 * C layer, currently only the Chain interface (level 2) supports Ogg 70 * FLAC files, and it is read-only i.e. no writing back changed 71 * metadata to file. 72 */ 73 74 75 namespace FLAC { 76 namespace Metadata { 77 78 // ============================================================ 79 // 80 // Metadata objects 81 // 82 // ============================================================ 83 84 /** \defgroup flacpp_metadata_object FLAC++/metadata.h: metadata object classes 85 * \ingroup flacpp_metadata 86 * 87 * This module contains classes representing FLAC metadata 88 * blocks in memory. 89 * 90 * The behavior closely mimics the C layer interface; be 91 * sure to read the detailed description of the 92 * \link flac_metadata_object C metadata object module \endlink. 93 * 94 * Any time a metadata object is constructed or assigned, you 95 * should check is_valid() to make sure the underlying 96 * ::FLAC__StreamMetadata object was able to be created. 97 * 98 * \warning 99 * When the get_*() methods of any metadata object method 100 * return you a const pointer, DO NOT disobey and write into it. 101 * Always use the set_*() methods. 102 * 103 * \{ 104 */ 105 106 /** Base class for all metadata block types. 107 * See the \link flacpp_metadata_object overview \endlink for more. 108 */ 109 class FLACPP_API Prototype { 110 protected: 111 //@{ 112 /** Constructs a copy of the given object. This form 113 * always performs a deep copy. 114 */ 115 Prototype(const Prototype &); 116 Prototype(const ::FLAC__StreamMetadata &); 117 Prototype(const ::FLAC__StreamMetadata *); 118 //@} 119 120 /** Constructs an object with copy control. When \a copy 121 * is \c true, behaves identically to 122 * FLAC::Metadata::Prototype::Prototype(const ::FLAC__StreamMetadata *object). 123 * When \a copy is \c false, the instance takes ownership of 124 * the pointer and the ::FLAC__StreamMetadata object will 125 * be freed by the destructor. 126 * 127 * \assert 128 * \code object != NULL \endcode 129 */ 130 Prototype(::FLAC__StreamMetadata *object, bool copy); 131 132 //@{ 133 /** Assign from another object. Always performs a deep copy. */ 134 Prototype &operator=(const Prototype &); 135 Prototype &operator=(const ::FLAC__StreamMetadata &); 136 Prototype &operator=(const ::FLAC__StreamMetadata *); 137 //@} 138 139 /** Assigns an object with copy control. See 140 * Prototype(::FLAC__StreamMetadata *object, bool copy). 141 */ 142 Prototype &assign_object(::FLAC__StreamMetadata *object, bool copy); 143 144 /** Deletes the underlying ::FLAC__StreamMetadata object. 145 */ 146 virtual void clear(); 147 148 ::FLAC__StreamMetadata *object_; 149 public: 150 /** Deletes the underlying ::FLAC__StreamMetadata object. 151 */ 152 virtual ~Prototype(); 153 154 //@{ 155 /** Check for equality, performing a deep compare by following pointers. 156 */ 157 inline bool operator==(const Prototype &) const; 158 inline bool operator==(const ::FLAC__StreamMetadata &) const; 159 inline bool operator==(const ::FLAC__StreamMetadata *) const; 160 //@} 161 162 //@{ 163 /** Check for inequality, performing a deep compare by following pointers. */ 164 inline bool operator!=(const Prototype &) const; 165 inline bool operator!=(const ::FLAC__StreamMetadata &) const; 166 inline bool operator!=(const ::FLAC__StreamMetadata *) const; 167 //@} 168 169 friend class SimpleIterator; 170 friend class Iterator; 171 172 /** Returns \c true if the object was correctly constructed 173 * (i.e. the underlying ::FLAC__StreamMetadata object was 174 * properly allocated), else \c false. 175 */ 176 inline bool is_valid() const; 177 178 /** Returns \c true if this block is the last block in a 179 * stream, else \c false. 180 * 181 * \assert 182 * \code is_valid() \endcode 183 */ 184 bool get_is_last() const; 185 186 /** Returns the type of the block. 187 * 188 * \assert 189 * \code is_valid() \endcode 190 */ 191 ::FLAC__MetadataType get_type() const; 192 193 /** Returns the stream length of the metadata block. 194 * 195 * \note 196 * The length does not include the metadata block header, 197 * per spec. 198 * 199 * \assert 200 * \code is_valid() \endcode 201 */ 202 unsigned get_length() const; 203 204 /** Sets the "is_last" flag for the block. When using the iterators 205 * it is not necessary to set this flag; they will do it for you. 206 * 207 * \assert 208 * \code is_valid() \endcode 209 */ 210 void set_is_last(bool); 211 212 /** Returns a pointer to the underlying ::FLAC__StreamMetadata 213 * object. This can be useful for plugging any holes between 214 * the C++ and C interfaces. 215 * 216 * \assert 217 * \code is_valid() \endcode 218 */ 219 inline operator const ::FLAC__StreamMetadata *() const; 220 private: 221 /** Private and undefined so you can't use it. */ 222 Prototype(); 223 224 // These are used only by Iterator 225 bool is_reference_; set_reference(bool x)226 inline void set_reference(bool x) { is_reference_ = x; } 227 }; 228 229 #ifdef _MSC_VER 230 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning) 231 #pragma warning ( disable : 4800 ) 232 #endif 233 234 inline bool Prototype::operator==(const Prototype &object) const 235 { return (bool)::FLAC__metadata_object_is_equal(object_, object.object_); } 236 237 inline bool Prototype::operator==(const ::FLAC__StreamMetadata &object) const 238 { return (bool)::FLAC__metadata_object_is_equal(object_, &object); } 239 240 inline bool Prototype::operator==(const ::FLAC__StreamMetadata *object) const 241 { return (bool)::FLAC__metadata_object_is_equal(object_, object); } 242 243 #ifdef _MSC_VER 244 #pragma warning ( default : 4800 ) 245 #endif 246 247 inline bool Prototype::operator!=(const Prototype &object) const 248 { return !operator==(object); } 249 250 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata &object) const 251 { return !operator==(object); } 252 253 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata *object) const 254 { return !operator==(object); } 255 is_valid()256 inline bool Prototype::is_valid() const 257 { return 0 != object_; } 258 259 inline Prototype::operator const ::FLAC__StreamMetadata *() const 260 { return object_; } 261 262 /** Create a deep copy of an object and return it. */ 263 FLACPP_API Prototype *clone(const Prototype *); 264 265 266 /** STREAMINFO metadata block. 267 * See the \link flacpp_metadata_object overview \endlink for more, 268 * and the <A HREF="../format.html#metadata_block_streaminfo">format specification</A>. 269 */ 270 class FLACPP_API StreamInfo : public Prototype { 271 public: 272 StreamInfo(); 273 274 //@{ 275 /** Constructs a copy of the given object. This form 276 * always performs a deep copy. 277 */ StreamInfo(const StreamInfo & object)278 inline StreamInfo(const StreamInfo &object): Prototype(object) { } StreamInfo(const::FLAC__StreamMetadata & object)279 inline StreamInfo(const ::FLAC__StreamMetadata &object): Prototype(object) { } StreamInfo(const::FLAC__StreamMetadata * object)280 inline StreamInfo(const ::FLAC__StreamMetadata *object): Prototype(object) { } 281 //@} 282 283 /** Constructs an object with copy control. See 284 * Prototype(::FLAC__StreamMetadata *object, bool copy). 285 */ StreamInfo(::FLAC__StreamMetadata * object,bool copy)286 inline StreamInfo(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 287 288 ~StreamInfo(); 289 290 //@{ 291 /** Assign from another object. Always performs a deep copy. */ 292 inline StreamInfo &operator=(const StreamInfo &object) { Prototype::operator=(object); return *this; } 293 inline StreamInfo &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 294 inline StreamInfo &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 295 //@} 296 297 /** Assigns an object with copy control. See 298 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 299 */ assign(::FLAC__StreamMetadata * object,bool copy)300 inline StreamInfo &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 301 302 //@{ 303 /** Check for equality, performing a deep compare by following pointers. */ 304 inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); } 305 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 306 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 307 //@} 308 309 //@{ 310 /** Check for inequality, performing a deep compare by following pointers. */ 311 inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); } 312 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 313 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 314 //@} 315 316 //@{ 317 /** See <A HREF="../format.html#metadata_block_streaminfo">format specification</A>. */ 318 unsigned get_min_blocksize() const; 319 unsigned get_max_blocksize() const; 320 unsigned get_min_framesize() const; 321 unsigned get_max_framesize() const; 322 unsigned get_sample_rate() const; 323 unsigned get_channels() const; 324 unsigned get_bits_per_sample() const; 325 FLAC__uint64 get_total_samples() const; 326 const FLAC__byte *get_md5sum() const; 327 328 void set_min_blocksize(unsigned value); 329 void set_max_blocksize(unsigned value); 330 void set_min_framesize(unsigned value); 331 void set_max_framesize(unsigned value); 332 void set_sample_rate(unsigned value); 333 void set_channels(unsigned value); 334 void set_bits_per_sample(unsigned value); 335 void set_total_samples(FLAC__uint64 value); 336 void set_md5sum(const FLAC__byte value[16]); 337 //@} 338 }; 339 340 /** PADDING metadata block. 341 * See the \link flacpp_metadata_object overview \endlink for more, 342 * and the <A HREF="../format.html#metadata_block_padding">format specification</A>. 343 */ 344 class FLACPP_API Padding : public Prototype { 345 public: 346 Padding(); 347 348 //@{ 349 /** Constructs a copy of the given object. This form 350 * always performs a deep copy. 351 */ Padding(const Padding & object)352 inline Padding(const Padding &object): Prototype(object) { } Padding(const::FLAC__StreamMetadata & object)353 inline Padding(const ::FLAC__StreamMetadata &object): Prototype(object) { } Padding(const::FLAC__StreamMetadata * object)354 inline Padding(const ::FLAC__StreamMetadata *object): Prototype(object) { } 355 //@} 356 357 /** Constructs an object with copy control. See 358 * Prototype(::FLAC__StreamMetadata *object, bool copy). 359 */ Padding(::FLAC__StreamMetadata * object,bool copy)360 inline Padding(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 361 362 /** Constructs an object with the given length. 363 */ 364 Padding(unsigned length); 365 366 ~Padding(); 367 368 //@{ 369 /** Assign from another object. Always performs a deep copy. */ 370 inline Padding &operator=(const Padding &object) { Prototype::operator=(object); return *this; } 371 inline Padding &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 372 inline Padding &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 373 //@} 374 375 /** Assigns an object with copy control. See 376 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 377 */ assign(::FLAC__StreamMetadata * object,bool copy)378 inline Padding &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 379 380 //@{ 381 /** Check for equality, performing a deep compare by following pointers. */ 382 inline bool operator==(const Padding &object) const { return Prototype::operator==(object); } 383 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 384 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 385 //@} 386 387 //@{ 388 /** Check for inequality, performing a deep compare by following pointers. */ 389 inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); } 390 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 391 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 392 //@} 393 394 /** Sets the length in bytes of the padding block. 395 */ 396 void set_length(unsigned length); 397 }; 398 399 /** APPLICATION metadata block. 400 * See the \link flacpp_metadata_object overview \endlink for more, 401 * and the <A HREF="../format.html#metadata_block_application">format specification</A>. 402 */ 403 class FLACPP_API Application : public Prototype { 404 public: 405 Application(); 406 // 407 //@{ 408 /** Constructs a copy of the given object. This form 409 * always performs a deep copy. 410 */ Application(const Application & object)411 inline Application(const Application &object): Prototype(object) { } Application(const::FLAC__StreamMetadata & object)412 inline Application(const ::FLAC__StreamMetadata &object): Prototype(object) { } Application(const::FLAC__StreamMetadata * object)413 inline Application(const ::FLAC__StreamMetadata *object): Prototype(object) { } 414 //@} 415 416 /** Constructs an object with copy control. See 417 * Prototype(::FLAC__StreamMetadata *object, bool copy). 418 */ Application(::FLAC__StreamMetadata * object,bool copy)419 inline Application(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 420 421 ~Application(); 422 423 //@{ 424 /** Assign from another object. Always performs a deep copy. */ 425 inline Application &operator=(const Application &object) { Prototype::operator=(object); return *this; } 426 inline Application &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 427 inline Application &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 428 //@} 429 430 /** Assigns an object with copy control. See 431 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 432 */ assign(::FLAC__StreamMetadata * object,bool copy)433 inline Application &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 434 435 //@{ 436 /** Check for equality, performing a deep compare by following pointers. */ 437 inline bool operator==(const Application &object) const { return Prototype::operator==(object); } 438 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 439 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 440 //@} 441 442 //@{ 443 /** Check for inequality, performing a deep compare by following pointers. */ 444 inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); } 445 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 446 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 447 //@} 448 449 const FLAC__byte *get_id() const; 450 const FLAC__byte *get_data() const; 451 452 void set_id(const FLAC__byte value[4]); 453 //! This form always copies \a data 454 bool set_data(const FLAC__byte *data, unsigned length); 455 bool set_data(FLAC__byte *data, unsigned length, bool copy); 456 }; 457 458 /** SEEKTABLE metadata block. 459 * See the \link flacpp_metadata_object overview \endlink for more, 460 * and the <A HREF="../format.html#metadata_block_seektable">format specification</A>. 461 */ 462 class FLACPP_API SeekTable : public Prototype { 463 public: 464 SeekTable(); 465 466 //@{ 467 /** Constructs a copy of the given object. This form 468 * always performs a deep copy. 469 */ SeekTable(const SeekTable & object)470 inline SeekTable(const SeekTable &object): Prototype(object) { } SeekTable(const::FLAC__StreamMetadata & object)471 inline SeekTable(const ::FLAC__StreamMetadata &object): Prototype(object) { } SeekTable(const::FLAC__StreamMetadata * object)472 inline SeekTable(const ::FLAC__StreamMetadata *object): Prototype(object) { } 473 //@} 474 475 /** Constructs an object with copy control. See 476 * Prototype(::FLAC__StreamMetadata *object, bool copy). 477 */ SeekTable(::FLAC__StreamMetadata * object,bool copy)478 inline SeekTable(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 479 480 ~SeekTable(); 481 482 //@{ 483 /** Assign from another object. Always performs a deep copy. */ 484 inline SeekTable &operator=(const SeekTable &object) { Prototype::operator=(object); return *this; } 485 inline SeekTable &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 486 inline SeekTable &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 487 //@} 488 489 /** Assigns an object with copy control. See 490 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 491 */ assign(::FLAC__StreamMetadata * object,bool copy)492 inline SeekTable &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 493 494 //@{ 495 /** Check for equality, performing a deep compare by following pointers. */ 496 inline bool operator==(const SeekTable &object) const { return Prototype::operator==(object); } 497 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 498 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 499 //@} 500 501 //@{ 502 /** Check for inequality, performing a deep compare by following pointers. */ 503 inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); } 504 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 505 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 506 //@} 507 508 unsigned get_num_points() const; 509 ::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const; 510 511 //! See FLAC__metadata_object_seektable_resize_points() 512 bool resize_points(unsigned new_num_points); 513 514 //! See FLAC__metadata_object_seektable_set_point() 515 void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point); 516 517 //! See FLAC__metadata_object_seektable_insert_point() 518 bool insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point); 519 520 //! See FLAC__metadata_object_seektable_delete_point() 521 bool delete_point(unsigned index); 522 523 //! See FLAC__metadata_object_seektable_is_legal() 524 bool is_legal() const; 525 526 //! See FLAC__metadata_object_seektable_template_append_placeholders() 527 bool template_append_placeholders(unsigned num); 528 529 //! See FLAC__metadata_object_seektable_template_append_point() 530 bool template_append_point(FLAC__uint64 sample_number); 531 532 //! See FLAC__metadata_object_seektable_template_append_points() 533 bool template_append_points(FLAC__uint64 sample_numbers[], unsigned num); 534 535 //! See FLAC__metadata_object_seektable_template_append_spaced_points() 536 bool template_append_spaced_points(unsigned num, FLAC__uint64 total_samples); 537 538 //! See FLAC__metadata_object_seektable_template_append_spaced_points_by_samples() 539 bool template_append_spaced_points_by_samples(unsigned samples, FLAC__uint64 total_samples); 540 541 //! See FLAC__metadata_object_seektable_template_sort() 542 bool template_sort(bool compact); 543 }; 544 545 /** VORBIS_COMMENT metadata block. 546 * See the \link flacpp_metadata_object overview \endlink for more, 547 * and the <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>. 548 */ 549 class FLACPP_API VorbisComment : public Prototype { 550 public: 551 /** Convenience class for encapsulating Vorbis comment 552 * entries. An entry is a vendor string or a comment 553 * field. In the case of a vendor string, the field 554 * name is undefined; only the field value is relevant. 555 * 556 * A \a field as used in the methods refers to an 557 * entire 'NAME=VALUE' string; for convenience the 558 * string is NUL-terminated. A length field is 559 * required in the unlikely event that the value 560 * contains contain embedded NULs. 561 * 562 * A \a field_name is what is on the left side of the 563 * first '=' in the \a field. By definition it is ASCII 564 * and so is NUL-terminated and does not require a 565 * length to describe it. \a field_name is undefined 566 * for a vendor string entry. 567 * 568 * A \a field_value is what is on the right side of the 569 * first '=' in the \a field. By definition, this may 570 * contain embedded NULs and so a \a field_value_length 571 * is required to describe it. However in practice, 572 * embedded NULs are not known to be used, so it is 573 * generally safe to treat field values as NUL- 574 * terminated UTF-8 strings. 575 * 576 * Always check is_valid() after the constructor or operator= 577 * to make sure memory was properly allocated and that the 578 * Entry conforms to the Vorbis comment specification. 579 */ 580 class FLACPP_API Entry { 581 public: 582 Entry(); 583 584 Entry(const char *field, unsigned field_length); 585 Entry(const char *field); // assumes \a field is NUL-terminated 586 587 Entry(const char *field_name, const char *field_value, unsigned field_value_length); 588 Entry(const char *field_name, const char *field_value); // assumes \a field_value is NUL-terminated 589 590 Entry(const Entry &entry); 591 592 Entry &operator=(const Entry &entry); 593 594 virtual ~Entry(); 595 596 virtual bool is_valid() const; ///< Returns \c true iff object was properly constructed. 597 598 unsigned get_field_length() const; 599 unsigned get_field_name_length() const; 600 unsigned get_field_value_length() const; 601 602 ::FLAC__StreamMetadata_VorbisComment_Entry get_entry() const; 603 const char *get_field() const; 604 const char *get_field_name() const; 605 const char *get_field_value() const; 606 607 bool set_field(const char *field, unsigned field_length); 608 bool set_field(const char *field); // assumes \a field is NUL-terminated 609 bool set_field_name(const char *field_name); 610 bool set_field_value(const char *field_value, unsigned field_value_length); 611 bool set_field_value(const char *field_value); // assumes \a field_value is NUL-terminated 612 protected: 613 bool is_valid_; 614 ::FLAC__StreamMetadata_VorbisComment_Entry entry_; 615 char *field_name_; 616 unsigned field_name_length_; 617 char *field_value_; 618 unsigned field_value_length_; 619 private: 620 void zero(); 621 void clear(); 622 void clear_entry(); 623 void clear_field_name(); 624 void clear_field_value(); 625 void construct(const char *field, unsigned field_length); 626 void construct(const char *field); // assumes \a field is NUL-terminated 627 void construct(const char *field_name, const char *field_value, unsigned field_value_length); 628 void construct(const char *field_name, const char *field_value); // assumes \a field_value is NUL-terminated 629 void compose_field(); 630 void parse_field(); 631 }; 632 633 VorbisComment(); 634 635 //@{ 636 /** Constructs a copy of the given object. This form 637 * always performs a deep copy. 638 */ VorbisComment(const VorbisComment & object)639 inline VorbisComment(const VorbisComment &object): Prototype(object) { } VorbisComment(const::FLAC__StreamMetadata & object)640 inline VorbisComment(const ::FLAC__StreamMetadata &object): Prototype(object) { } VorbisComment(const::FLAC__StreamMetadata * object)641 inline VorbisComment(const ::FLAC__StreamMetadata *object): Prototype(object) { } 642 //@} 643 644 /** Constructs an object with copy control. See 645 * Prototype(::FLAC__StreamMetadata *object, bool copy). 646 */ VorbisComment(::FLAC__StreamMetadata * object,bool copy)647 inline VorbisComment(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 648 649 ~VorbisComment(); 650 651 //@{ 652 /** Assign from another object. Always performs a deep copy. */ 653 inline VorbisComment &operator=(const VorbisComment &object) { Prototype::operator=(object); return *this; } 654 inline VorbisComment &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 655 inline VorbisComment &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 656 //@} 657 658 /** Assigns an object with copy control. See 659 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 660 */ assign(::FLAC__StreamMetadata * object,bool copy)661 inline VorbisComment &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 662 663 //@{ 664 /** Check for equality, performing a deep compare by following pointers. */ 665 inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); } 666 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 667 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 668 //@} 669 670 //@{ 671 /** Check for inequality, performing a deep compare by following pointers. */ 672 inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); } 673 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 674 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 675 //@} 676 677 unsigned get_num_comments() const; 678 const FLAC__byte *get_vendor_string() const; // NUL-terminated UTF-8 string 679 Entry get_comment(unsigned index) const; 680 681 //! See FLAC__metadata_object_vorbiscomment_set_vendor_string() 682 bool set_vendor_string(const FLAC__byte *string); // NUL-terminated UTF-8 string 683 684 //! See FLAC__metadata_object_vorbiscomment_resize_comments() 685 bool resize_comments(unsigned new_num_comments); 686 687 //! See FLAC__metadata_object_vorbiscomment_set_comment() 688 bool set_comment(unsigned index, const Entry &entry); 689 690 //! See FLAC__metadata_object_vorbiscomment_insert_comment() 691 bool insert_comment(unsigned index, const Entry &entry); 692 693 //! See FLAC__metadata_object_vorbiscomment_append_comment() 694 bool append_comment(const Entry &entry); 695 696 //! See FLAC__metadata_object_vorbiscomment_replace_comment() 697 bool replace_comment(const Entry &entry, bool all); 698 699 //! See FLAC__metadata_object_vorbiscomment_delete_comment() 700 bool delete_comment(unsigned index); 701 702 //! See FLAC__metadata_object_vorbiscomment_find_entry_from() 703 int find_entry_from(unsigned offset, const char *field_name); 704 705 //! See FLAC__metadata_object_vorbiscomment_remove_entry_matching() 706 int remove_entry_matching(const char *field_name); 707 708 //! See FLAC__metadata_object_vorbiscomment_remove_entries_matching() 709 int remove_entries_matching(const char *field_name); 710 }; 711 712 /** CUESHEET metadata block. 713 * See the \link flacpp_metadata_object overview \endlink for more, 714 * and the <A HREF="../format.html#metadata_block_cuesheet">format specification</A>. 715 */ 716 class FLACPP_API CueSheet : public Prototype { 717 public: 718 /** Convenience class for encapsulating a cue sheet 719 * track. 720 * 721 * Always check is_valid() after the constructor or operator= 722 * to make sure memory was properly allocated. 723 */ 724 class FLACPP_API Track { 725 protected: 726 ::FLAC__StreamMetadata_CueSheet_Track *object_; 727 public: 728 Track(); 729 Track(const ::FLAC__StreamMetadata_CueSheet_Track *track); 730 Track(const Track &track); 731 Track &operator=(const Track &track); 732 733 virtual ~Track(); 734 735 virtual bool is_valid() const; ///< Returns \c true iff object was properly constructed. 736 737 get_offset()738 inline FLAC__uint64 get_offset() const { return object_->offset; } get_number()739 inline FLAC__byte get_number() const { return object_->number; } get_isrc()740 inline const char *get_isrc() const { return object_->isrc; } get_type()741 inline unsigned get_type() const { return object_->type; } get_pre_emphasis()742 inline bool get_pre_emphasis() const { return object_->pre_emphasis; } 743 get_num_indices()744 inline FLAC__byte get_num_indices() const { return object_->num_indices; } 745 ::FLAC__StreamMetadata_CueSheet_Index get_index(unsigned i) const; 746 get_track()747 inline const ::FLAC__StreamMetadata_CueSheet_Track *get_track() const { return object_; } 748 set_offset(FLAC__uint64 value)749 inline void set_offset(FLAC__uint64 value) { object_->offset = value; } set_number(FLAC__byte value)750 inline void set_number(FLAC__byte value) { object_->number = value; } 751 void set_isrc(const char value[12]); 752 void set_type(unsigned value); set_pre_emphasis(bool value)753 inline void set_pre_emphasis(bool value) { object_->pre_emphasis = value? 1 : 0; } 754 755 void set_index(unsigned i, const ::FLAC__StreamMetadata_CueSheet_Index &index); 756 //@@@ It's awkward but to insert/delete index points 757 //@@@ you must use the routines in the CueSheet class. 758 }; 759 760 CueSheet(); 761 762 //@{ 763 /** Constructs a copy of the given object. This form 764 * always performs a deep copy. 765 */ CueSheet(const CueSheet & object)766 inline CueSheet(const CueSheet &object): Prototype(object) { } CueSheet(const::FLAC__StreamMetadata & object)767 inline CueSheet(const ::FLAC__StreamMetadata &object): Prototype(object) { } CueSheet(const::FLAC__StreamMetadata * object)768 inline CueSheet(const ::FLAC__StreamMetadata *object): Prototype(object) { } 769 //@} 770 771 /** Constructs an object with copy control. See 772 * Prototype(::FLAC__StreamMetadata *object, bool copy). 773 */ CueSheet(::FLAC__StreamMetadata * object,bool copy)774 inline CueSheet(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 775 776 ~CueSheet(); 777 778 //@{ 779 /** Assign from another object. Always performs a deep copy. */ 780 inline CueSheet &operator=(const CueSheet &object) { Prototype::operator=(object); return *this; } 781 inline CueSheet &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 782 inline CueSheet &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 783 //@} 784 785 /** Assigns an object with copy control. See 786 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 787 */ assign(::FLAC__StreamMetadata * object,bool copy)788 inline CueSheet &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 789 790 //@{ 791 /** Check for equality, performing a deep compare by following pointers. */ 792 inline bool operator==(const CueSheet &object) const { return Prototype::operator==(object); } 793 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 794 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 795 //@} 796 797 //@{ 798 /** Check for inequality, performing a deep compare by following pointers. */ 799 inline bool operator!=(const CueSheet &object) const { return Prototype::operator!=(object); } 800 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 801 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 802 //@} 803 804 const char *get_media_catalog_number() const; 805 FLAC__uint64 get_lead_in() const; 806 bool get_is_cd() const; 807 808 unsigned get_num_tracks() const; 809 Track get_track(unsigned i) const; 810 811 void set_media_catalog_number(const char value[128]); 812 void set_lead_in(FLAC__uint64 value); 813 void set_is_cd(bool value); 814 815 void set_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index); 816 817 //! See FLAC__metadata_object_cuesheet_track_resize_indices() 818 bool resize_indices(unsigned track_num, unsigned new_num_indices); 819 820 //! See FLAC__metadata_object_cuesheet_track_insert_index() 821 bool insert_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index); 822 823 //! See FLAC__metadata_object_cuesheet_track_insert_blank_index() 824 bool insert_blank_index(unsigned track_num, unsigned index_num); 825 826 //! See FLAC__metadata_object_cuesheet_track_delete_index() 827 bool delete_index(unsigned track_num, unsigned index_num); 828 829 //! See FLAC__metadata_object_cuesheet_resize_tracks() 830 bool resize_tracks(unsigned new_num_tracks); 831 832 //! See FLAC__metadata_object_cuesheet_set_track() 833 bool set_track(unsigned i, const Track &track); 834 835 //! See FLAC__metadata_object_cuesheet_insert_track() 836 bool insert_track(unsigned i, const Track &track); 837 838 //! See FLAC__metadata_object_cuesheet_insert_blank_track() 839 bool insert_blank_track(unsigned i); 840 841 //! See FLAC__metadata_object_cuesheet_delete_track() 842 bool delete_track(unsigned i); 843 844 //! See FLAC__metadata_object_cuesheet_is_legal() 845 bool is_legal(bool check_cd_da_subset = false, const char **violation = 0) const; 846 847 //! See FLAC__metadata_object_cuesheet_calculate_cddb_id() 848 FLAC__uint32 calculate_cddb_id() const; 849 }; 850 851 /** PICTURE metadata block. 852 * See the \link flacpp_metadata_object overview \endlink for more, 853 * and the <A HREF="../format.html#metadata_block_picture">format specification</A>. 854 */ 855 class FLACPP_API Picture : public Prototype { 856 public: 857 Picture(); 858 859 //@{ 860 /** Constructs a copy of the given object. This form 861 * always performs a deep copy. 862 */ Picture(const Picture & object)863 inline Picture(const Picture &object): Prototype(object) { } Picture(const::FLAC__StreamMetadata & object)864 inline Picture(const ::FLAC__StreamMetadata &object): Prototype(object) { } Picture(const::FLAC__StreamMetadata * object)865 inline Picture(const ::FLAC__StreamMetadata *object): Prototype(object) { } 866 //@} 867 868 /** Constructs an object with copy control. See 869 * Prototype(::FLAC__StreamMetadata *object, bool copy). 870 */ Picture(::FLAC__StreamMetadata * object,bool copy)871 inline Picture(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 872 873 ~Picture(); 874 875 //@{ 876 /** Assign from another object. Always performs a deep copy. */ 877 inline Picture &operator=(const Picture &object) { Prototype::operator=(object); return *this; } 878 inline Picture &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 879 inline Picture &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 880 //@} 881 882 /** Assigns an object with copy control. See 883 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 884 */ assign(::FLAC__StreamMetadata * object,bool copy)885 inline Picture &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 886 887 //@{ 888 /** Check for equality, performing a deep compare by following pointers. */ 889 inline bool operator==(const Picture &object) const { return Prototype::operator==(object); } 890 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 891 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 892 //@} 893 894 //@{ 895 /** Check for inequality, performing a deep compare by following pointers. */ 896 inline bool operator!=(const Picture &object) const { return Prototype::operator!=(object); } 897 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 898 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 899 //@} 900 901 ::FLAC__StreamMetadata_Picture_Type get_type() const; 902 const char *get_mime_type() const; // NUL-terminated printable ASCII string 903 const FLAC__byte *get_description() const; // NUL-terminated UTF-8 string 904 FLAC__uint32 get_width() const; 905 FLAC__uint32 get_height() const; 906 FLAC__uint32 get_depth() const; 907 FLAC__uint32 get_colors() const; ///< a return value of \c 0 means true-color, i.e. 2^depth colors 908 FLAC__uint32 get_data_length() const; 909 const FLAC__byte *get_data() const; 910 911 void set_type(::FLAC__StreamMetadata_Picture_Type type); 912 913 //! See FLAC__metadata_object_picture_set_mime_type() 914 bool set_mime_type(const char *string); // NUL-terminated printable ASCII string 915 916 //! See FLAC__metadata_object_picture_set_description() 917 bool set_description(const FLAC__byte *string); // NUL-terminated UTF-8 string 918 919 void set_width(FLAC__uint32 value) const; 920 void set_height(FLAC__uint32 value) const; 921 void set_depth(FLAC__uint32 value) const; 922 void set_colors(FLAC__uint32 value) const; ///< a value of \c 0 means true-color, i.e. 2^depth colors 923 924 //! See FLAC__metadata_object_picture_set_data() 925 bool set_data(const FLAC__byte *data, FLAC__uint32 data_length); 926 927 //! See FLAC__metadata_object_picture_is_legal() 928 bool is_legal(const char **violation); 929 }; 930 931 /** Opaque metadata block for storing unknown types. 932 * This should not be used unless you know what you are doing; 933 * it is currently used only internally to support forward 934 * compatibility of metadata blocks. 935 * See the \link flacpp_metadata_object overview \endlink for more, 936 */ 937 class FLACPP_API Unknown : public Prototype { 938 public: 939 Unknown(); 940 // 941 //@{ 942 /** Constructs a copy of the given object. This form 943 * always performs a deep copy. 944 */ Unknown(const Unknown & object)945 inline Unknown(const Unknown &object): Prototype(object) { } Unknown(const::FLAC__StreamMetadata & object)946 inline Unknown(const ::FLAC__StreamMetadata &object): Prototype(object) { } Unknown(const::FLAC__StreamMetadata * object)947 inline Unknown(const ::FLAC__StreamMetadata *object): Prototype(object) { } 948 //@} 949 950 /** Constructs an object with copy control. See 951 * Prototype(::FLAC__StreamMetadata *object, bool copy). 952 */ Unknown(::FLAC__StreamMetadata * object,bool copy)953 inline Unknown(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { } 954 955 ~Unknown(); 956 957 //@{ 958 /** Assign from another object. Always performs a deep copy. */ 959 inline Unknown &operator=(const Unknown &object) { Prototype::operator=(object); return *this; } 960 inline Unknown &operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); return *this; } 961 inline Unknown &operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); return *this; } 962 //@} 963 964 /** Assigns an object with copy control. See 965 * Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy). 966 */ assign(::FLAC__StreamMetadata * object,bool copy)967 inline Unknown &assign(::FLAC__StreamMetadata *object, bool copy) { Prototype::assign_object(object, copy); return *this; } 968 969 //@{ 970 /** Check for equality, performing a deep compare by following pointers. */ 971 inline bool operator==(const Unknown &object) const { return Prototype::operator==(object); } 972 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); } 973 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); } 974 //@} 975 976 //@{ 977 /** Check for inequality, performing a deep compare by following pointers. */ 978 inline bool operator!=(const Unknown &object) const { return Prototype::operator!=(object); } 979 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); } 980 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); } 981 //@} 982 983 const FLAC__byte *get_data() const; 984 985 //! This form always copies \a data 986 bool set_data(const FLAC__byte *data, unsigned length); 987 bool set_data(FLAC__byte *data, unsigned length, bool copy); 988 }; 989 990 /* \} */ 991 992 993 /** \defgroup flacpp_metadata_level0 FLAC++/metadata.h: metadata level 0 interface 994 * \ingroup flacpp_metadata 995 * 996 * \brief 997 * Level 0 metadata iterators. 998 * 999 * See the \link flac_metadata_level0 C layer equivalent \endlink 1000 * for more. 1001 * 1002 * \{ 1003 */ 1004 1005 FLACPP_API bool get_streaminfo(const char *filename, StreamInfo &streaminfo); ///< See FLAC__metadata_get_streaminfo(). 1006 1007 FLACPP_API bool get_tags(const char *filename, VorbisComment *&tags); ///< See FLAC__metadata_get_tags(). 1008 FLACPP_API bool get_tags(const char *filename, VorbisComment &tags); ///< See FLAC__metadata_get_tags(). 1009 1010 FLACPP_API bool get_cuesheet(const char *filename, CueSheet *&cuesheet); ///< See FLAC__metadata_get_cuesheet(). 1011 FLACPP_API bool get_cuesheet(const char *filename, CueSheet &cuesheet); ///< See FLAC__metadata_get_cuesheet(). 1012 1013 FLACPP_API bool get_picture(const char *filename, Picture *&picture, ::FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); ///< See FLAC__metadata_get_picture(). 1014 FLACPP_API bool get_picture(const char *filename, Picture &picture, ::FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); ///< See FLAC__metadata_get_picture(). 1015 1016 /* \} */ 1017 1018 1019 /** \defgroup flacpp_metadata_level1 FLAC++/metadata.h: metadata level 1 interface 1020 * \ingroup flacpp_metadata 1021 * 1022 * \brief 1023 * Level 1 metadata iterator. 1024 * 1025 * The flow through the iterator in the C++ layer is similar 1026 * to the C layer: 1027 * - Create a SimpleIterator instance 1028 * - Check SimpleIterator::is_valid() 1029 * - Call SimpleIterator::init() and check the return 1030 * - Traverse and/or edit. Edits are written to file 1031 * immediately. 1032 * - Destroy the SimpleIterator instance 1033 * 1034 * The ownership of pointers in the C++ layer follows that in 1035 * the C layer, i.e. 1036 * - The objects returned by get_block() are yours to 1037 * modify, but changes are not reflected in the FLAC file 1038 * until you call set_block(). The objects are also 1039 * yours to delete; they are not automatically deleted 1040 * when passed to set_block() or insert_block_after(). 1041 * 1042 * See the \link flac_metadata_level1 C layer equivalent \endlink 1043 * for more. 1044 * 1045 * \{ 1046 */ 1047 1048 /** This class is a wrapper around the FLAC__metadata_simple_iterator 1049 * structures and methods; see the 1050 * \link flacpp_metadata_level1 usage guide \endlink and 1051 * ::FLAC__Metadata_SimpleIterator. 1052 */ 1053 class FLACPP_API SimpleIterator { 1054 public: 1055 /** This class is a wrapper around FLAC__Metadata_SimpleIteratorStatus. 1056 */ 1057 class FLACPP_API Status { 1058 public: Status(::FLAC__Metadata_SimpleIteratorStatus status)1059 inline Status(::FLAC__Metadata_SimpleIteratorStatus status): status_(status) { } FLAC__Metadata_SimpleIteratorStatus()1060 inline operator ::FLAC__Metadata_SimpleIteratorStatus() const { return status_; } as_cstring()1061 inline const char *as_cstring() const { return ::FLAC__Metadata_SimpleIteratorStatusString[status_]; } 1062 protected: 1063 ::FLAC__Metadata_SimpleIteratorStatus status_; 1064 }; 1065 1066 SimpleIterator(); 1067 virtual ~SimpleIterator(); 1068 1069 bool is_valid() const; ///< Returns \c true iff object was properly constructed. 1070 1071 bool init(const char *filename, bool read_only, bool preserve_file_stats); ///< See FLAC__metadata_simple_iterator_init(). 1072 1073 Status status(); ///< See FLAC__metadata_simple_iterator_status(). 1074 bool is_writable() const; ///< See FLAC__metadata_simple_iterator_is_writable(). 1075 1076 bool next(); ///< See FLAC__metadata_simple_iterator_next(). 1077 bool prev(); ///< See FLAC__metadata_simple_iterator_prev(). 1078 bool is_last() const; ///< See FLAC__metadata_simple_iterator_is_last(). 1079 1080 off_t get_block_offset() const; ///< See FLAC__metadata_simple_iterator_get_block_offset(). 1081 ::FLAC__MetadataType get_block_type() const; ///< See FLAC__metadata_simple_iterator_get_block_type(). 1082 unsigned get_block_length() const; ///< See FLAC__metadata_simple_iterator_get_block_length(). 1083 bool get_application_id(FLAC__byte *id); ///< See FLAC__metadata_simple_iterator_get_application_id(). 1084 Prototype *get_block(); ///< See FLAC__metadata_simple_iterator_get_block(). 1085 bool set_block(Prototype *block, bool use_padding = true); ///< See FLAC__metadata_simple_iterator_set_block(). 1086 bool insert_block_after(Prototype *block, bool use_padding = true); ///< See FLAC__metadata_simple_iterator_insert_block_after(). 1087 bool delete_block(bool use_padding = true); ///< See FLAC__metadata_simple_iterator_delete_block(). 1088 1089 protected: 1090 ::FLAC__Metadata_SimpleIterator *iterator_; 1091 void clear(); 1092 1093 private: // Do not use. 1094 SimpleIterator(const SimpleIterator&); 1095 SimpleIterator&operator=(const SimpleIterator&); 1096 }; 1097 1098 /* \} */ 1099 1100 1101 /** \defgroup flacpp_metadata_level2 FLAC++/metadata.h: metadata level 2 interface 1102 * \ingroup flacpp_metadata 1103 * 1104 * \brief 1105 * Level 2 metadata iterator. 1106 * 1107 * The flow through the iterator in the C++ layer is similar 1108 * to the C layer: 1109 * - Create a Chain instance 1110 * - Check Chain::is_valid() 1111 * - Call Chain::read() and check the return 1112 * - Traverse and/or edit with an Iterator or with 1113 * Chain::merge_padding() or Chain::sort_padding() 1114 * - Write changes back to FLAC file with Chain::write() 1115 * - Destroy the Chain instance 1116 * 1117 * The ownership of pointers in the C++ layer is slightly 1118 * different than in the C layer, i.e. 1119 * - The objects returned by Iterator::get_block() are NOT 1120 * owned by the iterator and should be deleted by the 1121 * caller when finished, BUT, when you modify the block, 1122 * it will directly edit what's in the chain and you do 1123 * not need to call Iterator::set_block(). However the 1124 * changes will not be reflected in the FLAC file until 1125 * the chain is written with Chain::write(). 1126 * - When you pass an object to Iterator::set_block(), 1127 * Iterator::insert_block_before(), or 1128 * Iterator::insert_block_after(), the iterator takes 1129 * ownership of the block and it will be deleted by the 1130 * chain. 1131 * 1132 * See the \link flac_metadata_level2 C layer equivalent \endlink 1133 * for more. 1134 * 1135 * \{ 1136 */ 1137 1138 /** This class is a wrapper around the FLAC__metadata_chain 1139 * structures and methods; see the 1140 * \link flacpp_metadata_level2 usage guide \endlink and 1141 * ::FLAC__Metadata_Chain. 1142 */ 1143 class FLACPP_API Chain { 1144 public: 1145 /** This class is a wrapper around FLAC__Metadata_ChainStatus. 1146 */ 1147 class FLACPP_API Status { 1148 public: Status(::FLAC__Metadata_ChainStatus status)1149 inline Status(::FLAC__Metadata_ChainStatus status): status_(status) { } FLAC__Metadata_ChainStatus()1150 inline operator ::FLAC__Metadata_ChainStatus() const { return status_; } as_cstring()1151 inline const char *as_cstring() const { return ::FLAC__Metadata_ChainStatusString[status_]; } 1152 protected: 1153 ::FLAC__Metadata_ChainStatus status_; 1154 }; 1155 1156 Chain(); 1157 virtual ~Chain(); 1158 1159 friend class Iterator; 1160 1161 bool is_valid() const; ///< Returns \c true iff object was properly constructed. 1162 1163 Status status(); ///< See FLAC__metadata_chain_status(). 1164 1165 bool read(const char *filename, bool is_ogg = false); ///< See FLAC__metadata_chain_read(), FLAC__metadata_chain_read_ogg(). 1166 bool read(FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, bool is_ogg = false); ///< See FLAC__metadata_chain_read_with_callbacks(), FLAC__metadata_chain_read_ogg_with_callbacks(). 1167 1168 bool check_if_tempfile_needed(bool use_padding); ///< See FLAC__metadata_chain_check_if_tempfile_needed(). 1169 1170 bool write(bool use_padding = true, bool preserve_file_stats = false); ///< See FLAC__metadata_chain_write(). 1171 bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks); ///< See FLAC__metadata_chain_write_with_callbacks(). 1172 bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks, ::FLAC__IOHandle temp_handle, ::FLAC__IOCallbacks temp_callbacks); ///< See FLAC__metadata_chain_write_with_callbacks_and_tempfile(). 1173 1174 void merge_padding(); ///< See FLAC__metadata_chain_merge_padding(). 1175 void sort_padding(); ///< See FLAC__metadata_chain_sort_padding(). 1176 1177 protected: 1178 ::FLAC__Metadata_Chain *chain_; 1179 virtual void clear(); 1180 1181 private: // Do not use. 1182 Chain(const Chain&); 1183 Chain&operator=(const Chain&); 1184 }; 1185 1186 /** This class is a wrapper around the FLAC__metadata_iterator 1187 * structures and methods; see the 1188 * \link flacpp_metadata_level2 usage guide \endlink and 1189 * ::FLAC__Metadata_Iterator. 1190 */ 1191 class FLACPP_API Iterator { 1192 public: 1193 Iterator(); 1194 virtual ~Iterator(); 1195 1196 bool is_valid() const; ///< Returns \c true iff object was properly constructed. 1197 1198 1199 void init(Chain &chain); ///< See FLAC__metadata_iterator_init(). 1200 1201 bool next(); ///< See FLAC__metadata_iterator_next(). 1202 bool prev(); ///< See FLAC__metadata_iterator_prev(). 1203 1204 ::FLAC__MetadataType get_block_type() const; ///< See FLAC__metadata_iterator_get_block_type(). 1205 Prototype *get_block(); ///< See FLAC__metadata_iterator_get_block(). 1206 bool set_block(Prototype *block); ///< See FLAC__metadata_iterator_set_block(). 1207 bool delete_block(bool replace_with_padding); ///< See FLAC__metadata_iterator_delete_block(). 1208 bool insert_block_before(Prototype *block); ///< See FLAC__metadata_iterator_insert_block_before(). 1209 bool insert_block_after(Prototype *block); ///< See FLAC__metadata_iterator_insert_block_after(). 1210 1211 protected: 1212 ::FLAC__Metadata_Iterator *iterator_; 1213 virtual void clear(); 1214 1215 private: // Do not use. 1216 Iterator(const Iterator&); 1217 Iterator&operator=(const Iterator&); 1218 }; 1219 1220 /* \} */ 1221 1222 } 1223 } 1224 1225 #endif 1226