1 /* libFLAC++ - Free Lossless Audio Codec library
2 * Copyright (C) 2002-2009 Josh Coalson
3 * Copyright (C) 2011-2013 Xiph.Org Foundation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * - Neither the name of the Xiph.org Foundation nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #define __STDC_LIMIT_MACROS 1 /* otherwise SIZE_MAX is not defined for c++ */
38 #include "share/alloc.h"
39 #include "FLAC++/metadata.h"
40 #include "FLAC/assert.h"
41 #include <stdlib.h> // for malloc(), free()
42 #include <string.h> // for memcpy() etc.
45 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
46 #pragma warning ( disable : 4800 )
52 // local utility routines
56 Prototype
*construct_block(::FLAC__StreamMetadata
*object
)
59 switch(object
->type
) {
60 case FLAC__METADATA_TYPE_STREAMINFO
:
61 ret
= new StreamInfo(object
, /*copy=*/false);
63 case FLAC__METADATA_TYPE_PADDING
:
64 ret
= new Padding(object
, /*copy=*/false);
66 case FLAC__METADATA_TYPE_APPLICATION
:
67 ret
= new Application(object
, /*copy=*/false);
69 case FLAC__METADATA_TYPE_SEEKTABLE
:
70 ret
= new SeekTable(object
, /*copy=*/false);
72 case FLAC__METADATA_TYPE_VORBIS_COMMENT
:
73 ret
= new VorbisComment(object
, /*copy=*/false);
75 case FLAC__METADATA_TYPE_CUESHEET
:
76 ret
= new CueSheet(object
, /*copy=*/false);
78 case FLAC__METADATA_TYPE_PICTURE
:
79 ret
= new Picture(object
, /*copy=*/false);
82 ret
= new Unknown(object
, /*copy=*/false);
90 FLACPP_API Prototype
*clone(const Prototype
*object
)
92 FLAC__ASSERT(0 != object
);
94 const StreamInfo
*streaminfo
= dynamic_cast<const StreamInfo
*>(object
);
95 const Padding
*padding
= dynamic_cast<const Padding
*>(object
);
96 const Application
*application
= dynamic_cast<const Application
*>(object
);
97 const SeekTable
*seektable
= dynamic_cast<const SeekTable
*>(object
);
98 const VorbisComment
*vorbiscomment
= dynamic_cast<const VorbisComment
*>(object
);
99 const CueSheet
*cuesheet
= dynamic_cast<const CueSheet
*>(object
);
100 const Picture
*picture
= dynamic_cast<const Picture
*>(object
);
101 const Unknown
*unknown
= dynamic_cast<const Unknown
*>(object
);
104 return new StreamInfo(*streaminfo
);
105 else if(0 != padding
)
106 return new Padding(*padding
);
107 else if(0 != application
)
108 return new Application(*application
);
109 else if(0 != seektable
)
110 return new SeekTable(*seektable
);
111 else if(0 != vorbiscomment
)
112 return new VorbisComment(*vorbiscomment
);
113 else if(0 != cuesheet
)
114 return new CueSheet(*cuesheet
);
115 else if(0 != picture
)
116 return new Picture(*picture
);
117 else if(0 != unknown
)
118 return new Unknown(*unknown
);
129 Prototype::Prototype(const Prototype
&object
):
130 object_(::FLAC__metadata_object_clone(object
.object_
)),
133 FLAC__ASSERT(object
.is_valid());
136 Prototype::Prototype(const ::FLAC__StreamMetadata
&object
):
137 object_(::FLAC__metadata_object_clone(&object
)),
142 Prototype::Prototype(const ::FLAC__StreamMetadata
*object
):
143 object_(::FLAC__metadata_object_clone(object
)),
146 FLAC__ASSERT(0 != object
);
149 Prototype::Prototype(::FLAC__StreamMetadata
*object
, bool copy
):
150 object_(copy
? ::FLAC__metadata_object_clone(object
) : object
),
153 FLAC__ASSERT(0 != object
);
156 Prototype::~Prototype()
161 void Prototype::clear()
163 if(0 != object_
&& !is_reference_
)
164 FLAC__metadata_object_delete(object_
);
168 Prototype
&Prototype::operator=(const Prototype
&object
)
170 FLAC__ASSERT(object
.is_valid());
172 is_reference_
= false;
173 object_
= ::FLAC__metadata_object_clone(object
.object_
);
177 Prototype
&Prototype::operator=(const ::FLAC__StreamMetadata
&object
)
180 is_reference_
= false;
181 object_
= ::FLAC__metadata_object_clone(&object
);
185 Prototype
&Prototype::operator=(const ::FLAC__StreamMetadata
*object
)
187 FLAC__ASSERT(0 != object
);
189 is_reference_
= false;
190 object_
= ::FLAC__metadata_object_clone(object
);
194 Prototype
&Prototype::assign_object(::FLAC__StreamMetadata
*object
, bool copy
)
196 FLAC__ASSERT(0 != object
);
198 object_
= (copy
? ::FLAC__metadata_object_clone(object
) : object
);
199 is_reference_
= false;
203 bool Prototype::get_is_last() const
205 FLAC__ASSERT(is_valid());
206 return (bool)object_
->is_last
;
209 FLAC__MetadataType
Prototype::get_type() const
211 FLAC__ASSERT(is_valid());
212 return object_
->type
;
215 unsigned Prototype::get_length() const
217 FLAC__ASSERT(is_valid());
218 return object_
->length
;
221 void Prototype::set_is_last(bool value
)
223 FLAC__ASSERT(is_valid());
224 object_
->is_last
= value
;
232 StreamInfo::StreamInfo():
233 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO
), /*copy=*/false)
236 StreamInfo::~StreamInfo()
239 unsigned StreamInfo::get_min_blocksize() const
241 FLAC__ASSERT(is_valid());
242 return object_
->data
.stream_info
.min_blocksize
;
245 unsigned StreamInfo::get_max_blocksize() const
247 FLAC__ASSERT(is_valid());
248 return object_
->data
.stream_info
.max_blocksize
;
251 unsigned StreamInfo::get_min_framesize() const
253 FLAC__ASSERT(is_valid());
254 return object_
->data
.stream_info
.min_framesize
;
257 unsigned StreamInfo::get_max_framesize() const
259 FLAC__ASSERT(is_valid());
260 return object_
->data
.stream_info
.max_framesize
;
263 unsigned StreamInfo::get_sample_rate() const
265 FLAC__ASSERT(is_valid());
266 return object_
->data
.stream_info
.sample_rate
;
269 unsigned StreamInfo::get_channels() const
271 FLAC__ASSERT(is_valid());
272 return object_
->data
.stream_info
.channels
;
275 unsigned StreamInfo::get_bits_per_sample() const
277 FLAC__ASSERT(is_valid());
278 return object_
->data
.stream_info
.bits_per_sample
;
281 FLAC__uint64
StreamInfo::get_total_samples() const
283 FLAC__ASSERT(is_valid());
284 return object_
->data
.stream_info
.total_samples
;
287 const FLAC__byte
*StreamInfo::get_md5sum() const
289 FLAC__ASSERT(is_valid());
290 return object_
->data
.stream_info
.md5sum
;
293 void StreamInfo::set_min_blocksize(unsigned value
)
295 FLAC__ASSERT(is_valid());
296 FLAC__ASSERT(value
>= FLAC__MIN_BLOCK_SIZE
);
297 FLAC__ASSERT(value
<= FLAC__MAX_BLOCK_SIZE
);
298 object_
->data
.stream_info
.min_blocksize
= value
;
301 void StreamInfo::set_max_blocksize(unsigned value
)
303 FLAC__ASSERT(is_valid());
304 FLAC__ASSERT(value
>= FLAC__MIN_BLOCK_SIZE
);
305 FLAC__ASSERT(value
<= FLAC__MAX_BLOCK_SIZE
);
306 object_
->data
.stream_info
.max_blocksize
= value
;
309 void StreamInfo::set_min_framesize(unsigned value
)
311 FLAC__ASSERT(is_valid());
312 FLAC__ASSERT(value
< (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN
));
313 object_
->data
.stream_info
.min_framesize
= value
;
316 void StreamInfo::set_max_framesize(unsigned value
)
318 FLAC__ASSERT(is_valid());
319 FLAC__ASSERT(value
< (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN
));
320 object_
->data
.stream_info
.max_framesize
= value
;
323 void StreamInfo::set_sample_rate(unsigned value
)
325 FLAC__ASSERT(is_valid());
326 FLAC__ASSERT(FLAC__format_sample_rate_is_valid(value
));
327 object_
->data
.stream_info
.sample_rate
= value
;
330 void StreamInfo::set_channels(unsigned value
)
332 FLAC__ASSERT(is_valid());
333 FLAC__ASSERT(value
> 0);
334 FLAC__ASSERT(value
<= FLAC__MAX_CHANNELS
);
335 object_
->data
.stream_info
.channels
= value
;
338 void StreamInfo::set_bits_per_sample(unsigned value
)
340 FLAC__ASSERT(is_valid());
341 FLAC__ASSERT(value
>= FLAC__MIN_BITS_PER_SAMPLE
);
342 FLAC__ASSERT(value
<= FLAC__MAX_BITS_PER_SAMPLE
);
343 object_
->data
.stream_info
.bits_per_sample
= value
;
346 void StreamInfo::set_total_samples(FLAC__uint64 value
)
348 FLAC__ASSERT(is_valid());
349 FLAC__ASSERT(value
< (((FLAC__uint64
)1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
));
350 object_
->data
.stream_info
.total_samples
= value
;
353 void StreamInfo::set_md5sum(const FLAC__byte value
[16])
355 FLAC__ASSERT(is_valid());
356 FLAC__ASSERT(0 != value
);
357 memcpy(object_
->data
.stream_info
.md5sum
, value
, 16);
366 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING
), /*copy=*/false)
369 Padding::Padding(unsigned length
):
370 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING
), /*copy=*/false)
378 void Padding::set_length(unsigned length
)
380 FLAC__ASSERT(is_valid());
381 object_
->length
= length
;
389 Application::Application():
390 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION
), /*copy=*/false)
393 Application::~Application()
396 const FLAC__byte
*Application::get_id() const
398 FLAC__ASSERT(is_valid());
399 return object_
->data
.application
.id
;
402 const FLAC__byte
*Application::get_data() const
404 FLAC__ASSERT(is_valid());
405 return object_
->data
.application
.data
;
408 void Application::set_id(const FLAC__byte value
[4])
410 FLAC__ASSERT(is_valid());
411 FLAC__ASSERT(0 != value
);
412 memcpy(object_
->data
.application
.id
, value
, 4);
415 bool Application::set_data(const FLAC__byte
*data
, unsigned length
)
417 FLAC__ASSERT(is_valid());
418 return (bool)::FLAC__metadata_object_application_set_data(object_
, (FLAC__byte
*)data
, length
, true);
421 bool Application::set_data(FLAC__byte
*data
, unsigned length
, bool copy
)
423 FLAC__ASSERT(is_valid());
424 return (bool)::FLAC__metadata_object_application_set_data(object_
, data
, length
, copy
);
432 SeekTable::SeekTable():
433 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE
), /*copy=*/false)
436 SeekTable::~SeekTable()
439 unsigned SeekTable::get_num_points() const
441 FLAC__ASSERT(is_valid());
442 return object_
->data
.seek_table
.num_points
;
445 ::FLAC__StreamMetadata_SeekPoint
SeekTable::get_point(unsigned indx
) const
447 FLAC__ASSERT(is_valid());
448 FLAC__ASSERT(indx
< object_
->data
.seek_table
.num_points
);
449 return object_
->data
.seek_table
.points
[indx
];
452 bool SeekTable::resize_points(unsigned new_num_points
)
454 FLAC__ASSERT(is_valid());
455 return (bool)::FLAC__metadata_object_seektable_resize_points(object_
, new_num_points
);
458 void SeekTable::set_point(unsigned indx
, const ::FLAC__StreamMetadata_SeekPoint
&point
)
460 FLAC__ASSERT(is_valid());
461 FLAC__ASSERT(indx
< object_
->data
.seek_table
.num_points
);
462 ::FLAC__metadata_object_seektable_set_point(object_
, indx
, point
);
465 bool SeekTable::insert_point(unsigned indx
, const ::FLAC__StreamMetadata_SeekPoint
&point
)
467 FLAC__ASSERT(is_valid());
468 FLAC__ASSERT(indx
<= object_
->data
.seek_table
.num_points
);
469 return (bool)::FLAC__metadata_object_seektable_insert_point(object_
, indx
, point
);
472 bool SeekTable::delete_point(unsigned indx
)
474 FLAC__ASSERT(is_valid());
475 FLAC__ASSERT(indx
< object_
->data
.seek_table
.num_points
);
476 return (bool)::FLAC__metadata_object_seektable_delete_point(object_
, indx
);
479 bool SeekTable::is_legal() const
481 FLAC__ASSERT(is_valid());
482 return (bool)::FLAC__metadata_object_seektable_is_legal(object_
);
485 bool SeekTable::template_append_placeholders(unsigned num
)
487 FLAC__ASSERT(is_valid());
488 return (bool)::FLAC__metadata_object_seektable_template_append_placeholders(object_
, num
);
491 bool SeekTable::template_append_point(FLAC__uint64 sample_number
)
493 FLAC__ASSERT(is_valid());
494 return (bool)::FLAC__metadata_object_seektable_template_append_point(object_
, sample_number
);
497 bool SeekTable::template_append_points(FLAC__uint64 sample_numbers
[], unsigned num
)
499 FLAC__ASSERT(is_valid());
500 return (bool)::FLAC__metadata_object_seektable_template_append_points(object_
, sample_numbers
, num
);
503 bool SeekTable::template_append_spaced_points(unsigned num
, FLAC__uint64 total_samples
)
505 FLAC__ASSERT(is_valid());
506 return (bool)::FLAC__metadata_object_seektable_template_append_spaced_points(object_
, num
, total_samples
);
509 bool SeekTable::template_append_spaced_points_by_samples(unsigned samples
, FLAC__uint64 total_samples
)
511 FLAC__ASSERT(is_valid());
512 return (bool)::FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(object_
, samples
, total_samples
);
515 bool SeekTable::template_sort(bool compact
)
517 FLAC__ASSERT(is_valid());
518 return (bool)::FLAC__metadata_object_seektable_template_sort(object_
, compact
);
523 // VorbisComment::Entry
526 VorbisComment::Entry::Entry() :
530 field_name_length_(0),
532 field_value_length_(0)
537 VorbisComment::Entry::Entry(const char *field
, unsigned field_length
) :
541 field_name_length_(0),
543 field_value_length_(0)
546 construct(field
, field_length
);
549 VorbisComment::Entry::Entry(const char *field
) :
553 field_name_length_(0),
555 field_value_length_(0)
561 VorbisComment::Entry::Entry(const char *field_name
, const char *field_value
, unsigned field_value_length
) :
565 field_name_length_(0),
567 field_value_length_(0)
570 construct(field_name
, field_value
, field_value_length
);
573 VorbisComment::Entry::Entry(const char *field_name
, const char *field_value
) :
577 field_name_length_(0),
579 field_value_length_(0)
582 construct(field_name
, field_value
);
585 VorbisComment::Entry::Entry(const Entry
&entry
) :
589 field_name_length_(0),
591 field_value_length_(0)
593 FLAC__ASSERT(entry
.is_valid());
595 construct((const char *)entry
.entry_
.entry
, entry
.entry_
.length
);
598 VorbisComment::Entry
&VorbisComment::Entry::operator=(const Entry
&entry
)
600 FLAC__ASSERT(entry
.is_valid());
602 construct((const char *)entry
.entry_
.entry
, entry
.entry_
.length
);
606 VorbisComment::Entry::~Entry()
611 bool VorbisComment::Entry::is_valid() const
616 unsigned VorbisComment::Entry::get_field_length() const
618 FLAC__ASSERT(is_valid());
619 return entry_
.length
;
622 unsigned VorbisComment::Entry::get_field_name_length() const
624 FLAC__ASSERT(is_valid());
625 return field_name_length_
;
628 unsigned VorbisComment::Entry::get_field_value_length() const
630 FLAC__ASSERT(is_valid());
631 return field_value_length_
;
634 ::FLAC__StreamMetadata_VorbisComment_Entry
VorbisComment::Entry::get_entry() const
636 FLAC__ASSERT(is_valid());
640 const char *VorbisComment::Entry::get_field() const
642 FLAC__ASSERT(is_valid());
643 return (const char *)entry_
.entry
;
646 const char *VorbisComment::Entry::get_field_name() const
648 FLAC__ASSERT(is_valid());
652 const char *VorbisComment::Entry::get_field_value() const
654 FLAC__ASSERT(is_valid());
658 bool VorbisComment::Entry::set_field(const char *field
, unsigned field_length
)
660 FLAC__ASSERT(is_valid());
661 FLAC__ASSERT(0 != field
);
663 if(!::FLAC__format_vorbiscomment_entry_is_legal((const ::FLAC__byte
*)field
, field_length
))
664 return is_valid_
= false;
668 if(0 == (entry_
.entry
= (FLAC__byte
*)safe_malloc_add_2op_(field_length
, /*+*/1))) {
672 entry_
.length
= field_length
;
673 memcpy(entry_
.entry
, field
, field_length
);
674 entry_
.entry
[field_length
] = '\0';
675 (void) parse_field();
681 bool VorbisComment::Entry::set_field(const char *field
)
683 return set_field(field
, strlen(field
));
686 bool VorbisComment::Entry::set_field_name(const char *field_name
)
688 FLAC__ASSERT(is_valid());
689 FLAC__ASSERT(0 != field_name
);
691 if(!::FLAC__format_vorbiscomment_entry_name_is_legal(field_name
))
692 return is_valid_
= false;
696 if(0 == (field_name_
= strdup(field_name
))) {
700 field_name_length_
= strlen(field_name_
);
707 bool VorbisComment::Entry::set_field_value(const char *field_value
, unsigned field_value_length
)
709 FLAC__ASSERT(is_valid());
710 FLAC__ASSERT(0 != field_value
);
712 if(!::FLAC__format_vorbiscomment_entry_value_is_legal((const FLAC__byte
*)field_value
, field_value_length
))
713 return is_valid_
= false;
717 if(0 == (field_value_
= (char *)safe_malloc_add_2op_(field_value_length
, /*+*/1))) {
721 field_value_length_
= field_value_length
;
722 memcpy(field_value_
, field_value
, field_value_length
);
723 field_value_
[field_value_length
] = '\0';
730 bool VorbisComment::Entry::set_field_value(const char *field_value
)
732 return set_field_value(field_value
, strlen(field_value
));
735 void VorbisComment::Entry::zero()
741 field_name_length_
= 0;
743 field_value_length_
= 0;
746 void VorbisComment::Entry::clear()
754 void VorbisComment::Entry::clear_entry()
756 if(0 != entry_
.entry
) {
763 void VorbisComment::Entry::clear_field_name()
765 if(0 != field_name_
) {
768 field_name_length_
= 0;
772 void VorbisComment::Entry::clear_field_value()
774 if(0 != field_value_
) {
777 field_value_length_
= 0;
781 void VorbisComment::Entry::construct(const char *field
, unsigned field_length
)
783 if(set_field(field
, field_length
))
787 void VorbisComment::Entry::construct(const char *field
)
789 construct(field
, strlen(field
));
792 void VorbisComment::Entry::construct(const char *field_name
, const char *field_value
, unsigned field_value_length
)
794 if(set_field_name(field_name
) && set_field_value(field_value
, field_value_length
))
798 void VorbisComment::Entry::construct(const char *field_name
, const char *field_value
)
800 construct(field_name
, field_value
, strlen(field_value
));
803 void VorbisComment::Entry::compose_field()
807 if(0 == (entry_
.entry
= (FLAC__byte
*)safe_malloc_add_4op_(field_name_length_
, /*+*/1, /*+*/field_value_length_
, /*+*/1))) {
811 memcpy(entry_
.entry
, field_name_
, field_name_length_
);
812 entry_
.length
+= field_name_length_
;
813 memcpy(entry_
.entry
+ entry_
.length
, "=", 1);
815 memcpy(entry_
.entry
+ entry_
.length
, field_value_
, field_value_length_
);
816 entry_
.length
+= field_value_length_
;
817 entry_
.entry
[entry_
.length
] = '\0';
822 void VorbisComment::Entry::parse_field()
827 const char *p
= (const char *)memchr(entry_
.entry
, '=', entry_
.length
);
830 p
= (const char *)entry_
.entry
+ entry_
.length
;
832 field_name_length_
= (unsigned)(p
- (const char *)entry_
.entry
);
833 if(0 == (field_name_
= (char *)safe_malloc_add_2op_(field_name_length_
, /*+*/1))) { // +1 for the trailing \0
837 memcpy(field_name_
, entry_
.entry
, field_name_length_
);
838 field_name_
[field_name_length_
] = '\0';
840 if(entry_
.length
- field_name_length_
== 0) {
841 field_value_length_
= 0;
842 if(0 == (field_value_
= (char *)safe_malloc_(0))) {
848 field_value_length_
= entry_
.length
- field_name_length_
- 1;
849 if(0 == (field_value_
= (char *)safe_malloc_add_2op_(field_value_length_
, /*+*/1))) { // +1 for the trailing \0
853 memcpy(field_value_
, ++p
, field_value_length_
);
854 field_value_
[field_value_length_
] = '\0';
865 VorbisComment::VorbisComment():
866 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT
), /*copy=*/false)
869 VorbisComment::~VorbisComment()
872 unsigned VorbisComment::get_num_comments() const
874 FLAC__ASSERT(is_valid());
875 return object_
->data
.vorbis_comment
.num_comments
;
878 const FLAC__byte
*VorbisComment::get_vendor_string() const
880 FLAC__ASSERT(is_valid());
881 return object_
->data
.vorbis_comment
.vendor_string
.entry
;
884 VorbisComment::Entry
VorbisComment::get_comment(unsigned indx
) const
886 FLAC__ASSERT(is_valid());
887 FLAC__ASSERT(indx
< object_
->data
.vorbis_comment
.num_comments
);
888 return Entry((const char *)object_
->data
.vorbis_comment
.comments
[indx
].entry
, object_
->data
.vorbis_comment
.comments
[indx
].length
);
891 bool VorbisComment::set_vendor_string(const FLAC__byte
*string
)
893 FLAC__ASSERT(is_valid());
894 // vendor_string is a special kind of entry
895 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:
896 return (bool)::FLAC__metadata_object_vorbiscomment_set_vendor_string(object_
, vendor_string
, /*copy=*/true);
899 bool VorbisComment::resize_comments(unsigned new_num_comments
)
901 FLAC__ASSERT(is_valid());
902 return (bool)::FLAC__metadata_object_vorbiscomment_resize_comments(object_
, new_num_comments
);
905 bool VorbisComment::set_comment(unsigned indx
, const VorbisComment::Entry
&entry
)
907 FLAC__ASSERT(is_valid());
908 FLAC__ASSERT(indx
< object_
->data
.vorbis_comment
.num_comments
);
909 return (bool)::FLAC__metadata_object_vorbiscomment_set_comment(object_
, indx
, entry
.get_entry(), /*copy=*/true);
912 bool VorbisComment::insert_comment(unsigned indx
, const VorbisComment::Entry
&entry
)
914 FLAC__ASSERT(is_valid());
915 FLAC__ASSERT(indx
<= object_
->data
.vorbis_comment
.num_comments
);
916 return (bool)::FLAC__metadata_object_vorbiscomment_insert_comment(object_
, indx
, entry
.get_entry(), /*copy=*/true);
919 bool VorbisComment::append_comment(const VorbisComment::Entry
&entry
)
921 FLAC__ASSERT(is_valid());
922 return (bool)::FLAC__metadata_object_vorbiscomment_append_comment(object_
, entry
.get_entry(), /*copy=*/true);
925 bool VorbisComment::replace_comment(const VorbisComment::Entry
&entry
, bool all
)
927 FLAC__ASSERT(is_valid());
928 return (bool)::FLAC__metadata_object_vorbiscomment_replace_comment(object_
, entry
.get_entry(), all
, /*copy=*/true);
931 bool VorbisComment::delete_comment(unsigned indx
)
933 FLAC__ASSERT(is_valid());
934 FLAC__ASSERT(indx
< object_
->data
.vorbis_comment
.num_comments
);
935 return (bool)::FLAC__metadata_object_vorbiscomment_delete_comment(object_
, indx
);
938 int VorbisComment::find_entry_from(unsigned offset
, const char *field_name
)
940 FLAC__ASSERT(is_valid());
941 return ::FLAC__metadata_object_vorbiscomment_find_entry_from(object_
, offset
, field_name
);
944 int VorbisComment::remove_entry_matching(const char *field_name
)
946 FLAC__ASSERT(is_valid());
947 return ::FLAC__metadata_object_vorbiscomment_remove_entry_matching(object_
, field_name
);
950 int VorbisComment::remove_entries_matching(const char *field_name
)
952 FLAC__ASSERT(is_valid());
953 return ::FLAC__metadata_object_vorbiscomment_remove_entries_matching(object_
, field_name
);
961 CueSheet::Track::Track():
962 object_(::FLAC__metadata_object_cuesheet_track_new())
965 CueSheet::Track::Track(const ::FLAC__StreamMetadata_CueSheet_Track
*track
):
966 object_(::FLAC__metadata_object_cuesheet_track_clone(track
))
969 CueSheet::Track::Track(const Track
&track
):
970 object_(::FLAC__metadata_object_cuesheet_track_clone(track
.object_
))
973 CueSheet::Track
&CueSheet::Track::operator=(const Track
&track
)
976 ::FLAC__metadata_object_cuesheet_track_delete(object_
);
977 object_
= ::FLAC__metadata_object_cuesheet_track_clone(track
.object_
);
981 CueSheet::Track::~Track()
984 ::FLAC__metadata_object_cuesheet_track_delete(object_
);
987 bool CueSheet::Track::is_valid() const
989 return(0 != object_
);
992 ::FLAC__StreamMetadata_CueSheet_Index
CueSheet::Track::get_index(unsigned i
) const
994 FLAC__ASSERT(is_valid());
995 FLAC__ASSERT(i
< object_
->num_indices
);
996 return object_
->indices
[i
];
999 void CueSheet::Track::set_isrc(const char value
[12])
1001 FLAC__ASSERT(is_valid());
1002 FLAC__ASSERT(0 != value
);
1003 memcpy(object_
->isrc
, value
, 12);
1004 object_
->isrc
[12] = '\0';
1007 void CueSheet::Track::set_type(unsigned value
)
1009 FLAC__ASSERT(is_valid());
1010 FLAC__ASSERT(value
<= 1);
1011 object_
->type
= value
;
1014 void CueSheet::Track::set_index(unsigned i
, const ::FLAC__StreamMetadata_CueSheet_Index
&indx
)
1016 FLAC__ASSERT(is_valid());
1017 FLAC__ASSERT(i
< object_
->num_indices
);
1018 object_
->indices
[i
] = indx
;
1026 CueSheet::CueSheet():
1027 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET
), /*copy=*/false)
1030 CueSheet::~CueSheet()
1033 const char *CueSheet::get_media_catalog_number() const
1035 FLAC__ASSERT(is_valid());
1036 return object_
->data
.cue_sheet
.media_catalog_number
;
1039 FLAC__uint64
CueSheet::get_lead_in() const
1041 FLAC__ASSERT(is_valid());
1042 return object_
->data
.cue_sheet
.lead_in
;
1045 bool CueSheet::get_is_cd() const
1047 FLAC__ASSERT(is_valid());
1048 return object_
->data
.cue_sheet
.is_cd
? true : false;
1051 unsigned CueSheet::get_num_tracks() const
1053 FLAC__ASSERT(is_valid());
1054 return object_
->data
.cue_sheet
.num_tracks
;
1057 CueSheet::Track
CueSheet::get_track(unsigned i
) const
1059 FLAC__ASSERT(is_valid());
1060 FLAC__ASSERT(i
< object_
->data
.cue_sheet
.num_tracks
);
1061 return Track(object_
->data
.cue_sheet
.tracks
+ i
);
1064 void CueSheet::set_media_catalog_number(const char value
[128])
1066 FLAC__ASSERT(is_valid());
1067 FLAC__ASSERT(0 != value
);
1068 memcpy(object_
->data
.cue_sheet
.media_catalog_number
, value
, 128);
1069 object_
->data
.cue_sheet
.media_catalog_number
[128] = '\0';
1072 void CueSheet::set_lead_in(FLAC__uint64 value
)
1074 FLAC__ASSERT(is_valid());
1075 object_
->data
.cue_sheet
.lead_in
= value
;
1078 void CueSheet::set_is_cd(bool value
)
1080 FLAC__ASSERT(is_valid());
1081 object_
->data
.cue_sheet
.is_cd
= value
;
1084 void CueSheet::set_index(unsigned track_num
, unsigned index_num
, const ::FLAC__StreamMetadata_CueSheet_Index
&indx
)
1086 FLAC__ASSERT(is_valid());
1087 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1088 FLAC__ASSERT(index_num
< object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1089 object_
->data
.cue_sheet
.tracks
[track_num
].indices
[index_num
] = indx
;
1092 bool CueSheet::resize_indices(unsigned track_num
, unsigned new_num_indices
)
1094 FLAC__ASSERT(is_valid());
1095 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1096 return (bool)::FLAC__metadata_object_cuesheet_track_resize_indices(object_
, track_num
, new_num_indices
);
1099 bool CueSheet::insert_index(unsigned track_num
, unsigned index_num
, const ::FLAC__StreamMetadata_CueSheet_Index
&indx
)
1101 FLAC__ASSERT(is_valid());
1102 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1103 FLAC__ASSERT(index_num
<= object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1104 return (bool)::FLAC__metadata_object_cuesheet_track_insert_index(object_
, track_num
, index_num
, indx
);
1107 bool CueSheet::insert_blank_index(unsigned track_num
, unsigned index_num
)
1109 FLAC__ASSERT(is_valid());
1110 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1111 FLAC__ASSERT(index_num
<= object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1112 return (bool)::FLAC__metadata_object_cuesheet_track_insert_blank_index(object_
, track_num
, index_num
);
1115 bool CueSheet::delete_index(unsigned track_num
, unsigned index_num
)
1117 FLAC__ASSERT(is_valid());
1118 FLAC__ASSERT(track_num
< object_
->data
.cue_sheet
.num_tracks
);
1119 FLAC__ASSERT(index_num
< object_
->data
.cue_sheet
.tracks
[track_num
].num_indices
);
1120 return (bool)::FLAC__metadata_object_cuesheet_track_delete_index(object_
, track_num
, index_num
);
1123 bool CueSheet::resize_tracks(unsigned new_num_tracks
)
1125 FLAC__ASSERT(is_valid());
1126 return (bool)::FLAC__metadata_object_cuesheet_resize_tracks(object_
, new_num_tracks
);
1129 bool CueSheet::set_track(unsigned i
, const CueSheet::Track
&track
)
1131 FLAC__ASSERT(is_valid());
1132 FLAC__ASSERT(i
< object_
->data
.cue_sheet
.num_tracks
);
1133 // We can safely const_cast since copy=true
1134 return (bool)::FLAC__metadata_object_cuesheet_set_track(object_
, i
, const_cast< ::FLAC__StreamMetadata_CueSheet_Track
*>(track
.get_track()), /*copy=*/true);
1137 bool CueSheet::insert_track(unsigned i
, const CueSheet::Track
&track
)
1139 FLAC__ASSERT(is_valid());
1140 FLAC__ASSERT(i
<= object_
->data
.cue_sheet
.num_tracks
);
1141 // We can safely const_cast since copy=true
1142 return (bool)::FLAC__metadata_object_cuesheet_insert_track(object_
, i
, const_cast< ::FLAC__StreamMetadata_CueSheet_Track
*>(track
.get_track()), /*copy=*/true);
1145 bool CueSheet::insert_blank_track(unsigned i
)
1147 FLAC__ASSERT(is_valid());
1148 FLAC__ASSERT(i
<= object_
->data
.cue_sheet
.num_tracks
);
1149 return (bool)::FLAC__metadata_object_cuesheet_insert_blank_track(object_
, i
);
1152 bool CueSheet::delete_track(unsigned i
)
1154 FLAC__ASSERT(is_valid());
1155 FLAC__ASSERT(i
< object_
->data
.cue_sheet
.num_tracks
);
1156 return (bool)::FLAC__metadata_object_cuesheet_delete_track(object_
, i
);
1159 bool CueSheet::is_legal(bool check_cd_da_subset
, const char **violation
) const
1161 FLAC__ASSERT(is_valid());
1162 return (bool)::FLAC__metadata_object_cuesheet_is_legal(object_
, check_cd_da_subset
, violation
);
1165 FLAC__uint32
CueSheet::calculate_cddb_id() const
1167 FLAC__ASSERT(is_valid());
1168 return ::FLAC__metadata_object_cuesheet_calculate_cddb_id(object_
);
1177 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE
), /*copy=*/false)
1183 ::FLAC__StreamMetadata_Picture_Type
Picture::get_type() const
1185 FLAC__ASSERT(is_valid());
1186 return object_
->data
.picture
.type
;
1189 const char *Picture::get_mime_type() const
1191 FLAC__ASSERT(is_valid());
1192 return object_
->data
.picture
.mime_type
;
1195 const FLAC__byte
*Picture::get_description() const
1197 FLAC__ASSERT(is_valid());
1198 return object_
->data
.picture
.description
;
1201 FLAC__uint32
Picture::get_width() const
1203 FLAC__ASSERT(is_valid());
1204 return object_
->data
.picture
.width
;
1207 FLAC__uint32
Picture::get_height() const
1209 FLAC__ASSERT(is_valid());
1210 return object_
->data
.picture
.height
;
1213 FLAC__uint32
Picture::get_depth() const
1215 FLAC__ASSERT(is_valid());
1216 return object_
->data
.picture
.depth
;
1219 FLAC__uint32
Picture::get_colors() const
1221 FLAC__ASSERT(is_valid());
1222 return object_
->data
.picture
.colors
;
1225 FLAC__uint32
Picture::get_data_length() const
1227 FLAC__ASSERT(is_valid());
1228 return object_
->data
.picture
.data_length
;
1231 const FLAC__byte
*Picture::get_data() const
1233 FLAC__ASSERT(is_valid());
1234 return object_
->data
.picture
.data
;
1237 void Picture::set_type(::FLAC__StreamMetadata_Picture_Type type
)
1239 FLAC__ASSERT(is_valid());
1240 object_
->data
.picture
.type
= type
;
1243 bool Picture::set_mime_type(const char *string
)
1245 FLAC__ASSERT(is_valid());
1246 // We can safely const_cast since copy=true
1247 return (bool)::FLAC__metadata_object_picture_set_mime_type(object_
, const_cast<char*>(string
), /*copy=*/true);
1250 bool Picture::set_description(const FLAC__byte
*string
)
1252 FLAC__ASSERT(is_valid());
1253 // We can safely const_cast since copy=true
1254 return (bool)::FLAC__metadata_object_picture_set_description(object_
, const_cast<FLAC__byte
*>(string
), /*copy=*/true);
1257 void Picture::set_width(FLAC__uint32 value
) const
1259 FLAC__ASSERT(is_valid());
1260 object_
->data
.picture
.width
= value
;
1263 void Picture::set_height(FLAC__uint32 value
) const
1265 FLAC__ASSERT(is_valid());
1266 object_
->data
.picture
.height
= value
;
1269 void Picture::set_depth(FLAC__uint32 value
) const
1271 FLAC__ASSERT(is_valid());
1272 object_
->data
.picture
.depth
= value
;
1275 void Picture::set_colors(FLAC__uint32 value
) const
1277 FLAC__ASSERT(is_valid());
1278 object_
->data
.picture
.colors
= value
;
1281 bool Picture::set_data(const FLAC__byte
*data
, FLAC__uint32 data_length
)
1283 FLAC__ASSERT(is_valid());
1284 // We can safely const_cast since copy=true
1285 return (bool)::FLAC__metadata_object_picture_set_data(object_
, const_cast<FLAC__byte
*>(data
), data_length
, /*copy=*/true);
1288 bool Picture::is_legal(const char **violation
)
1290 FLAC__ASSERT(is_valid());
1291 return (bool)::FLAC__metadata_object_picture_is_legal(object_
, violation
);
1300 Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION
), /*copy=*/false)
1306 const FLAC__byte
*Unknown::get_data() const
1308 FLAC__ASSERT(is_valid());
1309 return object_
->data
.application
.data
;
1312 bool Unknown::set_data(const FLAC__byte
*data
, unsigned length
)
1314 FLAC__ASSERT(is_valid());
1315 return (bool)::FLAC__metadata_object_application_set_data(object_
, (FLAC__byte
*)data
, length
, true);
1318 bool Unknown::set_data(FLAC__byte
*data
, unsigned length
, bool copy
)
1320 FLAC__ASSERT(is_valid());
1321 return (bool)::FLAC__metadata_object_application_set_data(object_
, data
, length
, copy
);
1325 // ============================================================
1329 // ============================================================
1331 FLACPP_API
bool get_streaminfo(const char *filename
, StreamInfo
&streaminfo
)
1333 FLAC__ASSERT(0 != filename
);
1335 ::FLAC__StreamMetadata object
;
1337 if(::FLAC__metadata_get_streaminfo(filename
, &object
)) {
1338 streaminfo
= object
;
1345 FLACPP_API
bool get_tags(const char *filename
, VorbisComment
*&tags
)
1347 FLAC__ASSERT(0 != filename
);
1349 ::FLAC__StreamMetadata
*object
;
1353 if(::FLAC__metadata_get_tags(filename
, &object
)) {
1354 tags
= new VorbisComment(object
, /*copy=*/false);
1361 FLACPP_API
bool get_tags(const char *filename
, VorbisComment
&tags
)
1363 FLAC__ASSERT(0 != filename
);
1365 ::FLAC__StreamMetadata
*object
;
1367 if(::FLAC__metadata_get_tags(filename
, &object
)) {
1368 tags
.assign(object
, /*copy=*/false);
1375 FLACPP_API
bool get_cuesheet(const char *filename
, CueSheet
*&cuesheet
)
1377 FLAC__ASSERT(0 != filename
);
1379 ::FLAC__StreamMetadata
*object
;
1383 if(::FLAC__metadata_get_cuesheet(filename
, &object
)) {
1384 cuesheet
= new CueSheet(object
, /*copy=*/false);
1391 FLACPP_API
bool get_cuesheet(const char *filename
, CueSheet
&cuesheet
)
1393 FLAC__ASSERT(0 != filename
);
1395 ::FLAC__StreamMetadata
*object
;
1397 if(::FLAC__metadata_get_cuesheet(filename
, &object
)) {
1398 cuesheet
.assign(object
, /*copy=*/false);
1405 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
)
1407 FLAC__ASSERT(0 != filename
);
1409 ::FLAC__StreamMetadata
*object
;
1413 if(::FLAC__metadata_get_picture(filename
, &object
, type
, mime_type
, description
, max_width
, max_height
, max_depth
, max_colors
)) {
1414 picture
= new Picture(object
, /*copy=*/false);
1421 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
)
1423 FLAC__ASSERT(0 != filename
);
1425 ::FLAC__StreamMetadata
*object
;
1427 if(::FLAC__metadata_get_picture(filename
, &object
, type
, mime_type
, description
, max_width
, max_height
, max_depth
, max_colors
)) {
1428 picture
.assign(object
, /*copy=*/false);
1436 // ============================================================
1440 // ============================================================
1442 SimpleIterator::SimpleIterator():
1443 iterator_(::FLAC__metadata_simple_iterator_new())
1446 SimpleIterator::~SimpleIterator()
1451 void SimpleIterator::clear()
1454 FLAC__metadata_simple_iterator_delete(iterator_
);
1458 bool SimpleIterator::init(const char *filename
, bool read_only
, bool preserve_file_stats
)
1460 FLAC__ASSERT(0 != filename
);
1461 FLAC__ASSERT(is_valid());
1462 return (bool)::FLAC__metadata_simple_iterator_init(iterator_
, filename
, read_only
, preserve_file_stats
);
1465 bool SimpleIterator::is_valid() const
1467 return 0 != iterator_
;
1470 SimpleIterator::Status
SimpleIterator::status()
1472 FLAC__ASSERT(is_valid());
1473 return Status(::FLAC__metadata_simple_iterator_status(iterator_
));
1476 bool SimpleIterator::is_writable() const
1478 FLAC__ASSERT(is_valid());
1479 return (bool)::FLAC__metadata_simple_iterator_is_writable(iterator_
);
1482 bool SimpleIterator::next()
1484 FLAC__ASSERT(is_valid());
1485 return (bool)::FLAC__metadata_simple_iterator_next(iterator_
);
1488 bool SimpleIterator::prev()
1490 FLAC__ASSERT(is_valid());
1491 return (bool)::FLAC__metadata_simple_iterator_prev(iterator_
);
1495 bool SimpleIterator::is_last() const
1497 FLAC__ASSERT(is_valid());
1498 return (bool)::FLAC__metadata_simple_iterator_is_last(iterator_
);
1502 off_t
SimpleIterator::get_block_offset() const
1504 FLAC__ASSERT(is_valid());
1505 return ::FLAC__metadata_simple_iterator_get_block_offset(iterator_
);
1508 ::FLAC__MetadataType
SimpleIterator::get_block_type() const
1510 FLAC__ASSERT(is_valid());
1511 return ::FLAC__metadata_simple_iterator_get_block_type(iterator_
);
1515 unsigned SimpleIterator::get_block_length() const
1517 FLAC__ASSERT(is_valid());
1518 return ::FLAC__metadata_simple_iterator_get_block_length(iterator_
);
1522 bool SimpleIterator::get_application_id(FLAC__byte
*id
)
1524 FLAC__ASSERT(is_valid());
1525 return (bool)::FLAC__metadata_simple_iterator_get_application_id(iterator_
, id
);
1528 Prototype
*SimpleIterator::get_block()
1530 FLAC__ASSERT(is_valid());
1531 return local::construct_block(::FLAC__metadata_simple_iterator_get_block(iterator_
));
1534 bool SimpleIterator::set_block(Prototype
*block
, bool use_padding
)
1536 FLAC__ASSERT(0 != block
);
1537 FLAC__ASSERT(is_valid());
1538 return (bool)::FLAC__metadata_simple_iterator_set_block(iterator_
, block
->object_
, use_padding
);
1541 bool SimpleIterator::insert_block_after(Prototype
*block
, bool use_padding
)
1543 FLAC__ASSERT(0 != block
);
1544 FLAC__ASSERT(is_valid());
1545 return (bool)::FLAC__metadata_simple_iterator_insert_block_after(iterator_
, block
->object_
, use_padding
);
1548 bool SimpleIterator::delete_block(bool use_padding
)
1550 FLAC__ASSERT(is_valid());
1551 return (bool)::FLAC__metadata_simple_iterator_delete_block(iterator_
, use_padding
);
1555 // ============================================================
1559 // ============================================================
1562 chain_(::FLAC__metadata_chain_new())
1573 FLAC__metadata_chain_delete(chain_
);
1577 bool Chain::is_valid() const
1582 Chain::Status
Chain::status()
1584 FLAC__ASSERT(is_valid());
1585 return Status(::FLAC__metadata_chain_status(chain_
));
1588 bool Chain::read(const char *filename
, bool is_ogg
)
1590 FLAC__ASSERT(0 != filename
);
1591 FLAC__ASSERT(is_valid());
1593 (bool)::FLAC__metadata_chain_read_ogg(chain_
, filename
) :
1594 (bool)::FLAC__metadata_chain_read(chain_
, filename
)
1598 bool Chain::read(FLAC__IOHandle handle
, ::FLAC__IOCallbacks callbacks
, bool is_ogg
)
1600 FLAC__ASSERT(is_valid());
1602 (bool)::FLAC__metadata_chain_read_ogg_with_callbacks(chain_
, handle
, callbacks
) :
1603 (bool)::FLAC__metadata_chain_read_with_callbacks(chain_
, handle
, callbacks
)
1607 bool Chain::check_if_tempfile_needed(bool use_padding
)
1609 FLAC__ASSERT(is_valid());
1610 return (bool)::FLAC__metadata_chain_check_if_tempfile_needed(chain_
, use_padding
);
1613 bool Chain::write(bool use_padding
, bool preserve_file_stats
)
1615 FLAC__ASSERT(is_valid());
1616 return (bool)::FLAC__metadata_chain_write(chain_
, use_padding
, preserve_file_stats
);
1619 bool Chain::write(bool use_padding
, ::FLAC__IOHandle handle
, ::FLAC__IOCallbacks callbacks
)
1621 FLAC__ASSERT(is_valid());
1622 return (bool)::FLAC__metadata_chain_write_with_callbacks(chain_
, use_padding
, handle
, callbacks
);
1625 bool Chain::write(bool use_padding
, ::FLAC__IOHandle handle
, ::FLAC__IOCallbacks callbacks
, ::FLAC__IOHandle temp_handle
, ::FLAC__IOCallbacks temp_callbacks
)
1627 FLAC__ASSERT(is_valid());
1628 return (bool)::FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain_
, use_padding
, handle
, callbacks
, temp_handle
, temp_callbacks
);
1631 void Chain::merge_padding()
1633 FLAC__ASSERT(is_valid());
1634 ::FLAC__metadata_chain_merge_padding(chain_
);
1637 void Chain::sort_padding()
1639 FLAC__ASSERT(is_valid());
1640 ::FLAC__metadata_chain_sort_padding(chain_
);
1644 Iterator::Iterator():
1645 iterator_(::FLAC__metadata_iterator_new())
1648 Iterator::~Iterator()
1653 void Iterator::clear()
1656 FLAC__metadata_iterator_delete(iterator_
);
1660 bool Iterator::is_valid() const
1662 return 0 != iterator_
;
1665 void Iterator::init(Chain
&chain
)
1667 FLAC__ASSERT(is_valid());
1668 FLAC__ASSERT(chain
.is_valid());
1669 ::FLAC__metadata_iterator_init(iterator_
, chain
.chain_
);
1672 bool Iterator::next()
1674 FLAC__ASSERT(is_valid());
1675 return (bool)::FLAC__metadata_iterator_next(iterator_
);
1678 bool Iterator::prev()
1680 FLAC__ASSERT(is_valid());
1681 return (bool)::FLAC__metadata_iterator_prev(iterator_
);
1684 ::FLAC__MetadataType
Iterator::get_block_type() const
1686 FLAC__ASSERT(is_valid());
1687 return ::FLAC__metadata_iterator_get_block_type(iterator_
);
1690 Prototype
*Iterator::get_block()
1692 FLAC__ASSERT(is_valid());
1693 Prototype
*block
= local::construct_block(::FLAC__metadata_iterator_get_block(iterator_
));
1695 block
->set_reference(true);
1699 bool Iterator::set_block(Prototype
*block
)
1701 FLAC__ASSERT(0 != block
);
1702 FLAC__ASSERT(is_valid());
1703 bool ret
= (bool)::FLAC__metadata_iterator_set_block(iterator_
, block
->object_
);
1705 block
->set_reference(true);
1711 bool Iterator::delete_block(bool replace_with_padding
)
1713 FLAC__ASSERT(is_valid());
1714 return (bool)::FLAC__metadata_iterator_delete_block(iterator_
, replace_with_padding
);
1717 bool Iterator::insert_block_before(Prototype
*block
)
1719 FLAC__ASSERT(0 != block
);
1720 FLAC__ASSERT(is_valid());
1721 bool ret
= (bool)::FLAC__metadata_iterator_insert_block_before(iterator_
, block
->object_
);
1723 block
->set_reference(true);
1729 bool Iterator::insert_block_after(Prototype
*block
)
1731 FLAC__ASSERT(0 != block
);
1732 FLAC__ASSERT(is_valid());
1733 bool ret
= (bool)::FLAC__metadata_iterator_insert_block_after(iterator_
, block
->object_
);
1735 block
->set_reference(true);