metadata.h 36.6 KB
Newer Older
Josh Coalson's avatar
Josh Coalson committed
1
/* libFLAC++ - Free Lossless Audio Codec library
Josh Coalson's avatar
Josh Coalson committed
2
 * Copyright (C) 2002,2003,2004  Josh Coalson
Josh Coalson's avatar
Josh Coalson committed
3
 *
4
5
6
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
Josh Coalson's avatar
Josh Coalson committed
7
 *
8
9
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
Josh Coalson's avatar
Josh Coalson committed
10
 *
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of the Xiph.org Foundation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Josh Coalson's avatar
Josh Coalson committed
30
31
32
33
34
 */

#ifndef FLACPP__METADATA_H
#define FLACPP__METADATA_H

35
36
#include "export.h"

Josh Coalson's avatar
Josh Coalson committed
37
38
#include "FLAC/metadata.h"

Josh Coalson's avatar
Josh Coalson committed
39
40
41
42
43
44
45
// ===============================================================
//
//  Full documentation for the metadata interface can be found
//  in the C layer in include/FLAC/metadata.h
//
// ===============================================================

Josh Coalson's avatar
Josh Coalson committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/** \file include/FLAC++/metadata.h
 *
 *  \brief
 *  This module provides classes for creating and manipulating FLAC
 *  metadata blocks in memory, and three progressively more powerful
 *  interfaces for traversing and editing metadata in FLAC files.
 *
 *  See the detailed documentation for each interface in the
 *  \link flacpp_metadata metadata \endlink module.
 */

/** \defgroup flacpp_metadata FLAC++/metadata.h: metadata interfaces
 *  \ingroup flacpp
 *
 *  \brief
 *  This module provides classes for creating and manipulating FLAC
 *  metadata blocks in memory, and three progressively more powerful
 *  interfaces for traversing and editing metadata in FLAC files.
 *
 *  The behavior closely mimics the C layer interface; be sure to read
 *  the detailed description of the
 *  \link flac_metadata C metadata module \endlink.
 */

Josh Coalson's avatar
Josh Coalson committed
70

Josh Coalson's avatar
Josh Coalson committed
71
72
73
namespace FLAC {
	namespace Metadata {

Josh Coalson's avatar
Josh Coalson committed
74
75
76
77
78
79
		// ============================================================
		//
		//  Metadata objects
		//
		// ============================================================

Josh Coalson's avatar
Josh Coalson committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
		/** \defgroup flacpp_metadata_object FLAC++/metadata.h: metadata object classes
		 *  \ingroup flacpp_metadata
		 *
		 * This module contains classes representing FLAC metadata
		 * blocks in memory.
		 *
		 * The behavior closely mimics the C layer interface; be
		 * sure to read the detailed description of the
		 * \link flac_metadata_object C metadata object module \endlink.
		 *
		 * Any time a metadata object is constructed or assigned, you
		 * should check is_valid() to make sure the underlying
		 * ::FLAC__StreamMetadata object was able to be created.
		 *
		 * \warning
		 * When the get_*() methods of any metadata object method
		 * return you a const pointer, DO NOT disobey and write into it.
		 * Always use the set_*() methods.
		 *
		 * \{
		 */

		/** Base class for all metadata block types.
		 */
104
		class FLACPP_API Prototype {
Josh Coalson's avatar
Josh Coalson committed
105
		protected:
Josh Coalson's avatar
Josh Coalson committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
			Prototype(const Prototype &);
			Prototype(const ::FLAC__StreamMetadata &);
			Prototype(const ::FLAC__StreamMetadata *);
			//@}

			/** Constructs an object with copy control.  When \a copy
			 *  is \c true, behaves identically to
			 *  FLAC::Metadata::Prototype::Prototype(const ::FLAC__StreamMetadata *object).
			 *  When \a copy is \c false, the instance takes ownership of
			 *  the pointer and the ::FLAC__StreamMetadata object will
			 *  be freed by the destructor.
			 *
			 *  \assert
			 *    \code object != NULL \endcode
			 */
Josh Coalson's avatar
Josh Coalson committed
125
			Prototype(::FLAC__StreamMetadata *object, bool copy);
Josh Coalson's avatar
Josh Coalson committed
126

Josh Coalson's avatar
Josh Coalson committed
127
128
			//@{
			/** Assign from another object.  Always performs a deep copy. */
Josh Coalson's avatar
Josh Coalson committed
129
			void operator=(const Prototype &);
Josh Coalson's avatar
Josh Coalson committed
130
131
132
			void operator=(const ::FLAC__StreamMetadata &);
			void operator=(const ::FLAC__StreamMetadata *);
			//@}
133

Josh Coalson's avatar
Josh Coalson committed
134
135
			/** Deletes the underlying ::FLAC__StreamMetadata object.
			 */
Josh Coalson's avatar
Josh Coalson committed
136
137
			virtual void clear();

138
			::FLAC__StreamMetadata *object_;
Josh Coalson's avatar
Josh Coalson committed
139
		public:
Josh Coalson's avatar
Josh Coalson committed
140
141
			/** Deletes the underlying ::FLAC__StreamMetadata object.
			 */
142
143
			virtual ~Prototype();

Josh Coalson's avatar
Josh Coalson committed
144
145
			//@{
			/** Check for equality, performing a deep compare by following pointers. */
146
147
148
			inline bool operator==(const Prototype &) const;
			inline bool operator==(const ::FLAC__StreamMetadata &) const;
			inline bool operator==(const ::FLAC__StreamMetadata *) const;
Josh Coalson's avatar
Josh Coalson committed
149
150
151
152
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
153
154
155
			inline bool operator!=(const Prototype &) const;
			inline bool operator!=(const ::FLAC__StreamMetadata &) const;
			inline bool operator!=(const ::FLAC__StreamMetadata *) const;
Josh Coalson's avatar
Josh Coalson committed
156
			//@}
157

Josh Coalson's avatar
Josh Coalson committed
158
159
160
			friend class SimpleIterator;
			friend class Iterator;

Josh Coalson's avatar
Josh Coalson committed
161
162
163
164
			/** Returns \c true if the object was correctly constructed
			 *  (i.e. the underlying ::FLAC__StreamMetadata object was
			 *  properly allocated), else \c false.
			 */
165
			inline bool is_valid() const;
Josh Coalson's avatar
Josh Coalson committed
166

Josh Coalson's avatar
Josh Coalson committed
167
168
169
170
171
172
			/** Returns \c true if this block is the last block in a
			 *  stream, else \c false.
			 *
			 * \assert
			 *   \code is_valid() \endcode
			 */
Josh Coalson's avatar
Josh Coalson committed
173
			bool get_is_last() const;
174

Josh Coalson's avatar
Josh Coalson committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
			/** Returns the type of the block.
			 *
			 * \assert
			 *   \code is_valid() \endcode
			 */
			::FLAC__MetadataType get_type() const;

