1 /* libFLAC++ - Free Lossless Audio Codec library
2 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Josh Coalson
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * - Neither the name of the Xiph.org Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #define __STDC_LIMIT_MACROS 1 /* otherwise SIZE_MAX is not defined for c++ */
33 #include "share/alloc.h"
34 #include "FLAC++/metadata.h"
35 #include "FLAC/assert.h"
36 #include <stdlib.h> // for malloc(), free()
37 #include <string.h> // for memcpy() etc.
40 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
41 #pragma warning ( disable : 4800 )
47 // local utility routines
51 Prototype
*construct_block(::FLAC__StreamMetadata
*object
)
54 switch(object
->type
) {
55 case FLAC__METADATA_TYPE_STREAMINFO
:
56 ret
= new StreamInfo(object
, /*copy=*/false);
58 case FLAC__METADATA_TYPE_PADDING
:
59 ret
= new Padding(object
, /*copy=*/false);
61 case FLAC__METADATA_TYPE_APPLICATION
:
62 ret
= new Application(object
, /*copy=*/false);
64 case FLAC__METADATA_TYPE_SEEKTABLE
:
65 ret
= new SeekTable(object
, /*copy=*/false);
67 case FLAC__METADATA_TYPE_VORBIS_COMMENT
:
68 ret
= new VorbisComment(object
, /*copy=*/false);
70 case FLAC__METADATA_TYPE_CUESHEET
:
71 ret
= new CueSheet(object
, /*copy=*/false);
73 case FLAC__METADATA_TYPE_PICTURE
:
74 ret
= new Picture(object
, /*copy=*/false);
77 ret
= new Unknown(object
, /*copy=*/false);
85 FLACPP_API Prototype
*clone(const Prototype
*object
)
87 FLAC__ASSERT(0 != object
);
89 const StreamInfo
*streaminfo
= dynamic_cast<const StreamInfo
*>(object
);
90 const Padding
*padding
= dynamic_cast<const Padding
*>(object
);
91 const Application
*application
= dynamic_cast<const Application
*>(object
);
92 const SeekTable
*seektable
= dynamic_cast<const SeekTable
*>(object
);
93 const VorbisComment
*vorbiscomment
= dynamic_cast<const VorbisComment
*>(object
);
94 const CueSheet
*cuesheet
= dynamic_cast<const CueSheet
*>(object
);
95 const Picture
*picture
= dynamic_cast<const Picture
*>(object
);
96 const Unknown
*unknown
= dynamic_cast<const Unknown
*>(object
);
99 return new StreamInfo(*streaminfo
);
100 else if(0 != padding
)
101 return new Padding(*padding
);
102 else if(0 != application
)
103 return new Application(*application
);
104 else if(0 != seektable
)
105 return new SeekTable(*seektable
);
106 else if(0 != vorbiscomment
)
107 return new VorbisComment(*vorbiscomment
);
108 else if(0 != cuesheet
)
109 return new CueSheet(*cuesheet
);
110 else if(0 != picture
)
111 return new Picture(*picture
);
112 else if(0 != unknown
)
113 return new Unknown(*unknown
);
124 Prototype::Prototype(const Prototype
&object
):
125 object_(::FLAC__metadata_object_clone(object
.object_
)),
128 FLAC__ASSERT(object
.is_valid());
131 Prototype::Prototype(const ::FLAC__StreamMetadata
&object
):
132 object_(::FLAC__metadata_object_clone(&object
)),
137 Prototype::Prototype(const ::FLAC__StreamMetadata
*object
):
138 object_(::FLAC__metadata_object_clone(object
)),
141 FLAC__ASSERT(0 != object
);
144 Prototype::Prototype(::FLAC__StreamMetadata
*object
, bool copy
):
145 object_(copy
? ::FLAC__metadata_object_clone(object
) : object
),
148 FLAC__ASSERT(0 != object
);
151 Prototype::~Prototype()
156 void Prototype::clear()
158 if(0 != object_
&& !is_reference_
)
159 FLAC__metadata_object_delete(object_
);
163 Prototype
&Prototype::operator=(const Prototype
&object
)
165 FLAC__ASSERT(object
.is_valid());
167 is_reference_
= false;
168 object_
= ::FLAC__metadata_object_clone(object
.object_
);
172 Prototype
&Prototype::operator=(const ::FLAC__StreamMetadata
&object
)
175 is_reference_
= false;
176 object_
= ::FLAC__metadata_object_clone(&object
);
180 Prototype
&Prototype::operator=(const ::FLAC__StreamMetadata
*object
)
182 FLAC__ASSERT(0 != object
);
184 is_reference_
= false;
185 object_
= ::FLAC__metadata_object_clone(object
);
189 Prototype
&Prototype::assign_object(::FLAC__StreamMetadata
*object
, bool copy
)
191 FLAC__ASSERT(0 != object
);
193 object_
= (copy
? ::FLAC__metadata_object_clone(object
) : object
);
194 is_reference_
= false;
198 bool Prototype::get_is_last() const
200 FLAC__ASSERT(is_valid());
201 return (bool)object_
->is_last
;
204 FLAC__MetadataType
Prototype::get_type() const
206 FLAC__ASSERT(is_valid());
207 return object_
->type
;
210 unsigned Prototype::get_length() const
212 FLAC__ASSERT(is_valid());
213 return object_
->length
;
216 void Prototype::set_is_last(bool value
)
218 FLAC__ASSERT(is_valid());
219 object_
->is_last
= value
;
227 StreamInfo::StreamInfo():
228 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO
), /*copy=*/false)
231 StreamInfo::~StreamInfo()
234 unsigned StreamInfo::get_min_blocksize() const
236 FLAC__ASSERT(is_valid());
237 return object_
->data
.stream_info
.min_blocksize
;
240 unsigned StreamInfo::get_max_blocksize() const
242 FLAC__ASSERT(is_valid());
243 return object_
->data
.stream_info
.max_blocksize
;
246 unsigned StreamInfo::get_min_framesize() const
248 FLAC__ASSERT(is_valid());
249 return object_
->data
.stream_info
.min_framesize
;
252 unsigned StreamInfo::get_max_framesize() const
254 FLAC__ASSERT(is_valid());
255 return object_
->data
.stream_info
.max_framesize
;
258 unsigned StreamInfo::get_sample_rate() const
260 FLAC__ASSERT(is_valid());
261 return object_
->data
.stream_info
.sample_rate
;
264 unsigned StreamInfo::get_channels() const
266 FLAC__ASSERT(is_valid());
267 return object_
->data
.stream_info
.channels
;
270 unsigned StreamInfo::get_bits_per_sample() const
272 FLAC__ASSERT(is_valid());
273 return object_
->data
.stream_info
.bits_per_sample
;
276 FLAC__uint64
StreamInfo::get_total_samples() const
278 FLAC__ASSERT(is_valid());
279 return object_
->data
.stream_info
.total_samples
;
282 const FLAC__byte
*StreamInfo::get_md5sum() const
284 FLAC__ASSERT(is_valid());
285 return object_
->data
.stream_info
.md5sum
;
288 void StreamInfo::set_min_blocksize(unsigned value
)
290 FLAC__ASSERT(is_valid());
291 FLAC__ASSERT(value
>= FLAC__MIN_BLOCK_SIZE
);
292 FLAC__ASSERT(value
<= FLAC__MAX_BLOCK_SIZE
);
293 object_
->data
.stream_info
.min_blocksize
= value
;
296 void StreamInfo::set_max_blocksize(unsigned value
)
298 FLAC__ASSERT(is_valid());
299 FLAC__ASSERT(value
>= FLAC__MIN_BLOCK_SIZE
);
300 FLAC__ASSERT(value
<= FLAC__MAX_BLOCK_SIZE
);
301 object_
->data
.stream_info
.max_blocksize
= value
;
304 void StreamInfo::set_min_framesize(unsigned value
)
306 FLAC__ASSERT(is_valid());
307 FLAC__ASSERT(value
< (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN
));
308 object_
->data
.stream_info
.min_framesize
= value
;
311 void StreamInfo::set_max_framesize(unsigned value
)
313 FLAC__ASSERT(is_valid());
314 FLAC__ASSERT(value
< (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN
));
315 object_
->data
.stream_info
.max_framesize
= value
;
318 void StreamInfo::set_sample_rate(unsigned value
)
320 FLAC__ASSERT(is_valid());
321 FLAC__ASSERT(FLAC__format_sample_rate_is_valid(value
));
322 object_
->data
.stream_info
.sample_rate
= value
;
325 void StreamInfo::set_channels(unsigned value
)
327 FLAC__ASSERT(is_valid());
328 FLAC__ASSERT(value
> 0);
329 FLAC__ASSERT(value
<= FLAC__MAX_CHANNELS
);
330 object_
->data
.stream_info
.channels
= value
;
333 void StreamInfo::set_bits_per_sample(unsigned value
)
335 FLAC__ASSERT(is_valid());
336 FLAC__ASSERT(value
>= FLAC__MIN_BITS_PER_SAMPLE
);
337 FLAC__ASSERT(value
<= FLAC__MAX_BITS_PER_SAMPLE
);
338 object_
->data
.stream_info
.bits_per_sample
= value
;
341 void StreamInfo::set_total_samples(FLAC__uint64 value
)
343 FLAC__ASSERT(is_valid());
344 FLAC__ASSERT(value
< (((FLAC__uint64
)1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
));
345 object_
->data
.stream_info
.total_samples
= value
;
348 void StreamInfo::set_md5sum(const FLAC__byte value
[16])
350 FLAC__ASSERT(is_valid());
351 FLAC__ASSERT(0 != value
);
352 memcpy(object_
->data
.stream_info
.md5sum
, value
, 16);
361 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING
), /*copy=*/false)
367 void Padding::set_length(unsigned length
)
369 FLAC__ASSERT(is_valid());
370 object_
->length
= length
;
378 Application::Application():
379 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION
), /*copy=*/false)
382 Application::~Application()
385 const FLAC__byte
*Application::get_id() const
387 FLAC__ASSERT(is_valid());
388 return object_
->data
.application
.id
;
391 const FLAC__byte
*Application::get_data() const
393 FLAC__ASSERT(is_valid());
394 return object_
->data
.application
.data
;
397 void Application::set_id(const FLAC__byte value
[4])
399 FLAC__ASSERT(is_valid());
400 FLAC__ASSERT(0 != value
);
401 memcpy(object_
->data
.application
.id
, value
, 4);
404 bool Application::set_data(const FLAC__byte
*data
, unsigned length
)
406 FLAC__ASSERT(is_valid());
407 return (bool)::FLAC__metadata_object_application_set_data(object_
, (FLAC__byte
*)data
, length
, true);
410 bool Application::set_data(FLAC__byte
*data
, unsigned length
, bool copy
)
412 FLAC__ASSERT(is_valid());
413 return (bool)::FLAC__metadata_object_application_set_data(object_
, data
, length
, copy
);
421 SeekTable::SeekTable():
422 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE
), /*copy=*/false)
425 SeekTable::~SeekTable()
428 unsigned SeekTable::get_num_points() const
430 FLAC__ASSERT(is_valid());
431 return object_
->data
.seek_table
.num_points
;
434 ::FLAC__StreamMetadata_SeekPoint
SeekTable::get_point(unsigned index
) const
436 FLAC__ASSERT(is_valid());
437 FLAC__ASSERT(index
< object_
->data
.seek_table
.num_points
);
438 return object_
->data
.seek_table
.points
[index
];
441 bool SeekTable::resize_points(unsigned new_num_points
)
443 FLAC__ASSERT(is_valid());
444 return (bool)::FLAC__metadata_object_seektable_resize_points(object_
, new_num_points
);
447 void SeekTable::set_point(unsigned index
, const ::FLAC__StreamMetadata_SeekPoint
&point
)
449 FLAC__ASSERT(is_valid());
450 FLAC__ASSERT(index
< object_
->data
.seek_table
.num_points
);
451 ::FLAC__metadata_object_seektable_set_point(object_
, index
, point
);
454 bool SeekTable::insert_point(unsigned index
, const ::FLAC__StreamMetadata_SeekPoint
&point
)
456 FLAC__ASSERT(is_valid());
457 FLAC__ASSERT(index
<= object_
->data
.seek_table
.num_points
);
458 return (bool)::FLAC__metadata_object_seektable_insert_point(object_
, index
, point
);
461 bool SeekTable::delete_point(unsigned index
)
463 FLAC__ASSERT(is_valid());
464 FLAC__ASSERT(index
< object_
->data
.seek_table
.num_points
);
465 return (bool)::FLAC__metadata_object_seektable_delete_point(object_
, index
);
468 bool SeekTable::is_legal() const
470 FLAC__ASSERT(is_valid());
471 return (bool)::FLAC__metadata_object_seektable_is_legal(object_
);
474 bool SeekTable::template_append_placeholders(unsigned num
)
476 FLAC__ASSERT(is_valid());
477 return (bool)::FLAC__metadata_object_seektable_template_append_placeholders(object_
, num
);
480 bool SeekTable::template_append_point(FLAC__uint64 sample_number
)
482 FLAC__ASSERT(is_valid());
483 return (bool)::FLAC__metadata_object_seektable_template_append_point(object_
, sample_number
);
486 bool SeekTable::template_append_points(FLAC__uint64 sample_numbers
[], unsigned num
)
488 FLAC__ASSERT(is_valid());
489 return (bool)::FLAC__metadata_object_seektable_template_append_points(object_
, sample_numbers
, num
);
492 bool SeekTable::template_append_spaced_points(unsigned num
, FLAC__uint64 total_samples
)
494 FLAC__ASSERT(is_valid());
495 return (bool)::FLAC__metadata_object_seektable_template_append_spaced_points(object_
, num
, total_samples
);
498 bool SeekTable::template_append_spaced_points_by_samples(unsigned samples
, FLAC__uint64 total_samples
)
500 FLAC__ASSERT(is_valid());
501 return (bool)::FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(object_
, samples
, total_samples
);
504 bool SeekTable::template_sort(bool compact
)
506 FLAC__ASSERT(is_valid());
507 return (bool)::FLAC__metadata_object_seektable_template_sort(object_
, compact
);
512 // VorbisComment::Entry
515 VorbisComment::Entry::Entry()
520 VorbisComment::Entry::Entry(const char *field
, unsigned field_length
)
523 construct(field
, field_length
);
526 VorbisComment::Entry::Entry(const char *field
)
532 VorbisComment::Entry::Entry(const char *field_name
, const char *field_value
, unsigned field_value_length
)
535 construct(field_name
, field_value
, field_value_length
);
538 VorbisComment::Entry::Entry(const char *field_name
, const char *field_value
)
541 construct(field_name
, field_value
);
544 VorbisComment::Entry::Entry(const Entry
&entry
)
546 FLAC__ASSERT(entry
.is_valid());
548 construct((const char *)entry
.entry_
.entry
, entry
.entry_
.length
);
551 VorbisComment::Entry
&VorbisComment::Entry::operator=(const Entry
&entry
)
553 FLAC__ASSERT(entry
.is_valid());
555 construct((const char *)entry
.entry_
.entry
, entry
.entry_
.length
);
559 VorbisComment::Entry::~Entry()
564 bool VorbisComment::Entry::is_valid() const
569 unsigned VorbisComment::Entry::get_field_length() const
571 FLAC__ASSERT(is_valid());
572 return entry_
.length
;
575 unsigned VorbisComment::Entry::get_field_name_length() const
577 FLAC__ASSERT(is_valid());
578 return field_name_length_
;
581 unsigned VorbisComment::Entry::get_field_value_length() const
583 FLAC__ASSERT(is_valid());
584 return field_value_length_
;
587 ::FLAC__StreamMetadata_VorbisComment_Entry
VorbisComment::Entry::get_entry() const
589 FLAC__ASSERT(is_valid());
593 const char *VorbisComment::Entry::get_field() const
595 FLAC__ASSERT(is_valid());
596 return (const char *)entry_
.entry
;
599 const char *VorbisComment::Entry::get_field_name() const
601 FLAC__ASSERT(is_valid());
605 const char *VorbisComment::Entry::get_field_value() const
607 FLAC__ASSERT(is_valid());
611 bool VorbisComment::Entry::set_field(const char *field
, unsigned field_length
)
613 FLAC__ASSERT(is_valid());
614 FLAC__ASSERT(0 != field
);
616 if(!::FLAC__format_vorbiscomment_entry_is_legal((const ::FLAC__byte
*)field
, field_length
))
617 return is_valid_
= false;
621 if(0 == (entry_
.entry
= (FLAC__byte
*)safe_malloc_add_2op_(field_length
, /*+*/1))) {
625 entry_
.length
= field_length
;
626 memcpy(entry_
.entry
, field
, field_length
);
627 entry_
.entry
[field_length
] = '\0';
628 (void) parse_field();
634 bool VorbisComment::Entry::set_field(const char *field
)
636 return set_field(field
, strlen(field
));
639 bool VorbisComment::Entry::set_field_name(const char *field_name
)
641 FLAC__ASSERT(is_valid());
642 FLAC__ASSERT(0 != field_name
);
644 if(!::FLAC__format_vorbiscomment_entry_name_is_legal(field_name
))
645 return is_valid_
= false;
649 if(0 == (field_name_
= strdup(field_name
))) {
653 field_name_length_
= strlen(field_name_
);
660 bool VorbisComment::Entry::set_field_value(const char *field_value
, unsigned field_value_length
)
662 FLAC__ASSERT(is_valid());
663 FLAC__ASSERT(0 != field_value
);
665 if(!::FLAC__format_vorbiscomment_entry_value_is_legal((const FLAC__byte
*)field_value
, field_value_length
))
666 return is_valid_
= false;
670 if(0 == (field_value_
= (char *)safe_malloc_add_2op_(field_value_length
, /*+*/1))) {
674 field_value_length_
= field_value_length
;
675 memcpy(field_value_
, field_value
, field_value_length
);
676 field_value_
[field_value_length
] = '\0';
683 bool VorbisComment::Entry::set_field_value(const char *field_value
)
685 return set_field_value(field_value
, strlen(field_value
));
688 void VorbisComment::Entry::zero()
694 field_name_length_
= 0;
696 field_value_length_
= 0;
699 void VorbisComment::Entry::clear()
707 void VorbisComment::Entry::clear_entry()
709 if(0 != entry_
.entry
) {
716 void VorbisComment::Entry::clear_field_name()
718 if(0 != field_name_
) {
721 field_name_length_
= 0;
725 void VorbisComment::Entry::clear_field_value()
727 if(0 != field_value_
) {
730 field_value_length_
= 0;
734 void VorbisComment::Entry::construct(const char *field
, unsigned field_length
)
736 if(set_field(field
, field_length
))
740 void VorbisComment::Entry::construct(const char *field
)
742 construct(field
, strlen(field
));
745 void VorbisComment::Entry::construct(const char *field_name
, const char *field_value
, unsigned field_value_length
)
747 if(set_field_name(field_name
) && set_field_value(field_value
, field_value_length
))
751 void VorbisComment::Entry::construct(const char *field_name
, const char *field_value
)
753 construct(field_name
, field_value
, strlen(field_value
));
756 void VorbisComment::Entry::compose_field()
760 if(0 == (entry_
.entry
= (FLAC__byte
*)safe_malloc_add_4op_(field_name_length_
, /*+*/1, /*+*/field_value_length_
, /*+*/1))) {
764 memcpy(entry_
.entry
, field_name_
, field_name_length_
);
765 entry_
.length
+= field_name_length_
;
766 memcpy(entry_
.entry
+ entry_
.length
, "=", 1);
768 memcpy(entry_
.entry
+ entry_
.length
, field_value_
, field_value_length_
);
769 entry_
.length
+= field_value_length_
;
770 entry_
.entry
[entry_
.length
] = '\0';
775 void VorbisComment::Entry::parse_field()
780 const char *p
= (const char *)memchr(entry_
.entry
, '=', entry_
.length
);
783 p
= (const char *)entry_
.entry
+ entry_
.length
;
785 field_name_length_
= (unsigned)(p
- (const char *)entry_
.entry
);
786 if(0 == (field_name_
= (char *)safe_malloc_add_2op_(field_name_length_
, /*+*/1))) { // +1 for the trailing \0
790 memcpy(field_name_
, entry_
.entry
, field_name_length_
);
791 field_name_
[field_name_length_
] = '\0';
793 if(entry_
.length
- field_name_length_
== 0) {
794 field_value_length_
= 0;
795 if(0 == (field_value_
= (char *)safe_malloc_(0))) {
801 field_value_length_
= entry_
.length
- field_name_length_
- 1;
802 if(0 == (field_value_
= (char *)safe_malloc_add_2op_(field_value_length_
, /*+*/1))) { // +1 for the trailing \0
806 memcpy(field_value_
, ++p
, field_value_length_
);
807 field_value_
[field_value_length_
] = '\0';
818 VorbisComment::VorbisComment():
819 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT
), /*copy=*/false)
822 VorbisComment::~VorbisComment()
825 unsigned VorbisComment::get_num_comments() const
827 FLAC__ASSERT(is_valid());
828 return object_
->data
.vorbis_comment
.num_comments
;
831 const FLAC__byte
*VorbisComment::get_vendor_string() const
833 FLAC__ASSERT(is_valid());
834 return object_
->data
.vorbis_comment
.vendor_string
.entry
;
837 VorbisComment::Entry
VorbisComment::get_comment(unsigned index
) const
839 FLAC__ASSERT(is_valid());
840 FLAC__ASSERT(index
< object_
->data
.vorbis_comment
.num_comments
);
841 return Entry((const char *)object_
->data
.vorbis_comment
.comments
[index
].entry
, object_
->data
.vorbis_comment
.comments
[index
].length
);
844 bool VorbisComment::set_vendor_string(const FLAC__byte
*string
)
846 FLAC__ASSERT(is_valid());
847 // vendor_string is a special kind of entry
848 const ::FLAC__StreamMetadata_VorbisComment_Entry vendor_string
= { static_cast<FLAC__uint32
>(strlen((const char *)string
)), (FLAC__byte
*)string
}; // we can cheat on const-ness because we make a copy below:
849 return (bool)::FLAC__metadata_object_vorbiscomment_set_vendor_string(object_
, vendor_string
, /*copy=*/true);
852 bool VorbisComment::resize_comments(unsigned new_num_comments
)
854 FLAC__ASSERT(is_valid());
855 return (bool)::FLAC__metadata_object_vorbiscomment_resize_comments(object_
, new_num_comments
);
858 bool VorbisComment::set_comment(unsigned index
, const VorbisComment::Entry
&entry
)
860 FLAC__ASSERT(is_valid());
861 FLAC__ASSERT(index
< object_
->data
.vorbis_comment
.num_comments
);
862 return (bool)::FLAC__metadata_object_vorbiscomment_set_comment(object_
, index
, entry
.get_entry(), /*copy=*/true);
865 bool VorbisComment::insert_comment(unsigned index
, const VorbisComment::Entry
&entry
)
867 FLAC__ASSERT(is_valid());
868 FLAC__ASSERT(index
<= object_
->data
.vorbis_comment
.num_comments
);
869 return (bool)::FLAC__metadata_object_vorbiscomment_insert_comment(object_
, index
, entry
.get_entry(), /*copy=*/true);
872 bool VorbisComment::append_comment(const VorbisComment::Entry
&entry
)
874 FLAC__ASSERT(is_valid());
875 return (bool)::FLAC__metadata_object_vorbiscomment_append_comment(object_
, entry
.get_entry(), /*copy=*/true);
878 bool VorbisComment::replace_comment(const VorbisComment::Entry
&entry
, bool all
)
880 FLAC__ASSERT(is_valid());
881 return (bool)::FLAC__metadata_object_vorbiscomment_replace_comment(object_
, entry
.get_entry(), all
, /*copy=*/true);
884 bool VorbisComment::delete_comment(unsigned index
)
886 FLAC__ASSERT(is_valid());
887 FLAC__ASSERT(index
< object_
->data
.vorbis_comment
.num_comments
);
888 return (bool)::FLAC__metadata_object_vorbiscomment_delete_comment(object_
, index
);
891 int VorbisComment::find_entry_from(unsigned offset
, const char *field_name
)
893 FLAC__ASSERT(is_valid());
894 return ::FLAC__metadata_object_vorbiscomment_find_entry_from(object_
, offset
, field_name
);
897 int VorbisComment::remove_entry_matching(const char *field_name
)
899 FLAC__ASSERT(is_valid());
900 return ::FLAC__metadata_object_vorbiscomment_remove_entry_matching(object_
, field_name
);
903 int VorbisComment::remove_entries_matching(const char *field_name
)
905 FLAC__ASSERT(is_valid());
906 return ::FLAC__metadata_object_vorbiscomment_remove_entries_matching(object_
, field_name
);
914 CueSheet::Track::Track():
915 object_(::FLAC__metadata_object_cuesheet_track_new())
918 CueSheet::Track::Track(const ::FLAC__StreamMetadata_CueSheet_Track
*track
):
919 object_(::FLAC__metadata_object_cuesheet_track_clone(track
))
922 CueSheet::Track::Track(const Track
&track
):
923 object_(::FLAC__metadata_object_cuesheet_track_clone(track
.object_
))
926 CueSheet::Track
&CueSheet::Track::operator=(const Track
&track
)
929 ::FLAC__metadata_object_cuesheet_track_delete(object_
);
930 object_
= ::FLAC__metadata_object_cuesheet_track_clone(track
.object_
);
934 CueSheet::Track::~Track()
937 ::FLAC__metadata_object_cuesheet_track_delete(object_
);
940 bool CueSheet::Track::is_valid() const
942 return(0 != object_
);
945 ::FLAC__StreamMetadata_CueSheet_Index
CueSheet::Track::get_index(unsigned i
) const
947 FLAC__ASSERT(is_valid());
948 FLAC__ASSERT(i
< object_
->num_indices
);
949 return object_
->indices
[i
];
952 void CueSheet::Track::set_isrc(const char value
[12])
954 FLAC__ASSERT(is_valid());
955 FLAC__ASSERT(0 != value
);
956 memcpy(object_
->isrc
, value
, 12);
957 object_
->isrc
[12] = '\0';
960 void CueSheet::Track::set_type(unsigned value
)
962 FLAC__ASSERT(is_valid());
963 FLAC__ASSERT(value
<= 1);
964 object_
->type
= value
;
967 void CueSheet::Track::set_index(unsigned i
, const ::FLAC__StreamMetadata_CueSheet_Index
&index
)
969 FLAC__ASSERT(is_valid());
970 FLAC__ASSERT(i
< object_
->num_indices
);
971 object_
->indices
[i
] = index
;
979 CueSheet::CueSheet():
980 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET
), /*copy=*/false)
983 CueSheet::~CueSheet()
986 const char *CueSheet::get_media_catalog_number() const
988 FLAC__ASSERT(is_valid());
989 return object_
->data
.cue_sheet
.media_catalog_number
;
992 FLAC__uint64
CueSheet::get_lead_in() const
994 FLAC__ASSERT(is_valid());
995 return object_
->data
.cue_sheet
.lead_in
;
998 bool CueSheet::get_is_cd() const
1000 FLAC__ASSERT(is_valid());
1001 return object_
->data
.cue_sheet
.is_cd
? true : false;
1004 unsigned CueSheet::get_num_tracks() const
1006 FLAC__ASSERT(is_valid());
1007 return object_
->data
.cue_sheet
.num_tracks
;
1010 CueSheet::Track
CueSheet::get_track(unsigned i
) const
1012 FLAC__ASSERT(is_valid());
1013 FLAC__ASSERT(i
< object_
->data
.cue_sheet
.num_tracks
);
1014 return Track(object_
->data
.cue_sheet
.tracks
+ i
);
1017 void CueSheet::set_media_catalog_number(const char value
[128])
1019 FLAC__ASSERT(is_valid());
1020 FLAC__ASSERT(0 != value
);
1021 memcpy(object_
->data
.cue_sheet
.media_catalog_number
, value
, 128);
1022 object_
->data
.cue_sheet
.media_catalog_number
[128] = '\0';
1025 void CueSheet::set_lead_in(FLAC__uint64 value
)
1027 FLAC__ASSERT(is_valid());
1028 object_
->data
.cue_sheet
.lead_in
= value
;
1031 void CueSheet::set_is_cd(bool value
)
1033 FLAC__ASSERT(is_valid());
1034 object_
->data
.cue_sheet
.is_cd
= value
;
1037 void CueSheet::set_index(unsigned track_num
, unsigned index_num
, const ::FLAC__StreamMetadata_CueSheet_Index
&index
)
1039 FLAC__ASSERT(is_valid());
1040 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1041 FLAC__ASSERT(index_num
< object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1042 object_
->data
.cue_sheet
.tracks
[track_num
].indices
[index_num
] = index
;
1045 bool CueSheet::resize_indices(unsigned track_num
, unsigned new_num_indices
)
1047 FLAC__ASSERT(is_valid());
1048 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1049 return (bool)::FLAC__metadata_object_cuesheet_track_resize_indices(object_
, track_num
, new_num_indices
);
1052 bool CueSheet::insert_index(unsigned track_num
, unsigned index_num
, const ::FLAC__StreamMetadata_CueSheet_Index
&index
)
1054 FLAC__ASSERT(is_valid());
1055 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1056 FLAC__ASSERT(index_num
<= object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1057 return (bool)::FLAC__metadata_object_cuesheet_track_insert_index(object_
, track_num
, index_num
, index
);
1060 bool CueSheet::insert_blank_index(unsigned track_num
, unsigned index_num
)
1062 FLAC__ASSERT(is_valid());
1063 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1064 FLAC__ASSERT(index_num
<= object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1065 return (bool)::FLAC__metadata_object_cuesheet_track_insert_blank_index(object_
, track_num
, index_num
);
1068 bool CueSheet::delete_index(unsigned track_num
, unsigned index_num
)
1070 FLAC__ASSERT(is_valid());
1071 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1072 FLAC__ASSERT(index_num
< object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1073 return (bool)::FLAC__metadata_object_cuesheet_track_delete_index(object_
, track_num
, index_num
);
1076 bool CueSheet::resize_tracks(unsigned new_num_tracks
)
1078 FLAC__ASSERT(is_valid());
1079 return (bool)::FLAC__metadata_object_cuesheet_resize_tracks(object_
, new_num_tracks
);
1082 bool CueSheet::set_track(unsigned i
, const CueSheet::Track
&track
)
1084 FLAC__ASSERT(is_valid());
1085 FLAC__ASSERT(i
< object_
->data
.cue_sheet
.num_tracks
);
1086 // We can safely const_cast since copy=true
1087 return (bool)::FLAC__metadata_object_cuesheet_set_track(object_
, i
, const_cast< ::FLAC__StreamMetadata_CueSheet_Track
*>(track
.get_track()), /*copy=*/true);
1090 bool CueSheet::insert_track(unsigned i
, const CueSheet::Track
&track
)
1092 FLAC__ASSERT(is_valid());
1093 FLAC__ASSERT(i
<= object_
->data
.cue_sheet
.num_tracks
);
1094 // We can safely const_cast since copy=true
1095 return (bool)::FLAC__metadata_object_cuesheet_insert_track(object_
, i
, const_cast< ::FLAC__StreamMetadata_CueSheet_Track
*>(track
.get_track()), /*copy=*/true);
1098 bool CueSheet::insert_blank_track(unsigned i
)
1100 FLAC__ASSERT(is_valid());
1101 FLAC__ASSERT(i
<= object_
->data
.cue_sheet
.num_tracks
);
1102 return (bool)::FLAC__metadata_object_cuesheet_insert_blank_track(object_
, i
);
1105 bool CueSheet::delete_track(unsigned i
)
1107 FLAC__ASSERT(is_valid());
1108 FLAC__ASSERT(i
< object_
->data
.cue_sheet
.num_tracks
);
1109 return (bool)::FLAC__metadata_object_cuesheet_delete_track(object_
, i
);
1112 bool CueSheet::is_legal(bool check_cd_da_subset
, const char **violation
) const
1114 FLAC__ASSERT(is_valid());
1115 return (bool)::FLAC__metadata_object_cuesheet_is_legal(object_
, check_cd_da_subset
, violation
);
1118 FLAC__uint32
CueSheet::calculate_cddb_id() const
1120 FLAC__ASSERT(is_valid());
1121 return ::FLAC__metadata_object_cuesheet_calculate_cddb_id(object_
);
1130 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE
), /*copy=*/false)
1136 ::FLAC__StreamMetadata_Picture_Type
Picture::get_type() const
1138 FLAC__ASSERT(is_valid());
1139 return object_
->data
.picture
.type
;
1142 const char *Picture::get_mime_type() const
1144 FLAC__ASSERT(is_valid());
1145 return object_
->data
.picture
.mime_type
;
1148 const FLAC__byte
*Picture::get_description() const
1150 FLAC__ASSERT(is_valid());
1151 return object_
->data
.picture
.description
;
1154 FLAC__uint32
Picture::get_width() const
1156 FLAC__ASSERT(is_valid());
1157 return object_
->data
.picture
.width
;
1160 FLAC__uint32
Picture::get_height() const
1162 FLAC__ASSERT(is_valid());
1163 return object_
->data
.picture
.height
;
1166 FLAC__uint32
Picture::get_depth() const
1168 FLAC__ASSERT(is_valid());
1169 return object_
->data
.picture
.depth
;
1172 FLAC__uint32
Picture::get_colors() const
1174 FLAC__ASSERT(is_valid());
1175 return object_
->data
.picture
.colors
;
1178 FLAC__uint32
Picture::get_data_length() const
1180 FLAC__ASSERT(is_valid());
1181 return object_
->data
.picture
.data_length
;
1184 const FLAC__byte
*Picture::get_data() const
1186 FLAC__ASSERT(is_valid());
1187 return object_
->data
.picture
.data
;
1190 void Picture::set_type(::FLAC__StreamMetadata_Picture_Type type
)
1192 FLAC__ASSERT(is_valid());
1193 object_
->data
.picture
.type
= type
;
1196 bool Picture::set_mime_type(const char *string
)
1198 FLAC__ASSERT(is_valid());
1199 // We can safely const_cast since copy=true
1200 return (bool)::FLAC__metadata_object_picture_set_mime_type(object_
, const_cast<char*>(string
), /*copy=*/true);
1203 bool Picture::set_description(const FLAC__byte
*string
)
1205 FLAC__ASSERT(is_valid());
1206 // We can safely const_cast since copy=true
1207 return (bool)::FLAC__metadata_object_picture_set_description(object_
, const_cast<FLAC__byte
*>(string
), /*copy=*/true);
1210 void Picture::set_width(FLAC__uint32 value
) const
1212 FLAC__ASSERT(is_valid());
1213 object_
->data
.picture
.width
= value
;
1216 void Picture::set_height(FLAC__uint32 value
) const
1218 FLAC__ASSERT(is_valid());
1219 object_
->data
.picture
.height
= value
;
1222 void Picture::set_depth(FLAC__uint32 value
) const
1224 FLAC__ASSERT(is_valid());
1225 object_
->data
.picture
.depth
= value
;
1228 void Picture::set_colors(FLAC__uint32 value
) const
1230 FLAC__ASSERT(is_valid());
1231 object_
->data
.picture
.colors
= value
;
1234 bool Picture::set_data(const FLAC__byte
*data
, FLAC__uint32 data_length
)
1236 FLAC__ASSERT(is_valid());
1237 // We can safely const_cast since copy=true
1238 return (bool)::FLAC__metadata_object_picture_set_data(object_
, const_cast<FLAC__byte
*>(data
), data_length
, /*copy=*/true);
1241 bool Picture::is_legal(const char **violation
)
1243 FLAC__ASSERT(is_valid());
1244 return (bool)::FLAC__metadata_object_picture_is_legal(object_
, violation
);
1253 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION
), /*copy=*/false)
1259 const FLAC__byte
*Unknown::get_data() const
1261 FLAC__ASSERT(is_valid());
1262 return object_
->data
.application
.data
;
1265 bool Unknown::set_data(const FLAC__byte
*data
, unsigned length
)
1267 FLAC__ASSERT(is_valid());
1268 return (bool)::FLAC__metadata_object_application_set_data(object_
, (FLAC__byte
*)data
, length
, true);
1271 bool Unknown::set_data(FLAC__byte
*data
, unsigned length
, bool copy
)
1273 FLAC__ASSERT(is_valid());
1274 return (bool)::FLAC__metadata_object_application_set_data(object_
, data
, length
, copy
);
1278 // ============================================================
1282 // ============================================================
1284 FLACPP_API
bool get_streaminfo(const char *filename
, StreamInfo
&streaminfo
)
1286 FLAC__ASSERT(0 != filename
);
1288 ::FLAC__StreamMetadata object
;
1290 if(::FLAC__metadata_get_streaminfo(filename
, &object
)) {
1291 streaminfo
= object
;
1298 FLACPP_API
bool get_tags(const char *filename
, VorbisComment
*&tags
)
1300 FLAC__ASSERT(0 != filename
);
1302 ::FLAC__StreamMetadata
*object
;
1306 if(::FLAC__metadata_get_tags(filename
, &object
)) {
1307 tags
= new VorbisComment(object
, /*copy=*/false);
1314 FLACPP_API
bool get_tags(const char *filename
, VorbisComment
&tags
)
1316 FLAC__ASSERT(0 != filename
);
1318 ::FLAC__StreamMetadata
*object
;
1320 if(::FLAC__metadata_get_tags(filename
, &object
)) {
1321 tags
.assign(object
, /*copy=*/false);
1328 FLACPP_API
bool get_cuesheet(const char *filename
, CueSheet
*&cuesheet
)
1330 FLAC__ASSERT(0 != filename
);
1332 ::FLAC__StreamMetadata
*object
;
1336 if(::FLAC__metadata_get_cuesheet(filename
, &object
)) {
1337 cuesheet
= new CueSheet(object
, /*copy=*/false);
1344 FLACPP_API
bool get_cuesheet(const char *filename
, CueSheet
&cuesheet
)
1346 FLAC__ASSERT(0 != filename
);
1348 ::FLAC__StreamMetadata
*object
;
1350 if(::FLAC__metadata_get_cuesheet(filename
, &object
)) {
1351 cuesheet
.assign(object
, /*copy=*/false);
1358 FLACPP_API
bool get_picture(const char *filename
, Picture
*&picture
, ::FLAC__StreamMetadata_Picture_Type type
, const char *mime_type
, const FLAC__byte
*description
, unsigned max_width
, unsigned max_height
, unsigned max_depth
, unsigned max_colors
)
1360 FLAC__ASSERT(0 != filename
);
1362 ::FLAC__StreamMetadata
*object
;
1366 if(::FLAC__metadata_get_picture(filename
, &object
, type
, mime_type
, description
, max_width
, max_height
, max_depth
, max_colors
)) {
1367 picture
= new Picture(object
, /*copy=*/false);
1374 FLACPP_API
bool get_picture(const char *filename
, Picture
&picture
, ::FLAC__StreamMetadata_Picture_Type type
, const char *mime_type
, const FLAC__byte
*description
, unsigned max_width
, unsigned max_height
, unsigned max_depth
, unsigned max_colors
)
1376 FLAC__ASSERT(0 != filename
);
1378 ::FLAC__StreamMetadata
*object
;
1380 if(::FLAC__metadata_get_picture(filename
, &object
, type
, mime_type
, description
, max_width
, max_height
, max_depth
, max_colors
)) {
1381 picture
.assign(object
, /*copy=*/false);
1389 // ============================================================
1393 // ============================================================
1395 SimpleIterator::SimpleIterator():
1396 iterator_(::FLAC__metadata_simple_iterator_new())
1399 SimpleIterator::~SimpleIterator()
1404 void SimpleIterator::clear()
1407 FLAC__metadata_simple_iterator_delete(iterator_
);
1411 bool SimpleIterator::init(const char *filename
, bool read_only
, bool preserve_file_stats
)
1413 FLAC__ASSERT(0 != filename
);
1414 FLAC__ASSERT(is_valid());
1415 return (bool)::FLAC__metadata_simple_iterator_init(iterator_
, filename
, read_only
, preserve_file_stats
);
1418 bool SimpleIterator::is_valid() const
1420 return 0 != iterator_
;
1423 SimpleIterator::Status
SimpleIterator::status()
1425 FLAC__ASSERT(is_valid());
1426 return Status(::FLAC__metadata_simple_iterator_status(iterator_
));
1429 bool SimpleIterator::is_writable() const
1431 FLAC__ASSERT(is_valid());
1432 return (bool)::FLAC__metadata_simple_iterator_is_writable(iterator_
);
1435 bool SimpleIterator::next()
1437 FLAC__ASSERT(is_valid());
1438 return (bool)::FLAC__metadata_simple_iterator_next(iterator_
);
1441 bool SimpleIterator::prev()
1443 FLAC__ASSERT(is_valid());
1444 return (bool)::FLAC__metadata_simple_iterator_prev(iterator_
);
1448 bool SimpleIterator::is_last() const
1450 FLAC__ASSERT(is_valid());
1451 return (bool)::FLAC__metadata_simple_iterator_is_last(iterator_
);
1455 off_t
SimpleIterator::get_block_offset() const
1457 FLAC__ASSERT(is_valid());
1458 return ::FLAC__metadata_simple_iterator_get_block_offset(iterator_
);
1461 ::FLAC__MetadataType
SimpleIterator::get_block_type() const
1463 FLAC__ASSERT(is_valid());
1464 return ::FLAC__metadata_simple_iterator_get_block_type(iterator_
);
1468 unsigned SimpleIterator::get_block_length() const
1470 FLAC__ASSERT(is_valid());
1471 return ::FLAC__metadata_simple_iterator_get_block_length(iterator_
);
1475 bool SimpleIterator::get_application_id(FLAC__byte
*id
)
1477 FLAC__ASSERT(is_valid());
1478 return (bool)::FLAC__metadata_simple_iterator_get_application_id(iterator_
, id
);
1481 Prototype
*SimpleIterator::get_block()
1483 FLAC__ASSERT(is_valid());
1484 return local::construct_block(::FLAC__metadata_simple_iterator_get_block(iterator_
));
1487 bool SimpleIterator::set_block(Prototype
*block
, bool use_padding
)
1489 FLAC__ASSERT(0 != block
);
1490 FLAC__ASSERT(is_valid());
1491 return (bool)::FLAC__metadata_simple_iterator_set_block(iterator_
, block
->object_
, use_padding
);
1494 bool SimpleIterator::insert_block_after(Prototype
*block
, bool use_padding
)
1496 FLAC__ASSERT(0 != block
);
1497 FLAC__ASSERT(is_valid());
1498 return (bool)::FLAC__metadata_simple_iterator_insert_block_after(iterator_
, block
->object_
, use_padding
);
1501 bool SimpleIterator::delete_block(bool use_padding
)
1503 FLAC__ASSERT(is_valid());
1504 return (bool)::FLAC__metadata_simple_iterator_delete_block(iterator_
, use_padding
);
1508 // ============================================================
1512 // ============================================================
1515 chain_(::FLAC__metadata_chain_new())
1526 FLAC__metadata_chain_delete(chain_
);
1530 bool Chain::is_valid() const
1535 Chain::Status
Chain::status()
1537 FLAC__ASSERT(is_valid());
1538 return Status(::FLAC__metadata_chain_status(chain_
));
1541 bool Chain::read(const char *filename
, bool is_ogg
)
1543 FLAC__ASSERT(0 != filename
);
1544 FLAC__ASSERT(is_valid());
1546 (bool)::FLAC__metadata_chain_read_ogg(chain_
, filename
) :
1547 (bool)::FLAC__metadata_chain_read(chain_
, filename
)
1551 bool Chain::read(FLAC__IOHandle handle
, ::FLAC__IOCallbacks callbacks
, bool is_ogg
)
1553 FLAC__ASSERT(is_valid());
1555 (bool)::FLAC__metadata_chain_read_ogg_with_callbacks(chain_
, handle
, callbacks
) :
1556 (bool)::FLAC__metadata_chain_read_with_callbacks(chain_
, handle
, callbacks
)
1560 bool Chain::check_if_tempfile_needed(bool use_padding
)
1562 FLAC__ASSERT(is_valid());
1563 return (bool)::FLAC__metadata_chain_check_if_tempfile_needed(chain_
, use_padding
);
1566 bool Chain::write(bool use_padding
, bool preserve_file_stats
)
1568 FLAC__ASSERT(is_valid());
1569 return (bool)::FLAC__metadata_chain_write(chain_
, use_padding
, preserve_file_stats
);
1572 bool Chain::write(bool use_padding
, ::FLAC__IOHandle handle
, ::FLAC__IOCallbacks callbacks
)
1574 FLAC__ASSERT(is_valid());
1575 return (bool)::FLAC__metadata_chain_write_with_callbacks(chain_
, use_padding
, handle
, callbacks
);
1578 bool Chain::write(bool use_padding
, ::FLAC__IOHandle handle
, ::FLAC__IOCallbacks callbacks
, ::FLAC__IOHandle temp_handle
, ::FLAC__IOCallbacks temp_callbacks
)
1580 FLAC__ASSERT(is_valid());
1581 return (bool)::FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain_
, use_padding
, handle
, callbacks
, temp_handle
, temp_callbacks
);
1584 void Chain::merge_padding()
1586 FLAC__ASSERT(is_valid());
1587 ::FLAC__metadata_chain_merge_padding(chain_
);
1590 void Chain::sort_padding()
1592 FLAC__ASSERT(is_valid());
1593 ::FLAC__metadata_chain_sort_padding(chain_
);
1597 Iterator::Iterator():
1598 iterator_(::FLAC__metadata_iterator_new())
1601 Iterator::~Iterator()
1606 void Iterator::clear()
1609 FLAC__metadata_iterator_delete(iterator_
);
1613 bool Iterator::is_valid() const
1615 return 0 != iterator_
;
1618 void Iterator::init(Chain
&chain
)
1620 FLAC__ASSERT(is_valid());
1621 FLAC__ASSERT(chain
.is_valid());
1622 ::FLAC__metadata_iterator_init(iterator_
, chain
.chain_
);
1625 bool Iterator::next()
1627 FLAC__ASSERT(is_valid());
1628 return (bool)::FLAC__metadata_iterator_next(iterator_
);
1631 bool Iterator::prev()
1633 FLAC__ASSERT(is_valid());
1634 return (bool)::FLAC__metadata_iterator_prev(iterator_
);
1637 ::FLAC__MetadataType
Iterator::get_block_type() const
1639 FLAC__ASSERT(is_valid());
1640 return ::FLAC__metadata_iterator_get_block_type(iterator_
);
1643 Prototype
*Iterator::get_block()
1645 FLAC__ASSERT(is_valid());
1646 Prototype
*block
= local::construct_block(::FLAC__metadata_iterator_get_block(iterator_
));
1648 block
->set_reference(true);
1652 bool Iterator::set_block(Prototype
*block
)
1654 FLAC__ASSERT(0 != block
);
1655 FLAC__ASSERT(is_valid());
1656 bool ret
= (bool)::FLAC__metadata_iterator_set_block(iterator_
, block
->object_
);
1658 block
->set_reference(true);
1664 bool Iterator::delete_block(bool replace_with_padding
)
1666 FLAC__ASSERT(is_valid());
1667 return (bool)::FLAC__metadata_iterator_delete_block(iterator_
, replace_with_padding
);
1670 bool Iterator::insert_block_before(Prototype
*block
)
1672 FLAC__ASSERT(0 != block
);
1673 FLAC__ASSERT(is_valid());
1674 bool ret
= (bool)::FLAC__metadata_iterator_insert_block_before(iterator_
, block
->object_
);
1676 block
->set_reference(true);
1682 bool Iterator::insert_block_after(Prototype
*block
)
1684 FLAC__ASSERT(0 != block
);
1685 FLAC__ASSERT(is_valid());
1686 bool ret
= (bool)::FLAC__metadata_iterator_insert_block_after(iterator_
, block
->object_
);
1688 block
->set_reference(true);