blob: 28aa2514f55a3aa905b8756cf2ee73ed2480e4ca [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
50 // base class for all metadata blocks
51 class Prototype {
52 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +000053 Prototype(const Prototype &object); // this form always copies object.object_
54 Prototype(const ::FLAC__StreamMetadata &object); // this form always copies
55 Prototype(const ::FLAC__StreamMetadata *object); // this form always copies
56 Prototype(::FLAC__StreamMetadata *object, bool copy); // this form allows you to pass ownership to the Prototype using copy=false
Josh Coalsonfda98fb2002-05-17 06:33:39 +000057
Josh Coalsonfb74f102002-05-22 05:33:29 +000058 void operator=(const Prototype &);
Josh Coalsoncc682512002-06-08 04:53:42 +000059 void operator=(const ::FLAC__StreamMetadata &); // this form always copies
60 void operator=(const ::FLAC__StreamMetadata *); // this form always copies
Josh Coalson57ba6f42002-06-07 05:27:37 +000061
Josh Coalsonfb74f102002-05-22 05:33:29 +000062 virtual void clear();
63
Josh Coalsoncc682512002-06-08 04:53:42 +000064 ::FLAC__StreamMetadata *object_;
Josh Coalsonfda98fb2002-05-17 06:33:39 +000065 public:
Josh Coalson57ba6f42002-06-07 05:27:37 +000066 virtual ~Prototype();
67
Josh Coalsoncc682512002-06-08 04:53:42 +000068 inline bool operator==(const Prototype &) const;
69 inline bool operator==(const ::FLAC__StreamMetadata &) const;
70 inline bool operator==(const ::FLAC__StreamMetadata *) const;
71 inline bool operator!=(const Prototype &) const;
72 inline bool operator!=(const ::FLAC__StreamMetadata &) const;
73 inline bool operator!=(const ::FLAC__StreamMetadata *) const;
74
Josh Coalsonfb74f102002-05-22 05:33:29 +000075 friend class SimpleIterator;
76 friend class Iterator;
77
Josh Coalson57ba6f42002-06-07 05:27:37 +000078 inline bool is_valid() const;
Josh Coalsonfda98fb2002-05-17 06:33:39 +000079
80 bool get_is_last() const;
Josh Coalsoncc682512002-06-08 04:53:42 +000081 FLAC__MetadataType get_type() const;
Josh Coalsonfda98fb2002-05-17 06:33:39 +000082 unsigned get_length() const; // NOTE: does not include the header, per spec
Josh Coalsoncc682512002-06-08 04:53:42 +000083
84 void set_is_last(bool);
Josh Coalsonfb74f102002-05-22 05:33:29 +000085 private:
Josh Coalson5ac8bd12002-05-29 05:53:57 +000086 Prototype(); // Private and undefined so you can't use it
Josh Coalsonfb74f102002-05-22 05:33:29 +000087
88 // These are used only by Iterator
89 bool is_reference_;
90 inline void set_reference(bool x) { is_reference_ = x; }
Josh Coalsonfda98fb2002-05-17 06:33:39 +000091 };
92
Josh Coalson57ba6f42002-06-07 05:27:37 +000093 inline bool Prototype::operator==(const Prototype &object) const
94 { return ::FLAC__metadata_object_is_equal(object_, object.object_); }
95
Josh Coalsoncc682512002-06-08 04:53:42 +000096 inline bool Prototype::operator==(const ::FLAC__StreamMetadata &object) const
Josh Coalson57ba6f42002-06-07 05:27:37 +000097 { return ::FLAC__metadata_object_is_equal(object_, &object); }
98
Josh Coalsoncc682512002-06-08 04:53:42 +000099 inline bool Prototype::operator==(const ::FLAC__StreamMetadata *object) const
Josh Coalson57ba6f42002-06-07 05:27:37 +0000100 { return ::FLAC__metadata_object_is_equal(object_, object); }
101
102 inline bool Prototype::operator!=(const Prototype &object) const
103 { return !operator==(object); }
104
Josh Coalsoncc682512002-06-08 04:53:42 +0000105 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata &object) const
Josh Coalson57ba6f42002-06-07 05:27:37 +0000106 { return !operator==(object); }
107
Josh Coalsoncc682512002-06-08 04:53:42 +0000108 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata *object) const
Josh Coalson57ba6f42002-06-07 05:27:37 +0000109 { return !operator==(object); }
110
111 inline bool Prototype::is_valid() const
112 { return 0 != object_; }
113
114
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000115 class StreamInfo : public Prototype {
116 public:
117 StreamInfo();
Josh Coalsoncc682512002-06-08 04:53:42 +0000118 inline StreamInfo(const StreamInfo &object): Prototype(object) { }
119 inline StreamInfo(const ::FLAC__StreamMetadata &object): Prototype(object) { }
120 inline StreamInfo(const ::FLAC__StreamMetadata *object): Prototype(object) { }
121 inline StreamInfo(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000122 ~StreamInfo();
123
Josh Coalsonfb74f102002-05-22 05:33:29 +0000124 inline void operator=(const StreamInfo &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000125 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
126 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000127
Josh Coalson57ba6f42002-06-07 05:27:37 +0000128 inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000129 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
130 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000131 inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000132 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
133 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000134
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000135 unsigned get_min_blocksize() const;
136 unsigned get_max_blocksize() const;
137 unsigned get_min_framesize() const;
138 unsigned get_max_framesize() const;
139 unsigned get_sample_rate() const;
140 unsigned get_channels() const;
141 unsigned get_bits_per_sample() const;
142 FLAC__uint64 get_total_samples() const;
143 const FLAC__byte *get_md5sum() const;
144
145 void set_min_blocksize(unsigned value);
146 void set_max_blocksize(unsigned value);
147 void set_min_framesize(unsigned value);
148 void set_max_framesize(unsigned value);
149 void set_sample_rate(unsigned value);
150 void set_channels(unsigned value);
151 void set_bits_per_sample(unsigned value);
152 void set_total_samples(FLAC__uint64 value);
153 void set_md5sum(const FLAC__byte value[16]);
154 };
155
156 class Padding : public Prototype {
157 public:
158 Padding();
Josh Coalsoncc682512002-06-08 04:53:42 +0000159 inline Padding(const Padding &object): Prototype(object) { }
160 inline Padding(const ::FLAC__StreamMetadata &object): Prototype(object) { }
161 inline Padding(const ::FLAC__StreamMetadata *object): Prototype(object) { }
162 inline Padding(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000163 ~Padding();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000164
165 inline void operator=(const Padding &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000166 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
167 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000168
Josh Coalson57ba6f42002-06-07 05:27:37 +0000169 inline bool operator==(const Padding &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000170 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
171 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000172 inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000173 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
174 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000175
Josh Coalsonb2b53582002-05-31 06:20:50 +0000176 void set_length(unsigned length);
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000177 };
178
179 class Application : public Prototype {
180 public:
181 Application();
Josh Coalsoncc682512002-06-08 04:53:42 +0000182 inline Application(const Application &object): Prototype(object) { }
183 inline Application(const ::FLAC__StreamMetadata &object): Prototype(object) { }
184 inline Application(const ::FLAC__StreamMetadata *object): Prototype(object) { }
185 inline Application(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000186 ~Application();
187
Josh Coalsonfb74f102002-05-22 05:33:29 +0000188 inline void operator=(const Application &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000189 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
190 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000191
Josh Coalson57ba6f42002-06-07 05:27:37 +0000192 inline bool operator==(const Application &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000193 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
194 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000195 inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000196 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
197 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000198
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000199 const FLAC__byte *get_id() const;
200 const FLAC__byte *get_data() const;
201
Josh Coalsoncc682512002-06-08 04:53:42 +0000202 void set_id(const FLAC__byte value[4]);
203 bool set_data(const FLAC__byte *data, unsigned length); // this form always copies
204 bool set_data(FLAC__byte *data, unsigned length, bool copy);
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000205 };
206
207 class SeekTable : public Prototype {
208 public:
209 SeekTable();
Josh Coalsoncc682512002-06-08 04:53:42 +0000210 inline SeekTable(const SeekTable &object): Prototype(object) { }
211 inline SeekTable(const ::FLAC__StreamMetadata &object): Prototype(object) { }
212 inline SeekTable(const ::FLAC__StreamMetadata *object): Prototype(object) { }
213 inline SeekTable(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000214 ~SeekTable();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000215
216 inline void operator=(const SeekTable &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000217 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
218 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000219
Josh Coalson57ba6f42002-06-07 05:27:37 +0000220 inline bool operator==(const SeekTable &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 inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000224 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
225 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000226
Josh Coalsonb2b53582002-05-31 06:20:50 +0000227 unsigned get_num_points() const;
Josh Coalsoncc682512002-06-08 04:53:42 +0000228 ::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000229
Josh Coalsoncc682512002-06-08 04:53:42 +0000230 void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
231 bool insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
Josh Coalsonb2b53582002-05-31 06:20:50 +0000232 bool delete_point(unsigned index);
Josh Coalson28e08d82002-06-05 05:56:41 +0000233
234 bool is_legal() const;
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000235 };
236
237 class VorbisComment : public Prototype {
238 public:
Josh Coalsonb2b53582002-05-31 06:20:50 +0000239 class Entry {
240 public:
241 Entry();
242 Entry(const char *field, unsigned field_length);
243 Entry(const char *field_name, const char *field_value, unsigned field_value_length);
244 Entry(const Entry &entry);
245 void operator=(const Entry &entry);
246
247 virtual ~Entry();
248
249 virtual bool is_valid() const;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000250
251 unsigned get_field_length() const;
252 unsigned get_field_name_length() const;
253 unsigned get_field_value_length() const;
254
Josh Coalsoncc682512002-06-08 04:53:42 +0000255 ::FLAC__StreamMetadata_VorbisComment_Entry get_entry() const;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000256 const char *get_field() const;
257 const char *get_field_name() const;
258 const char *get_field_value() const;
259
260 bool set_field(const char *field, unsigned field_length);
261 bool set_field_name(const char *field_name);
262 bool set_field_value(const char *field_value, unsigned field_value_length);
263 protected:
264 bool is_valid_;
Josh Coalsoncc682512002-06-08 04:53:42 +0000265 ::FLAC__StreamMetadata_VorbisComment_Entry entry_;
Josh Coalsonb2b53582002-05-31 06:20:50 +0000266 char *field_name_;
267 unsigned field_name_length_;
268 char *field_value_;
269 unsigned field_value_length_;
270 private:
271 void zero();
272 void clear();
273 void clear_entry();
274 void clear_field_name();
275 void clear_field_value();
276 void construct(const char *field, unsigned field_length);
277 void construct(const char *field_name, const char *field_value, unsigned field_value_length);
278 void compose_field();
279 void parse_field();
280 };
281
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000282 VorbisComment();
Josh Coalsoncc682512002-06-08 04:53:42 +0000283 inline VorbisComment(const VorbisComment &object): Prototype(object) { }
284 inline VorbisComment(const ::FLAC__StreamMetadata &object): Prototype(object) { }
285 inline VorbisComment(const ::FLAC__StreamMetadata *object): Prototype(object) { }
286 inline VorbisComment(::FLAC__StreamMetadata *object, bool copy): Prototype(object, copy) { }
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000287 ~VorbisComment();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000288
289 inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000290 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
291 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000292
Josh Coalson57ba6f42002-06-07 05:27:37 +0000293 inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000294 inline bool operator==(const ::FLAC__StreamMetadata &object) const { return Prototype::operator==(object); }
295 inline bool operator==(const ::FLAC__StreamMetadata *object) const { return Prototype::operator==(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000296 inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); }
Josh Coalsoncc682512002-06-08 04:53:42 +0000297 inline bool operator!=(const ::FLAC__StreamMetadata &object) const { return Prototype::operator!=(object); }
298 inline bool operator!=(const ::FLAC__StreamMetadata *object) const { return Prototype::operator!=(object); }
Josh Coalson57ba6f42002-06-07 05:27:37 +0000299
Josh Coalsonb2b53582002-05-31 06:20:50 +0000300 unsigned get_num_comments() const;
Josh Coalsoncc682512002-06-08 04:53:42 +0000301 Entry get_vendor_string() const; // only the Entry's field name should be used
Josh Coalsonb2b53582002-05-31 06:20:50 +0000302 Entry get_comment(unsigned index) const;
303
Josh Coalsoncc682512002-06-08 04:53:42 +0000304 bool set_vendor_string(const Entry &entry); // only the Entry's field name will be used
Josh Coalsonb2b53582002-05-31 06:20:50 +0000305 bool set_comment(unsigned index, const Entry &entry);
306 bool insert_comment(unsigned index, const Entry &entry);
307 bool delete_comment(unsigned index);
Josh Coalsonfb74f102002-05-22 05:33:29 +0000308 };
309
Josh Coalsonb2b53582002-05-31 06:20:50 +0000310
Josh Coalsonfb74f102002-05-22 05:33:29 +0000311 // ============================================================
312 //
313 // Level 0
314 //
315 // ============================================================
316
317 bool get_streaminfo(const char *filename, StreamInfo &streaminfo);
318
Josh Coalsonb2b53582002-05-31 06:20:50 +0000319
Josh Coalsonfb74f102002-05-22 05:33:29 +0000320 // ============================================================
321 //
322 // Level 1
323 //
324 // ----------------------------------------------------------
325 //
326 // The flow through the iterator in the C++ layer is similar
327 // to the C layer:
328 //
329 // * Create a SimpleIterator instance
330 // * Check SimpleIterator::is_valid()
331 // * Call SimpleIterator::init() and check the return
332 // * Traverse and/or edit. Edits are written to file
333 // immediately.
334 // * Destroy the SimpleIterator instance
335 //
336 // ----------------------------------------------------------
337 //
338 // The ownership of pointers in the C++ layer follows that in
339 // the C layer, i.e.
340 // * The objects returned by get_block() are yours to
341 // modify, but changes are not reflected in the FLAC file
342 // until you call set_block(). The objects are also
343 // yours to delete; they are not automatically deleted
344 // when passed to set_block() or insert_block_after().
345 //
346 // ============================================================
347
348 class SimpleIterator {
349 public:
350 class Status {
351 public:
Josh Coalsoncc682512002-06-08 04:53:42 +0000352 inline Status(::FLAC__Metadata_SimpleIteratorStatus status): status_(status) { }
353 inline operator ::FLAC__Metadata_SimpleIteratorStatus() const { return status_; }
354 inline const char *as_cstring() const { return ::FLAC__Metadata_SimpleIteratorStatusString[status_]; }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000355 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000356 ::FLAC__Metadata_SimpleIteratorStatus status_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000357 };
358
359 SimpleIterator();
360 virtual ~SimpleIterator();
361
362 bool init(const char *filename, bool preserve_file_stats = false);
363
364 bool is_valid() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000365 Status status();
366 bool is_writable() const;
367
368 bool next();
369 bool prev();
370
Josh Coalsoncc682512002-06-08 04:53:42 +0000371 ::FLAC__MetadataType get_block_type() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000372 Prototype *get_block();
373 bool set_block(Prototype *block, bool use_padding = true);
374 bool insert_block_after(Prototype *block, bool use_padding = true);
375 bool delete_block(bool use_padding = true);
376
377 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000378 ::FLAC__Metadata_SimpleIterator *iterator_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000379 void clear();
380 };
381
Josh Coalsonb2b53582002-05-31 06:20:50 +0000382
Josh Coalsonfb74f102002-05-22 05:33:29 +0000383 // ============================================================
384 //
385 // Level 2
386 //
387 // ----------------------------------------------------------
388 //
389 // The flow through the iterator in the C++ layer is similar
390 // to the C layer:
391 //
392 // * Create a Chain instance
393 // * Check Chain::is_valid()
394 // * Call Chain::read() and check the return
395 // * Traverse and/or edit with an Iterator or with
396 // Chain::merge_padding() or Chain::sort_padding()
397 // * Write changes back to FLAC file with Chain::write()
398 // * Destroy the Chain instance
399 //
400 // ----------------------------------------------------------
401 //
402 // The ownership of pointers in the C++ layer follows that in
403 // the C layer, i.e.
404 // * The objects returned by Iterator::get_block() are
405 // owned by the iterator and should not be deleted.
406 // When you modify the block, you are directly editing
407 // what's in the chain and do not need to call
408 // Iterator::set_block(). However the changes will not
409 // be reflected in the FLAC file until the chain is
410 // written with Chain::write().
411 //
412 // * When you pass an object to Iterator::set_block(),
413 // Iterator::insert_block_before(), or
414 // Iterator::insert_block_after(), the iterator takes
415 // ownership of the block and it will be deleted with the
416 // chain.
417 //
418 // ============================================================
419
420 class Chain {
421 public:
422 class Status {
423 public:
Josh Coalsoncc682512002-06-08 04:53:42 +0000424 inline Status(::FLAC__Metadata_ChainStatus status): status_(status) { }
425 inline operator ::FLAC__Metadata_ChainStatus() const { return status_; }
426 inline const char *as_cstring() const { return ::FLAC__Metadata_ChainStatusString[status_]; }
Josh Coalsonfb74f102002-05-22 05:33:29 +0000427 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000428 ::FLAC__Metadata_ChainStatus status_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000429 };
430
431 Chain();
432 virtual ~Chain();
433
434 friend class Iterator;
435
436 bool is_valid() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000437 Status status();
438
439 bool read(const char *filename);
440 bool write(bool use_padding = true, bool preserve_file_stats = false);
441
442 void merge_padding();
443 void sort_padding();
444
445 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000446 ::FLAC__Metadata_Chain *chain_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000447 virtual void clear();
448 };
449
450 class Iterator {
451 public:
452 Iterator();
453 virtual ~Iterator();
454
455 bool is_valid() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000456
457 void init(Chain *chain);
458
459 bool next();
460 bool prev();
461
Josh Coalsoncc682512002-06-08 04:53:42 +0000462 ::FLAC__MetadataType get_block_type() const;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000463 Prototype *get_block();
464 bool set_block(Prototype *block);
465 bool delete_block(bool replace_with_padding);
466 bool insert_block_before(Prototype *block);
467 bool insert_block_after(Prototype *block);
468
469 protected:
Josh Coalsoncc682512002-06-08 04:53:42 +0000470 ::FLAC__Metadata_Iterator *iterator_;
Josh Coalsonfb74f102002-05-22 05:33:29 +0000471 virtual void clear();
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000472 };
473
474 };
475};
476
477#endif