			/** Returns the stream length of the metadata block.
			 *
			 * \note
			 *   The length does not include the metadata block header,
			 *   per spec.
			 *
			 * \assert
			 *   \code is_valid() \endcode
			 */
			unsigned get_length() const;

			/** Sets the "is_last" flag for the block.  When using the iterators
			 *  it is not necessary to set this flag; they will do it for you.
			 *
			 * \assert
			 *   \code is_valid() \endcode
			 */
199
			void set_is_last(bool);
200
201
202
203
204
205
206
207
208

			/** Returns a pointer to the underlying ::FLAC__StreamMetadata
			 *  object.  This can be useful for plugging any holes between
			 *  the C++ and C interfaces.
			 *
			 * \assert
			 *   \code is_valid() \endcode
			 */
			inline operator const ::FLAC__StreamMetadata *() const;
Josh Coalson's avatar
Josh Coalson committed
209
		private:
Josh Coalson's avatar
Josh Coalson committed
210
211
			/** Private and undefined so you can't use it. */
			Prototype();
Josh Coalson's avatar
Josh Coalson committed
212
213
214
215

			// These are used only by Iterator
			bool is_reference_;
			inline void set_reference(bool x) { is_reference_ = x; }
Josh Coalson's avatar
Josh Coalson committed
216
217
		};

218
219
220
221
222
#ifdef _MSC_VER
// warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
#pragma warning ( disable : 4800 )
#endif

Josh Coalson's avatar
Josh Coalson committed
223
		inline bool Prototype::operator==(const Prototype &object) const
224
		{ return (bool)::FLAC__metadata_object_is_equal(object_, object.object_); }
225

Josh Coalson's avatar
Josh Coalson committed
226
		inline bool Prototype::operator==(const ::FLAC__StreamMetadata &object) const
227
		{ return (bool)::FLAC__metadata_object_is_equal(object_, &object); }
228

Josh Coalson's avatar
Josh Coalson committed
229
		inline bool Prototype::operator==(const ::FLAC__StreamMetadata *object) const
230
		{ return (bool)::FLAC__metadata_object_is_equal(object_, object); }
231

232
233
234
235
236
#ifdef _MSC_VER
// @@@ how to re-enable?  the following doesn't work
// #pragma warning ( enable : 4800 )
#endif

Josh Coalson's avatar
Josh Coalson committed
237
		inline bool Prototype::operator!=(const Prototype &object) const
238
239
		{ return !operator==(object); }

Josh Coalson's avatar
Josh Coalson committed
240
		inline bool Prototype::operator!=(const ::FLAC__StreamMetadata &object) const
241
242
		{ return !operator==(object); }

Josh Coalson's avatar
Josh Coalson committed
243
		inline bool Prototype::operator!=(const ::FLAC__StreamMetadata *object) const
244
245
246
247
248
		{ return !operator==(object); }

		inline bool Prototype::is_valid() const
		{ return 0 != object_; }

249
250
251
		inline Prototype::operator const ::FLAC__StreamMetadata *() const
		{ return object_; }

Josh Coalson's avatar
Josh Coalson committed
252
		/** Create a deep copy of an object and return it. */
253
		FLACPP_API Prototype *clone(const Prototype *);
254

Josh Coalson's avatar
Josh Coalson committed
255
256

		/** STREAMINFO metadata block.
Josh Coalson's avatar
Josh Coalson committed
257
		 *  See <A HREF="../format.html#metadata_block_streaminfo">format specification</A>.
Josh Coalson's avatar
Josh Coalson committed
258
		 */
259
		class FLACPP_API StreamInfo : public Prototype {
Josh Coalson's avatar
Josh Coalson committed
260
261
		public:
			StreamInfo();
Josh Coalson's avatar
Josh Coalson committed
262
263
264
265
266

			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
267
268
269
			inline StreamInfo(const StreamInfo &object): Prototype(object) { }
			inline StreamInfo(const ::FLAC__StreamMetadata &object): Prototype(object) { }
			inline StreamInfo(const ::FLAC__StreamMetadata *object): Prototype(object) { }
Josh Coalson's avatar
Josh Coalson committed
270
271
272
273
274
			//@}

