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 #include "FLAC++/metadata.h"
21 #include "FLAC/assert.h"
22 #include <stdlib.h> // for malloc(), free()
23 #include <string.h> // for memcpy() etc.
28 // local utility routines
32 Prototype *construct_block(::FLAC__StreamMetadata *object)
35 switch(object->type) {
36 case FLAC__METADATA_TYPE_STREAMINFO:
37 ret = new StreamInfo(object, /*copy=*/false);
39 case FLAC__METADATA_TYPE_PADDING:
40 ret = new Padding(object, /*copy=*/false);
42 case FLAC__METADATA_TYPE_APPLICATION:
43 ret = new Application(object, /*copy=*/false);
45 case FLAC__METADATA_TYPE_SEEKTABLE:
46 ret = new SeekTable(object, /*copy=*/false);
48 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
49 ret = new VorbisComment(object, /*copy=*/false);
51 case FLAC__METADATA_TYPE_CUESHEET:
52 ret = new CueSheet(object, /*copy=*/false);
63 FLACPP_API Prototype *clone(const Prototype *object)
65 FLAC__ASSERT(0 != object);
67 const StreamInfo *streaminfo = dynamic_cast<const StreamInfo *>(object);
68 const Padding *padding = dynamic_cast<const Padding *>(object);
69 const Application *application = dynamic_cast<const Application *>(object);
70 const SeekTable *seektable = dynamic_cast<const SeekTable *>(object);
71 const VorbisComment *vorbiscomment = dynamic_cast<const VorbisComment *>(object);
74 return new StreamInfo(*streaminfo);
76 return new Padding(*padding);
77 else if(0 != application)
78 return new Application(*application);
79 else if(0 != seektable)
80 return new SeekTable(*seektable);
81 else if(0 != vorbiscomment)
82 return new VorbisComment(*vorbiscomment);
93 Prototype::Prototype(const Prototype &object):
94 object_(::FLAC__metadata_object_clone(object.object_)),
97 FLAC__ASSERT(object.is_valid());
100 Prototype::Prototype(const ::FLAC__StreamMetadata &object):
101 object_(::FLAC__metadata_object_clone(&object)),
106 Prototype::Prototype(const ::FLAC__StreamMetadata *object):
107 object_(::FLAC__metadata_object_clone(object)),
110 FLAC__ASSERT(0 != object);
113 Prototype::Prototype(::FLAC__StreamMetadata *object, bool copy):
114 object_(copy? ::FLAC__metadata_object_clone(object) : object),
117 FLAC__ASSERT(0 != object);
120 Prototype::~Prototype()
125 void Prototype::clear()
127 if(0 != object_ && !is_reference_)
128 FLAC__metadata_object_delete(object_);
132 void Prototype::operator=(const Prototype &object)
134 FLAC__ASSERT(object.is_valid());
136 is_reference_ = false;
137 object_ = ::FLAC__metadata_object_clone(object.object_);
140 void Prototype::operator=(const ::FLAC__StreamMetadata &object)
143 is_reference_ = false;
144 object_ = ::FLAC__metadata_object_clone(&object);
147 void Prototype::operator=(const ::FLAC__StreamMetadata *object)
149 FLAC__ASSERT(0 != object);
151 is_reference_ = false;
152 object_ = ::FLAC__metadata_object_clone(object);
155 bool Prototype::get_is_last() const
157 FLAC__ASSERT(is_valid());
158 return (bool)object_->is_last;
161 FLAC__MetadataType Prototype::get_type() const
163 FLAC__ASSERT(is_valid());
164 return object_->type;
167 unsigned Prototype::get_length() const
169 FLAC__ASSERT(is_valid());
170 return object_->length;
173 void Prototype::set_is_last(bool value)
175 FLAC__ASSERT(is_valid());
176 object_->is_last = value;
184 StreamInfo::StreamInfo():
185 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO), /*copy=*/false)
188 StreamInfo::~StreamInfo()
191 unsigned StreamInfo::get_min_blocksize() const
193 FLAC__ASSERT(is_valid());
194 return object_->data.stream_info.min_blocksize;
197 unsigned StreamInfo::get_max_blocksize() const
199 FLAC__ASSERT(is_valid());
200 return object_->data.stream_info.max_blocksize;
203 unsigned StreamInfo::get_min_framesize() const
205 FLAC__ASSERT(is_valid());
206 return object_->data.stream_info.min_framesize;
209 unsigned StreamInfo::get_max_framesize() const
211 FLAC__ASSERT(is_valid());
212 return object_->data.stream_info.max_framesize;
215 unsigned StreamInfo::get_sample_rate() const
217 FLAC__ASSERT(is_valid());
218 return object_->data.stream_info.sample_rate;
221 unsigned StreamInfo::get_channels() const
223 FLAC__ASSERT(is_valid());
224 return object_->data.stream_info.channels;
227 unsigned StreamInfo::get_bits_per_sample() const
229 FLAC__ASSERT(is_valid());
230 return object_->data.stream_info.bits_per_sample;
233 FLAC__uint64 StreamInfo::get_total_samples() const
235 FLAC__ASSERT(is_valid());
236 return object_->data.stream_info.total_samples;
239 const FLAC__byte *StreamInfo::get_md5sum() const
241 FLAC__ASSERT(is_valid());
242 return object_->data.stream_info.md5sum;
245 void StreamInfo::set_min_blocksize(unsigned value)
247 FLAC__ASSERT(is_valid());
248 FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
249 FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
250 object_->data.stream_info.min_blocksize = value;
253 void StreamInfo::set_max_blocksize(unsigned value)
255 FLAC__ASSERT(is_valid());
256 FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
257 FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
258 object_->data.stream_info.max_blocksize = value;
261 void StreamInfo::set_min_framesize(unsigned value)
263 FLAC__ASSERT(is_valid());
264 FLAC__ASSERT(value < (1u < FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN));
265 object_->data.stream_info.min_framesize = value;
268 void StreamInfo::set_max_framesize(unsigned value)
270 FLAC__ASSERT(is_valid());
271 FLAC__ASSERT(value < (1u < FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN));
272 object_->data.stream_info.max_framesize = value;
275 void StreamInfo::set_sample_rate(unsigned value)
277 FLAC__ASSERT(is_valid());
278 FLAC__ASSERT(FLAC__format_sample_rate_is_valid(value));
279 object_->data.stream_info.sample_rate = value;
282 void StreamInfo::set_channels(unsigned value)
284 FLAC__ASSERT(is_valid());
285 FLAC__ASSERT(value > 0);
286 FLAC__ASSERT(value <= FLAC__MAX_CHANNELS);
287 object_->data.stream_info.channels = value;
290 void StreamInfo::set_bits_per_sample(unsigned value)
292 FLAC__ASSERT(is_valid());
293 FLAC__ASSERT(value >= FLAC__MIN_BITS_PER_SAMPLE);
294 FLAC__ASSERT(value <= FLAC__MAX_BITS_PER_SAMPLE);
295 object_->data.stream_info.bits_per_sample = value;
298 void StreamInfo::set_total_samples(FLAC__uint64 value)
300 FLAC__ASSERT(is_valid());
301 FLAC__ASSERT(value < (1u << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN));
302 object_->data.stream_info.total_samples = value;
305 void StreamInfo::set_md5sum(const FLAC__byte value[16])
307 FLAC__ASSERT(is_valid());
308 FLAC__ASSERT(0 != value);
309 memcpy(object_->data.stream_info.md5sum, value, 16);
318 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING), /*copy=*/false)
324 void Padding::set_length(unsigned length)
326 FLAC__ASSERT(is_valid());
327 object_->length = length;
335 Application::Application():
336 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), /*copy=*/false)
339 Application::~Application()
342 const FLAC__byte *Application::get_id() const
344 FLAC__ASSERT(is_valid());
345 return object_->data.application.id;
348 const FLAC__byte *Application::get_data() const
350 FLAC__ASSERT(is_valid());
351 return object_->data.application.data;
354 void Application::set_id(const FLAC__byte value[4])
356 FLAC__ASSERT(is_valid());
357 FLAC__ASSERT(0 != value);
358 memcpy(object_->data.application.id, value, 4);
361 bool Application::set_data(const FLAC__byte *data, unsigned length)
363 FLAC__ASSERT(is_valid());
364 return (bool)::FLAC__metadata_object_application_set_data(object_, (FLAC__byte*)data, length, true);
367 bool Application::set_data(FLAC__byte *data, unsigned length, bool copy)
369 FLAC__ASSERT(is_valid());
370 return (bool)::FLAC__metadata_object_application_set_data(object_, data, length, copy);
378 SeekTable::SeekTable():
379 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE), /*copy=*/false)
382 SeekTable::~SeekTable()
385 unsigned SeekTable::get_num_points() const
387 FLAC__ASSERT(is_valid());
388 return object_->data.seek_table.num_points;
391 ::FLAC__StreamMetadata_SeekPoint SeekTable::get_point(unsigned index) const
393 FLAC__ASSERT(is_valid());
394 FLAC__ASSERT(index < object_->data.seek_table.num_points);
395 return object_->data.seek_table.points[index];
398 void SeekTable::set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point)
400 FLAC__ASSERT(is_valid());
401 FLAC__ASSERT(index < object_->data.seek_table.num_points);
402 ::FLAC__metadata_object_seektable_set_point(object_, index, point);
405 bool SeekTable::insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point)
407 FLAC__ASSERT(is_valid());
408 FLAC__ASSERT(index <= object_->data.seek_table.num_points);
409 return (bool)::FLAC__metadata_object_seektable_insert_point(object_, index, point);
412 bool SeekTable::delete_point(unsigned index)
414 FLAC__ASSERT(is_valid());
415 FLAC__ASSERT(index < object_->data.seek_table.num_points);
416 return (bool)::FLAC__metadata_object_seektable_delete_point(object_, index);
419 bool SeekTable::is_legal() const
421 FLAC__ASSERT(is_valid());
422 return (bool)::FLAC__metadata_object_seektable_is_legal(object_);
427 // VorbisComment::Entry
430 VorbisComment::Entry::Entry()
435 VorbisComment::Entry::Entry(const char *field, unsigned field_length)
438 construct(field, field_length);
441 VorbisComment::Entry::Entry(const char *field_name, const char *field_value, unsigned field_value_length)
444 construct(field_name, field_value, field_value_length);
447 VorbisComment::Entry::Entry(const Entry &entry)
449 FLAC__ASSERT(entry.is_valid());
451 construct((const char *)entry.entry_.entry, entry.entry_.length);
454 void VorbisComment::Entry::operator=(const Entry &entry)
456 FLAC__ASSERT(entry.is_valid());
458 construct((const char *)entry.entry_.entry, entry.entry_.length);
461 VorbisComment::Entry::~Entry()
466 bool VorbisComment::Entry::is_valid() const
471 unsigned VorbisComment::Entry::get_field_length() const
473 FLAC__ASSERT(is_valid());
474 return entry_.length;
477 unsigned VorbisComment::Entry::get_field_name_length() const
479 FLAC__ASSERT(is_valid());
480 return field_name_length_;
483 unsigned VorbisComment::Entry::get_field_value_length() const
485 FLAC__ASSERT(is_valid());
486 return field_value_length_;
489 ::FLAC__StreamMetadata_VorbisComment_Entry VorbisComment::Entry::get_entry() const
491 FLAC__ASSERT(is_valid());
495 const char *VorbisComment::Entry::get_field() const
497 FLAC__ASSERT(is_valid());
498 return (const char *)entry_.entry;
501 const char *VorbisComment::Entry::get_field_name() const
503 FLAC__ASSERT(is_valid());
507 const char *VorbisComment::Entry::get_field_value() const
509 FLAC__ASSERT(is_valid());
513 bool VorbisComment::Entry::set_field(const char *field, unsigned field_length)
515 FLAC__ASSERT(is_valid());
516 FLAC__ASSERT(0 != field);
520 if(0 == (entry_.entry = (FLAC__byte*)malloc(field_length))) {
524 entry_.length = field_length;
525 memcpy(entry_.entry, field, field_length);
526 (void) parse_field();
532 bool VorbisComment::Entry::set_field_name(const char *field_name)
534 FLAC__ASSERT(is_valid());
535 FLAC__ASSERT(0 != field_name);
539 if(0 == (field_name_ = strdup(field_name))) {
543 field_name_length_ = strlen(field_name_);
550 bool VorbisComment::Entry::set_field_value(const char *field_value, unsigned field_value_length)
552 FLAC__ASSERT(is_valid());
553 FLAC__ASSERT(0 != field_value);
557 if(0 == (field_value_ = (char *)malloc(field_value_length))) {
561 field_value_length_ = field_value_length;
562 memcpy(field_value_, field_value, field_value_length);
569 void VorbisComment::Entry::zero()
575 field_name_length_ = 0;
577 field_value_length_ = 0;
580 void VorbisComment::Entry::clear()
588 void VorbisComment::Entry::clear_entry()
590 if(0 != entry_.entry) {
597 void VorbisComment::Entry::clear_field_name()
599 if(0 != field_name_) {
602 field_name_length_ = 0;
606 void VorbisComment::Entry::clear_field_value()
608 if(0 != field_value_) {
611 field_value_length_ = 0;
615 void VorbisComment::Entry::construct(const char *field, unsigned field_length)
617 if(set_field(field, field_length))
621 void VorbisComment::Entry::construct(const char *field_name, const char *field_value, unsigned field_value_length)
623 if(set_field_name(field_name) && set_field_value(field_value, field_value_length))
627 void VorbisComment::Entry::compose_field()
631 if(0 == (entry_.entry = (FLAC__byte*)malloc(field_name_length_ + 1 + field_value_length_))) {
635 memcpy(entry_.entry, field_name_, field_name_length_);
636 entry_.length += field_name_length_;
637 memcpy(entry_.entry + entry_.length, "=", 1);
639 memcpy(entry_.entry + entry_.length, field_value_, field_value_length_);
640 entry_.length += field_value_length_;
645 void VorbisComment::Entry::parse_field()
650 const char *p = (const char *)memchr(entry_.entry, '=', entry_.length);
653 p = (const char *)entry_.entry + entry_.length;
655 field_name_length_ = p - (const char *)entry_.entry;
656 if(0 == (field_name_ = (char *)malloc(field_name_length_ + 1))) { // +1 for the trailing \0
660 memcpy(field_name_, entry_.entry, field_name_length_);
661 field_name_[field_name_length_] = '\0';
663 if(entry_.length - field_name_length_ == 0) {
664 field_value_length_ = 0;
665 if(0 == (field_value_ = (char *)malloc(0))) {
671 field_value_length_ = entry_.length - field_name_length_ - 1;
672 if(0 == (field_value_ = (char *)malloc(field_value_length_))) {
676 memcpy(field_value_, ++p, field_value_length_);
687 VorbisComment::VorbisComment():
688 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT), /*copy=*/false)
691 VorbisComment::~VorbisComment()
694 unsigned VorbisComment::get_num_comments() const
696 FLAC__ASSERT(is_valid());
697 return object_->data.vorbis_comment.num_comments;
700 VorbisComment::Entry VorbisComment::get_vendor_string() const
702 FLAC__ASSERT(is_valid());
703 return Entry((const char *)object_->data.vorbis_comment.vendor_string.entry, object_->data.vorbis_comment.vendor_string.length);
706 VorbisComment::Entry VorbisComment::get_comment(unsigned index) const
708 FLAC__ASSERT(is_valid());
709 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
710 return Entry((const char *)object_->data.vorbis_comment.comments[index].entry, object_->data.vorbis_comment.comments[index].length);
713 bool VorbisComment::set_vendor_string(const VorbisComment::Entry &entry)
715 FLAC__ASSERT(is_valid());
716 // vendor_string is a special kind of entry
717 ::FLAC__StreamMetadata_VorbisComment_Entry vendor_string;
718 vendor_string.length = entry.get_field_name_length();
719 vendor_string.entry = (FLAC__byte*)entry.get_field_name(); // we can cheat on const-ness because we make a copy below:
720 return (bool)::FLAC__metadata_object_vorbiscomment_set_vendor_string(object_, vendor_string, /*copy=*/true);
723 bool VorbisComment::set_comment(unsigned index, const VorbisComment::Entry &entry)
725 FLAC__ASSERT(is_valid());
726 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
727 return (bool)::FLAC__metadata_object_vorbiscomment_set_comment(object_, index, entry.get_entry(), /*copy=*/true);
730 bool VorbisComment::insert_comment(unsigned index, const VorbisComment::Entry &entry)
732 FLAC__ASSERT(is_valid());
733 FLAC__ASSERT(index <= object_->data.vorbis_comment.num_comments);
734 return (bool)::FLAC__metadata_object_vorbiscomment_insert_comment(object_, index, entry.get_entry(), /*copy=*/true);
737 bool VorbisComment::delete_comment(unsigned index)
739 FLAC__ASSERT(is_valid());
740 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
741 return (bool)::FLAC__metadata_object_vorbiscomment_delete_comment(object_, index);
749 CueSheet::Track::Track():
750 object_(::FLAC__metadata_object_cuesheet_track_new())
753 CueSheet::Track::Track(const ::FLAC__StreamMetadata_CueSheet_Track *track):
754 object_(::FLAC__metadata_object_cuesheet_track_clone(track))
757 CueSheet::Track::Track(const Track &track):
758 object_(::FLAC__metadata_object_cuesheet_track_clone(track.object_))
761 void CueSheet::Track::operator=(const Track &track)
763 object_ = ::FLAC__metadata_object_cuesheet_track_clone(track.object_);
766 CueSheet::Track::~Track()
772 bool CueSheet::Track::is_valid() const
774 return(0 != object_);
777 ::FLAC__StreamMetadata_CueSheet_Index CueSheet::Track::get_index(unsigned i) const
779 FLAC__ASSERT(is_valid());
780 FLAC__ASSERT(i < object_->num_indices);
781 return object_->indices[i];
784 void CueSheet::Track::set_isrc(char value[12])
786 FLAC__ASSERT(is_valid());
787 FLAC__ASSERT(0 != value);
788 memcpy(object_->isrc, value, 12);
789 object_->isrc[12] = '\0';
792 void CueSheet::Track::set_type(unsigned value)
794 FLAC__ASSERT(is_valid());
795 FLAC__ASSERT(value <= 1);
796 object_->type = value;
799 void CueSheet::Track::set_index(unsigned i, const ::FLAC__StreamMetadata_CueSheet_Index &index)
801 FLAC__ASSERT(is_valid());
802 FLAC__ASSERT(i < object_->num_indices);
803 object_->indices[i] = index;
811 CueSheet::CueSheet():
812 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET), /*copy=*/false)
815 CueSheet::~CueSheet()
818 unsigned CueSheet::get_num_tracks() const
820 FLAC__ASSERT(is_valid());
821 return object_->data.cue_sheet.num_tracks;
824 CueSheet::Track CueSheet::get_track(unsigned i) const
826 FLAC__ASSERT(is_valid());
827 FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
828 return Track(object_->data.cue_sheet.tracks + i);
831 bool CueSheet::insert_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index)
833 FLAC__ASSERT(is_valid());
834 FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
835 FLAC__ASSERT(index_num <= object_->data.cue_sheet.tracks[track_num].num_indices);
836 return (bool)::FLAC__metadata_object_cuesheet_track_insert_index(object_, track_num, index_num, index);
839 bool CueSheet::delete_index(unsigned track_num, unsigned index_num)
841 FLAC__ASSERT(is_valid());
842 FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
843 FLAC__ASSERT(index_num < object_->data.cue_sheet.tracks[track_num].num_indices);
844 return (bool)::FLAC__metadata_object_cuesheet_track_delete_index(object_, track_num, index_num);
847 bool CueSheet::set_track(unsigned i, const CueSheet::Track &track)
849 FLAC__ASSERT(is_valid());
850 FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
851 // We can safely const_cast since copy=true
852 return (bool)::FLAC__metadata_object_cuesheet_set_track(object_, i, const_cast< ::FLAC__StreamMetadata_CueSheet_Track*>(track.get_track()), /*copy=*/true);
855 bool CueSheet::insert_track(unsigned i, const CueSheet::Track &track)
857 FLAC__ASSERT(is_valid());
858 FLAC__ASSERT(i <= object_->data.cue_sheet.num_tracks);
859 // We can safely const_cast since copy=true
860 return (bool)::FLAC__metadata_object_cuesheet_insert_track(object_, i, const_cast< ::FLAC__StreamMetadata_CueSheet_Track*>(track.get_track()), /*copy=*/true);
863 bool CueSheet::delete_track(unsigned i)
865 FLAC__ASSERT(is_valid());
866 FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
867 return (bool)::FLAC__metadata_object_cuesheet_delete_track(object_, i);
870 bool CueSheet::is_legal(bool check_cd_da_subset, const char **violation) const
872 FLAC__ASSERT(is_valid());
873 return (bool)::FLAC__metadata_object_cuesheet_is_legal(object_, check_cd_da_subset, violation);
877 // ============================================================
881 // ============================================================
883 FLACPP_API bool get_streaminfo(const char *filename, StreamInfo &streaminfo)
885 FLAC__ASSERT(0 != filename);
887 ::FLAC__StreamMetadata s;
889 if(::FLAC__metadata_get_streaminfo(filename, &s)) {
898 // ============================================================
902 // ============================================================
904 SimpleIterator::SimpleIterator():
905 iterator_(::FLAC__metadata_simple_iterator_new())
908 SimpleIterator::~SimpleIterator()
913 void SimpleIterator::clear()
916 FLAC__metadata_simple_iterator_delete(iterator_);
920 bool SimpleIterator::init(const char *filename, bool read_only, bool preserve_file_stats)
922 FLAC__ASSERT(0 != filename);
923 FLAC__ASSERT(is_valid());
924 return (bool)::FLAC__metadata_simple_iterator_init(iterator_, filename, read_only, preserve_file_stats);
927 bool SimpleIterator::is_valid() const
929 return 0 != iterator_;
932 SimpleIterator::Status SimpleIterator::status()
934 FLAC__ASSERT(is_valid());
935 return Status(::FLAC__metadata_simple_iterator_status(iterator_));
938 bool SimpleIterator::is_writable() const
940 FLAC__ASSERT(is_valid());
941 return (bool)::FLAC__metadata_simple_iterator_is_writable(iterator_);
944 bool SimpleIterator::next()
946 FLAC__ASSERT(is_valid());
947 return (bool)::FLAC__metadata_simple_iterator_next(iterator_);
950 bool SimpleIterator::prev()
952 FLAC__ASSERT(is_valid());
953 return (bool)::FLAC__metadata_simple_iterator_prev(iterator_);
956 ::FLAC__MetadataType SimpleIterator::get_block_type() const
958 FLAC__ASSERT(is_valid());
959 return ::FLAC__metadata_simple_iterator_get_block_type(iterator_);
962 Prototype *SimpleIterator::get_block()
964 FLAC__ASSERT(is_valid());
965 return local::construct_block(::FLAC__metadata_simple_iterator_get_block(iterator_));
968 bool SimpleIterator::set_block(Prototype *block, bool use_padding)
970 FLAC__ASSERT(0 != block);
971 FLAC__ASSERT(is_valid());
972 return (bool)::FLAC__metadata_simple_iterator_set_block(iterator_, block->object_, use_padding);
975 bool SimpleIterator::insert_block_after(Prototype *block, bool use_padding)
977 FLAC__ASSERT(0 != block);
978 FLAC__ASSERT(is_valid());
979 return (bool)::FLAC__metadata_simple_iterator_insert_block_after(iterator_, block->object_, use_padding);
982 bool SimpleIterator::delete_block(bool use_padding)
984 FLAC__ASSERT(is_valid());
985 return (bool)::FLAC__metadata_simple_iterator_delete_block(iterator_, use_padding);
989 // ============================================================
993 // ============================================================
996 chain_(::FLAC__metadata_chain_new())
1007 FLAC__metadata_chain_delete(chain_);
1011 bool Chain::is_valid() const
1016 Chain::Status Chain::status()
1018 FLAC__ASSERT(is_valid());
1019 return Status(::FLAC__metadata_chain_status(chain_));
1022 bool Chain::read(const char *filename)
1024 FLAC__ASSERT(0 != filename);
1025 FLAC__ASSERT(is_valid());
1026 return (bool)::FLAC__metadata_chain_read(chain_, filename);
1029 bool Chain::write(bool use_padding, bool preserve_file_stats)
1031 FLAC__ASSERT(is_valid());
1032 return (bool)::FLAC__metadata_chain_write(chain_, use_padding, preserve_file_stats);
1035 void Chain::merge_padding()
1037 FLAC__ASSERT(is_valid());
1038 ::FLAC__metadata_chain_merge_padding(chain_);
1041 void Chain::sort_padding()
1043 FLAC__ASSERT(is_valid());
1044 ::FLAC__metadata_chain_sort_padding(chain_);
1048 Iterator::Iterator():
1049 iterator_(::FLAC__metadata_iterator_new())
1052 Iterator::~Iterator()
1057 void Iterator::clear()
1060 FLAC__metadata_iterator_delete(iterator_);
1064 bool Iterator::is_valid() const
1066 return 0 != iterator_;
1069 void Iterator::init(Chain &chain)
1071 FLAC__ASSERT(is_valid());
1072 FLAC__ASSERT(chain.is_valid());
1073 ::FLAC__metadata_iterator_init(iterator_, chain.chain_);
1076 bool Iterator::next()
1078 FLAC__ASSERT(is_valid());
1079 return (bool)::FLAC__metadata_iterator_next(iterator_);
1082 bool Iterator::prev()
1084 FLAC__ASSERT(is_valid());
1085 return (bool)::FLAC__metadata_iterator_prev(iterator_);
1088 ::FLAC__MetadataType Iterator::get_block_type() const
1090 FLAC__ASSERT(is_valid());
1091 return ::FLAC__metadata_iterator_get_block_type(iterator_);
1094 Prototype *Iterator::get_block()
1096 FLAC__ASSERT(is_valid());
1097 Prototype *block = local::construct_block(::FLAC__metadata_iterator_get_block(iterator_));
1099 block->set_reference(true);
1103 bool Iterator::set_block(Prototype *block)
1105 FLAC__ASSERT(0 != block);
1106 FLAC__ASSERT(is_valid());
1107 bool ret = (bool)::FLAC__metadata_iterator_set_block(iterator_, block->object_);
1109 block->set_reference(true);
1115 bool Iterator::delete_block(bool replace_with_padding)
1117 FLAC__ASSERT(is_valid());
1118 return (bool)::FLAC__metadata_iterator_delete_block(iterator_, replace_with_padding);
1121 bool Iterator::insert_block_before(Prototype *block)
1123 FLAC__ASSERT(0 != block);
1124 FLAC__ASSERT(is_valid());
1125 bool ret = (bool)::FLAC__metadata_iterator_insert_block_before(iterator_, block->object_);
1127 block->set_reference(true);
1133 bool Iterator::insert_block_after(Prototype *block)
1135 FLAC__ASSERT(0 != block);
1136 FLAC__ASSERT(is_valid());
1137 bool ret = (bool)::FLAC__metadata_iterator_insert_block_after(iterator_, block->object_);
1139 block->set_reference(true);