1 /* libFLAC++ - Free Lossless Audio Codec library
2 * Copyright (C) 2002 Josh Coalson
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.
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.
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.
20 #ifndef FLACPP__METADATA_H
21 #define FLACPP__METADATA_H
23 #include "FLAC/metadata.h"
25 // ===============================================================
27 // Full documentation for the metadata interface can be found
28 // in the C layer in include/FLAC/metadata.h
30 // ===============================================================
36 // ============================================================
40 // ============================================================
44 Prototype *clone(const Prototype *);
46 // NOTE: When the get_*() methods return you a const pointer,
47 // DO NOT disobey and write into it. Always use the set_*()
50 // base class for all metadata blocks
53 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
58 void operator=(const Prototype &);
59 void operator=(const ::FLAC__StreamMetadata &); // this form always copies
60 void operator=(const ::FLAC__StreamMetadata *); // this form always copies
64 ::FLAC__StreamMetadata *object_;
68 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;
75 friend class SimpleIterator;
76 friend class Iterator;
78 inline bool is_valid() const;
80 bool get_is_last() const;
81 FLAC__MetadataType get_type() const;
82 unsigned get_length() const; // NOTE: does not include the header, per spec
84 void set_is_last(bool);
86 Prototype(); // Private and undefined so you can't use it
88 // These are used only by Iterator
90 inline void set_reference(bool x) { is_reference_ = x; }
93 inline bool Prototype::operator==(const Prototype &object) const
94 { return ::FLAC__metadata_object_is_equal(object_, object.object_); }
96 inline bool Prototype::operator==(const ::FLAC__StreamMetadata &object) const
97 { return ::FLAC__metadata_object_is_equal(object_, &object); }
99 inline bool Prototype::operator==(const ::FLAC__StreamMetadata *object) const
100 { return ::FLAC__metadata_object_is_equal(object_, object); }
102 inline bool Prototype::operator!=(const Prototype &object) const
103 { return !operator==(object); }
105 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata &object) const
106 { return !operator==(object); }
108 inline bool Prototype::operator!=(const ::FLAC__StreamMetadata *object) const
109 { return !operator==(object); }
111 inline bool Prototype::is_valid() const
112 { return 0 != object_; }
115 class StreamInfo : public Prototype {
118 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) { }
124 inline void operator=(const StreamInfo &object) { Prototype::operator=(object); }
125 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
126 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
128 inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); }
129 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); }
131 inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); }
132 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); }
135 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;
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]);
156 class Padding : public Prototype {
159 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) { }
165 inline void operator=(const Padding &object) { Prototype::operator=(object); }
166 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
167 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
169 inline bool operator==(const Padding &object) const { return Prototype::operator==(object); }
170 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); }
172 inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); }
173 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); }
176 void set_length(unsigned length);
179 class Application : public Prototype {
182 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) { }
188 inline void operator=(const Application &object) { Prototype::operator=(object); }
189 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
190 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
192 inline bool operator==(const Application &object) const { return Prototype::operator==(object); }
193 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); }
195 inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); }
196 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); }
199 const FLAC__byte *get_id() const;
200 const FLAC__byte *get_data() const;
202 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);
207 class SeekTable : public Prototype {
210 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) { }
216 inline void operator=(const SeekTable &object) { Prototype::operator=(object); }
217 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
218 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
220 inline bool operator==(const SeekTable &object) const { return Prototype::operator==(object); }
221 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); }
223 inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); }
224 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); }
227 unsigned get_num_points() const;
228 ::FLAC__StreamMetadata_SeekPoint get_point(unsigned index) const;
230 void set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
231 bool insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point);
232 bool delete_point(unsigned index);
234 bool is_legal() const;
237 class VorbisComment : public Prototype {
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);
249 virtual bool is_valid() const;
251 unsigned get_field_length() const;
252 unsigned get_field_name_length() const;
253 unsigned get_field_value_length() const;
255 ::FLAC__StreamMetadata_VorbisComment_Entry get_entry() const;
256 const char *get_field() const;
257 const char *get_field_name() const;
258 const char *get_field_value() const;
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);
265 ::FLAC__StreamMetadata_VorbisComment_Entry entry_;
267 unsigned field_name_length_;
269 unsigned field_value_length_;
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();
283 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) { }
289 inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
290 inline void operator=(const ::FLAC__StreamMetadata &object) { Prototype::operator=(object); }
291 inline void operator=(const ::FLAC__StreamMetadata *object) { Prototype::operator=(object); }
293 inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); }
294 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); }
296 inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); }
297 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); }
300 unsigned get_num_comments() const;
301 Entry get_vendor_string() const; // only the Entry's field name should be used
302 Entry get_comment(unsigned index) const;
304 bool set_vendor_string(const Entry &entry); // only the Entry's field name will be used
305 bool set_comment(unsigned index, const Entry &entry);
306 bool insert_comment(unsigned index, const Entry &entry);
307 bool delete_comment(unsigned index);
311 // ============================================================
315 // ============================================================
317 bool get_streaminfo(const char *filename, StreamInfo &streaminfo);
320 // ============================================================
324 // ----------------------------------------------------------
326 // The flow through the iterator in the C++ layer is similar
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
334 // * Destroy the SimpleIterator instance
336 // ----------------------------------------------------------
338 // The ownership of pointers in the C++ layer follows that in
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().
346 // ============================================================
348 class SimpleIterator {
352 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_]; }
356 ::FLAC__Metadata_SimpleIteratorStatus status_;
360 virtual ~SimpleIterator();
362 bool init(const char *filename, bool preserve_file_stats = false);
364 bool is_valid() const;
366 bool is_writable() const;
371 ::FLAC__MetadataType get_block_type() const;
372 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);
378 ::FLAC__Metadata_SimpleIterator *iterator_;
383 // ============================================================
387 // ----------------------------------------------------------
389 // The flow through the iterator in the C++ layer is similar
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
400 // ----------------------------------------------------------
402 // The ownership of pointers in the C++ layer follows that in
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().
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
418 // ============================================================
424 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_]; }
428 ::FLAC__Metadata_ChainStatus status_;
434 friend class Iterator;
436 bool is_valid() const;
439 bool read(const char *filename);
440 bool write(bool use_padding = true, bool preserve_file_stats = false);
442 void merge_padding();
446 ::FLAC__Metadata_Chain *chain_;
447 virtual void clear();
455 bool is_valid() const;
457 void init(Chain &chain);
462 ::FLAC__MetadataType get_block_type() const;
463 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);
470 ::FLAC__Metadata_Iterator *iterator_;
471 virtual void clear();