			/** Constructs an object with copy control.  See
			 *  Prototype(::FLAC__StreamMetadata *object, bool copy).
			 */
275
			inline StreamInfo(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalson's avatar
Josh Coalson committed
276

Josh Coalson's avatar
Josh Coalson committed
277
278
			~StreamInfo();

Josh Coalson's avatar
Josh Coalson committed
279
280
			//@{
			/** Assign from another object.  Always performs a deep copy. */
Josh Coalson's avatar
Josh Coalson committed
281
			inline void operator=(const StreamInfo &object) { Prototype::operator=(object); }
282
283
			inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalson's avatar
Josh Coalson committed
284
			//@}
Josh Coalson's avatar
Josh Coalson committed
285

Josh Coalson's avatar
Josh Coalson committed
286
287
			//@{
			/** Check for equality, performing a deep compare by following pointers. */
288
			inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); }
289
290
			inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson's avatar
Josh Coalson committed
291
292
293
294
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
295
			inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); }
296
297
			inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson's avatar
Josh Coalson committed
298
			//@}
299

Josh Coalson's avatar
Josh Coalson committed
300
301
			//@{
			/** See <A HREF="../format.html#metadata_block_streaminfo">format specification</A>. */
Josh Coalson's avatar
Josh Coalson committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
			unsigned get_min_blocksize() const;
			unsigned get_max_blocksize() const;
			unsigned get_min_framesize() const;
			unsigned get_max_framesize() const;
			unsigned get_sample_rate() const;
			unsigned get_channels() const;
			unsigned get_bits_per_sample() const;
			FLAC__uint64 get_total_samples() const;
			const FLAC__byte *get_md5sum() const;

			void set_min_blocksize(unsigned value);
			void set_max_blocksize(unsigned value);
			void set_min_framesize(unsigned value);
			void set_max_framesize(unsigned value);
			void set_sample_rate(unsigned value);
			void set_channels(unsigned value);
			void set_bits_per_sample(unsigned value);
			void set_total_samples(FLAC__uint64 value);
			void set_md5sum(const FLAC__byte value[16]);
Josh Coalson's avatar
Josh Coalson committed
321
			//@}
Josh Coalson's avatar
Josh Coalson committed
322
323
		};

Josh Coalson's avatar
Josh Coalson committed
324
325
		/** PADDING metadata block.
		 *  See <A HREF="../format.html#metadata_block_padding">format specification</A>.
Josh Coalson's avatar
Josh Coalson committed
326
		 */
327
		class FLACPP_API Padding : public Prototype {
Josh Coalson's avatar
Josh Coalson committed
328
329
		public:
			Padding();
Josh Coalson's avatar
Josh Coalson committed
330
331
332
333
334

			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
335
336
337
			inline Padding(const Padding &object): Prototype(object) { }
			inline Padding(const ::FLAC__StreamMetadata &object): Prototype(object) { }
			inline Padding(const ::FLAC__StreamMetadata *object): Prototype(object) { }
Josh Coalson's avatar
Josh Coalson committed
338
339
340
341
342
			//@}

			/** Constructs an object with copy control.  See
			 *  Prototype(::FLAC__StreamMetadata *object, bool copy).
			 */
343
			inline Padding(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalson's avatar
Josh Coalson committed
344

Josh Coalson's avatar
Josh Coalson committed
345
			~Padding();
Josh Coalson's avatar
Josh Coalson committed
346

Josh Coalson's avatar
Josh Coalson committed
347
348
			//@{
			/** Assign from another object.  Always performs a deep copy. */
Josh Coalson's avatar
Josh Coalson committed
349
			inline void operator=(const Padding &object) { Prototype::operator=(object); }
350
351
			inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalson's avatar
Josh Coalson committed
352
			//@}
353

Josh Coalson's avatar
Josh Coalson committed
354
355
			//@{
			/** Check for equality, performing a deep compare by following pointers. */
356
			inline bool operator==(const Padding &object) const { return Prototype::operator==(object); }
357
358
			inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson's avatar
Josh Coalson committed
359
360
361
362
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
363
			inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); }
364
365
			inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson's avatar
Josh Coalson committed
366
			//@}
367

368
			void set_length(unsigned length);
Josh Coalson's avatar
Josh Coalson committed
369
370
		};

Josh Coalson's avatar
Josh Coalson committed
371
372
		/** APPLICATION metadata block.
		 *  See <A HREF="../format.html#metadata_block_application">format specification</A>.
Josh Coalson's avatar
Josh Coalson committed
373
		 */
