blob: eb019daf57c2c7714b103f29109b59e021397766 [file] [log] [blame]
Josh Coalsonfda98fb2002-05-17 06:33:39 +00001/* 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
Josh Coalsonfb74f102002-05-22 05:33:29 +000025// ===============================================================
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
Josh Coalsonfda98fb2002-05-17 06:33:39 +000033namespace FLAC {
34 namespace Metadata {
35
Josh Coalsonfb74f102002-05-22 05:33:29 +000036 // ============================================================
37 //
38 // Metadata objects
39 //
40 // ============================================================
41
Josh Coalsoncc682512002-06-08 04:53:42 +000042 class Prototype;
43
44 Prototype *clone(const Prototype *);
45
Josh Coalsonfda98fb2002-05-17 06:33:39 +000046 // NOTE: When the get_*() methods return you a const pointer,
Josh Coalsonfb74f102002-05-22 05:33:29 +000047 // DO NOT disobey and write into it. Always use the set_*()
Josh Coalsonfda98fb2002-05-17 06:33:39 +000048 // methods.
49
Josh Coalson83961752002-07-09 06:12:59 +000050 //!
51 //! Base class for all metadata blocks.
52 //!
Josh Coalsonfda98fb2002-05-17 06:33:39 +000053 class Prototype {
54 protected:
Josh Coalson83961752002-07-09 06:12:59 +000055 //!
56 //! Constructs a copy of the given object. This form
57 //! always performs a deep copy.
58 //!
59 Prototype(const Prototype &object);
60
61 //!
62 //! Constructs a copy of the given object. This form
63 //! always performs a deep copy.
64 //!
65 Prototype(const ::FLAC__StreamMetadata &object);
66
67 //!
68 //! Constructs a copy of the given object. This form
69 //! always performs a deep copy.
70 //!
71 Prototype(const ::FLAC__StreamMetadata *object);
72
73 //!
74 //! Constructs an object with copy control. When 'copy'
75 //! is true, behaves identically to
76 //! FLAC::Metadata::Prototype::Prototype(const ::FLAC__StreamMetadata *object).
77 //! When 'copy' is false, the instance takes ownership of
78 //! the pointer and the ::FLAC__StreamMetadata object will
79 //! be freed by the destructor.
80 //!
81 Prototype(::FLAC__StreamMetadata *object, bool copy);
Josh Coalsonfda98fb2002-05-17 06:33:39 +000082
Josh Coalsonfb74f102002-05-22 05:33:29 +000083 void operator=(const Prototype &);
Josh Coalsoncc682512002-06-08 04:53:42 +000084 void operator=(const ::FLAC__StreamMetadata &); // this form always copies
85 void operator=(const ::FLAC__StreamMetadata *); // this form always copies
Josh Coalson57ba6f42002-06-07 05:27:37 +000086
Josh Coalsonfb74f102002-05-22 05:33:29 +000087 virtual void clear();
88
Josh Coalsoncc682512002-06-08 04:53:42 +000089 ::FLAC__StreamMetadata *object_;
Josh Coalsonfda98fb2002-05-17 06:33:39 +000090 public:
Josh Coalson57ba6f42002-06-07 05:27:37 +000091 virtual ~Prototype();
92
Josh Coalsoncc682512002-06-08 04:53:42 +000093 inline bool operator==(const Prototype &) const;
94 inline bool operator==(const ::FLAC__StreamMetadata &) const;
95 inline bool operator==(const ::FLAC__StreamMetadata *) const;
96 inline bool operator!=(const Prototype &) const;
97 inline bool operator!=(const ::FLAC__StreamMetadata &) const;
98 inline bool operator!=(const ::FLAC__StreamMetadata *) const;
99
Josh Coalsonfb74f102002-05-22 05:33:29 +0000100 friend class SimpleIterator;
101 friend class Iterator;
102
Josh Coalson57ba6f42002-06-07 05:27:37 +0000103 inline bool is_valid() const;
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000104
105 bool get_is_last() const;
Josh Coalsoncc682512002-06-08 04:53:42 +0000106 FLAC__MetadataType get_type() const;
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000107 unsigned get_length() const; // NOTE: does not include the header, per spec
Josh Coalsoncc682512002-06-08 04:53:42 +0000108
109 void set_is_last(bool);
Josh Coalsonfb74f102002-05-22 05:33:29 +0000110 private:
Josh Coalson5ac8bd12002-05-29 05:53:57 +0000111 Prototype(); // Private and undefined so you can't use it
Josh Coalsonfb74f102002-05-22 05:33:29 +0000112
113 // These are used only by Iterator
114 bool is_reference_;
115 inline void set_reference(bool x) { is_reference_ = x; }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000116 };
117
Josh Coalson57ba6f42002-06-07 05:27:37 +0000118 inline bool Prototype::operator==(const Prototype &object) const
Josh Coalsond57c8d32002-06-11 06:15:28 +0000119 { return (bool)::FLAC__metadata_object_is_equal(object_, object.object_); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000120
Josh Coalsoncc682512002-06-08 04:53:42 +0000121 inline bool Prototype::operator==(const ::FLAC__StreamMetadata &object) const
Josh Coalsond57c8d32002-06-11 06:15:28 +0000122 { return (bool)::FLAC__metadata_object_is_equal(object_, &object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000123
Josh Coalsoncc682512002-06-08 04:53:42 +0000124 inline bool Prototype::operator==(const ::FLAC__StreamMetadata *object) const
Josh Coalsond57c8d32002-06-11 06:15:28 +0000125 { return (bool)::FLAC__metadata_object_is_equal(object_, object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000126
127 inline bool Prototype::operator!=(const Prototype &object) const
128 { return !operator==(object); }
129
Josh Coalsoncc682512002-06-08 04:53:42 +0000130 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata &object) const
Josh Coalson57ba6f42002-06-07 05:27:37 +0000131 { return !operator==(object); }
132
Josh Coalsoncc682512002-06-08 04:53:42 +0000133 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata *object) const
Josh Coalson57ba6f42002-06-07 05:27:37 +0000134 { return !operator==(object); }
135
136 inline bool Prototype::is_valid() const
137 { return 0 != object_; }
138
139
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000140 class StreamInfo : public Prototype {
141 public:
142 StreamInfo();
Josh Coalsoncc682512002-06-08 04:53:42 +0000143 inline StreamInfo(const StreamInfo &object): Prototype(object) { }
144 inline StreamInfo(const ::FLAC__StreamMetadata &object): Prototype(object) { }
145 inline StreamInfo(const ::FLAC__StreamMetadata *object): Prototype(object) { }
146 inline StreamInfo(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000147 ~StreamInfo();
148
Josh Coalsonfb74f102002-05-22 05:33:29 +0000149 inline void operator=(const StreamInfo &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000150 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
151 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000152
Josh Coalson57ba6f42002-06-07 05:27:37 +0000153 inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000154 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
155 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000156 inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000157 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
158 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000159
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000160 unsigned get_min_blocksize() const;
161 unsigned get_max_blocksize() const;
162 unsigned get_min_framesize() const;
163 unsigned get_max_framesize() const;
164 unsigned get_sample_rate() const;
165 unsigned get_channels() const;
166 unsigned get_bits_per_sample() const;
167 FLAC__uint64 get_total_samples() const;
168 const FLAC__byte *get_md5sum() const;
169
170 void set_min_blocksize(unsigned value);
171 void set_max_blocksize(unsigned value);
172 void set_min_framesize(unsigned value);
173 void set_max_framesize(unsigned value);
174 void set_sample_rate(unsigned value);
175 void set_channels(unsigned value);
176 void set_bits_per_sample(unsigned value);
177 void set_total_samples(FLAC__uint64 value);
178 void set_md5sum(const FLAC__byte value[16]);
179 };
180
181 class Padding : public Prototype {
182 public:
183 Padding();
Josh Coalsoncc682512002-06-08 04:53:42 +0000184 inline Padding(const Padding &object): Prototype(object) { }
185 inline Padding(const ::FLAC__StreamMetadata &object): Prototype(object) { }
186 inline Padding(const ::FLAC__StreamMetadata *object): Prototype(object) { }
187 inline Padding(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000188 ~Padding();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000189
190 inline void operator=(const Padding &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000191 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
192 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000193
Josh Coalson57ba6f42002-06-07 05:27:37 +0000194 inline bool operator==(const Padding &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000195 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
196 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000197 inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000198 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
199 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000200
Josh Coalsonb2b53582002-05-31 06:20:50 +0000201 void set_length(unsigned length);
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000202 };
203
204 class Application : public Prototype {
205 public:
206 Application();
Josh Coalsoncc682512002-06-08 04:53:42 +0000207 inline Application(const Application &object): Prototype(object) { }
208 inline Application(const ::FLAC__StreamMetadata &object): Prototype(object) { }
209 inline Application(const ::FLAC__StreamMetadata *object): Prototype(object) { }
210 inline Application(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000211 ~Application();
212
Josh Coalsonfb74f102002-05-22 05:33:29 +0000213 inline void operator=(const Application &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000214 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
215 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000216
Josh Coalson57ba6f42002-06-07 05:27:37 +0000217 inline bool operator==(const Application &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000218 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
219 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000220 inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000221 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
222 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000223
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000224 const FLAC__byte *get_id() const;
225 const FLAC__byte *get_data() const;
226
Josh Coalsoncc682512002-06-08 04:53:42 +0000227 void set_id(const FLAC__byte value[4]);
228 bool set_data(const FLAC__byte *data, unsigned length); // this form always copies
229 bool set_data(FLAC__byte *data, unsigned length, bool copy);
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000230 };
231
232 class SeekTable : public Prototype {
233 public:
234 SeekTable();
Josh Coalsoncc682512002-06-08 04:53:42 +0000235 inline SeekTable(const SeekTable &object): Prototype(object) { }
236 inline SeekTable(const ::FLAC__StreamMetadata &object): Prototype(object) { }
237 inline SeekTable(const ::FLAC__StreamMetadata *object): Prototype(object) { }
238 inline SeekTable(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000239 ~SeekTable();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000240
241 inline void operator=(const SeekTable &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000242 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
243 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000244
Josh Coalson57ba6f42002-06-07 05:27:37 +0000245 inline bool operator==(const SeekTable &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000246 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
247 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000248 inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000249 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
250 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000251
Josh Coalsonb2b53582002-05-31 06:20:50 +0000252 unsigned get_num_points() const;
Josh Coalsoncc682512002-06-08 04:53:42 +0000253 ::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000254
Josh Coalsoncc682512002-06-08 04:53:42 +0000255 void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
256 bool insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
Josh Coalsonb2b53582002-05-31 06:20:50 +0000257 bool delete_point(unsigned index);
Josh Coalson28e08d82002-06-05 05:56:41 +0000258
259 bool is_legal() const;
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000260 };
261
262 class VorbisComment : public Prototype {
263 public:
Josh Coalsonb2b53582002-05-31 06:20:50 +0000264 class Entry {
265 public:
266 Entry();
267 Entry(const char *field, unsigned field_length);
268 Entry(const char *field_name, const char *field_value, unsigned field_value_length);
269 Entry(const Entry &entry);
270 void operator=(const Entry &entry);
271
272 virtual ~Entry();
273
274 virtual bool is_valid() const;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000275
276 unsigned get_field_length() const;
277 unsigned get_field_name_length() const;
278 unsigned get_field_value_length() const;
279
Josh Coalsoncc682512002-06-08 04:53:42 +0000280 ::FLAC__StreamMetadata_VorbisComment_Entry get_entry() const;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000281 const char *get_field() const;
282 const char *get_field_name() const;
283 const char *get_field_value() const;
284
285 bool set_field(const char *field, unsigned field_length);
286 bool set_field_name(const char *field_name);
287 bool set_field_value(const char *field_value, unsigned field_value_length);
288 protected:
289 bool is_valid_;
Josh Coalsoncc682512002-06-08 04:53:42 +0000290 ::FLAC__StreamMetadata_VorbisComment_Entry entry_;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000291 char *field_name_;
292 unsigned field_name_length_;
293 char *field_value_;
294 unsigned field_value_length_;
295 private:
296 void zero();
297 void clear();
298 void clear_entry();
299 void clear_field_name();
300 void clear_field_value();
301 void construct(const char *field, unsigned field_length);
302 void construct(const char *field_name, const char *field_value, unsigned field_value_length);
303 void compose_field();
304 void parse_field();
305 };
306
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000307 VorbisComment();
Josh Coalsoncc682512002-06-08 04:53:42 +0000308 inline VorbisComment(const VorbisComment &object): Prototype(object) { }
309 inline VorbisComment(const ::FLAC__StreamMetadata &object): Prototype(object) { }
310 inline VorbisComment(const ::FLAC__StreamMetadata *object): Prototype(object) { }
311 inline VorbisComment(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000312 ~VorbisComment();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000313
314 inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000315 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
316 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000317
Josh Coalson57ba6f42002-06-07 05:27:37 +0000318 inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000319 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
320 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000321 inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000322 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
323 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000324
Josh Coalsonb2b53582002-05-31 06:20:50 +0000325 unsigned get_num_comments() const;
Josh Coalsoncc682512002-06-08 04:53:42 +0000326 Entry get_vendor_string() const; // only the Entry's field name should be used
Josh Coalsonb2b53582002-05-31 06:20:50 +0000327 Entry get_comment(unsigned index) const;
328
Josh Coalsoncc682512002-06-08 04:53:42 +0000329 bool set_vendor_string(const Entry &entry); // only the Entry's field name will be used
Josh Coalsonb2b53582002-05-31 06:20:50 +0000330 bool set_comment(unsigned index, const Entry &entry);
331 bool insert_comment(unsigned index, const Entry &entry);
332 bool delete_comment(unsigned index);
Josh Coalsonfb74f102002-05-22 05:33:29 +0000333 };
334
Josh Coalsonb2b53582002-05-31 06:20:50 +0000335
Josh Coalsonfb74f102002-05-22 05:33:29 +0000336 // ============================================================
337 //
338 // Level 0
339 //
340 // ============================================================
341
342 bool get_streaminfo(const char *filename, StreamInfo &streaminfo);
343
Josh Coalsonb2b53582002-05-31 06:20:50 +0000344
Josh Coalsonfb74f102002-05-22 05:33:29 +0000345 // ============================================================
346 //
347 // Level 1
348 //
349 // ----------------------------------------------------------
350 //
351 // The flow through the iterator in the C++ layer is similar
352 // to the C layer:
353 //
354 // * Create a SimpleIterator instance
355 // * Check SimpleIterator::is_valid()
356 // * Call SimpleIterator::init() and check the return
357 // * Traverse and/or edit. Edits are written to file
358 // immediately.
359 // * Destroy the SimpleIterator instance
360 //
361 // ----------------------------------------------------------
362 //
363 // The ownership of pointers in the C++ layer follows that in
364 // the C layer, i.e.
365 // * The objects returned by get_block() are yours to
366 // modify, but changes are not reflected in the FLAC file
367 // until you call set_block(). The objects are also
368 // yours to delete; they are not automatically deleted
369 // when passed to set_block() or insert_block_after().
370 //
371 // ============================================================
372
373 class SimpleIterator {
374 public:
375 class Status {
376 public:
Josh Coalsoncc682512002-06-08 04:53:42 +0000377 inline Status(::FLAC__Metadata_SimpleIteratorStatus status): status_(status) { }
378 inline operator ::FLAC__Metadata_SimpleIteratorStatus() const { return status_; }
379 inline const char *as_cstring() const { return ::FLAC__Metadata_SimpleIteratorStatusString[status_]; }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000380 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000381 ::FLAC__Metadata_SimpleIteratorStatus status_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000382 };
383
384 SimpleIterator();
385 virtual ~SimpleIterator();
386
387 bool init(const char *filename, bool preserve_file_stats = false);
388
389 bool is_valid() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000390 Status status();
391 bool is_writable() const;
392
393 bool next();
394 bool prev();
395
Josh Coalsoncc682512002-06-08 04:53:42 +0000396 ::FLAC__MetadataType get_block_type() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000397 Prototype *get_block();
398 bool set_block(Prototype *block, bool use_padding = true);
399 bool insert_block_after(Prototype *block, bool use_padding = true);
400 bool delete_block(bool use_padding = true);
401
402 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000403 ::FLAC__Metadata_SimpleIterator *iterator_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000404 void clear();
405 };
406
Josh Coalsonb2b53582002-05-31 06:20:50 +0000407
Josh Coalsonfb74f102002-05-22 05:33:29 +0000408 // ============================================================
409 //
410 // Level 2
411 //
412 // ----------------------------------------------------------
413 //
414 // The flow through the iterator in the C++ layer is similar
415 // to the C layer:
416 //
417 // * Create a Chain instance
418 // * Check Chain::is_valid()
419 // * Call Chain::read() and check the return
420 // * Traverse and/or edit with an Iterator or with
421 // Chain::merge_padding() or Chain::sort_padding()
422 // * Write changes back to FLAC file with Chain::write()
423 // * Destroy the Chain instance
424 //
425 // ----------------------------------------------------------
426 //
427 // The ownership of pointers in the C++ layer follows that in
428 // the C layer, i.e.
429 // * The objects returned by Iterator::get_block() are
430 // owned by the iterator and should not be deleted.
431 // When you modify the block, you are directly editing
432 // what's in the chain and do not need to call
433 // Iterator::set_block(). However the changes will not
434 // be reflected in the FLAC file until the chain is
435 // written with Chain::write().
436 //
437 // * When you pass an object to Iterator::set_block(),
438 // Iterator::insert_block_before(), or
439 // Iterator::insert_block_after(), the iterator takes
440 // ownership of the block and it will be deleted with the
441 // chain.
442 //
443 // ============================================================
444
445 class Chain {
446 public:
447 class Status {
448 public:
Josh Coalsoncc682512002-06-08 04:53:42 +0000449 inline Status(::FLAC__Metadata_ChainStatus status): status_(status) { }
450 inline operator ::FLAC__Metadata_ChainStatus() const { return status_; }
451 inline const char *as_cstring() const { return ::FLAC__Metadata_ChainStatusString[status_]; }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000452 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000453 ::FLAC__Metadata_ChainStatus status_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000454 };
455
456 Chain();
457 virtual ~Chain();
458
459 friend class Iterator;
460
461 bool is_valid() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000462 Status status();
463
464 bool read(const char *filename);
465 bool write(bool use_padding = true, bool preserve_file_stats = false);
466
467 void merge_padding();
468 void sort_padding();
469
470 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000471 ::FLAC__Metadata_Chain *chain_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000472 virtual void clear();
473 };
474
475 class Iterator {
476 public:
477 Iterator();
478 virtual ~Iterator();
479
480 bool is_valid() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000481
Josh Coalson999be3b2002-06-10 04:42:35 +0000482 void init(Chain &chain);
Josh Coalsonfb74f102002-05-22 05:33:29 +0000483
484 bool next();
485 bool prev();
486
Josh Coalsoncc682512002-06-08 04:53:42 +0000487 ::FLAC__MetadataType get_block_type() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000488 Prototype *get_block();
489 bool set_block(Prototype *block);
490 bool delete_block(bool replace_with_padding);
491 bool insert_block_before(Prototype *block);
492 bool insert_block_after(Prototype *block);
493
494 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000495 ::FLAC__Metadata_Iterator *iterator_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000496 virtual void clear();
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000497 };
498
499 };
500};
501
502#endif