blob: 32c6ebbbf0b3e28941e675b59e0268257a64c5ff [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 Coalsonfda98fb2002-05-17 06:33:39 +0000154 };
155
156 class VorbisComment : public Prototype {
157 public:
Josh Coalsonb2b53582002-05-31 06:20:50 +0000158 class Entry {
159 public:
160 Entry();
161 Entry(const char *field, unsigned field_length);
162 Entry(const char *field_name, const char *field_value, unsigned field_value_length);
163 Entry(const Entry &entry);
164 void operator=(const Entry &entry);
165
166 virtual ~Entry();
167
168 virtual bool is_valid() const;
169 inline operator bool() const { return is_valid(); }
170
171 unsigned get_field_length() const;
172 unsigned get_field_name_length() const;
173 unsigned get_field_value_length() const;
174
175 ::FLAC__StreamMetaData_VorbisComment_Entry get_entry() const;
176 const char *get_field() const;
177 const char *get_field_name() const;
178 const char *get_field_value() const;
179
180 bool set_field(const char *field, unsigned field_length);
181 bool set_field_name(const char *field_name);
182 bool set_field_value(const char *field_value, unsigned field_value_length);
183 protected:
184 bool is_valid_;
185 ::FLAC__StreamMetaData_VorbisComment_Entry entry_;
186 char *field_name_;
187 unsigned field_name_length_;
188 char *field_value_;
189 unsigned field_value_length_;
190 private:
191 void zero();
192 void clear();
193 void clear_entry();
194 void clear_field_name();
195 void clear_field_value();
196 void construct(const char *field, unsigned field_length);
197 void construct(const char *field_name, const char *field_value, unsigned field_value_length);
198 void compose_field();
199 void parse_field();
200 };
201
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000202 VorbisComment();
203 VorbisComment(::FLAC__StreamMetaData *object, bool copy = false);
204 ~VorbisComment();
Josh Coalsonfb74f102002-05-22 05:33:29 +0000205
206 inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
207 inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
208 inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
Josh Coalsonb2b53582002-05-31 06:20:50 +0000209
210 unsigned get_num_comments() const;
211 Entry get_vendor_string() const;
212 Entry get_comment(unsigned index) const;
213
214 bool set_vendor_string(const Entry &entry);
215 bool set_comment(unsigned index, const Entry &entry);
216 bool insert_comment(unsigned index, const Entry &entry);
217 bool delete_comment(unsigned index);
Josh Coalsonfb74f102002-05-22 05:33:29 +0000218 };
219
Josh Coalsonb2b53582002-05-31 06:20:50 +0000220
Josh Coalsonfb74f102002-05-22 05:33:29 +0000221 // ============================================================
222 //
223 // Level 0
224 //
225 // ============================================================
226
227 bool get_streaminfo(const char *filename, StreamInfo &streaminfo);
228
Josh Coalsonb2b53582002-05-31 06:20:50 +0000229
Josh Coalsonfb74f102002-05-22 05:33:29 +0000230 // ============================================================
231 //
232 // Level 1
233 //
234 // ----------------------------------------------------------
235 //
236 // The flow through the iterator in the C++ layer is similar
237 // to the C layer:
238 //
239 // * Create a SimpleIterator instance
240 // * Check SimpleIterator::is_valid()
241 // * Call SimpleIterator::init() and check the return
242 // * Traverse and/or edit. Edits are written to file
243 // immediately.
244 // * Destroy the SimpleIterator instance
245 //
246 // ----------------------------------------------------------
247 //
248 // The ownership of pointers in the C++ layer follows that in
249 // the C layer, i.e.
250 // * The objects returned by get_block() are yours to
251 // modify, but changes are not reflected in the FLAC file
252 // until you call set_block(). The objects are also
253 // yours to delete; they are not automatically deleted
254 // when passed to set_block() or insert_block_after().
255 //
256 // ============================================================
257
258 class SimpleIterator {
259 public:
260 class Status {
261 public:
262 inline Status(::FLAC__MetaData_SimpleIteratorStatus status): status_(status) { }
263 inline operator ::FLAC__MetaData_SimpleIteratorStatus() const { return status_; }
264 inline const char *as_cstring() const { return ::FLAC__MetaData_SimpleIteratorStatusString[status_]; }
265 protected:
266 ::FLAC__MetaData_SimpleIteratorStatus status_;
267 };
268
269 SimpleIterator();
270 virtual ~SimpleIterator();
271
272 bool init(const char *filename, bool preserve_file_stats = false);
273
274 bool is_valid() const;
275 inline operator bool() const { return is_valid(); }
276 Status status();
277 bool is_writable() const;
278
279 bool next();
280 bool prev();
281
282 ::FLAC__MetaDataType get_block_type() const;
283 Prototype *get_block();
284 bool set_block(Prototype *block, bool use_padding = true);
285 bool insert_block_after(Prototype *block, bool use_padding = true);
286 bool delete_block(bool use_padding = true);
287
288 protected:
289 ::FLAC__MetaData_SimpleIterator *iterator_;
290 void clear();
291 };
292
Josh Coalsonb2b53582002-05-31 06:20:50 +0000293
Josh Coalsonfb74f102002-05-22 05:33:29 +0000294 // ============================================================
295 //
296 // Level 2
297 //
298 // ----------------------------------------------------------
299 //
300 // The flow through the iterator in the C++ layer is similar
301 // to the C layer:
302 //
303 // * Create a Chain instance
304 // * Check Chain::is_valid()
305 // * Call Chain::read() and check the return
306 // * Traverse and/or edit with an Iterator or with
307 // Chain::merge_padding() or Chain::sort_padding()
308 // * Write changes back to FLAC file with Chain::write()
309 // * Destroy the Chain instance
310 //
311 // ----------------------------------------------------------
312 //
313 // The ownership of pointers in the C++ layer follows that in
314 // the C layer, i.e.
315 // * The objects returned by Iterator::get_block() are
316 // owned by the iterator and should not be deleted.
317 // When you modify the block, you are directly editing
318 // what's in the chain and do not need to call
319 // Iterator::set_block(). However the changes will not
320 // be reflected in the FLAC file until the chain is
321 // written with Chain::write().
322 //
323 // * When you pass an object to Iterator::set_block(),
324 // Iterator::insert_block_before(), or
325 // Iterator::insert_block_after(), the iterator takes
326 // ownership of the block and it will be deleted with the
327 // chain.
328 //
329 // ============================================================
330
331 class Chain {
332 public:
333 class Status {
334 public:
335 inline Status(::FLAC__MetaData_ChainStatus status): status_(status) { }
336 inline operator ::FLAC__MetaData_ChainStatus() const { return status_; }
337 inline const char *as_cstring() const { return ::FLAC__MetaData_ChainStatusString[status_]; }
338 protected:
339 ::FLAC__MetaData_ChainStatus status_;
340 };
341
342 Chain();
343 virtual ~Chain();
344
345 friend class Iterator;
346
347 bool is_valid() const;
348 inline operator bool() const { return is_valid(); }
349 Status status();
350
351 bool read(const char *filename);
352 bool write(bool use_padding = true, bool preserve_file_stats = false);
353
354 void merge_padding();
355 void sort_padding();
356
357 protected:
358 ::FLAC__MetaData_Chain *chain_;
359 virtual void clear();
360 };
361
362 class Iterator {
363 public:
364 Iterator();
365 virtual ~Iterator();
366
367 bool is_valid() const;
368 inline operator bool() const { return is_valid(); }
369
370 void init(Chain *chain);
371
372 bool next();
373 bool prev();
374
375 ::FLAC__MetaDataType get_block_type() const;
376 Prototype *get_block();
377 bool set_block(Prototype *block);
378 bool delete_block(bool replace_with_padding);
379 bool insert_block_before(Prototype *block);
380 bool insert_block_after(Prototype *block);
381
382 protected:
383 ::FLAC__MetaData_Iterator *iterator_;
384 virtual void clear();
Josh Coalsonfda98fb2002-05-17 06:33:39 +0000385 };
386
387 };
388};
389
390#endif