374
		class FLACPP_API Application : public Prototype {
Josh Coalson's avatar
Josh Coalson committed
375
376
		public:
			Application();
Josh Coalson's avatar
Josh Coalson committed
377
378
379
380
381
			//
			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
382
383
384
			inline Application(const Application &object): Prototype(object) { }
			inline Application(const ::FLAC__StreamMetadata &object): Prototype(object) { }
			inline Application(const ::FLAC__StreamMetadata *object): Prototype(object) { }
Josh Coalson's avatar
Josh Coalson committed
385
386
387
388
389
			//@}

			/** Constructs an object with copy control.  See
			 *  Prototype(::FLAC__StreamMetadata *object, bool copy).
			 */
390
			inline Application(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalson's avatar
Josh Coalson committed
391

Josh Coalson's avatar
Josh Coalson committed
392
393
			~Application();

Josh Coalson's avatar
Josh Coalson committed
394
395
			//@{
			/** Assign from another object.  Always performs a deep copy. */
Josh Coalson's avatar
Josh Coalson committed
396
			inline void operator=(const Application &object) { Prototype::operator=(object); }
397
398
			inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalson's avatar
Josh Coalson committed
399
			//@}
Josh Coalson's avatar
Josh Coalson committed
400

Josh Coalson's avatar
Josh Coalson committed
401
402
			//@{
			/** Check for equality, performing a deep compare by following pointers. */
403
			inline bool operator==(const Application &object) const { return Prototype::operator==(object); }
404
405
			inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson's avatar
Josh Coalson committed
406
407
408
409
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
410
			inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); }
411
412
			inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson's avatar
Josh Coalson committed
413
			//@}
414

Josh Coalson's avatar
Josh Coalson committed
415
416
417
			const FLAC__byte *get_id() const;
			const FLAC__byte *get_data() const;

418
			void set_id(const FLAC__byte value[4]);
Josh Coalson's avatar
Josh Coalson committed
419
420
			//! This form always copies \a data
			bool set_data(const FLAC__byte *data, unsigned length);
421
			bool set_data(FLAC__byte *data, unsigned length, bool copy);
Josh Coalson's avatar
Josh Coalson committed
422
423
		};

Josh Coalson's avatar
Josh Coalson committed
424
425
		/** SEEKTABLE metadata block.
		 *  See <A HREF="../format.html#metadata_block_seektable">format specification</A>.
Josh Coalson's avatar
Josh Coalson committed
426
		 */
427
		class FLACPP_API SeekTable : public Prototype {
Josh Coalson's avatar
Josh Coalson committed
428
429
		public:
			SeekTable();
Josh Coalson's avatar
Josh Coalson committed
430
431
432
433
434

			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
435
436
437
			inline SeekTable(const SeekTable &object): Prototype(object) { }
			inline SeekTable(const ::FLAC__StreamMetadata &object): Prototype(object) { }
			inline SeekTable(const ::FLAC__StreamMetadata *object): Prototype(object) { }
Josh Coalson's avatar
Josh Coalson committed
438
439
440
441
442
			//@}

			/** Constructs an object with copy control.  See
			 *  Prototype(::FLAC__StreamMetadata *object, bool copy).
			 */
443
			inline SeekTable(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalson's avatar
Josh Coalson committed
444

Josh Coalson's avatar
Josh Coalson committed
445
			~SeekTable();
Josh Coalson's avatar
Josh Coalson committed
446

Josh Coalson's avatar
Josh Coalson committed
447
448
			//@{
			/** Assign from another object.  Always performs a deep copy. */
Josh Coalson's avatar
Josh Coalson committed
449
			inline void operator=(const SeekTable &object) { Prototype::operator=(object); }
450
451
			inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalson's avatar
Josh Coalson committed
452
			//@}
453

Josh Coalson's avatar
Josh Coalson committed
454
455
			//@{
			/** Check for equality, performing a deep compare by following pointers. */
456
			inline bool operator==(const SeekTable &object) const { return Prototype::operator==(object); }
457
458
			inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson's avatar
Josh Coalson committed
459
460
461
462
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
463
			inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); }
464
465
			inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson's avatar
Josh Coalson committed
466
			//@}
467

468
			unsigned get_num_points() const;
469
			::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const;
470

Josh Coalson's avatar
Josh Coalson committed
471
			//! See FLAC__metadata_object_seektable_set_point()
472
			void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
Josh Coalson's avatar
Josh Coalson committed
473
474

			//! See FLAC__metadata_object_seektable_insert_point()
475
			bool insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
Josh Coalson's avatar
Josh Coalson committed
476
477

			//! See FLAC__metadata_object_seektable_delete_point()
478
			bool delete_point(unsigned index);
479

Josh Coalson's avatar
Josh Coalson committed
480
			//! See FLAC__metadata_object_seektable_is_legal()
481
			bool is_legal() const;
Josh Coalson's avatar
Josh Coalson committed
482
483
		};

Josh Coalson's avatar
Josh Coalson committed
484
485
		/** VORBIS_COMMENT metadata block.
		 *  See <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>.
Josh Coalson's avatar
Josh Coalson committed
486
		 */
