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);
60 FLACPP_API Prototype *clone(const Prototype *object)
62 FLAC__ASSERT(0 != object);
64 const StreamInfo *streaminfo = dynamic_cast<const StreamInfo *>(object);
65 const Padding *padding = dynamic_cast<const Padding *>(object);
66 const Application *application = dynamic_cast<const Application *>(object);
67 const SeekTable *seektable = dynamic_cast<const SeekTable *>(object);
68 const VorbisComment *vorbiscomment = dynamic_cast<const VorbisComment *>(object);
71 return new StreamInfo(*streaminfo);
73 return new Padding(*padding);
74 else if(0 != application)
75 return new Application(*application);
76 else if(0 != seektable)
77 return new SeekTable(*seektable);
78 else if(0 != vorbiscomment)
79 return new VorbisComment(*vorbiscomment);
90 Prototype::Prototype(const Prototype &object):
91 object_(::FLAC__metadata_object_clone(object.object_)),
94 FLAC__ASSERT(object.is_valid());
97 Prototype::Prototype(const ::FLAC__StreamMetadata &object):
98 object_(::FLAC__metadata_object_clone(&object)),
103 Prototype::Prototype(const ::FLAC__StreamMetadata *object):
104 object_(::FLAC__metadata_object_clone(object)),
107 FLAC__ASSERT(0 != object);
110 Prototype::Prototype(::FLAC__StreamMetadata *object, bool copy):
111 object_(copy? ::FLAC__metadata_object_clone(object) : object),
114 FLAC__ASSERT(0 != object);
117 Prototype::~Prototype()
122 void Prototype::clear()
124 if(0 != object_ && !is_reference_)
125 FLAC__metadata_object_delete(object_);
129 void Prototype::operator=(const Prototype &object)
131 FLAC__ASSERT(object.is_valid());
133 is_reference_ = false;
134 object_ = ::FLAC__metadata_object_clone(object.object_);
137 void Prototype::operator=(const ::FLAC__StreamMetadata &object)
140 is_reference_ = false;
141 object_ = ::FLAC__metadata_object_clone(&object);
144 void Prototype::operator=(const ::FLAC__StreamMetadata *object)
146 FLAC__ASSERT(0 != object);
148 is_reference_ = false;
149 object_ = ::FLAC__metadata_object_clone(object);
152 bool Prototype::get_is_last() const
154 FLAC__ASSERT(is_valid());
155 return (bool)object_->is_last;
158 FLAC__MetadataType Prototype::get_type() const
160 FLAC__ASSERT(is_valid());
161 return object_->type;
164 unsigned Prototype::get_length() const
166 FLAC__ASSERT(is_valid());
167 return object_->length;
170 void Prototype::set_is_last(bool value)
172 FLAC__ASSERT(is_valid());
173 object_->is_last = value;
181 StreamInfo::StreamInfo():
182 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO), /*copy=*/false)
185 StreamInfo::~StreamInfo()
188 unsigned StreamInfo::get_min_blocksize() const
190 FLAC__ASSERT(is_valid());
191 return object_->data.stream_info.min_blocksize;
194 unsigned StreamInfo::get_max_blocksize() const
196 FLAC__ASSERT(is_valid());
197 return object_->data.stream_info.max_blocksize;
200 unsigned StreamInfo::get_min_framesize() const
202 FLAC__ASSERT(is_valid());
203 return object_->data.stream_info.min_framesize;
206 unsigned StreamInfo::get_max_framesize() const
208 FLAC__ASSERT(is_valid());
209 return object_->data.stream_info.max_framesize;
212 unsigned StreamInfo::get_sample_rate() const
214 FLAC__ASSERT(is_valid());
215 return object_->data.stream_info.sample_rate;
218 unsigned StreamInfo::get_channels() const
220 FLAC__ASSERT(is_valid());
221 return object_->data.stream_info.channels;
224 unsigned StreamInfo::get_bits_per_sample() const
226 FLAC__ASSERT(is_valid());
227 return object_->data.stream_info.bits_per_sample;
230 FLAC__uint64 StreamInfo::get_total_samples() const
232 FLAC__ASSERT(is_valid());
233 return object_->data.stream_info.total_samples;
236 const FLAC__byte *StreamInfo::get_md5sum() const
238 FLAC__ASSERT(is_valid());
239 return object_->data.stream_info.md5sum;
242 void StreamInfo::set_min_blocksize(unsigned value)
244 FLAC__ASSERT(is_valid());
245 FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
246 FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
247 object_->data.stream_info.min_blocksize = value;
250 void StreamInfo::set_max_blocksize(unsigned value)
252 FLAC__ASSERT(is_valid());
253 FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
254 FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
255 object_->data.stream_info.max_blocksize = value;
258 void StreamInfo::set_min_framesize(unsigned value)
260 FLAC__ASSERT(is_valid());
261 FLAC__ASSERT(value < (1u < FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN));
262 object_->data.stream_info.min_framesize = value;
265 void StreamInfo::set_max_framesize(unsigned value)
267 FLAC__ASSERT(is_valid());
268 FLAC__ASSERT(value < (1u < FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN));
269 object_->data.stream_info.max_framesize = value;
272 void StreamInfo::set_sample_rate(unsigned value)
274 FLAC__ASSERT(is_valid());
275 FLAC__ASSERT(FLAC__format_sample_rate_is_valid(value));
276 object_->data.stream_info.sample_rate = value;
279 void StreamInfo::set_channels(unsigned value)
281 FLAC__ASSERT(is_valid());
282 FLAC__ASSERT(value > 0);
283 FLAC__ASSERT(value <= FLAC__MAX_CHANNELS);
284 object_->data.stream_info.channels = value;
287 void StreamInfo::set_bits_per_sample(unsigned value)
289 FLAC__ASSERT(is_valid());
290 FLAC__ASSERT(value >= FLAC__MIN_BITS_PER_SAMPLE);
291 FLAC__ASSERT(value <= FLAC__MAX_BITS_PER_SAMPLE);
292 object_->data.stream_info.bits_per_sample = value;
295 void StreamInfo::set_total_samples(FLAC__uint64 value)
297 FLAC__ASSERT(is_valid());
298 FLAC__ASSERT(value < (1u << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN));
299 object_->data.stream_info.total_samples = value;
302 void StreamInfo::set_md5sum(const FLAC__byte value[16])
304 FLAC__ASSERT(is_valid());
305 FLAC__ASSERT(0 != value);
306 memcpy(object_->data.stream_info.md5sum, value, 16);
315 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING), /*copy=*/false)
321 void Padding::set_length(unsigned length)
323 FLAC__ASSERT(is_valid());
324 object_->length = length;
332 Application::Application():
333 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), /*copy=*/false)
336 Application::~Application()
339 const FLAC__byte *Application::get_id() const
341 FLAC__ASSERT(is_valid());
342 return object_->data.application.id;
345 const FLAC__byte *Application::get_data() const
347 FLAC__ASSERT(is_valid());
348 return object_->data.application.data;
351 void Application::set_id(const FLAC__byte value[4])
353 FLAC__ASSERT(is_valid());
354 FLAC__ASSERT(0 != value);
355 memcpy(object_->data.application.id, value, 4);
358 bool Application::set_data(const FLAC__byte *data, unsigned length)
360 FLAC__ASSERT(is_valid());
361 return (bool)::FLAC__metadata_object_application_set_data(object_, (FLAC__byte*)data, length, true);
364 bool Application::set_data(FLAC__byte *data, unsigned length, bool copy)
366 FLAC__ASSERT(is_valid());
367 return (bool)::FLAC__metadata_object_application_set_data(object_, data, length, copy);
375 SeekTable::SeekTable():
376 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE), /*copy=*/false)
379 SeekTable::~SeekTable()
382 unsigned SeekTable::get_num_points() const
384 FLAC__ASSERT(is_valid());
385 return object_->data.seek_table.num_points;
388 ::FLAC__StreamMetadata_SeekPoint SeekTable::get_point(unsigned index) const
390 FLAC__ASSERT(is_valid());
391 FLAC__ASSERT(index < object_->data.seek_table.num_points);
392 return object_->data.seek_table.points[index];
395 void SeekTable::set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point)
397 FLAC__ASSERT(is_valid());
398 FLAC__ASSERT(index < object_->data.seek_table.num_points);
399 ::FLAC__metadata_object_seektable_set_point(object_, index, point);
402 bool SeekTable::insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point)
404 FLAC__ASSERT(is_valid());
405 FLAC__ASSERT(index <= object_->data.seek_table.num_points);
406 return (bool)::FLAC__metadata_object_seektable_insert_point(object_, index, point);
409 bool SeekTable::delete_point(unsigned index)
411 FLAC__ASSERT(is_valid());
412 FLAC__ASSERT(index < object_->data.seek_table.num_points);
413 return (bool)::FLAC__metadata_object_seektable_delete_point(object_, index);
416 bool SeekTable::is_legal() const
418 FLAC__ASSERT(is_valid());
419 return (bool)::FLAC__metadata_object_seektable_is_legal(object_);
424 // VorbisComment::Entry
427 VorbisComment::Entry::Entry()
432 VorbisComment::Entry::Entry(const char *field, unsigned field_length)
435 construct(field, field_length);
438 VorbisComment::Entry::Entry(const char *field_name, const char *field_value, unsigned field_value_length)
441 construct(field_name, field_value, field_value_length);
444 VorbisComment::Entry::Entry(const Entry &entry)
446 FLAC__ASSERT(entry.is_valid());
448 construct((const char *)entry.entry_.entry, entry.entry_.length);
451 void VorbisComment::Entry::operator=(const Entry &entry)
453 FLAC__ASSERT(entry.is_valid());
455 construct((const char *)entry.entry_.entry, entry.entry_.length);
458 VorbisComment::Entry::~Entry()
463 bool VorbisComment::Entry::is_valid() const
468 unsigned VorbisComment::Entry::get_field_length() const
470 FLAC__ASSERT(is_valid());
471 return entry_.length;
474 unsigned VorbisComment::Entry::get_field_name_length() const
476 FLAC__ASSERT(is_valid());
477 return field_name_length_;
480 unsigned VorbisComment::Entry::get_field_value_length() const
482 FLAC__ASSERT(is_valid());
483 return field_value_length_;
486 ::FLAC__StreamMetadata_VorbisComment_Entry VorbisComment::Entry::get_entry() const
488 FLAC__ASSERT(is_valid());
492 const char *VorbisComment::Entry::get_field() const
494 FLAC__ASSERT(is_valid());
495 return (const char *)entry_.entry;
498 const char *VorbisComment::Entry::get_field_name() const
500 FLAC__ASSERT(is_valid());
504 const char *VorbisComment::Entry::get_field_value() const
506 FLAC__ASSERT(is_valid());
510 bool VorbisComment::Entry::set_field(const char *field, unsigned field_length)
512 FLAC__ASSERT(is_valid());
513 FLAC__ASSERT(0 != field);
517 if(0 == (entry_.entry = (FLAC__byte*)malloc(field_length))) {
521 entry_.length = field_length;
522 memcpy(entry_.entry, field, field_length);
523 (void) parse_field();
529 bool VorbisComment::Entry::set_field_name(const char *field_name)
531 FLAC__ASSERT(is_valid());
532 FLAC__ASSERT(0 != field_name);
536 if(0 == (field_name_ = strdup(field_name))) {
540 field_name_length_ = strlen(field_name_);
547 bool VorbisComment::Entry::set_field_value(const char *field_value, unsigned field_value_length)
549 FLAC__ASSERT(is_valid());
550 FLAC__ASSERT(0 != field_value);
554 if(0 == (field_value_ = (char *)malloc(field_value_length))) {
558 field_value_length_ = field_value_length;
559 memcpy(field_value_, field_value, field_value_length);
566 void VorbisComment::Entry::zero()
572 field_name_length_ = 0;
574 field_value_length_ = 0;
577 void VorbisComment::Entry::clear()
585 void VorbisComment::Entry::clear_entry()
587 if(0 != entry_.entry) {
594 void VorbisComment::Entry::clear_field_name()
596 if(0 != field_name_) {
599 field_name_length_ = 0;
603 void VorbisComment::Entry::clear_field_value()
605 if(0 != field_value_) {
608 field_value_length_ = 0;
612 void VorbisComment::Entry::construct(const char *field, unsigned field_length)
614 if(set_field(field, field_length))
618 void VorbisComment::Entry::construct(const char *field_name, const char *field_value, unsigned field_value_length)
620 if(set_field_name(field_name) && set_field_value(field_value, field_value_length))
624 void VorbisComment::Entry::compose_field()
628 if(0 == (entry_.entry = (FLAC__byte*)malloc(field_name_length_ + 1 + field_value_length_))) {
632 memcpy(entry_.entry, field_name_, field_name_length_);
633 entry_.length += field_name_length_;
634 memcpy(entry_.entry + entry_.length, "=", 1);
636 memcpy(entry_.entry + entry_.length, field_value_, field_value_length_);
637 entry_.length += field_value_length_;
642 void VorbisComment::Entry::parse_field()
647 const char *p = (const char *)memchr(entry_.entry, '=', entry_.length);
650 p = (const char *)entry_.entry + entry_.length;
652 field_name_length_ = p - (const char *)entry_.entry;
653 if(0 == (field_name_ = (char *)malloc(field_name_length_ + 1))) { // +1 for the trailing \0
657 memcpy(field_name_, entry_.entry, field_name_length_);
658 field_name_[field_name_length_] = '\0';
660 if(entry_.length - field_name_length_ == 0) {
661 field_value_length_ = 0;
662 if(0 == (field_value_ = (char *)malloc(0))) {
668 field_value_length_ = entry_.length - field_name_length_ - 1;
669 if(0 == (field_value_ = (char *)malloc(field_value_length_))) {
673 memcpy(field_value_, ++p, field_value_length_);
684 VorbisComment::VorbisComment():
685 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT), /*copy=*/false)
688 VorbisComment::~VorbisComment()
691 unsigned VorbisComment::get_num_comments() const
693 FLAC__ASSERT(is_valid());
694 return object_->data.vorbis_comment.num_comments;
697 VorbisComment::Entry VorbisComment::get_vendor_string() const
699 FLAC__ASSERT(is_valid());
700 return Entry((const char *)object_->data.vorbis_comment.vendor_string.entry, object_->data.vorbis_comment.vendor_string.length);
703 VorbisComment::Entry VorbisComment::get_comment(unsigned index) const
705 FLAC__ASSERT(is_valid());
706 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
707 return Entry((const char *)object_->data.vorbis_comment.comments[index].entry, object_->data.vorbis_comment.comments[index].length);
710 bool VorbisComment::set_vendor_string(const VorbisComment::Entry &entry)
712 FLAC__ASSERT(is_valid());
713 // vendor_string is a special kind of entry
714 ::FLAC__StreamMetadata_VorbisComment_Entry vendor_string;
715 vendor_string.length = entry.get_field_name_length();
716 vendor_string.entry = (FLAC__byte*)entry.get_field_name(); // we can cheat on const-ness because we make a copy below:
717 return (bool)::FLAC__metadata_object_vorbiscomment_set_vendor_string(object_, vendor_string, /*copy=*/true);
720 bool VorbisComment::set_comment(unsigned index, const VorbisComment::Entry &entry)
722 FLAC__ASSERT(is_valid());
723 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
724 return (bool)::FLAC__metadata_object_vorbiscomment_set_comment(object_, index, entry.get_entry(), /*copy=*/true);
727 bool VorbisComment::insert_comment(unsigned index, const VorbisComment::Entry &entry)
729 FLAC__ASSERT(is_valid());
730 FLAC__ASSERT(index <= object_->data.vorbis_comment.num_comments);
731 return (bool)::FLAC__metadata_object_vorbiscomment_insert_comment(object_, index, entry.get_entry(), /*copy=*/true);
734 bool VorbisComment::delete_comment(unsigned index)
736 FLAC__ASSERT(is_valid());
737 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
738 return (bool)::FLAC__metadata_object_vorbiscomment_delete_comment(object_, index);
742 // ============================================================
746 // ============================================================
748 FLACPP_API bool get_streaminfo(const char *filename, StreamInfo &streaminfo)
750 FLAC__ASSERT(0 != filename);
752 ::FLAC__StreamMetadata s;
754 if(::FLAC__metadata_get_streaminfo(filename, &s)) {
763 // ============================================================
767 // ============================================================
769 SimpleIterator::SimpleIterator():
770 iterator_(::FLAC__metadata_simple_iterator_new())
773 SimpleIterator::~SimpleIterator()
778 void SimpleIterator::clear()
781 FLAC__metadata_simple_iterator_delete(iterator_);
785 bool SimpleIterator::init(const char *filename, bool read_only, bool preserve_file_stats)
787 FLAC__ASSERT(0 != filename);
788 FLAC__ASSERT(is_valid());
789 return (bool)::FLAC__metadata_simple_iterator_init(iterator_, filename, read_only, preserve_file_stats);
792 bool SimpleIterator::is_valid() const
794 return 0 != iterator_;
797 SimpleIterator::Status SimpleIterator::status()
799 FLAC__ASSERT(is_valid());
800 return Status(::FLAC__metadata_simple_iterator_status(iterator_));
803 bool SimpleIterator::is_writable() const
805 FLAC__ASSERT(is_valid());
806 return (bool)::FLAC__metadata_simple_iterator_is_writable(iterator_);
809 bool SimpleIterator::next()
811 FLAC__ASSERT(is_valid());
812 return (bool)::FLAC__metadata_simple_iterator_next(iterator_);
815 bool SimpleIterator::prev()
817 FLAC__ASSERT(is_valid());
818 return (bool)::FLAC__metadata_simple_iterator_prev(iterator_);
821 ::FLAC__MetadataType SimpleIterator::get_block_type() const
823 FLAC__ASSERT(is_valid());
824 return ::FLAC__metadata_simple_iterator_get_block_type(iterator_);
827 Prototype *SimpleIterator::get_block()
829 FLAC__ASSERT(is_valid());
830 return local::construct_block(::FLAC__metadata_simple_iterator_get_block(iterator_));
833 bool SimpleIterator::set_block(Prototype *block, bool use_padding)
835 FLAC__ASSERT(0 != block);
836 FLAC__ASSERT(is_valid());
837 return (bool)::FLAC__metadata_simple_iterator_set_block(iterator_, block->object_, use_padding);
840 bool SimpleIterator::insert_block_after(Prototype *block, bool use_padding)
842 FLAC__ASSERT(0 != block);
843 FLAC__ASSERT(is_valid());
844 return (bool)::FLAC__metadata_simple_iterator_insert_block_after(iterator_, block->object_, use_padding);
847 bool SimpleIterator::delete_block(bool use_padding)
849 FLAC__ASSERT(is_valid());
850 return (bool)::FLAC__metadata_simple_iterator_delete_block(iterator_, use_padding);
854 // ============================================================
858 // ============================================================
861 chain_(::FLAC__metadata_chain_new())
872 FLAC__metadata_chain_delete(chain_);
876 bool Chain::is_valid() const
881 Chain::Status Chain::status()
883 FLAC__ASSERT(is_valid());
884 return Status(::FLAC__metadata_chain_status(chain_));
887 bool Chain::read(const char *filename)
889 FLAC__ASSERT(0 != filename);
890 FLAC__ASSERT(is_valid());
891 return (bool)::FLAC__metadata_chain_read(chain_, filename);
894 bool Chain::write(bool use_padding, bool preserve_file_stats)
896 FLAC__ASSERT(is_valid());
897 return (bool)::FLAC__metadata_chain_write(chain_, use_padding, preserve_file_stats);
900 void Chain::merge_padding()
902 FLAC__ASSERT(is_valid());
903 ::FLAC__metadata_chain_merge_padding(chain_);
906 void Chain::sort_padding()
908 FLAC__ASSERT(is_valid());
909 ::FLAC__metadata_chain_sort_padding(chain_);
913 Iterator::Iterator():
914 iterator_(::FLAC__metadata_iterator_new())
917 Iterator::~Iterator()
922 void Iterator::clear()
925 FLAC__metadata_iterator_delete(iterator_);
929 bool Iterator::is_valid() const
931 return 0 != iterator_;
934 void Iterator::init(Chain &chain)
936 FLAC__ASSERT(is_valid());
937 FLAC__ASSERT(chain.is_valid());
938 ::FLAC__metadata_iterator_init(iterator_, chain.chain_);
941 bool Iterator::next()
943 FLAC__ASSERT(is_valid());
944 return (bool)::FLAC__metadata_iterator_next(iterator_);
947 bool Iterator::prev()
949 FLAC__ASSERT(is_valid());
950 return (bool)::FLAC__metadata_iterator_prev(iterator_);
953 ::FLAC__MetadataType Iterator::get_block_type() const
955 FLAC__ASSERT(is_valid());
956 return ::FLAC__metadata_iterator_get_block_type(iterator_);
959 Prototype *Iterator::get_block()
961 FLAC__ASSERT(is_valid());
962 Prototype *block = local::construct_block(::FLAC__metadata_iterator_get_block(iterator_));
964 block->set_reference(true);
968 bool Iterator::set_block(Prototype *block)
970 FLAC__ASSERT(0 != block);
971 FLAC__ASSERT(is_valid());
972 bool ret = (bool)::FLAC__metadata_iterator_set_block(iterator_, block->object_);
974 block->set_reference(true);
980 bool Iterator::delete_block(bool replace_with_padding)
982 FLAC__ASSERT(is_valid());
983 return (bool)::FLAC__metadata_iterator_delete_block(iterator_, replace_with_padding);
986 bool Iterator::insert_block_before(Prototype *block)
988 FLAC__ASSERT(0 != block);
989 FLAC__ASSERT(is_valid());
990 bool ret = (bool)::FLAC__metadata_iterator_insert_block_before(iterator_, block->object_);
992 block->set_reference(true);
998 bool Iterator::insert_block_after(Prototype *block)
1000 FLAC__ASSERT(0 != block);
1001 FLAC__ASSERT(is_valid());
1002 bool ret = (bool)::FLAC__metadata_iterator_insert_block_after(iterator_, block->object_);
1004 block->set_reference(true);