blob: 7e0cbbd8889969c29761b29f0f0b243e8507c645 [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 Coalsonfda98fb2002-05-17 06:33:39 +000042 // NOTE: When the get_*() methods return you a const pointer,
Josh Coalsonfb74f102002-05-22 05:33:29 +000043 // DO NOT disobey and write into it. Always use the set_*()
Josh Coalsonfda98fb2002-05-17 06:33:39 +000044 // methods.
45
46 // base class for all metadata blocks
47 class Prototype {
48 protected:
49 Prototype(::FLAC__StreamMetaData *object, bool copy);
50 virtual ~Prototype();
51
Josh Coalsonfb74f102002-05-22 05:33:29 +000052 void operator=(const Prototype &);
53 void operator=(const ::FLAC__StreamMetaData &);
54 void operator=(const ::FLAC__StreamMetaData *);
55
56 virtual void clear();
57
Josh Coalsonfda98fb2002-05-17 06:33:39 +000058 ::FLAC__StreamMetaData *object_;
59 public:
Josh Coalsonfb74f102002-05-22 05:33:29 +000060 friend class SimpleIterator;
61 friend class Iterator;
62
Josh Coalsonfda98fb2002-05-17 06:33:39 +000063 inline bool is_valid() const { return 0 != object_; }
64 inline operator bool() const { return is_valid(); }
65
66 bool get_is_last() const;
67 FLAC__MetaDataType get_type() const;
68 unsigned get_length() const; // NOTE: does not include the header, per spec
Josh Coalsonfb74f102002-05-22 05:33:29 +000069 private:
Josh Coalson5ac8bd12002-05-29 05:53:57 +000070 Prototype(); // Private and undefined so you can't use it
Josh Coalsonfb74f102002-05-22 05:33:29 +000071
72 // These are used only by Iterator
73 bool is_reference_;
74 inline void set_reference(bool x) { is_reference_ = x; }
Josh Coalsonfda98fb2002-05-17 06:33:39 +000075 };
76
77 class StreamInfo : public Prototype {
78 public:
79 StreamInfo();
80 StreamInfo(::FLAC__StreamMetaData *object, bool copy = false);
81 ~StreamInfo();
82
Josh Coalsonfb74f102002-05-22 05:33:29 +000083 inline void operator=(const StreamInfo &object) { Prototype::operator=(object); }
84 inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
85 inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
86
Josh Coalsonfda98fb2002-05-17 06:33:39 +000087 unsigned get_min_blocksize() const;
88 unsigned get_max_blocksize() const;
89 unsigned get_min_framesize() const;
90 unsigned get_max_framesize() const;
91 unsigned get_sample_rate() const;
92 unsigned get_channels() const;
93 unsigned get_bits_per_sample() const;
94 FLAC__uint64 get_total_samples() const;
95 const FLAC__byte *get_md5sum() const;
96
97 void set_min_blocksize(unsigned value);
98 void set_max_blocksize(unsigned value);
99 void set_min_framesize(unsigned value);
100 void set_max_framesize(unsigned value);
101 void set_sample_rate(unsigned value);
102 void set_channels(unsigned value);
103 void set_bits_per_sample(unsigned value);
104 void set_total_samples(FLAC__uint64 value);
105 void set_md5sum(const FLAC__byte value[16]);
106 };
107
108 class Padding : public Prototype {
109 public:
110 Padding();
111 Padding(::FLAC__StreamMetaData *object, bool copy = false);
112 ~Padding();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000113
114 inline void operator=(const Padding &object) { Prototype::operator=(object); }
115 inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
116 inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000117
118 void set_length(unsigned length);
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000119 };
120
121 class Application : public Prototype {
122 public:
123 Application();
124 Application(::FLAC__StreamMetaData *object, bool copy = false);
125 ~Application();
126
Josh Coalsonfb74f102002-05-22 05:33:29 +0000127 inline void operator=(const Application &object) { Prototype::operator=(object); }
128 inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
129 inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
130
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000131 const FLAC__byte *get_id() const;
132 const FLAC__byte *get_data() const;
133
134 void set_id(FLAC__byte value[4]);
135 bool set_data(FLAC__byte *data, unsigned length, bool copy = false);
136 };
137
138 class SeekTable : public Prototype {
139 public:
140 SeekTable();
141 SeekTable(::FLAC__StreamMetaData *object, bool copy = false);
142 ~SeekTable();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000143
144 inline void operator=(const SeekTable &object) { Prototype::operator=(object); }
145 inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
146 inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000147
148 unsigned get_num_points() const;
149 ::FLAC__StreamMetaData_SeekPoint get_point(unsigned index) const;
150
151 void set_point(unsigned index, const ::FLAC__StreamMetaData_SeekPoint &point);
152 bool insert_point(unsigned index, const ::FLAC__StreamMetaData_SeekPoint &point);
153 bool delete_point(unsigned index);
Josh Coalson28e08d82002-06-05 05:56:41 +0000154
155 bool is_legal() const;
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000156 };
157
158 class VorbisComment : public Prototype {
159 public:
Josh Coalsonb2b53582002-05-31 06:20:50 +0000160 class Entry {
161 public:
162 Entry();
163 Entry(const char *field, unsigned field_length);
164 Entry(const char *field_name, const char *field_value, unsigned field_value_length);
165 Entry(const Entry &entry);
166 void operator=(const Entry &entry);
167
168 virtual ~Entry();
169
170 virtual bool is_valid() const;
171 inline operator bool() const { return is_valid(); }
172
173 unsigned get_field_length() const;
174 unsigned get_field_name_length() const;
175 unsigned get_field_value_length() const;
176
177 ::FLAC__StreamMetaData_VorbisComment_Entry get_entry() const;
178 const char *get_field() const;
179 const char *get_field_name() const;
180 const char *get_field_value() const;
181
182 bool set_field(const char *field, unsigned field_length);
183 bool set_field_name(const char *field_name);
184 bool set_field_value(const char *field_value, unsigned field_value_length);
185 protected:
186 bool is_valid_;
187 ::FLAC__StreamMetaData_VorbisComment_Entry entry_;
188 char *field_name_;
189 unsigned field_name_length_;
190 char *field_value_;
191 unsigned field_value_length_;
192 private:
193 void zero();
194 void clear();
195 void clear_entry();
196 void clear_field_name();
197 void clear_field_value();
198 void construct(const char *field, unsigned field_length);
199 void construct(const char *field_name, const char *field_value, unsigned field_value_length);
200 void compose_field();
201 void parse_field();
202 };
203
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000204 VorbisComment();
205 VorbisComment(::FLAC__StreamMetaData *object, bool copy = false);
206 ~VorbisComment();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000207
208 inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
209 inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
210 inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000211
212 unsigned get_num_comments() const;
213 Entry get_vendor_string() const;
214 Entry get_comment(unsigned index) const;
215
216 bool set_vendor_string(const Entry &entry);
217 bool set_comment(unsigned index, const Entry &entry);
218 bool insert_comment(unsigned index, const Entry &entry);
219 bool delete_comment(unsigned index);
Josh Coalsonfb74f102002-05-22 05:33:29 +0000220 };
221
Josh Coalsonb2b53582002-05-31 06:20:50 +0000222
Josh Coalsonfb74f102002-05-22 05:33:29 +0000223 // ============================================================
224 //
225 // Level 0
226 //
227 // ============================================================
228
229 bool get_streaminfo(const char *filename, StreamInfo &streaminfo);
230
Josh Coalsonb2b53582002-05-31 06:20:50 +0000231
Josh Coalsonfb74f102002-05-22 05:33:29 +0000232 // ============================================================
233 //
234 // Level 1
235 //
236 // ----------------------------------------------------------
237 //
238 // The flow through the iterator in the C++ layer is similar
239 // to the C layer:
240 //
241 // * Create a SimpleIterator instance
242 // * Check SimpleIterator::is_valid()
243 // * Call SimpleIterator::init() and check the return
244 // * Traverse and/or edit. Edits are written to file
245 // immediately.
246 // * Destroy the SimpleIterator instance
247 //
248 // ----------------------------------------------------------
249 //
250 // The ownership of pointers in the C++ layer follows that in
251 // the C layer, i.e.
252 // * The objects returned by get_block() are yours to
253 // modify, but changes are not reflected in the FLAC file
254 // until you call set_block(). The objects are also
255 // yours to delete; they are not automatically deleted
256 // when passed to set_block() or insert_block_after().
257 //
258 // ============================================================
259
260 class SimpleIterator {
261 public:
262 class Status {
263 public:
264 inline Status(::FLAC__MetaData_SimpleIteratorStatus status): status_(status) { }
265 inline operator ::FLAC__MetaData_SimpleIteratorStatus() const { return status_; }
266 inline const char *as_cstring() const { return ::FLAC__MetaData_SimpleIteratorStatusString[status_]; }
267 protected:
268 ::FLAC__MetaData_SimpleIteratorStatus status_;
269 };
270
271 SimpleIterator();
272 virtual ~SimpleIterator();
273
274 bool init(const char *filename, bool preserve_file_stats = false);
275
276 bool is_valid() const;
277 inline operator bool() const { return is_valid(); }
278 Status status();
279 bool is_writable() const;
280
281 bool next();
282 bool prev();
283
284 ::FLAC__MetaDataType get_block_type() const;
285 Prototype *get_block();
286 bool set_block(Prototype *block, bool use_padding = true);
287 bool insert_block_after(Prototype *block, bool use_padding = true);
288 bool delete_block(bool use_padding = true);
289
290 protected:
291 ::FLAC__MetaData_SimpleIterator *iterator_;
292 void clear();
293 };
294
Josh Coalsonb2b53582002-05-31 06:20:50 +0000295
Josh Coalsonfb74f102002-05-22 05:33:29 +0000296 // ============================================================
297 //
298 // Level 2
299 //
300 // ----------------------------------------------------------
301 //
302 // The flow through the iterator in the C++ layer is similar
303 // to the C layer:
304 //
305 // * Create a Chain instance
306 // * Check Chain::is_valid()
307 // * Call Chain::read() and check the return
308 // * Traverse and/or edit with an Iterator or with
309 // Chain::merge_padding() or Chain::sort_padding()
310 // * Write changes back to FLAC file with Chain::write()
311 // * Destroy the Chain instance
312 //
313 // ----------------------------------------------------------
314 //
315 // The ownership of pointers in the C++ layer follows that in
316 // the C layer, i.e.
317 // * The objects returned by Iterator::get_block() are
318 // owned by the iterator and should not be deleted.
319 // When you modify the block, you are directly editing
320 // what's in the chain and do not need to call
321 // Iterator::set_block(). However the changes will not
322 // be reflected in the FLAC file until the chain is
323 // written with Chain::write().
324 //
325 // * When you pass an object to Iterator::set_block(),
326 // Iterator::insert_block_before(), or
327 // Iterator::insert_block_after(), the iterator takes
328 // ownership of the block and it will be deleted with the
329 // chain.
330 //
331 // ============================================================
332
333 class Chain {
334 public:
335 class Status {
336 public:
337 inline Status(::FLAC__MetaData_ChainStatus status): status_(status) { }
338 inline operator ::FLAC__MetaData_ChainStatus() const { return status_; }
339 inline const char *as_cstring() const { return ::FLAC__MetaData_ChainStatusString[status_]; }
340 protected:
341 ::FLAC__MetaData_ChainStatus status_;
342 };
343
344 Chain();
345 virtual ~Chain();
346
347 friend class Iterator;
348
349 bool is_valid() const;
350 inline operator bool() const { return is_valid(); }
351 Status status();
352
353 bool read(const char *filename);
354 bool write(bool use_padding = true, bool preserve_file_stats = false);
355
356 void merge_padding();
357 void sort_padding();
358
359 protected:
360 ::FLAC__MetaData_Chain *chain_;
361 virtual void clear();
362 };
363
364 class Iterator {
365 public:
366 Iterator();
367 virtual ~Iterator();
368
369 bool is_valid() const;
370 inline operator bool() const { return is_valid(); }
371
372 void init(Chain *chain);
373
374 bool next();
375 bool prev();
376
377 ::FLAC__MetaDataType get_block_type() const;
378 Prototype *get_block();
379 bool set_block(Prototype *block);
380 bool delete_block(bool replace_with_padding);
381 bool insert_block_before(Prototype *block);
382 bool insert_block_after(Prototype *block);
383
384 protected:
385 ::FLAC__MetaData_Iterator *iterator_;
386 virtual void clear();
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000387 };
388
389 };
390};
391
392#endif