487
		class FLACPP_API VorbisComment : public Prototype {
Josh Coalson's avatar
Josh Coalson committed
488
		public:
Josh Coalson's avatar
Josh Coalson committed
489
490
491
492
493
494
			/** Convenience class for encapsulating Vorbis comment
			 *  entries.  An entry is a vendor string or a comment
			 *  field.  In the case of a vendor string, the field
			 *  name is undefined; only the field value is relevant.
			 *
			 *  A \a field as used in the methods refers to an
495
			 *  entire 'NAME=VALUE' string; for convenience the
496
			 *  string is NUL-terminated.  A length field is
497
			 *  required in the unlikely event that the value
498
			 *  contains contain embedded NULs.
Josh Coalson's avatar
Josh Coalson committed
499
500
501
			 *
			 *  A \a field_name is what is on the left side of the
			 *  first '=' in the \a field.  By definition it is ASCII
502
			 *  and so is NUL-terminated and does not require a
Josh Coalson's avatar
Josh Coalson committed
503
504
505
506
507
			 *  length to describe it.  \a field_name is undefined
			 *  for a vendor string entry.
			 *
			 *  A \a field_value is what is on the right side of the
			 *  first '=' in the \a field.  By definition, this may
508
			 *  contain embedded NULs and so a \a field_value_length
509
			 *  is required to describe it.  However in practice,
510
511
			 *  embedded NULs are not known to be used, so it is
			 *  generally safe to treat field values as NUL-
512
			 *  terminated UTF-8 strings.
Josh Coalson's avatar
Josh Coalson committed
513
514
			 *
			 *  Always check is_valid() after the constructor or operator=
515
516
			 *  to make sure memory was properly allocated and that the
			 *  Entry conforms to the Vorbis comment specification.
Josh Coalson's avatar
Josh Coalson committed
517
			 */
518
			class FLACPP_API Entry {
519
520
			public:
				Entry();
521

522
				Entry(const char *field, unsigned field_length);
523
				Entry(const char *field); // assumes \a field is NUL-terminated
524

525
				Entry(const char *field_name, const char *field_value, unsigned field_value_length);
526
				Entry(const char *field_name, const char *field_value); // assumes \a field_value is NUL-terminated
527

528
				Entry(const Entry &entry);
529

530
531
532
533
534
535
536
537
538
539
				void operator=(const Entry &entry);

				virtual ~Entry();

				virtual bool is_valid() const;

				unsigned get_field_length() const;
				unsigned get_field_name_length() const;
				unsigned get_field_value_length() const;

540
				::FLAC__StreamMetadata_VorbisComment_Entry get_entry() const;
541
542
543
544
545
				const char *get_field() const;
				const char *get_field_name() const;
				const char *get_field_value() const;

				bool set_field(const char *field, unsigned field_length);
546
				bool set_field(const char *field); // assumes \a field is NUL-terminated
547
548
				bool set_field_name(const char *field_name);
				bool set_field_value(const char *field_value, unsigned field_value_length);
549
				bool set_field_value(const char *field_value); // assumes \a field_value is NUL-terminated
550
551
			protected:
				bool is_valid_;
552
				::FLAC__StreamMetadata_VorbisComment_Entry entry_;
553
554
555
556
557
558
559
560
561
562
563
				char *field_name_;
				unsigned field_name_length_;
				char *field_value_;
				unsigned field_value_length_;
			private:
				void zero();
				void clear();
				void clear_entry();
				void clear_field_name();
				void clear_field_value();
				void construct(const char *field, unsigned field_length);
564
				void construct(const char *field); // assumes \a field is NUL-terminated
565
				void construct(const char *field_name, const char *field_value, unsigned field_value_length);
566
				void construct(const char *field_name, const char *field_value); // assumes \a field_value is NUL-terminated
567
568
569
570
				void compose_field();
				void parse_field();
			};

Josh Coalson's avatar
Josh Coalson committed
571
			VorbisComment();
Josh Coalson's avatar
Josh Coalson committed
572
573
574
575
576

			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
577
578
579
			inline VorbisComment(const VorbisComment &object): Prototype(object) { }
			inline VorbisComment(const ::FLAC__StreamMetadata &object): Prototype(object) { }
			inline VorbisComment(const ::FLAC__StreamMetadata *object): Prototype(object) { }
Josh Coalson's avatar
Josh Coalson committed
580
581
582
583
584
			//@}

			/** Constructs an object with copy control.  See
			 *  Prototype(::FLAC__StreamMetadata *object, bool copy).
			 */
585
			inline VorbisComment(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalson's avatar
Josh Coalson committed
586

Josh Coalson's avatar
Josh Coalson committed
587
			~VorbisComment();
Josh Coalson's avatar
Josh Coalson committed
588

Josh Coalson's avatar
Josh Coalson committed
589
590
			//@{
			/** Assign from another object.  Always performs a deep copy. */
Josh Coalson's avatar
Josh Coalson committed
591
			inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
592
593
			inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalson's avatar
Josh Coalson committed
594
			//@}
595

Josh Coalson's avatar
Josh Coalson committed
596
597
			//@{
			/** Check for equality, performing a deep compare by following pointers. */
598
			inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); }
599
600
			inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson's avatar
Josh Coalson committed
601
602
603
604
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
605
			inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); }
606
607
			inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson's avatar
Josh Coalson committed
608
			//@}
609

610
			unsigned get_num_comments() const;
611
			const FLAC__byte *get_vendor_string() const; // NUL-terminated UTF-8 string
612
613
			Entry get_comment(unsigned index) const;

Josh Coalson's avatar
Josh Coalson committed
614
			//! See FLAC__metadata_object_vorbiscomment_set_vendor_string()
615
			bool set_vendor_string(const FLAC__byte *string); // NUL-terminated UTF-8 string
Josh Coalson's avatar
Josh Coalson committed
616

Josh Coalson's avatar
Josh Coalson committed
617
			//! See FLAC__metadata_object_vorbiscomment_set_comment()
618
			bool set_comment(unsigned index, const Entry &entry);
Josh Coalson's avatar
Josh Coalson committed
619

Josh Coalson's avatar
Josh Coalson committed
620
			//! See FLAC__metadata_object_vorbiscomment_insert_comment()
621
			bool insert_comment(unsigned index, const Entry &entry);
Josh Coalson's avatar
Josh Coalson committed
622

