c55d8c4833dc87e697439f9d401b8982d9f279da
[platform/upstream/flac.git] / include / FLAC++ / metadata.h
1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #ifndef FLACPP__METADATA_H
21 #define FLACPP__METADATA_H
22
23 #include "FLAC/metadata.h"
24
25 // ===============================================================
26 //
27 //  Full documentation for the metadata interface can be found
28 //  in the C layer in include/FLAC/metadata.h
29 //
30 // ===============================================================
31
32 /** \file include/FLAC++/metadata.h
33  *
34  *  \brief
35  *  This module provides classes for creating and manipulating FLAC
36  *  metadata blocks in memory, and three progressively more powerful
37  *  interfaces for traversing and editing metadata in FLAC files.
38  *
39  *  See the detailed documentation for each interface in the
40  *  \link flacpp_metadata metadata \endlink module.
41  */
42
43 /** \defgroup flacpp_metadata FLAC++/metadata.h: metadata interfaces
44  *  \ingroup flacpp
45  *
46  *  \brief
47  *  This module provides classes for creating and manipulating FLAC
48  *  metadata blocks in memory, and three progressively more powerful
49  *  interfaces for traversing and editing metadata in FLAC files.
50  *
51  *  The behavior closely mimics the C layer interface; be sure to read
52  *  the detailed description of the
53  *  \link flac_metadata C metadata module \endlink.
54  */
55
56
57 namespace FLAC {
58         namespace Metadata {
59
60                 // ============================================================
61                 //
62                 //  Metadata objects
63                 //
64                 // ============================================================
65
66                 /** \defgroup flacpp_metadata_object FLAC++/metadata.h: metadata object classes
67                  *  \ingroup flacpp_metadata
68                  *
69                  * This module contains classes representing FLAC metadata
70                  * blocks in memory.
71                  *
72                  * The behavior closely mimics the C layer interface; be
73                  * sure to read the detailed description of the
74                  * \link flac_metadata_object C metadata object module \endlink.
75                  *
76                  * Any time a metadata object is constructed or assigned, you
77                  * should check is_valid() to make sure the underlying
78                  * ::FLAC__StreamMetadata object was able to be created.
79                  *
80                  * \warning
81                  * When the get_*() methods of any metadata object method
82                  * return you a const pointer, DO NOT disobey and write into it.
83                  * Always use the set_*() methods.
84                  *
85                  * \{
86                  */
87
88                 /** Base class for all metadata block types.
89                  */
90                 class Prototype {
91                 protected:
92                         //@{
93                         /** Constructs a copy of the given object.  This form
94                          *  always performs a deep copy.
95                          */
96                         Prototype(const Prototype &);
97                         Prototype(const ::FLAC__StreamMetadata &);
98                         Prototype(const ::FLAC__StreamMetadata *);
99                         //@}
100
101                         /** Constructs an object with copy control.  When \a copy
102                          *  is \c true, behaves identically to
103                          *  FLAC::Metadata::Prototype::Prototype(const ::FLAC__StreamMetadata *object).
104                          *  When \a copy is \c false, the instance takes ownership of
105                          *  the pointer and the ::FLAC__StreamMetadata object will
106                          *  be freed by the destructor.
107                          *
108                          *  \assert
109                          *    \code object != NULL \endcode
110                          */
111                         Prototype(::FLAC__StreamMetadata *object, bool copy);
112
113                         //@{
114                         /** Assign from another object.  Always performs a deep copy. */
115                         void operator=(const Prototype &);
116                         void operator=(const ::FLAC__StreamMetadata &);
117                         void operator=(const ::FLAC__StreamMetadata *);
118                         //@}
119
120                         /** Deletes the underlying ::FLAC__StreamMetadata object.
121                          */
122                         virtual void clear();
123
124                         ::FLAC__StreamMetadata *object_;
125                 public:
126                         /** Deletes the underlying ::FLAC__StreamMetadata object.
127                          */
128                         virtual ~Prototype();
129
130                         //@{
131                         /** Check for equality, performing a deep compare by following pointers. */
132                         inline bool operator==(const Prototype &) const;
133                         inline bool operator==(const ::FLAC__StreamMetadata &) const;
134                         inline bool operator==(const ::FLAC__StreamMetadata *) const;
135                         //@}
136
137                         //@{
138                         /** Check for inequality, performing a deep compare by following pointers. */
139                         inline bool operator!=(const Prototype &) const;
140                         inline bool operator!=(const ::FLAC__StreamMetadata &) const;
141                         inline bool operator!=(const ::FLAC__StreamMetadata *) const;
142                         //@}
143
144                         friend class SimpleIterator;
145                         friend class Iterator;
146
147                         /** Returns \c true if the object was correctly constructed
148                          *  (i.e. the underlying ::FLAC__StreamMetadata object was
149                          *  properly allocated), else \c false.
150                          */
151                         inline bool is_valid() const;
152
153                         /** Returns \c true if this block is the last block in a
154                          *  stream, else \c false.
155                          *
156                          * \assert
157                          *   \code is_valid() \endcode
158                          */
159                         bool get_is_last() const;
160
161                         /** Returns the type of the block.
162                          *
163                          * \assert
164                          *   \code is_valid() \endcode
165                          */
166                         ::FLAC__MetadataType get_type() const;
167
168                         /** Returns the stream length of the metadata block.
169                          *
170                          * \note
171                          *   The length does not include the metadata block header,
172                          *   per spec.
173                          *
174                          * \assert
175                          *   \code is_valid() \endcode
176                          */
177                         unsigned get_length() const;
178
179                         /** Sets the "is_last" flag for the block.  When using the iterators
180                          *  it is not necessary to set this flag; they will do it for you.
181                          *
182                          * \assert
183                          *   \code is_valid() \endcode
184                          */
185                         void set_is_last(bool);
186                 private:
187                         /** Private and undefined so you can't use it. */
188                         Prototype();
189
190                         // These are used only by Iterator
191                         bool is_reference_;
192                         inline void set_reference(bool x) { is_reference_ = x; }
193                 };
194
195                 inline bool Prototype::operator==(const Prototype &object) const
196                 { return (bool)::FLAC__metadata_object_is_equal(object_, object.object_); }
197
198                 inline bool Prototype::operator==(const ::FLAC__StreamMetadata &object) const
199                 { return (bool)::FLAC__metadata_object_is_equal(object_, &object); }
200
201                 inline bool Prototype::operator==(const ::FLAC__StreamMetadata *object) const
202                 { return (bool)::FLAC__metadata_object_is_equal(object_, object); }
203
204                 inline bool Prototype::operator!=(const Prototype &object) const
205                 { return !operator==(object); }
206
207                 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata &object) const
208                 { return !operator==(object); }
209
210                 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata *object) const
211                 { return !operator==(object); }
212
213                 inline bool Prototype::is_valid() const
214                 { return 0 != object_; }
215
216                 /** Create a deep copy of an object and return it. */
217                 Prototype *clone(const Prototype *);
218
219
220                 /** STREAMINFO metadata block.
221                  *  See <A HREF="../format.html#metadata_block_streaminfo">format specification</A>.
222                  */
223                 class StreamInfo : public Prototype {
224                 public:
225                         StreamInfo();
226
227                         //@{
228                         /** Constructs a copy of the given object.  This form
229                          *  always performs a deep copy.
230                          */
231                         inline StreamInfo(const StreamInfo &object): Prototype(object) { }
232                         inline StreamInfo(const ::FLAC__StreamMetadata &object): Prototype(object) { }
233                         inline StreamInfo(const ::FLAC__StreamMetadata *object): Prototype(object) { }
234                         //@}
235
236                         /** Constructs an object with copy control.  See
237                          *  Prototype(::FLAC__StreamMetadata *object, bool copy).
238                          */
239                         inline StreamInfo(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
240
241                         ~StreamInfo();
242
243                         //@{
244                         /** Assign from another object.  Always performs a deep copy. */
245                         inline void operator=(const StreamInfo &object) { Prototype::operator=(object); }
246                         inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
247                         inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
248                         //@}
249
250                         //@{
251                         /** Check for equality, performing a deep compare by following pointers. */
252                         inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); }
253                         inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
254                         inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
255                         //@}
256
257                         //@{
258                         /** Check for inequality, performing a deep compare by following pointers. */
259                         inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); }
260                         inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
261                         inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
262                         //@}
263
264                         //@{
265                         /** See <A HREF="../format.html#metadata_block_streaminfo">format specification</A>. */
266                         unsigned get_min_blocksize() const;
267                         unsigned get_max_blocksize() const;
268                         unsigned get_min_framesize() const;
269                         unsigned get_max_framesize() const;
270                         unsigned get_sample_rate() const;
271                         unsigned get_channels() const;
272                         unsigned get_bits_per_sample() const;
273                         FLAC__uint64 get_total_samples() const;
274                         const FLAC__byte *get_md5sum() const;
275
276                         void set_min_blocksize(unsigned value);
277                         void set_max_blocksize(unsigned value);
278                         void set_min_framesize(unsigned value);
279                         void set_max_framesize(unsigned value);
280                         void set_sample_rate(unsigned value);
281                         void set_channels(unsigned value);
282                         void set_bits_per_sample(unsigned value);
283                         void set_total_samples(FLAC__uint64 value);
284                         void set_md5sum(const FLAC__byte value[16]);
285                         //@}
286                 };
287
288                 /** PADDING metadata block.
289                  *  See <A HREF="../format.html#metadata_block_padding">format specification</A>.
290                  */
291                 class Padding : public Prototype {
292                 public:
293                         Padding();
294
295                         //@{
296                         /** Constructs a copy of the given object.  This form
297                          *  always performs a deep copy.
298                          */
299                         inline Padding(const Padding &object): Prototype(object) { }
300                         inline Padding(const ::FLAC__StreamMetadata &object): Prototype(object) { }
301                         inline Padding(const ::FLAC__StreamMetadata *object): Prototype(object) { }
302                         //@}
303
304                         /** Constructs an object with copy control.  See
305                          *  Prototype(::FLAC__StreamMetadata *object, bool copy).
306                          */
307                         inline Padding(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
308
309                         ~Padding();
310
311                         //@{
312                         /** Assign from another object.  Always performs a deep copy. */
313                         inline void operator=(const Padding &object) { Prototype::operator=(object); }
314                         inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
315                         inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
316                         //@}
317
318                         //@{
319                         /** Check for equality, performing a deep compare by following pointers. */
320                         inline bool operator==(const Padding &object) const { return Prototype::operator==(object); }
321                         inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
322                         inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
323                         //@}
324
325                         //@{
326                         /** Check for inequality, performing a deep compare by following pointers. */
327                         inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); }
328                         inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
329                         inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
330                         //@}
331
332                         void set_length(unsigned length);
333                 };
334
335                 /** APPLICATION metadata block.
336                  *  See <A HREF="../format.html#metadata_block_application">format specification</A>.
337                  */
338                 class Application : public Prototype {
339                 public:
340                         Application();
341                         //
342                         //@{
343                         /** Constructs a copy of the given object.  This form
344                          *  always performs a deep copy.
345                          */
346                         inline Application(const Application &object): Prototype(object) { }
347                         inline Application(const ::FLAC__StreamMetadata &object): Prototype(object) { }
348                         inline Application(const ::FLAC__StreamMetadata *object): Prototype(object) { }
349                         //@}
350
351                         /** Constructs an object with copy control.  See
352                          *  Prototype(::FLAC__StreamMetadata *object, bool copy).
353                          */
354                         inline Application(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
355
356                         ~Application();
357
358                         //@{
359                         /** Assign from another object.  Always performs a deep copy. */
360                         inline void operator=(const Application &object) { Prototype::operator=(object); }
361                         inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
362                         inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
363                         //@}
364
365                         //@{
366                         /** Check for equality, performing a deep compare by following pointers. */
367                         inline bool operator==(const Application &object) const { return Prototype::operator==(object); }
368                         inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
369                         inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
370                         //@}
371
372                         //@{
373                         /** Check for inequality, performing a deep compare by following pointers. */
374                         inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); }
375                         inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
376                         inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
377                         //@}
378
379                         const FLAC__byte *get_id() const;
380                         const FLAC__byte *get_data() const;
381
382                         void set_id(const FLAC__byte value[4]);
383                         //! This form always copies \a data
384                         bool set_data(const FLAC__byte *data, unsigned length);
385                         bool set_data(FLAC__byte *data, unsigned length, bool copy);
386                 };
387
388                 /** SEEKTABLE metadata block.
389                  *  See <A HREF="../format.html#metadata_block_seektable">format specification</A>.
390                  */
391                 class SeekTable : public Prototype {
392                 public:
393                         SeekTable();
394
395                         //@{
396                         /** Constructs a copy of the given object.  This form
397                          *  always performs a deep copy.
398                          */
399                         inline SeekTable(const SeekTable &object): Prototype(object) { }
400                         inline SeekTable(const ::FLAC__StreamMetadata &object): Prototype(object) { }
401                         inline SeekTable(const ::FLAC__StreamMetadata *object): Prototype(object) { }
402                         //@}
403
404                         /** Constructs an object with copy control.  See
405                          *  Prototype(::FLAC__StreamMetadata *object, bool copy).
406                          */
407                         inline SeekTable(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
408
409                         ~SeekTable();
410
411                         //@{
412                         /** Assign from another object.  Always performs a deep copy. */
413                         inline void operator=(const SeekTable &object) { Prototype::operator=(object); }
414                         inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
415                         inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
416                         //@}
417
418                         //@{
419                         /** Check for equality, performing a deep compare by following pointers. */
420                         inline bool operator==(const SeekTable &object) const { return Prototype::operator==(object); }
421                         inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
422                         inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
423                         //@}
424
425                         //@{
426                         /** Check for inequality, performing a deep compare by following pointers. */
427                         inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); }
428                         inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
429                         inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
430                         //@}
431
432                         unsigned get_num_points() const;
433                         ::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const;
434
435                         //! See FLAC__metadata_object_seektable_set_point()
436                         void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
437
438                         //! See FLAC__metadata_object_seektable_insert_point()
439                         bool insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
440
441                         //! See FLAC__metadata_object_seektable_delete_point()
442                         bool delete_point(unsigned index);
443
444                         //! See FLAC__metadata_object_seektable_is_legal()
445                         bool is_legal() const;
446                 };
447
448                 /** VORBIS_COMMENT metadata block.
449                  *  See <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>.
450                  */
451                 class VorbisComment : public Prototype {
452                 public:
453                         /** Convenience class for encapsulating Vorbis comment
454                          *  entries.  An entry is a vendor string or a comment
455                          *  field.  In the case of a vendor string, the field
456                          *  name is undefined; only the field value is relevant.
457                          *
458                          *  A \a field as used in the methods refers to an
459                          *  entire 'NAME=VALUE' string; the string is not null-
460                          *  terminated and a length field is required since the
461                          *  string may contain embedded nulls.
462                          *
463                          *  A \a field_name is what is on the left side of the
464                          *  first '=' in the \a field.  By definition it is ASCII
465                          *  and so is null-terminated and does not require a
466                          *  length to describe it.  \a field_name is undefined
467                          *  for a vendor string entry.
468                          *
469                          *  A \a field_value is what is on the right side of the
470                          *  first '=' in the \a field.  By definition, this may
471                          *  contain embedded nulls and so a \a field_value_length
472                          *  is requires to describe it.
473                          *
474                          *  Always check is_valid() after the constructor or operator=
475                          *  to make sure memory was properly allocated.
476                          */
477                         class Entry {
478                         public:
479                                 Entry();
480                                 Entry(const char *field, unsigned field_length);
481                                 Entry(const char *field_name, const char *field_value, unsigned field_value_length);
482                                 Entry(const Entry &entry);
483                                 void operator=(const Entry &entry);
484
485                                 virtual ~Entry();
486
487                                 virtual bool is_valid() const;
488
489                                 unsigned get_field_length() const;
490                                 unsigned get_field_name_length() const;
491                                 unsigned get_field_value_length() const;
492
493                                 ::FLAC__StreamMetadata_VorbisComment_Entry get_entry() const;
494                                 const char *get_field() const;
495                                 const char *get_field_name() const;
496                                 const char *get_field_value() const;
497
498                                 bool set_field(const char *field, unsigned field_length);
499                                 bool set_field_name(const char *field_name);
500                                 bool set_field_value(const char *field_value, unsigned field_value_length);
501                         protected:
502                                 bool is_valid_;
503                                 ::FLAC__StreamMetadata_VorbisComment_Entry entry_;
504                                 char *field_name_;
505                                 unsigned field_name_length_;
506                                 char *field_value_;
507                                 unsigned field_value_length_;
508                         private:
509                                 void zero();
510                                 void clear();
511                                 void clear_entry();
512                                 void clear_field_name();
513                                 void clear_field_value();
514                                 void construct(const char *field, unsigned field_length);
515                                 void construct(const char *field_name, const char *field_value, unsigned field_value_length);
516                                 void compose_field();
517                                 void parse_field();
518                         };
519
520                         VorbisComment();
521
522                         //@{
523                         /** Constructs a copy of the given object.  This form
524                          *  always performs a deep copy.
525                          */
526                         inline VorbisComment(const VorbisComment &object): Prototype(object) { }
527                         inline VorbisComment(const ::FLAC__StreamMetadata &object): Prototype(object) { }
528                         inline VorbisComment(const ::FLAC__StreamMetadata *object): Prototype(object) { }
529                         //@}
530
531                         /** Constructs an object with copy control.  See
532                          *  Prototype(::FLAC__StreamMetadata *object, bool copy).
533                          */
534                         inline VorbisComment(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
535
536                         ~VorbisComment();
537
538                         //@{
539                         /** Assign from another object.  Always performs a deep copy. */
540                         inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
541                         inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
542                         inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
543                         //@}
544
545                         //@{
546                         /** Check for equality, performing a deep compare by following pointers. */
547                         inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); }
548                         inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
549                         inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
550                         //@}
551
552                         //@{
553                         /** Check for inequality, performing a deep compare by following pointers. */
554                         inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); }
555                         inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
556                         inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
557                         //@}
558
559                         unsigned get_num_comments() const;
560                         Entry get_vendor_string() const; // only the Entry's field name should be used
561                         Entry get_comment(unsigned index) const;
562
563                         //! See FLAC__metadata_object_vorbiscomment_set_vendor_string()
564                         //! \note Only the Entry's field name will be used.
565                         bool set_vendor_string(const Entry &entry); // only the Entry's field name will be used
566
567                         //! See FLAC__metadata_object_vorbiscomment_set_comment()
568                         bool set_comment(unsigned index, const Entry &entry);
569
570                         //! See FLAC__metadata_object_vorbiscomment_insert_comment()
571                         bool insert_comment(unsigned index, const Entry &entry);
572
573                         //! See FLAC__metadata_object_vorbiscomment_delete_comment()
574                         bool delete_comment(unsigned index);
575                 };
576
577                 /* \} */
578
579
580                 /** \defgroup flacpp_metadata_level0 FLAC++/metadata.h: metadata level 0 interface
581                  *  \ingroup flacpp_metadata
582                  *
583                  *  \brief
584                  *  Level 0 metadata iterator.
585                  *
586                  *  See the \link flac_metadata_level0 C layer equivalent \endlink
587                  *  for more.
588                  *
589                  * \{
590                  */
591
592                 //! See FLAC__metadata_get_streaminfo().
593                 bool get_streaminfo(const char *filename, StreamInfo &streaminfo);
594
595                 /* \} */
596
597
598                 /** \defgroup flacpp_metadata_level1 FLAC++/metadata.h: metadata level 1 interface
599                  *  \ingroup flacpp_metadata
600                  *
601                  *  \brief
602                  *  Level 1 metadata iterator.
603                  *
604                  *  The flow through the iterator in the C++ layer is similar
605                  *  to the C layer:
606                  *    - Create a SimpleIterator instance
607                  *    - Check SimpleIterator::is_valid()
608                  *    - Call SimpleIterator::init() and check the return
609                  *    - Traverse and/or edit.  Edits are written to file
610                  *      immediately.
611                  *    - Destroy the SimpleIterator instance
612                  *
613                  *  The ownership of pointers in the C++ layer follows that in
614                  *  the C layer, i.e.
615                  *    - The objects returned by get_block() are yours to
616                  *      modify, but changes are not reflected in the FLAC file
617                  *      until you call set_block().  The objects are also
618                  *      yours to delete; they are not automatically deleted
619                  *      when passed to set_block() or insert_block_after().
620                  *
621                  *  See the \link flac_metadata_level1 C layer equivalent \endlink
622                  *  for more.
623                  *
624                  * \{
625                  */
626
627                 /** This class is a wrapper around the FLAC__metadata_simple_iterator
628                  *  structures and methods; see ::FLAC__Metadata_SimpleIterator.
629                  */
630                 class SimpleIterator {
631                 public:
632                         class Status {
633                         public:
634                                 inline Status(::FLAC__Metadata_SimpleIteratorStatus status): status_(status) { }
635                                 inline operator ::FLAC__Metadata_SimpleIteratorStatus() const { return status_; }
636                                 inline const char *as_cstring() const { return ::FLAC__Metadata_SimpleIteratorStatusString[status_]; }
637                         protected:
638                                 ::FLAC__Metadata_SimpleIteratorStatus status_;
639                         };
640
641                         SimpleIterator();
642                         virtual ~SimpleIterator();
643
644                         bool init(const char *filename, bool read_only, bool preserve_file_stats);
645
646                         bool is_valid() const;
647                         Status status();
648                         bool is_writable() const;
649
650                         bool next();
651                         bool prev();
652
653                         ::FLAC__MetadataType get_block_type() const;
654                         Prototype *get_block();
655                         bool set_block(Prototype *block, bool use_padding = true);
656                         bool insert_block_after(Prototype *block, bool use_padding = true);
657                         bool delete_block(bool use_padding = true);
658
659                 protected:
660                         ::FLAC__Metadata_SimpleIterator *iterator_;
661                         void clear();
662                 };
663
664                 /* \} */
665
666
667                 /** \defgroup flacpp_metadata_level2 FLAC++/metadata.h: metadata level 2 interface
668                  *  \ingroup flacpp_metadata
669                  *
670                  *  \brief
671                  *  Level 2 metadata iterator.
672                  *
673                  *  The flow through the iterator in the C++ layer is similar
674                  *  to the C layer:
675                  *    - Create a Chain instance
676                  *    - Check Chain::is_valid()
677                  *    - Call Chain::read() and check the return
678                  *    - Traverse and/or edit with an Iterator or with
679                  *      Chain::merge_padding() or Chain::sort_padding()
680                  *    - Write changes back to FLAC file with Chain::write()
681                  *    - Destroy the Chain instance
682                  *
683                  *  The ownership of pointers in the C++ layer follows that in
684                  *  the C layer, i.e.
685                  *    - The objects returned by Iterator::get_block() are
686                  *      owned by the iterator and should not be deleted.
687                  *      When you modify the block, you are directly editing
688                  *      what's in the chain and do not need to call
689                  *      Iterator::set_block().  However the changes will not
690                  *      be reflected in the FLAC file until the chain is
691                  *      written with Chain::write().
692                  *    - When you pass an object to Iterator::set_block(),
693                  *      Iterator::insert_block_before(), or
694                  *      Iterator::insert_block_after(), the iterator takes
695                  *      ownership of the block and it will be deleted with the
696                  *      chain.
697                  *
698                  *  See the \link flac_metadata_level2 C layer equivalent \endlink
699                  *  for more.
700                  *
701                  * \{
702                  */
703
704                 /** This class is a wrapper around the FLAC__metadata_chain
705                  *  structures and methods; see ::FLAC__Metadata_Chain.
706                  */
707                 class Chain {
708                 public:
709                         class Status {
710                         public:
711                                 inline Status(::FLAC__Metadata_ChainStatus status): status_(status) { }
712                                 inline operator ::FLAC__Metadata_ChainStatus() const { return status_; }
713                                 inline const char *as_cstring() const { return ::FLAC__Metadata_ChainStatusString[status_]; }
714                         protected:
715                                 ::FLAC__Metadata_ChainStatus status_;
716                         };
717
718                         Chain();
719                         virtual ~Chain();
720
721                         friend class Iterator;
722
723                         bool is_valid() const;
724                         Status status();
725
726                         bool read(const char *filename);
727                         bool write(bool use_padding = true, bool preserve_file_stats = false);
728
729                         void merge_padding();
730                         void sort_padding();
731
732                 protected:
733                         ::FLAC__Metadata_Chain *chain_;
734                         virtual void clear();
735                 };
736
737                 /** This class is a wrapper around the FLAC__metadata_iterator
738                  *  structures and methods; see ::FLAC__Metadata_Iterator.
739                  */
740                 class Iterator {
741                 public:
742                         Iterator();
743                         virtual ~Iterator();
744
745                         bool is_valid() const;
746
747                         void init(Chain &chain);
748
749                         bool next();
750                         bool prev();
751
752                         ::FLAC__MetadataType get_block_type() const;
753                         Prototype *get_block();
754                         bool set_block(Prototype *block);
755                         bool delete_block(bool replace_with_padding);
756                         bool insert_block_before(Prototype *block);
757                         bool insert_block_after(Prototype *block);
758
759                 protected:
760                         ::FLAC__Metadata_Iterator *iterator_;
761                         virtual void clear();
762                 };
763
764                 /* \} */
765
766         };
767 };
768
769 #endif