1 /* libFLAC++ - Free Lossless Audio Codec library
2 * Copyright (C) 2002,2003 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);
55 ret = new Unknown(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);
72 const CueSheet *cuesheet = dynamic_cast<const CueSheet *>(object);
73 const Unknown *unknown = dynamic_cast<const Unknown *>(object);
76 return new StreamInfo(*streaminfo);
78 return new Padding(*padding);
79 else if(0 != application)
80 return new Application(*application);
81 else if(0 != seektable)
82 return new SeekTable(*seektable);
83 else if(0 != vorbiscomment)
84 return new VorbisComment(*vorbiscomment);
85 else if(0 != cuesheet)
86 return new CueSheet(*cuesheet);
88 return new Unknown(*unknown);
99 Prototype::Prototype(const Prototype &object):
100 object_(::FLAC__metadata_object_clone(object.object_)),
103 FLAC__ASSERT(object.is_valid());
106 Prototype::Prototype(const ::FLAC__StreamMetadata &object):
107 object_(::FLAC__metadata_object_clone(&object)),
112 Prototype::Prototype(const ::FLAC__StreamMetadata *object):
113 object_(::FLAC__metadata_object_clone(object)),
116 FLAC__ASSERT(0 != object);
119 Prototype::Prototype(::FLAC__StreamMetadata *object, bool copy):
120 object_(copy? ::FLAC__metadata_object_clone(object) : object),
123 FLAC__ASSERT(0 != object);
126 Prototype::~Prototype()
131 void Prototype::clear()
133 if(0 != object_ && !is_reference_)
134 FLAC__metadata_object_delete(object_);
138 void Prototype::operator=(const Prototype &object)
140 FLAC__ASSERT(object.is_valid());
142 is_reference_ = false;
143 object_ = ::FLAC__metadata_object_clone(object.object_);
146 void Prototype::operator=(const ::FLAC__StreamMetadata &object)
149 is_reference_ = false;
150 object_ = ::FLAC__metadata_object_clone(&object);
153 void Prototype::operator=(const ::FLAC__StreamMetadata *object)
155 FLAC__ASSERT(0 != object);
157 is_reference_ = false;
158 object_ = ::FLAC__metadata_object_clone(object);
161 bool Prototype::get_is_last() const
163 FLAC__ASSERT(is_valid());
164 return (bool)object_->is_last;
167 FLAC__MetadataType Prototype::get_type() const
169 FLAC__ASSERT(is_valid());
170 return object_->type;
173 unsigned Prototype::get_length() const
175 FLAC__ASSERT(is_valid());
176 return object_->length;
179 void Prototype::set_is_last(bool value)
181 FLAC__ASSERT(is_valid());
182 object_->is_last = value;
190 StreamInfo::StreamInfo():
191 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO), /*copy=*/false)
194 StreamInfo::~StreamInfo()
197 unsigned StreamInfo::get_min_blocksize() const
199 FLAC__ASSERT(is_valid());
200 return object_->data.stream_info.min_blocksize;
203 unsigned StreamInfo::get_max_blocksize() const
205 FLAC__ASSERT(is_valid());
206 return object_->data.stream_info.max_blocksize;
209 unsigned StreamInfo::get_min_framesize() const
211 FLAC__ASSERT(is_valid());
212 return object_->data.stream_info.min_framesize;
215 unsigned StreamInfo::get_max_framesize() const
217 FLAC__ASSERT(is_valid());
218 return object_->data.stream_info.max_framesize;
221 unsigned StreamInfo::get_sample_rate() const
223 FLAC__ASSERT(is_valid());
224 return object_->data.stream_info.sample_rate;
227 unsigned StreamInfo::get_channels() const
229 FLAC__ASSERT(is_valid());
230 return object_->data.stream_info.channels;
233 unsigned StreamInfo::get_bits_per_sample() const
235 FLAC__ASSERT(is_valid());
236 return object_->data.stream_info.bits_per_sample;
239 FLAC__uint64 StreamInfo::get_total_samples() const
241 FLAC__ASSERT(is_valid());
242 return object_->data.stream_info.total_samples;
245 const FLAC__byte *StreamInfo::get_md5sum() const
247 FLAC__ASSERT(is_valid());
248 return object_->data.stream_info.md5sum;
251 void StreamInfo::set_min_blocksize(unsigned value)
253 FLAC__ASSERT(is_valid());
254 FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
255 FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
256 object_->data.stream_info.min_blocksize = value;
259 void StreamInfo::set_max_blocksize(unsigned value)
261 FLAC__ASSERT(is_valid());
262 FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
263 FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
264 object_->data.stream_info.max_blocksize = value;
267 void StreamInfo::set_min_framesize(unsigned value)
269 FLAC__ASSERT(is_valid());
270 FLAC__ASSERT(value < (1u < FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN));
271 object_->data.stream_info.min_framesize = value;
274 void StreamInfo::set_max_framesize(unsigned value)
276 FLAC__ASSERT(is_valid());
277 FLAC__ASSERT(value < (1u < FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN));
278 object_->data.stream_info.max_framesize = value;
281 void StreamInfo::set_sample_rate(unsigned value)
283 FLAC__ASSERT(is_valid());
284 FLAC__ASSERT(FLAC__format_sample_rate_is_valid(value));
285 object_->data.stream_info.sample_rate = value;
288 void StreamInfo::set_channels(unsigned value)
290 FLAC__ASSERT(is_valid());
291 FLAC__ASSERT(value > 0);
292 FLAC__ASSERT(value <= FLAC__MAX_CHANNELS);
293 object_->data.stream_info.channels = value;
296 void StreamInfo::set_bits_per_sample(unsigned value)
298 FLAC__ASSERT(is_valid());
299 FLAC__ASSERT(value >= FLAC__MIN_BITS_PER_SAMPLE);
300 FLAC__ASSERT(value <= FLAC__MAX_BITS_PER_SAMPLE);
301 object_->data.stream_info.bits_per_sample = value;
304 void StreamInfo::set_total_samples(FLAC__uint64 value)
306 FLAC__ASSERT(is_valid());
307 FLAC__ASSERT(value < (1u << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN));
308 object_->data.stream_info.total_samples = value;
311 void StreamInfo::set_md5sum(const FLAC__byte value[16])
313 FLAC__ASSERT(is_valid());
314 FLAC__ASSERT(0 != value);
315 memcpy(object_->data.stream_info.md5sum, value, 16);
324 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING), /*copy=*/false)
330 void Padding::set_length(unsigned length)
332 FLAC__ASSERT(is_valid());
333 object_->length = length;
341 Application::Application():
342 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), /*copy=*/false)
345 Application::~Application()
348 const FLAC__byte *Application::get_id() const
350 FLAC__ASSERT(is_valid());
351 return object_->data.application.id;
354 const FLAC__byte *Application::get_data() const
356 FLAC__ASSERT(is_valid());
357 return object_->data.application.data;
360 void Application::set_id(const FLAC__byte value[4])
362 FLAC__ASSERT(is_valid());
363 FLAC__ASSERT(0 != value);
364 memcpy(object_->data.application.id, value, 4);
367 bool Application::set_data(const FLAC__byte *data, unsigned length)
369 FLAC__ASSERT(is_valid());
370 return (bool)::FLAC__metadata_object_application_set_data(object_, (FLAC__byte*)data, length, true);
373 bool Application::set_data(FLAC__byte *data, unsigned length, bool copy)
375 FLAC__ASSERT(is_valid());
376 return (bool)::FLAC__metadata_object_application_set_data(object_, data, length, copy);
384 SeekTable::SeekTable():
385 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE), /*copy=*/false)
388 SeekTable::~SeekTable()
391 unsigned SeekTable::get_num_points() const
393 FLAC__ASSERT(is_valid());
394 return object_->data.seek_table.num_points;
397 ::FLAC__StreamMetadata_SeekPoint SeekTable::get_point(unsigned index) const
399 FLAC__ASSERT(is_valid());
400 FLAC__ASSERT(index < object_->data.seek_table.num_points);
401 return object_->data.seek_table.points[index];
404 void SeekTable::set_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point)
406 FLAC__ASSERT(is_valid());
407 FLAC__ASSERT(index < object_->data.seek_table.num_points);
408 ::FLAC__metadata_object_seektable_set_point(object_, index, point);
411 bool SeekTable::insert_point(unsigned index, const ::FLAC__StreamMetadata_SeekPoint &point)
413 FLAC__ASSERT(is_valid());
414 FLAC__ASSERT(index <= object_->data.seek_table.num_points);
415 return (bool)::FLAC__metadata_object_seektable_insert_point(object_, index, point);
418 bool SeekTable::delete_point(unsigned index)
420 FLAC__ASSERT(is_valid());
421 FLAC__ASSERT(index < object_->data.seek_table.num_points);
422 return (bool)::FLAC__metadata_object_seektable_delete_point(object_, index);
425 bool SeekTable::is_legal() const
427 FLAC__ASSERT(is_valid());
428 return (bool)::FLAC__metadata_object_seektable_is_legal(object_);
433 // VorbisComment::Entry
436 VorbisComment::Entry::Entry()
441 VorbisComment::Entry::Entry(const char *field, unsigned field_length)
444 construct(field, field_length);
447 VorbisComment::Entry::Entry(const char *field_name, const char *field_value, unsigned field_value_length)
450 construct(field_name, field_value, field_value_length);
453 VorbisComment::Entry::Entry(const Entry &entry)
455 FLAC__ASSERT(entry.is_valid());
457 construct((const char *)entry.entry_.entry, entry.entry_.length);
460 void VorbisComment::Entry::operator=(const Entry &entry)
462 FLAC__ASSERT(entry.is_valid());
464 construct((const char *)entry.entry_.entry, entry.entry_.length);
467 VorbisComment::Entry::~Entry()
472 bool VorbisComment::Entry::is_valid() const
477 unsigned VorbisComment::Entry::get_field_length() const
479 FLAC__ASSERT(is_valid());
480 return entry_.length;
483 unsigned VorbisComment::Entry::get_field_name_length() const
485 FLAC__ASSERT(is_valid());
486 return field_name_length_;
489 unsigned VorbisComment::Entry::get_field_value_length() const
491 FLAC__ASSERT(is_valid());
492 return field_value_length_;
495 ::FLAC__StreamMetadata_VorbisComment_Entry VorbisComment::Entry::get_entry() const
497 FLAC__ASSERT(is_valid());
501 const char *VorbisComment::Entry::get_field() const
503 FLAC__ASSERT(is_valid());
504 return (const char *)entry_.entry;
507 const char *VorbisComment::Entry::get_field_name() const
509 FLAC__ASSERT(is_valid());
513 const char *VorbisComment::Entry::get_field_value() const
515 FLAC__ASSERT(is_valid());
519 bool VorbisComment::Entry::set_field(const char *field, unsigned field_length)
521 FLAC__ASSERT(is_valid());
522 FLAC__ASSERT(0 != field);
526 if(0 == (entry_.entry = (FLAC__byte*)malloc(field_length))) {
530 entry_.length = field_length;
531 memcpy(entry_.entry, field, field_length);
532 (void) parse_field();
538 bool VorbisComment::Entry::set_field_name(const char *field_name)
540 FLAC__ASSERT(is_valid());
541 FLAC__ASSERT(0 != field_name);
545 if(0 == (field_name_ = strdup(field_name))) {
549 field_name_length_ = strlen(field_name_);
556 bool VorbisComment::Entry::set_field_value(const char *field_value, unsigned field_value_length)
558 FLAC__ASSERT(is_valid());
559 FLAC__ASSERT(0 != field_value);
563 if(0 == (field_value_ = (char *)malloc(field_value_length))) {
567 field_value_length_ = field_value_length;
568 memcpy(field_value_, field_value, field_value_length);
575 void VorbisComment::Entry::zero()
581 field_name_length_ = 0;
583 field_value_length_ = 0;
586 void VorbisComment::Entry::clear()
594 void VorbisComment::Entry::clear_entry()
596 if(0 != entry_.entry) {
603 void VorbisComment::Entry::clear_field_name()
605 if(0 != field_name_) {
608 field_name_length_ = 0;
612 void VorbisComment::Entry::clear_field_value()
614 if(0 != field_value_) {
617 field_value_length_ = 0;
621 void VorbisComment::Entry::construct(const char *field, unsigned field_length)
623 if(set_field(field, field_length))
627 void VorbisComment::Entry::construct(const char *field_name, const char *field_value, unsigned field_value_length)
629 if(set_field_name(field_name) && set_field_value(field_value, field_value_length))
633 void VorbisComment::Entry::compose_field()
637 if(0 == (entry_.entry = (FLAC__byte*)malloc(field_name_length_ + 1 + field_value_length_))) {
641 memcpy(entry_.entry, field_name_, field_name_length_);
642 entry_.length += field_name_length_;
643 memcpy(entry_.entry + entry_.length, "=", 1);
645 memcpy(entry_.entry + entry_.length, field_value_, field_value_length_);
646 entry_.length += field_value_length_;
651 void VorbisComment::Entry::parse_field()
656 const char *p = (const char *)memchr(entry_.entry, '=', entry_.length);
659 p = (const char *)entry_.entry + entry_.length;
661 field_name_length_ = p - (const char *)entry_.entry;
662 if(0 == (field_name_ = (char *)malloc(field_name_length_ + 1))) { // +1 for the trailing \0
666 memcpy(field_name_, entry_.entry, field_name_length_);
667 field_name_[field_name_length_] = '\0';
669 if(entry_.length - field_name_length_ == 0) {
670 field_value_length_ = 0;
671 if(0 == (field_value_ = (char *)malloc(0))) {
677 field_value_length_ = entry_.length - field_name_length_ - 1;
678 if(0 == (field_value_ = (char *)malloc(field_value_length_))) {
682 memcpy(field_value_, ++p, field_value_length_);
693 VorbisComment::VorbisComment():
694 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT), /*copy=*/false)
697 VorbisComment::~VorbisComment()
700 unsigned VorbisComment::get_num_comments() const
702 FLAC__ASSERT(is_valid());
703 return object_->data.vorbis_comment.num_comments;
706 VorbisComment::Entry VorbisComment::get_vendor_string() const
708 FLAC__ASSERT(is_valid());
709 return Entry((const char *)object_->data.vorbis_comment.vendor_string.entry, object_->data.vorbis_comment.vendor_string.length);
712 VorbisComment::Entry VorbisComment::get_comment(unsigned index) const
714 FLAC__ASSERT(is_valid());
715 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
716 return Entry((const char *)object_->data.vorbis_comment.comments[index].entry, object_->data.vorbis_comment.comments[index].length);
719 bool VorbisComment::set_vendor_string(const VorbisComment::Entry &entry)
721 FLAC__ASSERT(is_valid());
722 // vendor_string is a special kind of entry
723 ::FLAC__StreamMetadata_VorbisComment_Entry vendor_string;
724 vendor_string.length = entry.get_field_name_length();
725 vendor_string.entry = (FLAC__byte*)entry.get_field_name(); // we can cheat on const-ness because we make a copy below:
726 return (bool)::FLAC__metadata_object_vorbiscomment_set_vendor_string(object_, vendor_string, /*copy=*/true);
729 bool VorbisComment::set_comment(unsigned index, const VorbisComment::Entry &entry)
731 FLAC__ASSERT(is_valid());
732 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
733 return (bool)::FLAC__metadata_object_vorbiscomment_set_comment(object_, index, entry.get_entry(), /*copy=*/true);
736 bool VorbisComment::insert_comment(unsigned index, const VorbisComment::Entry &entry)
738 FLAC__ASSERT(is_valid());
739 FLAC__ASSERT(index <= object_->data.vorbis_comment.num_comments);
740 return (bool)::FLAC__metadata_object_vorbiscomment_insert_comment(object_, index, entry.get_entry(), /*copy=*/true);
743 bool VorbisComment::delete_comment(unsigned index)
745 FLAC__ASSERT(is_valid());
746 FLAC__ASSERT(index < object_->data.vorbis_comment.num_comments);
747 return (bool)::FLAC__metadata_object_vorbiscomment_delete_comment(object_, index);
755 CueSheet::Track::Track():
756 object_(::FLAC__metadata_object_cuesheet_track_new())
759 CueSheet::Track::Track(const ::FLAC__StreamMetadata_CueSheet_Track *track):
760 object_(::FLAC__metadata_object_cuesheet_track_clone(track))
763 CueSheet::Track::Track(const Track &track):
764 object_(::FLAC__metadata_object_cuesheet_track_clone(track.object_))
767 void CueSheet::Track::operator=(const Track &track)
770 ::FLAC__metadata_object_cuesheet_track_delete(object_);
771 object_ = ::FLAC__metadata_object_cuesheet_track_clone(track.object_);
774 CueSheet::Track::~Track()
777 ::FLAC__metadata_object_cuesheet_track_delete(object_);
780 bool CueSheet::Track::is_valid() const
782 return(0 != object_);
785 ::FLAC__StreamMetadata_CueSheet_Index CueSheet::Track::get_index(unsigned i) const
787 FLAC__ASSERT(is_valid());
788 FLAC__ASSERT(i < object_->num_indices);
789 return object_->indices[i];
792 void CueSheet::Track::set_isrc(const char value[12])
794 FLAC__ASSERT(is_valid());
795 FLAC__ASSERT(0 != value);
796 memcpy(object_->isrc, value, 12);
797 object_->isrc[12] = '\0';
800 void CueSheet::Track::set_type(unsigned value)
802 FLAC__ASSERT(is_valid());
803 FLAC__ASSERT(value <= 1);
804 object_->type = value;
807 void CueSheet::Track::set_index(unsigned i, const ::FLAC__StreamMetadata_CueSheet_Index &index)
809 FLAC__ASSERT(is_valid());
810 FLAC__ASSERT(i < object_->num_indices);
811 object_->indices[i] = index;
819 CueSheet::CueSheet():
820 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET), /*copy=*/false)
823 CueSheet::~CueSheet()
826 const char *CueSheet::get_media_catalog_number() const
828 FLAC__ASSERT(is_valid());
829 return object_->data.cue_sheet.media_catalog_number;
832 FLAC__uint64 CueSheet::get_lead_in() const
834 FLAC__ASSERT(is_valid());
835 return object_->data.cue_sheet.lead_in;
838 bool CueSheet::get_is_cd() const
840 FLAC__ASSERT(is_valid());
841 return object_->data.cue_sheet.is_cd? true : false;
844 unsigned CueSheet::get_num_tracks() const
846 FLAC__ASSERT(is_valid());
847 return object_->data.cue_sheet.num_tracks;
850 CueSheet::Track CueSheet::get_track(unsigned i) const
852 FLAC__ASSERT(is_valid());
853 FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
854 return Track(object_->data.cue_sheet.tracks + i);
857 void CueSheet::set_media_catalog_number(const char value[128])
859 FLAC__ASSERT(is_valid());
860 FLAC__ASSERT(0 != value);
861 memcpy(object_->data.cue_sheet.media_catalog_number, value, 128);
862 object_->data.cue_sheet.media_catalog_number[128] = '\0';
865 void CueSheet::set_lead_in(FLAC__uint64 value)
867 FLAC__ASSERT(is_valid());
868 object_->data.cue_sheet.lead_in = value;
871 void CueSheet::set_is_cd(bool value)
873 FLAC__ASSERT(is_valid());
874 object_->data.cue_sheet.is_cd = value;
877 void CueSheet::set_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index)
879 FLAC__ASSERT(is_valid());
880 FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
881 FLAC__ASSERT(index_num < object_->data.cue_sheet.tracks[track_num].num_indices);
882 object_->data.cue_sheet.tracks[track_num].indices[index_num] = index;
885 bool CueSheet::insert_index(unsigned track_num, unsigned index_num, const ::FLAC__StreamMetadata_CueSheet_Index &index)
887 FLAC__ASSERT(is_valid());
888 FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
889 FLAC__ASSERT(index_num <= object_->data.cue_sheet.tracks[track_num].num_indices);
890 return (bool)::FLAC__metadata_object_cuesheet_track_insert_index(object_, track_num, index_num, index);
893 bool CueSheet::delete_index(unsigned track_num, unsigned index_num)
895 FLAC__ASSERT(is_valid());
896 FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
897 FLAC__ASSERT(index_num < object_->data.cue_sheet.tracks[track_num].num_indices);
898 return (bool)::FLAC__metadata_object_cuesheet_track_delete_index(object_, track_num, index_num);
901 bool CueSheet::set_track(unsigned i, const CueSheet::Track &track)
903 FLAC__ASSERT(is_valid());
904 FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
905 // We can safely const_cast since copy=true
906 return (bool)::FLAC__metadata_object_cuesheet_set_track(object_, i, const_cast< ::FLAC__StreamMetadata_CueSheet_Track*>(track.get_track()), /*copy=*/true);
909 bool CueSheet::insert_track(unsigned i, const CueSheet::Track &track)
911 FLAC__ASSERT(is_valid());
912 FLAC__ASSERT(i <= object_->data.cue_sheet.num_tracks);
913 // We can safely const_cast since copy=true
914 return (bool)::FLAC__metadata_object_cuesheet_insert_track(object_, i, const_cast< ::FLAC__StreamMetadata_CueSheet_Track*>(track.get_track()), /*copy=*/true);
917 bool CueSheet::delete_track(unsigned i)
919 FLAC__ASSERT(is_valid());
920 FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
921 return (bool)::FLAC__metadata_object_cuesheet_delete_track(object_, i);
924 bool CueSheet::is_legal(bool check_cd_da_subset, const char **violation) const
926 FLAC__ASSERT(is_valid());
927 return (bool)::FLAC__metadata_object_cuesheet_is_legal(object_, check_cd_da_subset, violation);
936 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), /*copy=*/false)
942 const FLAC__byte *Unknown::get_data() const
944 FLAC__ASSERT(is_valid());
945 return object_->data.application.data;
948 bool Unknown::set_data(const FLAC__byte *data, unsigned length)
950 FLAC__ASSERT(is_valid());
951 return (bool)::FLAC__metadata_object_application_set_data(object_, (FLAC__byte*)data, length, true);
954 bool Unknown::set_data(FLAC__byte *data, unsigned length, bool copy)
956 FLAC__ASSERT(is_valid());
957 return (bool)::FLAC__metadata_object_application_set_data(object_, data, length, copy);
961 // ============================================================
965 // ============================================================
967 FLACPP_API bool get_streaminfo(const char *filename, StreamInfo &streaminfo)
969 FLAC__ASSERT(0 != filename);
971 ::FLAC__StreamMetadata s;
973 if(::FLAC__metadata_get_streaminfo(filename, &s)) {
982 // ============================================================
986 // ============================================================
988 SimpleIterator::SimpleIterator():
989 iterator_(::FLAC__metadata_simple_iterator_new())
992 SimpleIterator::~SimpleIterator()
997 void SimpleIterator::clear()
1000 FLAC__metadata_simple_iterator_delete(iterator_);
1004 bool SimpleIterator::init(const char *filename, bool read_only, bool preserve_file_stats)
1006 FLAC__ASSERT(0 != filename);
1007 FLAC__ASSERT(is_valid());
1008 return (bool)::FLAC__metadata_simple_iterator_init(iterator_, filename, read_only, preserve_file_stats);
1011 bool SimpleIterator::is_valid() const
1013 return 0 != iterator_;
1016 SimpleIterator::Status SimpleIterator::status()
1018 FLAC__ASSERT(is_valid());
1019 return Status(::FLAC__metadata_simple_iterator_status(iterator_));
1022 bool SimpleIterator::is_writable() const
1024 FLAC__ASSERT(is_valid());
1025 return (bool)::FLAC__metadata_simple_iterator_is_writable(iterator_);
1028 bool SimpleIterator::next()
1030 FLAC__ASSERT(is_valid());
1031 return (bool)::FLAC__metadata_simple_iterator_next(iterator_);
1034 bool SimpleIterator::prev()
1036 FLAC__ASSERT(is_valid());
1037 return (bool)::FLAC__metadata_simple_iterator_prev(iterator_);
1040 ::FLAC__MetadataType SimpleIterator::get_block_type() const
1042 FLAC__ASSERT(is_valid());
1043 return ::FLAC__metadata_simple_iterator_get_block_type(iterator_);
1046 Prototype *SimpleIterator::get_block()
1048 FLAC__ASSERT(is_valid());
1049 return local::construct_block(::FLAC__metadata_simple_iterator_get_block(iterator_));
1052 bool SimpleIterator::set_block(Prototype *block, bool use_padding)
1054 FLAC__ASSERT(0 != block);
1055 FLAC__ASSERT(is_valid());
1056 return (bool)::FLAC__metadata_simple_iterator_set_block(iterator_, block->object_, use_padding);
1059 bool SimpleIterator::insert_block_after(Prototype *block, bool use_padding)
1061 FLAC__ASSERT(0 != block);
1062 FLAC__ASSERT(is_valid());
1063 return (bool)::FLAC__metadata_simple_iterator_insert_block_after(iterator_, block->object_, use_padding);
1066 bool SimpleIterator::delete_block(bool use_padding)
1068 FLAC__ASSERT(is_valid());
1069 return (bool)::FLAC__metadata_simple_iterator_delete_block(iterator_, use_padding);
1073 // ============================================================
1077 // ============================================================
1080 chain_(::FLAC__metadata_chain_new())
1091 FLAC__metadata_chain_delete(chain_);
1095 bool Chain::is_valid() const
1100 Chain::Status Chain::status()
1102 FLAC__ASSERT(is_valid());
1103 return Status(::FLAC__metadata_chain_status(chain_));
1106 bool Chain::read(const char *filename)
1108 FLAC__ASSERT(0 != filename);
1109 FLAC__ASSERT(is_valid());
1110 return (bool)::FLAC__metadata_chain_read(chain_, filename);
1113 bool Chain::write(bool use_padding, bool preserve_file_stats)
1115 FLAC__ASSERT(is_valid());
1116 return (bool)::FLAC__metadata_chain_write(chain_, use_padding, preserve_file_stats);
1119 void Chain::merge_padding()
1121 FLAC__ASSERT(is_valid());
1122 ::FLAC__metadata_chain_merge_padding(chain_);
1125 void Chain::sort_padding()
1127 FLAC__ASSERT(is_valid());
1128 ::FLAC__metadata_chain_sort_padding(chain_);
1132 Iterator::Iterator():
1133 iterator_(::FLAC__metadata_iterator_new())
1136 Iterator::~Iterator()
1141 void Iterator::clear()
1144 FLAC__metadata_iterator_delete(iterator_);
1148 bool Iterator::is_valid() const
1150 return 0 != iterator_;
1153 void Iterator::init(Chain &chain)
1155 FLAC__ASSERT(is_valid());
1156 FLAC__ASSERT(chain.is_valid());
1157 ::FLAC__metadata_iterator_init(iterator_, chain.chain_);
1160 bool Iterator::next()
1162 FLAC__ASSERT(is_valid());
1163 return (bool)::FLAC__metadata_iterator_next(iterator_);
1166 bool Iterator::prev()
1168 FLAC__ASSERT(is_valid());
1169 return (bool)::FLAC__metadata_iterator_prev(iterator_);
1172 ::FLAC__MetadataType Iterator::get_block_type() const
1174 FLAC__ASSERT(is_valid());
1175 return ::FLAC__metadata_iterator_get_block_type(iterator_);
1178 Prototype *Iterator::get_block()
1180 FLAC__ASSERT(is_valid());
1181 Prototype *block = local::construct_block(::FLAC__metadata_iterator_get_block(iterator_));
1183 block->set_reference(true);
1187 bool Iterator::set_block(Prototype *block)
1189 FLAC__ASSERT(0 != block);
1190 FLAC__ASSERT(is_valid());
1191 bool ret = (bool)::FLAC__metadata_iterator_set_block(iterator_, block->object_);
1193 block->set_reference(true);
1199 bool Iterator::delete_block(bool replace_with_padding)
1201 FLAC__ASSERT(is_valid());
1202 return (bool)::FLAC__metadata_iterator_delete_block(iterator_, replace_with_padding);
1205 bool Iterator::insert_block_before(Prototype *block)
1207 FLAC__ASSERT(0 != block);
1208 FLAC__ASSERT(is_valid());
1209 bool ret = (bool)::FLAC__metadata_iterator_insert_block_before(iterator_, block->object_);
1211 block->set_reference(true);
1217 bool Iterator::insert_block_after(Prototype *block)
1219 FLAC__ASSERT(0 != block);
1220 FLAC__ASSERT(is_valid());
1221 bool ret = (bool)::FLAC__metadata_iterator_insert_block_after(iterator_, block->object_);
1223 block->set_reference(true);