623
624
625
			//! See FLAC__metadata_object_vorbiscomment_append_comment()
			bool append_comment(const Entry &entry);

Josh Coalson's avatar
Josh Coalson committed
626
			//! See FLAC__metadata_object_vorbiscomment_delete_comment()
627
			bool delete_comment(unsigned index);
Josh Coalson's avatar
Josh Coalson committed
628
629
		};

Josh Coalson's avatar
Josh Coalson committed
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
		/** CUESHEET metadata block.
		 *  See <A HREF="../format.html#metadata_block_cuesheet">format specification</A>.
		 */
		class FLACPP_API CueSheet : public Prototype {
		public:
			/** Convenience class for encapsulating a cue sheet
			 *  track.
			 *
			 *  Always check is_valid() after the constructor or operator=
			 *  to make sure memory was properly allocated.
			 */
			class FLACPP_API Track {
			protected:
				::FLAC__StreamMetadata_CueSheet_Track *object_;
			public:
				Track();
				Track(const ::FLAC__StreamMetadata_CueSheet_Track *track);
				Track(const Track &track);
				void operator=(const Track &track);

				virtual ~Track();

				virtual bool is_valid() const;

				inline FLAC__uint64 get_offset() const { return object_->offset; }
				inline FLAC__byte get_number() const { return object_->number; }
				inline const char *get_isrc() const { return object_->isrc; }
				inline unsigned get_type() const { return object_->type; }
				inline bool get_pre_emphasis() const { return object_->pre_emphasis; }

660
				inline FLAC__byte get_num_indices() const { return object_->num_indices; }
Josh Coalson's avatar
Josh Coalson committed
661
662
663
664
665
666
				::FLAC__StreamMetadata_CueSheet_Index get_index(unsigned i) const;

				inline const ::FLAC__StreamMetadata_CueSheet_Track *get_track() const { return object_; }

				inline void set_offset(FLAC__uint64 value) { object_->offset = value; }
				inline void set_number(FLAC__byte value) { object_->number = value; }
667
				void set_isrc(const char value[12]);
Josh Coalson's avatar
Josh Coalson committed
668
669
670
				void set_type(unsigned value);
				inline void set_pre_emphasis(bool value) { object_->pre_emphasis = value? 1 : 0; }

671
 				void set_index(unsigned i, const ::FLAC__StreamMetadata_CueSheet_Index &index);
Josh Coalson's avatar
Josh Coalson committed
672
673
				//@@@ It's awkward but to insert/delete index points
				//@@@ you must use the routines in the CueSheet class.
Josh Coalson's avatar
Josh Coalson committed
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
			};

			CueSheet();

			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
			inline CueSheet(const CueSheet &object): Prototype(object) { }
			inline CueSheet(const ::FLAC__StreamMetadata &object): Prototype(object) { }
			inline CueSheet(const ::FLAC__StreamMetadata *object): Prototype(object) { }
			//@}

			/** Constructs an object with copy control.  See
			 *  Prototype(::FLAC__StreamMetadata *object, bool copy).
			 */
			inline CueSheet(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }

			~CueSheet();

			//@{
			/** Assign from another object.  Always performs a deep copy. */
			inline void operator=(const CueSheet &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
			//@}

			//@{
			/** Check for equality, performing a deep compare by following pointers. */
			inline bool operator==(const CueSheet &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
			inline bool operator!=(const CueSheet &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
			//@}

			const char *get_media_catalog_number() const;
			FLAC__uint64 get_lead_in() const;
717
			bool get_is_cd() const;
Josh Coalson's avatar
Josh Coalson committed
718
719
720
721

			unsigned get_num_tracks() const;
			Track get_track(unsigned i) const;

722
723
			void set_media_catalog_number(const char value[128]);
			void set_lead_in(FLAC__uint64 value);
724
			void set_is_cd(bool value);
725
726

			void set_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index);
Josh Coalson's avatar
Josh Coalson committed
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

			//! See FLAC__metadata_object_cuesheet_track_insert_index()
			bool insert_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index);

			//! See FLAC__metadata_object_cuesheet_track_delete_index()
			bool delete_index(unsigned track_num, unsigned index_num);

			//! See FLAC__metadata_object_cuesheet_set_track()
			bool set_track(unsigned i, const Track &track);

			//! See FLAC__metadata_object_cuesheet_insert_track()
			bool insert_track(unsigned i, const Track &track);

			//! See FLAC__metadata_object_cuesheet_delete_track()
			bool delete_track(unsigned i);

			//! See FLAC__metadata_object_cuesheet_is_legal()
			bool is_legal(bool check_cd_da_subset = false, const char **violation = 0) const;
		};

747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
		/** Opaque metadata block for storing unknown types.
		 *  This should not be used unless you know what you are doing;
		 *  it is currently used only internally to support forward
		 *  compatibility of metadata blocks.
		 */
		class FLACPP_API Unknown : public Prototype {
		public:
			Unknown();
			//
			//@{
			/** Constructs a copy of the given object.  This form
			 *  always performs a deep copy.
			 */
			inline Unknown(const Unknown &object): Prototype(object) { }
			inline Unknown(const ::FLAC__StreamMetadata &object): Prototype(object) { }
			inline Unknown(const ::FLAC__StreamMetadata *object): Prototype(object) { }
			//@}

			/** Constructs an object with copy control.  See
			 *  Prototype(::FLAC__StreamMetadata *object, bool copy).
			 */
			inline Unknown(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }

			~Unknown();

			//@{
			/** Assign from another object.  Always performs a deep copy. */
			inline void operator=(const Unknown &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
			inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
			//@}

			//@{
			/** Check for equality, performing a deep compare by following pointers. */
			inline bool operator==(const Unknown &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
			inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
			//@}

			//@{
			/** Check for inequality, performing a deep compare by following pointers. */
			inline bool operator!=(const Unknown &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
			inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
			//@}

			const FLAC__byte *get_data() const;

			//! This form always copies \a data
			bool set_data(const FLAC__byte *data, unsigned length);
			bool set_data(FLAC__byte *data, unsigned length, bool copy);
		};

Josh Coalson's avatar
Josh Coalson committed
800
801
		/* \} */

802

Josh Coalson's avatar
Josh Coalson committed
803
804
805
806
		/** \defgroup flacpp_metadata_level0 FLAC++/metadata.h: metadata level 0 interface
		 *  \ingroup flacpp_metadata
		 *
		 *  \brief
807
		 *  Level 0 metadata iterators.
Josh Coalson's avatar
Josh Coalson committed
808
		 *
Josh Coalson's avatar
Josh Coalson committed
809
810
		 *  See the \link flac_metadata_level0 C layer equivalent \endlink
		 *  for more.
Josh Coalson's avatar
Josh Coalson committed
811
812
813
814
		 *
		 * \{
		 */

Josh Coalson's avatar
Josh Coalson committed
815
	 	//! See FLAC__metadata_get_streaminfo().
816
		FLACPP_API bool get_streaminfo(const char *filename, StreamInfo &streaminfo);
Josh Coalson's avatar
Josh Coalson committed
817

818
819
	 	//! See FLAC__metadata_get_tags().
		FLACPP_API bool get_tags(const char *filename, VorbisComment *&tags);
Josh Coalson's avatar
Josh Coalson committed
820

Josh Coalson's avatar
Josh Coalson committed
821
822
		/* \} */

823

Josh Coalson's avatar
Josh Coalson committed
824
825
826
		/** \defgroup flacpp_metadata_level1 FLAC++/metadata.h: metadata level 1 interface
		 *  \ingroup flacpp_metadata
		 *
Josh Coalson's avatar
Josh Coalson committed
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
		 *  \brief
		 *  Level 1 metadata iterator.
		 *
		 *  The flow through the iterator in the C++ layer is similar
		 *  to the C layer:
		 *    - Create a SimpleIterator instance
		 *    - Check SimpleIterator::is_valid()
		 *    - Call SimpleIterator::init() and check the return
		 *    - Traverse and/or edit.  Edits are written to file
		 *      immediately.
		 *    - Destroy the SimpleIterator instance
		 *
		 *  The ownership of pointers in the C++ layer follows that in
		 *  the C layer, i.e.
		 *    - The objects returned by get_block() are yours to
		 *      modify, but changes are not reflected in the FLAC file
		 *      until you call set_block().  The objects are also
		 *      yours to delete; they are not automatically deleted
		 *      when passed to set_block() or insert_block_after().
Josh Coalson's avatar
Josh Coalson committed
846
		 *
Josh Coalson's avatar
Josh Coalson committed
847
848
		 *  See the \link flac_metadata_level1 C layer equivalent \endlink
		 *  for more.
Josh Coalson's avatar
Josh Coalson committed
849
850
851
852
		 *
		 * \{
		 */

Josh Coalson's avatar
Josh Coalson committed
853
854
		/** This class is a wrapper around the FLAC__metadata_simple_iterator
		 *  structures and methods; see ::FLAC__Metadata_SimpleIterator.
Josh Coalson's avatar
Josh Coalson committed
855
		 */
856
		class FLACPP_API SimpleIterator {
Josh Coalson's avatar
Josh Coalson committed
857
		public:
858
			class FLACPP_API Status {
Josh Coalson's avatar
Josh Coalson committed
859
			public:
860
861
862
				inline Status(::FLAC__Metadata_SimpleIteratorStatus status): status_(status) { }
				inline operator ::FLAC__Metadata_SimpleIteratorStatus() const { return status_; }
				inline const char *as_cstring() const { return ::FLAC__Metadata_SimpleIteratorStatusString[status_]; }
Josh Coalson's avatar
Josh Coalson committed
863
			protected:
864
				::FLAC__Metadata_SimpleIteratorStatus status_;
Josh Coalson's avatar
Josh Coalson committed
865
866
867
868
869
			};

			SimpleIterator();
			virtual ~SimpleIterator();

870
			bool init(const char *filename, bool read_only, bool preserve_file_stats);
Josh Coalson's avatar
Josh Coalson committed
871
872
873
874
875
876
877
878

			bool is_valid() const;
			Status status();
			bool is_writable() const;

			bool next();
			bool prev();

879
			::FLAC__MetadataType get_block_type() const;
Josh Coalson's avatar
Josh Coalson committed
880
881
882
883
884
885
			Prototype *get_block();
			bool set_block(Prototype *block, bool use_padding = true);
			bool insert_block_after(Prototype *block, bool use_padding = true);
			bool delete_block(bool use_padding = true);

		protected:
886
			::FLAC__Metadata_SimpleIterator *iterator_;
Josh Coalson's avatar
Josh Coalson committed
887
888
889
			void clear();
		};

Josh Coalson's avatar
Josh Coalson committed
890
891
		/* \} */

892

Josh Coalson's avatar
Josh Coalson committed
893
894
895
		/** \defgroup flacpp_metadata_level2 FLAC++/metadata.h: metadata level 2 interface
		 *  \ingroup flacpp_metadata
		 *
Josh Coalson's avatar
Josh Coalson committed
896
897
898
899
900
901
902
903
904
905
906
907
908
		 *  \brief
		 *  Level 2 metadata iterator.
		 *
		 *  The flow through the iterator in the C++ layer is similar
		 *  to the C layer:
		 *    - Create a Chain instance
		 *    - Check Chain::is_valid()
		 *    - Call Chain::read() and check the return
		 *    - Traverse and/or edit with an Iterator or with
		 *      Chain::merge_padding() or Chain::sort_padding()
		 *    - Write changes back to FLAC file with Chain::write()
		 *    - Destroy the Chain instance
		 *
909
910
911
912
913
914
915
916
917
		 *  The ownership of pointers in the C++ layer is slightly
		 *  different than in the C layer, i.e.
		 *    - The objects returned by Iterator::get_block() are NOT
		 *      owned by the iterator and should be deleted by the
		 *      caller when finished, BUT, when you modify the block,
		 *      it will directly edit what's in the chain and you do
		 *      not need to call Iterator::set_block().  However the
		 *      changes will not be reflected in the FLAC file until
		 *      the chain is written with Chain::write().
Josh Coalson's avatar
Josh Coalson committed
918
919
920
		 *    - When you pass an object to Iterator::set_block(),
		 *      Iterator::insert_block_before(), or
		 *      Iterator::insert_block_after(), the iterator takes
921
		 *      ownership of the block and it will be deleted by the
Josh Coalson's avatar
Josh Coalson committed
922
		 *      chain.
Josh Coalson's avatar
Josh Coalson committed
923
		 *
Josh Coalson's avatar
Josh Coalson committed
924
925
		 *  See the \link flac_metadata_level2 C layer equivalent \endlink
		 *  for more.
Josh Coalson's avatar
Josh Coalson committed
926
927
928
929
		 *
		 * \{
		 */

Josh Coalson's avatar
Josh Coalson committed
930
931
		/** This class is a wrapper around the FLAC__metadata_chain
		 *  structures and methods; see ::FLAC__Metadata_Chain.
Josh Coalson's avatar
Josh Coalson committed
932
		 */
933
		class FLACPP_API Chain {
Josh Coalson's avatar
Josh Coalson committed
934
		public:
935
			class FLACPP_API Status {
Josh Coalson's avatar
Josh Coalson committed
936
			public:
937
938
939
				inline Status(::FLAC__Metadata_ChainStatus status): status_(status) { }
				inline operator ::FLAC__Metadata_ChainStatus() const { return status_; }
				inline const char *as_cstring() const { return ::FLAC__Metadata_ChainStatusString[status_]; }
Josh Coalson's avatar
Josh Coalson committed
940
			protected:
941
				::FLAC__Metadata_ChainStatus status_;
Josh Coalson's avatar
Josh Coalson committed
942
943
944
945
946
947
948
949
950
951
952
			};

			Chain();
			virtual ~Chain();

			friend class Iterator;

			bool is_valid() const;
			Status status();

			bool read(const char *filename);
953
954
955
956
			bool read(FLAC__IOHandle handle, FLAC__IOCallbacks callbacks);

			bool check_if_tempfile_needed(bool use_padding);

Josh Coalson's avatar
Josh Coalson committed
957
			bool write(bool use_padding = true, bool preserve_file_stats = false);
958
959
			bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks);
			bool write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks, ::FLAC__IOHandle temp_handle, ::FLAC__IOCallbacks temp_callbacks);
Josh Coalson's avatar
Josh Coalson committed
960
961
962
963
964

			void merge_padding();
			void sort_padding();

		protected:
965
			::FLAC__Metadata_Chain *chain_;
Josh Coalson's avatar
Josh Coalson committed
966
967
968
			virtual void clear();
		};

Josh Coalson's avatar
Josh Coalson committed
969
970
		/** This class is a wrapper around the FLAC__metadata_iterator
		 *  structures and methods; see ::FLAC__Metadata_Iterator.
Josh Coalson's avatar
Josh Coalson committed
971
		 */
972
		class FLACPP_API Iterator {
Josh Coalson's avatar
Josh Coalson committed
973
974
975
976
977
978
		public:
			Iterator();
			virtual ~Iterator();

			bool is_valid() const;

979
			void init(Chain &chain);
Josh Coalson's avatar
Josh Coalson committed
980
981
982
983

			bool next();
			bool prev();

984
			::FLAC__MetadataType get_block_type() const;
Josh Coalson's avatar
Josh Coalson committed
985
986
987
988
989
990
991
			Prototype *get_block();
			bool set_block(Prototype *block);
			bool delete_block(bool replace_with_padding);
			bool insert_block_before(Prototype *block);
			bool insert_block_after(Prototype *block);

		protected:
992
			::FLAC__Metadata_Iterator *iterator_;
Josh Coalson's avatar
Josh Coalson committed
993
			virtual void clear();
Josh Coalson's avatar
Josh Coalson committed
994
995
		};

Josh Coalson's avatar
Josh Coalson committed
996
997
		/* \} */

Josh Coalson's avatar
Josh Coalson committed
998
999
1000
1001
	};
};

#endif