xref: /aosp_15_r20/external/flac/src/libFLAC++/metadata.cpp (revision 600f14f40d737144c998e2ec7a483122d3776fbc)
1*600f14f4SXin Li /* libFLAC++ - Free Lossless Audio Codec library
2*600f14f4SXin Li  * Copyright (C) 2002-2009  Josh Coalson
3*600f14f4SXin Li  * Copyright (C) 2011-2023  Xiph.Org Foundation
4*600f14f4SXin Li  *
5*600f14f4SXin Li  * Redistribution and use in source and binary forms, with or without
6*600f14f4SXin Li  * modification, are permitted provided that the following conditions
7*600f14f4SXin Li  * are met:
8*600f14f4SXin Li  *
9*600f14f4SXin Li  * - Redistributions of source code must retain the above copyright
10*600f14f4SXin Li  * notice, this list of conditions and the following disclaimer.
11*600f14f4SXin Li  *
12*600f14f4SXin Li  * - Redistributions in binary form must reproduce the above copyright
13*600f14f4SXin Li  * notice, this list of conditions and the following disclaimer in the
14*600f14f4SXin Li  * documentation and/or other materials provided with the distribution.
15*600f14f4SXin Li  *
16*600f14f4SXin Li  * - Neither the name of the Xiph.org Foundation nor the names of its
17*600f14f4SXin Li  * contributors may be used to endorse or promote products derived from
18*600f14f4SXin Li  * this software without specific prior written permission.
19*600f14f4SXin Li  *
20*600f14f4SXin Li  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*600f14f4SXin Li  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*600f14f4SXin Li  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*600f14f4SXin Li  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24*600f14f4SXin Li  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25*600f14f4SXin Li  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26*600f14f4SXin Li  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27*600f14f4SXin Li  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28*600f14f4SXin Li  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29*600f14f4SXin Li  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30*600f14f4SXin Li  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*600f14f4SXin Li  */
32*600f14f4SXin Li 
33*600f14f4SXin Li #define __STDC_LIMIT_MACROS 1 /* otherwise SIZE_MAX is not defined for c++ */
34*600f14f4SXin Li #ifdef HAVE_CONFIG_H
35*600f14f4SXin Li #include "config.h"
36*600f14f4SXin Li #endif
37*600f14f4SXin Li 
38*600f14f4SXin Li #include "share/alloc.h"
39*600f14f4SXin Li #include "FLAC++/metadata.h"
40*600f14f4SXin Li #include "FLAC/assert.h"
41*600f14f4SXin Li #include <cstdlib> // for malloc(), free()
42*600f14f4SXin Li #include <cstring> // for memcpy() etc.
43*600f14f4SXin Li 
44*600f14f4SXin Li #ifdef _MSC_VER
45*600f14f4SXin Li // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
46*600f14f4SXin Li #pragma warning ( disable : 4800 )
47*600f14f4SXin Li #endif
48*600f14f4SXin Li 
49*600f14f4SXin Li namespace FLAC {
50*600f14f4SXin Li 	namespace Metadata {
51*600f14f4SXin Li 
52*600f14f4SXin Li 		// local utility routines
53*600f14f4SXin Li 
54*600f14f4SXin Li 		namespace local {
55*600f14f4SXin Li 
construct_block(::FLAC__StreamMetadata * object)56*600f14f4SXin Li 			Prototype *construct_block(::FLAC__StreamMetadata *object)
57*600f14f4SXin Li 			{
58*600f14f4SXin Li 				if (0 == object)
59*600f14f4SXin Li 					return 0;
60*600f14f4SXin Li 
61*600f14f4SXin Li 				Prototype *ret = 0;
62*600f14f4SXin Li 				switch(object->type) {
63*600f14f4SXin Li 					case FLAC__METADATA_TYPE_STREAMINFO:
64*600f14f4SXin Li 						ret = new StreamInfo(object, /*copy=*/false);
65*600f14f4SXin Li 						break;
66*600f14f4SXin Li 					case FLAC__METADATA_TYPE_PADDING:
67*600f14f4SXin Li 						ret = new Padding(object, /*copy=*/false);
68*600f14f4SXin Li 						break;
69*600f14f4SXin Li 					case FLAC__METADATA_TYPE_APPLICATION:
70*600f14f4SXin Li 						ret = new Application(object, /*copy=*/false);
71*600f14f4SXin Li 						break;
72*600f14f4SXin Li 					case FLAC__METADATA_TYPE_SEEKTABLE:
73*600f14f4SXin Li 						ret = new SeekTable(object, /*copy=*/false);
74*600f14f4SXin Li 						break;
75*600f14f4SXin Li 					case FLAC__METADATA_TYPE_VORBIS_COMMENT:
76*600f14f4SXin Li 						ret = new VorbisComment(object, /*copy=*/false);
77*600f14f4SXin Li 						break;
78*600f14f4SXin Li 					case FLAC__METADATA_TYPE_CUESHEET:
79*600f14f4SXin Li 						ret = new CueSheet(object, /*copy=*/false);
80*600f14f4SXin Li 						break;
81*600f14f4SXin Li 					case FLAC__METADATA_TYPE_PICTURE:
82*600f14f4SXin Li 						ret = new Picture(object, /*copy=*/false);
83*600f14f4SXin Li 						break;
84*600f14f4SXin Li 					default:
85*600f14f4SXin Li 						ret = new Unknown(object, /*copy=*/false);
86*600f14f4SXin Li 						break;
87*600f14f4SXin Li 				}
88*600f14f4SXin Li 				return ret;
89*600f14f4SXin Li 			}
90*600f14f4SXin Li 
91*600f14f4SXin Li 		} // namespace local
92*600f14f4SXin Li 
clone(const Prototype * object)93*600f14f4SXin Li 		FLACPP_API Prototype *clone(const Prototype *object)
94*600f14f4SXin Li 		{
95*600f14f4SXin Li 			FLAC__ASSERT(0 != object);
96*600f14f4SXin Li 
97*600f14f4SXin Li 			const StreamInfo *streaminfo = dynamic_cast<const StreamInfo *>(object);
98*600f14f4SXin Li 			const Padding *padding = dynamic_cast<const Padding *>(object);
99*600f14f4SXin Li 			const Application *application = dynamic_cast<const Application *>(object);
100*600f14f4SXin Li 			const SeekTable *seektable = dynamic_cast<const SeekTable *>(object);
101*600f14f4SXin Li 			const VorbisComment *vorbiscomment = dynamic_cast<const VorbisComment *>(object);
102*600f14f4SXin Li 			const CueSheet *cuesheet = dynamic_cast<const CueSheet *>(object);
103*600f14f4SXin Li 			const Picture *picture = dynamic_cast<const Picture *>(object);
104*600f14f4SXin Li 			const Unknown *unknown = dynamic_cast<const Unknown *>(object);
105*600f14f4SXin Li 
106*600f14f4SXin Li 			if(0 != streaminfo)
107*600f14f4SXin Li 				return new StreamInfo(*streaminfo);
108*600f14f4SXin Li 			if(0 != padding)
109*600f14f4SXin Li 				return new Padding(*padding);
110*600f14f4SXin Li 			if(0 != application)
111*600f14f4SXin Li 				return new Application(*application);
112*600f14f4SXin Li 			if(0 != seektable)
113*600f14f4SXin Li 				return new SeekTable(*seektable);
114*600f14f4SXin Li 			if(0 != vorbiscomment)
115*600f14f4SXin Li 				return new VorbisComment(*vorbiscomment);
116*600f14f4SXin Li 			if(0 != cuesheet)
117*600f14f4SXin Li 				return new CueSheet(*cuesheet);
118*600f14f4SXin Li 			if(0 != picture)
119*600f14f4SXin Li 				return new Picture(*picture);
120*600f14f4SXin Li 			if(0 != unknown)
121*600f14f4SXin Li 				return new Unknown(*unknown);
122*600f14f4SXin Li 
123*600f14f4SXin Li 			FLAC__ASSERT(0);
124*600f14f4SXin Li 			return 0;
125*600f14f4SXin Li 		}
126*600f14f4SXin Li 
127*600f14f4SXin Li 		//
128*600f14f4SXin Li 		// Prototype
129*600f14f4SXin Li 		//
130*600f14f4SXin Li 
Prototype(const Prototype & object)131*600f14f4SXin Li 		Prototype::Prototype(const Prototype &object):
132*600f14f4SXin Li 		object_(::FLAC__metadata_object_clone(object.object_)),
133*600f14f4SXin Li 		is_reference_(false)
134*600f14f4SXin Li 		{
135*600f14f4SXin Li 			FLAC__ASSERT(object.is_valid());
136*600f14f4SXin Li 		}
137*600f14f4SXin Li 
Prototype(const::FLAC__StreamMetadata & object)138*600f14f4SXin Li 		Prototype::Prototype(const ::FLAC__StreamMetadata &object):
139*600f14f4SXin Li 		object_(::FLAC__metadata_object_clone(&object)),
140*600f14f4SXin Li 		is_reference_(false)
141*600f14f4SXin Li 		{
142*600f14f4SXin Li 		}
143*600f14f4SXin Li 
Prototype(const::FLAC__StreamMetadata * object)144*600f14f4SXin Li 		Prototype::Prototype(const ::FLAC__StreamMetadata *object):
145*600f14f4SXin Li 		object_(::FLAC__metadata_object_clone(object)),
146*600f14f4SXin Li 		is_reference_(false)
147*600f14f4SXin Li 		{
148*600f14f4SXin Li 			FLAC__ASSERT(0 != object);
149*600f14f4SXin Li 		}
150*600f14f4SXin Li 
Prototype(::FLAC__StreamMetadata * object,bool copy)151*600f14f4SXin Li 		Prototype::Prototype(::FLAC__StreamMetadata *object, bool copy):
152*600f14f4SXin Li 		object_(copy? ::FLAC__metadata_object_clone(object) : object),
153*600f14f4SXin Li 		is_reference_(false)
154*600f14f4SXin Li 		{
155*600f14f4SXin Li 			FLAC__ASSERT(0 != object);
156*600f14f4SXin Li 		}
157*600f14f4SXin Li 
~Prototype()158*600f14f4SXin Li 		Prototype::~Prototype()
159*600f14f4SXin Li 		{
160*600f14f4SXin Li 			clear();
161*600f14f4SXin Li 		}
162*600f14f4SXin Li 
clear()163*600f14f4SXin Li 		void Prototype::clear()
164*600f14f4SXin Li 		{
165*600f14f4SXin Li 			if(0 != object_ && !is_reference_)
166*600f14f4SXin Li 				FLAC__metadata_object_delete(object_);
167*600f14f4SXin Li 			object_ = 0;
168*600f14f4SXin Li 		}
169*600f14f4SXin Li 
operator =(const Prototype & object)170*600f14f4SXin Li 		Prototype &Prototype::operator=(const Prototype &object)
171*600f14f4SXin Li 		{
172*600f14f4SXin Li 			FLAC__ASSERT(object.is_valid());
173*600f14f4SXin Li 			clear();
174*600f14f4SXin Li 			is_reference_ = false;
175*600f14f4SXin Li 			object_ = ::FLAC__metadata_object_clone(object.object_);
176*600f14f4SXin Li 			return *this;
177*600f14f4SXin Li 		}
178*600f14f4SXin Li 
operator =(const::FLAC__StreamMetadata & object)179*600f14f4SXin Li 		Prototype &Prototype::operator=(const ::FLAC__StreamMetadata &object)
180*600f14f4SXin Li 		{
181*600f14f4SXin Li 			clear();
182*600f14f4SXin Li 			is_reference_ = false;
183*600f14f4SXin Li 			object_ = ::FLAC__metadata_object_clone(&object);
184*600f14f4SXin Li 			return *this;
185*600f14f4SXin Li 		}
186*600f14f4SXin Li 
operator =(const::FLAC__StreamMetadata * object)187*600f14f4SXin Li 		Prototype &Prototype::operator=(const ::FLAC__StreamMetadata *object)
188*600f14f4SXin Li 		{
189*600f14f4SXin Li 			FLAC__ASSERT(0 != object);
190*600f14f4SXin Li 			clear();
191*600f14f4SXin Li 			is_reference_ = false;
192*600f14f4SXin Li 			object_ = ::FLAC__metadata_object_clone(object);
193*600f14f4SXin Li 			return *this;
194*600f14f4SXin Li 		}
195*600f14f4SXin Li 
assign_object(::FLAC__StreamMetadata * object,bool copy)196*600f14f4SXin Li 		Prototype &Prototype::assign_object(::FLAC__StreamMetadata *object, bool copy)
197*600f14f4SXin Li 		{
198*600f14f4SXin Li 			FLAC__ASSERT(0 != object);
199*600f14f4SXin Li 			clear();
200*600f14f4SXin Li 			object_ = (copy? ::FLAC__metadata_object_clone(object) : object);
201*600f14f4SXin Li 			is_reference_ = false;
202*600f14f4SXin Li 			return *this;
203*600f14f4SXin Li 		}
204*600f14f4SXin Li 
get_is_last() const205*600f14f4SXin Li 		bool Prototype::get_is_last() const
206*600f14f4SXin Li 		{
207*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
208*600f14f4SXin Li 			return static_cast<bool>(object_->is_last);
209*600f14f4SXin Li 		}
210*600f14f4SXin Li 
get_type() const211*600f14f4SXin Li 		FLAC__MetadataType Prototype::get_type() const
212*600f14f4SXin Li 		{
213*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
214*600f14f4SXin Li 			return object_->type;
215*600f14f4SXin Li 		}
216*600f14f4SXin Li 
get_length() const217*600f14f4SXin Li 		uint32_t Prototype::get_length() const
218*600f14f4SXin Li 		{
219*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
220*600f14f4SXin Li 			return object_->length;
221*600f14f4SXin Li 		}
222*600f14f4SXin Li 
set_is_last(bool value)223*600f14f4SXin Li 		void Prototype::set_is_last(bool value)
224*600f14f4SXin Li 		{
225*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
226*600f14f4SXin Li 			object_->is_last = value;
227*600f14f4SXin Li 		}
228*600f14f4SXin Li 
229*600f14f4SXin Li 
230*600f14f4SXin Li 		//
231*600f14f4SXin Li 		// StreamInfo
232*600f14f4SXin Li 		//
233*600f14f4SXin Li 
StreamInfo()234*600f14f4SXin Li 		StreamInfo::StreamInfo():
235*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO), /*copy=*/false)
236*600f14f4SXin Li 		{ }
237*600f14f4SXin Li 
~StreamInfo()238*600f14f4SXin Li 		StreamInfo::~StreamInfo()
239*600f14f4SXin Li 		{ }
240*600f14f4SXin Li 
get_min_blocksize() const241*600f14f4SXin Li 		uint32_t StreamInfo::get_min_blocksize() const
242*600f14f4SXin Li 		{
243*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
244*600f14f4SXin Li 			return object_->data.stream_info.min_blocksize;
245*600f14f4SXin Li 		}
246*600f14f4SXin Li 
get_max_blocksize() const247*600f14f4SXin Li 		uint32_t StreamInfo::get_max_blocksize() const
248*600f14f4SXin Li 		{
249*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
250*600f14f4SXin Li 			return object_->data.stream_info.max_blocksize;
251*600f14f4SXin Li 		}
252*600f14f4SXin Li 
get_min_framesize() const253*600f14f4SXin Li 		uint32_t StreamInfo::get_min_framesize() const
254*600f14f4SXin Li 		{
255*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
256*600f14f4SXin Li 			return object_->data.stream_info.min_framesize;
257*600f14f4SXin Li 		}
258*600f14f4SXin Li 
get_max_framesize() const259*600f14f4SXin Li 		uint32_t StreamInfo::get_max_framesize() const
260*600f14f4SXin Li 		{
261*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
262*600f14f4SXin Li 			return object_->data.stream_info.max_framesize;
263*600f14f4SXin Li 		}
264*600f14f4SXin Li 
get_sample_rate() const265*600f14f4SXin Li 		uint32_t StreamInfo::get_sample_rate() const
266*600f14f4SXin Li 		{
267*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
268*600f14f4SXin Li 			return object_->data.stream_info.sample_rate;
269*600f14f4SXin Li 		}
270*600f14f4SXin Li 
get_channels() const271*600f14f4SXin Li 		uint32_t StreamInfo::get_channels() const
272*600f14f4SXin Li 		{
273*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
274*600f14f4SXin Li 			return object_->data.stream_info.channels;
275*600f14f4SXin Li 		}
276*600f14f4SXin Li 
get_bits_per_sample() const277*600f14f4SXin Li 		uint32_t StreamInfo::get_bits_per_sample() const
278*600f14f4SXin Li 		{
279*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
280*600f14f4SXin Li 			return object_->data.stream_info.bits_per_sample;
281*600f14f4SXin Li 		}
282*600f14f4SXin Li 
get_total_samples() const283*600f14f4SXin Li 		FLAC__uint64 StreamInfo::get_total_samples() const
284*600f14f4SXin Li 		{
285*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
286*600f14f4SXin Li 			return object_->data.stream_info.total_samples;
287*600f14f4SXin Li 		}
288*600f14f4SXin Li 
get_md5sum() const289*600f14f4SXin Li 		const FLAC__byte *StreamInfo::get_md5sum() const
290*600f14f4SXin Li 		{
291*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
292*600f14f4SXin Li 			return object_->data.stream_info.md5sum;
293*600f14f4SXin Li 		}
294*600f14f4SXin Li 
set_min_blocksize(uint32_t value)295*600f14f4SXin Li 		void StreamInfo::set_min_blocksize(uint32_t value)
296*600f14f4SXin Li 		{
297*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
298*600f14f4SXin Li 			FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
299*600f14f4SXin Li 			FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
300*600f14f4SXin Li 			object_->data.stream_info.min_blocksize = value;
301*600f14f4SXin Li 		}
302*600f14f4SXin Li 
set_max_blocksize(uint32_t value)303*600f14f4SXin Li 		void StreamInfo::set_max_blocksize(uint32_t value)
304*600f14f4SXin Li 		{
305*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
306*600f14f4SXin Li 			FLAC__ASSERT(value >= FLAC__MIN_BLOCK_SIZE);
307*600f14f4SXin Li 			FLAC__ASSERT(value <= FLAC__MAX_BLOCK_SIZE);
308*600f14f4SXin Li 			object_->data.stream_info.max_blocksize = value;
309*600f14f4SXin Li 		}
310*600f14f4SXin Li 
set_min_framesize(uint32_t value)311*600f14f4SXin Li 		void StreamInfo::set_min_framesize(uint32_t value)
312*600f14f4SXin Li 		{
313*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
314*600f14f4SXin Li 			FLAC__ASSERT(value < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN));
315*600f14f4SXin Li 			object_->data.stream_info.min_framesize = value;
316*600f14f4SXin Li 		}
317*600f14f4SXin Li 
set_max_framesize(uint32_t value)318*600f14f4SXin Li 		void StreamInfo::set_max_framesize(uint32_t value)
319*600f14f4SXin Li 		{
320*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
321*600f14f4SXin Li 			FLAC__ASSERT(value < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN));
322*600f14f4SXin Li 			object_->data.stream_info.max_framesize = value;
323*600f14f4SXin Li 		}
324*600f14f4SXin Li 
set_sample_rate(uint32_t value)325*600f14f4SXin Li 		void StreamInfo::set_sample_rate(uint32_t value)
326*600f14f4SXin Li 		{
327*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
328*600f14f4SXin Li 			FLAC__ASSERT(FLAC__format_sample_rate_is_valid(value));
329*600f14f4SXin Li 			object_->data.stream_info.sample_rate = value;
330*600f14f4SXin Li 		}
331*600f14f4SXin Li 
set_channels(uint32_t value)332*600f14f4SXin Li 		void StreamInfo::set_channels(uint32_t value)
333*600f14f4SXin Li 		{
334*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
335*600f14f4SXin Li 			FLAC__ASSERT(value > 0);
336*600f14f4SXin Li 			FLAC__ASSERT(value <= FLAC__MAX_CHANNELS);
337*600f14f4SXin Li 			object_->data.stream_info.channels = value;
338*600f14f4SXin Li 		}
339*600f14f4SXin Li 
set_bits_per_sample(uint32_t value)340*600f14f4SXin Li 		void StreamInfo::set_bits_per_sample(uint32_t value)
341*600f14f4SXin Li 		{
342*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
343*600f14f4SXin Li 			FLAC__ASSERT(value >= FLAC__MIN_BITS_PER_SAMPLE);
344*600f14f4SXin Li 			FLAC__ASSERT(value <= FLAC__MAX_BITS_PER_SAMPLE);
345*600f14f4SXin Li 			object_->data.stream_info.bits_per_sample = value;
346*600f14f4SXin Li 		}
347*600f14f4SXin Li 
set_total_samples(FLAC__uint64 value)348*600f14f4SXin Li 		void StreamInfo::set_total_samples(FLAC__uint64 value)
349*600f14f4SXin Li 		{
350*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
351*600f14f4SXin Li 			FLAC__ASSERT(value < (((FLAC__uint64)1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN));
352*600f14f4SXin Li 			object_->data.stream_info.total_samples = value;
353*600f14f4SXin Li 		}
354*600f14f4SXin Li 
set_md5sum(const FLAC__byte value[16])355*600f14f4SXin Li 		void StreamInfo::set_md5sum(const FLAC__byte value[16])
356*600f14f4SXin Li 		{
357*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
358*600f14f4SXin Li 			FLAC__ASSERT(0 != value);
359*600f14f4SXin Li 			std::memcpy(object_->data.stream_info.md5sum, value, 16);
360*600f14f4SXin Li 		}
361*600f14f4SXin Li 
362*600f14f4SXin Li 
363*600f14f4SXin Li 		//
364*600f14f4SXin Li 		// Padding
365*600f14f4SXin Li 		//
366*600f14f4SXin Li 
Padding()367*600f14f4SXin Li 		Padding::Padding():
368*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING), /*copy=*/false)
369*600f14f4SXin Li 		{ }
370*600f14f4SXin Li 
Padding(uint32_t length)371*600f14f4SXin Li 		Padding::Padding(uint32_t length):
372*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING), /*copy=*/false)
373*600f14f4SXin Li 		{
374*600f14f4SXin Li 			set_length(length);
375*600f14f4SXin Li 		}
376*600f14f4SXin Li 
~Padding()377*600f14f4SXin Li 		Padding::~Padding()
378*600f14f4SXin Li 		{ }
379*600f14f4SXin Li 
set_length(uint32_t length)380*600f14f4SXin Li 		void Padding::set_length(uint32_t length)
381*600f14f4SXin Li 		{
382*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
383*600f14f4SXin Li 			object_->length = length;
384*600f14f4SXin Li 		}
385*600f14f4SXin Li 
386*600f14f4SXin Li 
387*600f14f4SXin Li 		//
388*600f14f4SXin Li 		// Application
389*600f14f4SXin Li 		//
390*600f14f4SXin Li 
Application()391*600f14f4SXin Li 		Application::Application():
392*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), /*copy=*/false)
393*600f14f4SXin Li 		{ }
394*600f14f4SXin Li 
~Application()395*600f14f4SXin Li 		Application::~Application()
396*600f14f4SXin Li 		{ }
397*600f14f4SXin Li 
get_id() const398*600f14f4SXin Li 		const FLAC__byte *Application::get_id() const
399*600f14f4SXin Li 		{
400*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
401*600f14f4SXin Li 			return object_->data.application.id;
402*600f14f4SXin Li 		}
403*600f14f4SXin Li 
get_data() const404*600f14f4SXin Li 		const FLAC__byte *Application::get_data() const
405*600f14f4SXin Li 		{
406*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
407*600f14f4SXin Li 			return object_->data.application.data;
408*600f14f4SXin Li 		}
409*600f14f4SXin Li 
set_id(const FLAC__byte value[4])410*600f14f4SXin Li 		void Application::set_id(const FLAC__byte value[4])
411*600f14f4SXin Li 		{
412*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
413*600f14f4SXin Li 			FLAC__ASSERT(0 != value);
414*600f14f4SXin Li 			std::memcpy(object_->data.application.id, value, 4);
415*600f14f4SXin Li 		}
416*600f14f4SXin Li 
set_data(const FLAC__byte * data,uint32_t length)417*600f14f4SXin Li 		bool Application::set_data(const FLAC__byte *data, uint32_t length)
418*600f14f4SXin Li 		{
419*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
420*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_application_set_data(object_, const_cast<FLAC__byte*>(data), length, true));
421*600f14f4SXin Li 		}
422*600f14f4SXin Li 
set_data(FLAC__byte * data,uint32_t length,bool copy)423*600f14f4SXin Li 		bool Application::set_data(FLAC__byte *data, uint32_t length, bool copy)
424*600f14f4SXin Li 		{
425*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
426*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_application_set_data(object_, data, length, copy));
427*600f14f4SXin Li 		}
428*600f14f4SXin Li 
429*600f14f4SXin Li 
430*600f14f4SXin Li 		//
431*600f14f4SXin Li 		// SeekTable
432*600f14f4SXin Li 		//
433*600f14f4SXin Li 
SeekTable()434*600f14f4SXin Li 		SeekTable::SeekTable():
435*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE), /*copy=*/false)
436*600f14f4SXin Li 		{ }
437*600f14f4SXin Li 
~SeekTable()438*600f14f4SXin Li 		SeekTable::~SeekTable()
439*600f14f4SXin Li 		{ }
440*600f14f4SXin Li 
get_num_points() const441*600f14f4SXin Li 		uint32_t SeekTable::get_num_points() const
442*600f14f4SXin Li 		{
443*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
444*600f14f4SXin Li 			return object_->data.seek_table.num_points;
445*600f14f4SXin Li 		}
446*600f14f4SXin Li 
get_point(uint32_t indx) const447*600f14f4SXin Li 		::FLAC__StreamMetadata_SeekPoint SeekTable::get_point(uint32_t indx) const
448*600f14f4SXin Li 		{
449*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
450*600f14f4SXin Li 			FLAC__ASSERT(indx < object_->data.seek_table.num_points);
451*600f14f4SXin Li 			return object_->data.seek_table.points[indx];
452*600f14f4SXin Li 		}
453*600f14f4SXin Li 
resize_points(uint32_t new_num_points)454*600f14f4SXin Li 		bool SeekTable::resize_points(uint32_t new_num_points)
455*600f14f4SXin Li 		{
456*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
457*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_resize_points(object_, new_num_points));
458*600f14f4SXin Li 		}
459*600f14f4SXin Li 
set_point(uint32_t indx,const::FLAC__StreamMetadata_SeekPoint & point)460*600f14f4SXin Li 		void SeekTable::set_point(uint32_t indx, const ::FLAC__StreamMetadata_SeekPoint &point)
461*600f14f4SXin Li 		{
462*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
463*600f14f4SXin Li 			FLAC__ASSERT(indx < object_->data.seek_table.num_points);
464*600f14f4SXin Li 			::FLAC__metadata_object_seektable_set_point(object_, indx, point);
465*600f14f4SXin Li 		}
466*600f14f4SXin Li 
insert_point(uint32_t indx,const::FLAC__StreamMetadata_SeekPoint & point)467*600f14f4SXin Li 		bool SeekTable::insert_point(uint32_t indx, const ::FLAC__StreamMetadata_SeekPoint &point)
468*600f14f4SXin Li 		{
469*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
470*600f14f4SXin Li 			FLAC__ASSERT(indx <= object_->data.seek_table.num_points);
471*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_insert_point(object_, indx, point));
472*600f14f4SXin Li 		}
473*600f14f4SXin Li 
delete_point(uint32_t indx)474*600f14f4SXin Li 		bool SeekTable::delete_point(uint32_t indx)
475*600f14f4SXin Li 		{
476*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
477*600f14f4SXin Li 			FLAC__ASSERT(indx < object_->data.seek_table.num_points);
478*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_delete_point(object_, indx));
479*600f14f4SXin Li 		}
480*600f14f4SXin Li 
is_legal() const481*600f14f4SXin Li 		bool SeekTable::is_legal() const
482*600f14f4SXin Li 		{
483*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
484*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_is_legal(object_));
485*600f14f4SXin Li 		}
486*600f14f4SXin Li 
template_append_placeholders(uint32_t num)487*600f14f4SXin Li 		bool SeekTable::template_append_placeholders(uint32_t num)
488*600f14f4SXin Li 		{
489*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
490*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_template_append_placeholders(object_, num));
491*600f14f4SXin Li 		}
492*600f14f4SXin Li 
template_append_point(FLAC__uint64 sample_number)493*600f14f4SXin Li 		bool SeekTable::template_append_point(FLAC__uint64 sample_number)
494*600f14f4SXin Li 		{
495*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
496*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_template_append_point(object_, sample_number));
497*600f14f4SXin Li 		}
498*600f14f4SXin Li 
template_append_points(FLAC__uint64 sample_numbers[],uint32_t num)499*600f14f4SXin Li 		bool SeekTable::template_append_points(FLAC__uint64 sample_numbers[], uint32_t num)
500*600f14f4SXin Li 		{
501*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
502*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_template_append_points(object_, sample_numbers, num));
503*600f14f4SXin Li 		}
504*600f14f4SXin Li 
template_append_spaced_points(uint32_t num,FLAC__uint64 total_samples)505*600f14f4SXin Li 		bool SeekTable::template_append_spaced_points(uint32_t num, FLAC__uint64 total_samples)
506*600f14f4SXin Li 		{
507*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
508*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_template_append_spaced_points(object_, num, total_samples));
509*600f14f4SXin Li 		}
510*600f14f4SXin Li 
template_append_spaced_points_by_samples(uint32_t samples,FLAC__uint64 total_samples)511*600f14f4SXin Li 		bool SeekTable::template_append_spaced_points_by_samples(uint32_t samples, FLAC__uint64 total_samples)
512*600f14f4SXin Li 		{
513*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
514*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(object_, samples, total_samples));
515*600f14f4SXin Li 		}
516*600f14f4SXin Li 
template_sort(bool compact)517*600f14f4SXin Li 		bool SeekTable::template_sort(bool compact)
518*600f14f4SXin Li 		{
519*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
520*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_seektable_template_sort(object_, compact));
521*600f14f4SXin Li 		}
522*600f14f4SXin Li 
523*600f14f4SXin Li 
524*600f14f4SXin Li 		//
525*600f14f4SXin Li 		// VorbisComment::Entry
526*600f14f4SXin Li 		//
527*600f14f4SXin Li 
Entry()528*600f14f4SXin Li 		VorbisComment::Entry::Entry() :
529*600f14f4SXin Li 			is_valid_(true),
530*600f14f4SXin Li 			entry_(),
531*600f14f4SXin Li 			field_name_(0),
532*600f14f4SXin Li 			field_name_length_(0),
533*600f14f4SXin Li 			field_value_(0),
534*600f14f4SXin Li 			field_value_length_(0)
535*600f14f4SXin Li 		{
536*600f14f4SXin Li 			zero();
537*600f14f4SXin Li 		}
538*600f14f4SXin Li 
Entry(const char * field,uint32_t field_length)539*600f14f4SXin Li 		VorbisComment::Entry::Entry(const char *field, uint32_t field_length) :
540*600f14f4SXin Li 			is_valid_(true),
541*600f14f4SXin Li 			entry_(),
542*600f14f4SXin Li 			field_name_(0),
543*600f14f4SXin Li 			field_name_length_(0),
544*600f14f4SXin Li 			field_value_(0),
545*600f14f4SXin Li 			field_value_length_(0)
546*600f14f4SXin Li 		{
547*600f14f4SXin Li 			zero();
548*600f14f4SXin Li 			construct(field, field_length);
549*600f14f4SXin Li 		}
550*600f14f4SXin Li 
Entry(const char * field)551*600f14f4SXin Li 		VorbisComment::Entry::Entry(const char *field) :
552*600f14f4SXin Li 			is_valid_(true),
553*600f14f4SXin Li 			entry_(),
554*600f14f4SXin Li 			field_name_(0),
555*600f14f4SXin Li 			field_name_length_(0),
556*600f14f4SXin Li 			field_value_(0),
557*600f14f4SXin Li 			field_value_length_(0)
558*600f14f4SXin Li 		{
559*600f14f4SXin Li 			zero();
560*600f14f4SXin Li 			construct(field);
561*600f14f4SXin Li 		}
562*600f14f4SXin Li 
Entry(const char * field_name,const char * field_value,uint32_t field_value_length)563*600f14f4SXin Li 		VorbisComment::Entry::Entry(const char *field_name, const char *field_value, uint32_t field_value_length) :
564*600f14f4SXin Li 			is_valid_(true),
565*600f14f4SXin Li 			entry_(),
566*600f14f4SXin Li 			field_name_(0),
567*600f14f4SXin Li 			field_name_length_(0),
568*600f14f4SXin Li 			field_value_(0),
569*600f14f4SXin Li 			field_value_length_(0)
570*600f14f4SXin Li 		{
571*600f14f4SXin Li 			zero();
572*600f14f4SXin Li 			construct(field_name, field_value, field_value_length);
573*600f14f4SXin Li 		}
574*600f14f4SXin Li 
Entry(const char * field_name,const char * field_value)575*600f14f4SXin Li 		VorbisComment::Entry::Entry(const char *field_name, const char *field_value) :
576*600f14f4SXin Li 			is_valid_(true),
577*600f14f4SXin Li 			entry_(),
578*600f14f4SXin Li 			field_name_(0),
579*600f14f4SXin Li 			field_name_length_(0),
580*600f14f4SXin Li 			field_value_(0),
581*600f14f4SXin Li 			field_value_length_(0)
582*600f14f4SXin Li 		{
583*600f14f4SXin Li 			zero();
584*600f14f4SXin Li 			construct(field_name, field_value);
585*600f14f4SXin Li 		}
586*600f14f4SXin Li 
Entry(const Entry & entry)587*600f14f4SXin Li 		VorbisComment::Entry::Entry(const Entry &entry) :
588*600f14f4SXin Li 			is_valid_(true),
589*600f14f4SXin Li 			entry_(),
590*600f14f4SXin Li 			field_name_(0),
591*600f14f4SXin Li 			field_name_length_(0),
592*600f14f4SXin Li 			field_value_(0),
593*600f14f4SXin Li 			field_value_length_(0)
594*600f14f4SXin Li 		{
595*600f14f4SXin Li 			FLAC__ASSERT(entry.is_valid());
596*600f14f4SXin Li 			zero();
597*600f14f4SXin Li 			construct(reinterpret_cast<const char *>(entry.entry_.entry), entry.entry_.length);
598*600f14f4SXin Li 		}
599*600f14f4SXin Li 
operator =(const Entry & entry)600*600f14f4SXin Li 		VorbisComment::Entry &VorbisComment::Entry::operator=(const Entry &entry)
601*600f14f4SXin Li 		{
602*600f14f4SXin Li 			FLAC__ASSERT(entry.is_valid());
603*600f14f4SXin Li 			clear();
604*600f14f4SXin Li 			construct(reinterpret_cast<const char *>(entry.entry_.entry), entry.entry_.length);
605*600f14f4SXin Li 			return *this;
606*600f14f4SXin Li 		}
607*600f14f4SXin Li 
~Entry()608*600f14f4SXin Li 		VorbisComment::Entry::~Entry()
609*600f14f4SXin Li 		{
610*600f14f4SXin Li 			clear();
611*600f14f4SXin Li 		}
612*600f14f4SXin Li 
is_valid() const613*600f14f4SXin Li 		bool VorbisComment::Entry::is_valid() const
614*600f14f4SXin Li 		{
615*600f14f4SXin Li 			return is_valid_;
616*600f14f4SXin Li 		}
617*600f14f4SXin Li 
get_field_length() const618*600f14f4SXin Li 		uint32_t VorbisComment::Entry::get_field_length() const
619*600f14f4SXin Li 		{
620*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
621*600f14f4SXin Li 			return entry_.length;
622*600f14f4SXin Li 		}
623*600f14f4SXin Li 
get_field_name_length() const624*600f14f4SXin Li 		uint32_t VorbisComment::Entry::get_field_name_length() const
625*600f14f4SXin Li 		{
626*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
627*600f14f4SXin Li 			return field_name_length_;
628*600f14f4SXin Li 		}
629*600f14f4SXin Li 
get_field_value_length() const630*600f14f4SXin Li 		uint32_t VorbisComment::Entry::get_field_value_length() const
631*600f14f4SXin Li 		{
632*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
633*600f14f4SXin Li 			return field_value_length_;
634*600f14f4SXin Li 		}
635*600f14f4SXin Li 
get_entry() const636*600f14f4SXin Li 		::FLAC__StreamMetadata_VorbisComment_Entry VorbisComment::Entry::get_entry() const
637*600f14f4SXin Li 		{
638*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
639*600f14f4SXin Li 			return entry_;
640*600f14f4SXin Li 		}
641*600f14f4SXin Li 
get_field() const642*600f14f4SXin Li 		const char *VorbisComment::Entry::get_field() const
643*600f14f4SXin Li 		{
644*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
645*600f14f4SXin Li 			return reinterpret_cast<const char *>(entry_.entry);
646*600f14f4SXin Li 		}
647*600f14f4SXin Li 
get_field_name() const648*600f14f4SXin Li 		const char *VorbisComment::Entry::get_field_name() const
649*600f14f4SXin Li 		{
650*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
651*600f14f4SXin Li 			return field_name_;
652*600f14f4SXin Li 		}
653*600f14f4SXin Li 
get_field_value() const654*600f14f4SXin Li 		const char *VorbisComment::Entry::get_field_value() const
655*600f14f4SXin Li 		{
656*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
657*600f14f4SXin Li 			return field_value_;
658*600f14f4SXin Li 		}
659*600f14f4SXin Li 
set_field(const char * field,uint32_t field_length)660*600f14f4SXin Li 		bool VorbisComment::Entry::set_field(const char *field, uint32_t field_length)
661*600f14f4SXin Li 		{
662*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
663*600f14f4SXin Li 			FLAC__ASSERT(0 != field);
664*600f14f4SXin Li 
665*600f14f4SXin Li 			if(!::FLAC__format_vorbiscomment_entry_is_legal(reinterpret_cast<const ::FLAC__byte*>(field), field_length))
666*600f14f4SXin Li 				return is_valid_ = false;
667*600f14f4SXin Li 
668*600f14f4SXin Li 			clear_entry();
669*600f14f4SXin Li 
670*600f14f4SXin Li 			if(0 == (entry_.entry = static_cast<FLAC__byte*>(safe_malloc_add_2op_(field_length, /*+*/1)))) {
671*600f14f4SXin Li 				is_valid_ = false;
672*600f14f4SXin Li 			}
673*600f14f4SXin Li 			else {
674*600f14f4SXin Li 				entry_.length = field_length;
675*600f14f4SXin Li 				std::memcpy(entry_.entry, field, field_length);
676*600f14f4SXin Li 				entry_.entry[field_length] = '\0';
677*600f14f4SXin Li 				(void) parse_field();
678*600f14f4SXin Li 			}
679*600f14f4SXin Li 
680*600f14f4SXin Li 			return is_valid_;
681*600f14f4SXin Li 		}
682*600f14f4SXin Li 
set_field(const char * field)683*600f14f4SXin Li 		bool VorbisComment::Entry::set_field(const char *field)
684*600f14f4SXin Li 		{
685*600f14f4SXin Li 			return set_field(field, std::strlen(field));
686*600f14f4SXin Li 		}
687*600f14f4SXin Li 
set_field_name(const char * field_name)688*600f14f4SXin Li 		bool VorbisComment::Entry::set_field_name(const char *field_name)
689*600f14f4SXin Li 		{
690*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
691*600f14f4SXin Li 			FLAC__ASSERT(0 != field_name);
692*600f14f4SXin Li 
693*600f14f4SXin Li 			if(!::FLAC__format_vorbiscomment_entry_name_is_legal(field_name))
694*600f14f4SXin Li 				return is_valid_ = false;
695*600f14f4SXin Li 
696*600f14f4SXin Li 			clear_field_name();
697*600f14f4SXin Li 
698*600f14f4SXin Li 			if(0 == (field_name_ = strdup(field_name))) {
699*600f14f4SXin Li 				is_valid_ = false;
700*600f14f4SXin Li 			}
701*600f14f4SXin Li 			else {
702*600f14f4SXin Li 				field_name_length_ = std::strlen(field_name_);
703*600f14f4SXin Li 				compose_field();
704*600f14f4SXin Li 			}
705*600f14f4SXin Li 
706*600f14f4SXin Li 			return is_valid_;
707*600f14f4SXin Li 		}
708*600f14f4SXin Li 
set_field_value(const char * field_value,uint32_t field_value_length)709*600f14f4SXin Li 		bool VorbisComment::Entry::set_field_value(const char *field_value, uint32_t field_value_length)
710*600f14f4SXin Li 		{
711*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
712*600f14f4SXin Li 			FLAC__ASSERT(0 != field_value);
713*600f14f4SXin Li 
714*600f14f4SXin Li 			if(!::FLAC__format_vorbiscomment_entry_value_is_legal(reinterpret_cast<const FLAC__byte*>(field_value), field_value_length))
715*600f14f4SXin Li 				return is_valid_ = false;
716*600f14f4SXin Li 
717*600f14f4SXin Li 			clear_field_value();
718*600f14f4SXin Li 
719*600f14f4SXin Li 			if(0 == (field_value_ = static_cast<char *>(safe_malloc_add_2op_(field_value_length, /*+*/1)))) {
720*600f14f4SXin Li 				is_valid_ = false;
721*600f14f4SXin Li 			}
722*600f14f4SXin Li 			else {
723*600f14f4SXin Li 				field_value_length_ = field_value_length;
724*600f14f4SXin Li 				std::memcpy(field_value_, field_value, field_value_length);
725*600f14f4SXin Li 				field_value_[field_value_length] = '\0';
726*600f14f4SXin Li 				compose_field();
727*600f14f4SXin Li 			}
728*600f14f4SXin Li 
729*600f14f4SXin Li 			return is_valid_;
730*600f14f4SXin Li 		}
731*600f14f4SXin Li 
set_field_value(const char * field_value)732*600f14f4SXin Li 		bool VorbisComment::Entry::set_field_value(const char *field_value)
733*600f14f4SXin Li 		{
734*600f14f4SXin Li 			return set_field_value(field_value, std::strlen(field_value));
735*600f14f4SXin Li 		}
736*600f14f4SXin Li 
zero()737*600f14f4SXin Li 		void VorbisComment::Entry::zero()
738*600f14f4SXin Li 		{
739*600f14f4SXin Li 			is_valid_ = true;
740*600f14f4SXin Li 			entry_.length = 0;
741*600f14f4SXin Li 			entry_.entry = 0;
742*600f14f4SXin Li 			field_name_ = 0;
743*600f14f4SXin Li 			field_name_length_ = 0;
744*600f14f4SXin Li 			field_value_ = 0;
745*600f14f4SXin Li 			field_value_length_ = 0;
746*600f14f4SXin Li 		}
747*600f14f4SXin Li 
clear()748*600f14f4SXin Li 		void VorbisComment::Entry::clear()
749*600f14f4SXin Li 		{
750*600f14f4SXin Li 			clear_entry();
751*600f14f4SXin Li 			clear_field_name();
752*600f14f4SXin Li 			clear_field_value();
753*600f14f4SXin Li 			is_valid_ = true;
754*600f14f4SXin Li 		}
755*600f14f4SXin Li 
clear_entry()756*600f14f4SXin Li 		void VorbisComment::Entry::clear_entry()
757*600f14f4SXin Li 		{
758*600f14f4SXin Li 			if(0 != entry_.entry) {
759*600f14f4SXin Li 				std::free(entry_.entry);
760*600f14f4SXin Li 				entry_.entry = 0;
761*600f14f4SXin Li 				entry_.length = 0;
762*600f14f4SXin Li 			}
763*600f14f4SXin Li 		}
764*600f14f4SXin Li 
clear_field_name()765*600f14f4SXin Li 		void VorbisComment::Entry::clear_field_name()
766*600f14f4SXin Li 		{
767*600f14f4SXin Li 			if(0 != field_name_) {
768*600f14f4SXin Li 				std::free(field_name_);
769*600f14f4SXin Li 				field_name_ = 0;
770*600f14f4SXin Li 				field_name_length_ = 0;
771*600f14f4SXin Li 			}
772*600f14f4SXin Li 		}
773*600f14f4SXin Li 
clear_field_value()774*600f14f4SXin Li 		void VorbisComment::Entry::clear_field_value()
775*600f14f4SXin Li 		{
776*600f14f4SXin Li 			if(0 != field_value_) {
777*600f14f4SXin Li 				std::free(field_value_);
778*600f14f4SXin Li 				field_value_ = 0;
779*600f14f4SXin Li 				field_value_length_ = 0;
780*600f14f4SXin Li 			}
781*600f14f4SXin Li 		}
782*600f14f4SXin Li 
construct(const char * field,uint32_t field_length)783*600f14f4SXin Li 		void VorbisComment::Entry::construct(const char *field, uint32_t field_length)
784*600f14f4SXin Li 		{
785*600f14f4SXin Li 			if(set_field(field, field_length))
786*600f14f4SXin Li 				parse_field();
787*600f14f4SXin Li 		}
788*600f14f4SXin Li 
construct(const char * field)789*600f14f4SXin Li 		void VorbisComment::Entry::construct(const char *field)
790*600f14f4SXin Li 		{
791*600f14f4SXin Li 			construct(field, std::strlen(field));
792*600f14f4SXin Li 		}
793*600f14f4SXin Li 
construct(const char * field_name,const char * field_value,uint32_t field_value_length)794*600f14f4SXin Li 		void VorbisComment::Entry::construct(const char *field_name, const char *field_value, uint32_t field_value_length)
795*600f14f4SXin Li 		{
796*600f14f4SXin Li 			if(set_field_name(field_name) && set_field_value(field_value, field_value_length))
797*600f14f4SXin Li 				compose_field();
798*600f14f4SXin Li 		}
799*600f14f4SXin Li 
construct(const char * field_name,const char * field_value)800*600f14f4SXin Li 		void VorbisComment::Entry::construct(const char *field_name, const char *field_value)
801*600f14f4SXin Li 		{
802*600f14f4SXin Li 			construct(field_name, field_value, std::strlen(field_value));
803*600f14f4SXin Li 		}
804*600f14f4SXin Li 
compose_field()805*600f14f4SXin Li 		void VorbisComment::Entry::compose_field()
806*600f14f4SXin Li 		{
807*600f14f4SXin Li 			clear_entry();
808*600f14f4SXin Li 
809*600f14f4SXin Li 			if(0 == (entry_.entry = static_cast<FLAC__byte*>(safe_malloc_add_4op_(field_name_length_, /*+*/1, /*+*/field_value_length_, /*+*/1)))) {
810*600f14f4SXin Li 				is_valid_ = false;
811*600f14f4SXin Li 			}
812*600f14f4SXin Li 			else {
813*600f14f4SXin Li 				std::memcpy(entry_.entry, field_name_, field_name_length_);
814*600f14f4SXin Li 				entry_.length += field_name_length_;
815*600f14f4SXin Li 				std::memcpy(entry_.entry + entry_.length, "=", 1);
816*600f14f4SXin Li 				entry_.length += 1;
817*600f14f4SXin Li 				if (field_value_length_ > 0)
818*600f14f4SXin Li 					std::memcpy(entry_.entry + entry_.length, field_value_, field_value_length_);
819*600f14f4SXin Li 				entry_.length += field_value_length_;
820*600f14f4SXin Li 				entry_.entry[entry_.length] = '\0';
821*600f14f4SXin Li 				is_valid_ = true;
822*600f14f4SXin Li 			}
823*600f14f4SXin Li 		}
824*600f14f4SXin Li 
parse_field()825*600f14f4SXin Li 		void VorbisComment::Entry::parse_field()
826*600f14f4SXin Li 		{
827*600f14f4SXin Li 			clear_field_name();
828*600f14f4SXin Li 			clear_field_value();
829*600f14f4SXin Li 
830*600f14f4SXin Li 			const char *p = static_cast<const char *>(std::memchr(entry_.entry, '=', entry_.length));
831*600f14f4SXin Li 
832*600f14f4SXin Li 			if(0 == p)
833*600f14f4SXin Li 				p = reinterpret_cast<const char *>(entry_.entry) + entry_.length;
834*600f14f4SXin Li 
835*600f14f4SXin Li 			field_name_length_ = static_cast<uint32_t>(p - reinterpret_cast<const char *>(entry_.entry));
836*600f14f4SXin Li 			if(0 == (field_name_ = static_cast<char *>(safe_malloc_add_2op_(field_name_length_, /*+*/1)))) { // +1 for the trailing \0
837*600f14f4SXin Li 				is_valid_ = false;
838*600f14f4SXin Li 				return;
839*600f14f4SXin Li 			}
840*600f14f4SXin Li 			std::memcpy(field_name_, entry_.entry, field_name_length_);
841*600f14f4SXin Li 			field_name_[field_name_length_] = '\0';
842*600f14f4SXin Li 
843*600f14f4SXin Li 			if(entry_.length - field_name_length_ == 0) {
844*600f14f4SXin Li 				field_value_length_ = 0;
845*600f14f4SXin Li 				if(0 == (field_value_ = static_cast<char *>(safe_malloc_(0)))) {
846*600f14f4SXin Li 					is_valid_ = false;
847*600f14f4SXin Li 					return;
848*600f14f4SXin Li 				}
849*600f14f4SXin Li 			}
850*600f14f4SXin Li 			else {
851*600f14f4SXin Li 				field_value_length_ = entry_.length - field_name_length_ - 1;
852*600f14f4SXin Li 				if(0 == (field_value_ = static_cast<char *>(safe_malloc_add_2op_(field_value_length_, /*+*/1)))) { // +1 for the trailing \0
853*600f14f4SXin Li 					is_valid_ = false;
854*600f14f4SXin Li 					return;
855*600f14f4SXin Li 				}
856*600f14f4SXin Li 				std::memcpy(field_value_, ++p, field_value_length_);
857*600f14f4SXin Li 				field_value_[field_value_length_] = '\0';
858*600f14f4SXin Li 			}
859*600f14f4SXin Li 
860*600f14f4SXin Li 			is_valid_ = true;
861*600f14f4SXin Li 		}
862*600f14f4SXin Li 
863*600f14f4SXin Li 
864*600f14f4SXin Li 		//
865*600f14f4SXin Li 		// VorbisComment
866*600f14f4SXin Li 		//
867*600f14f4SXin Li 
VorbisComment()868*600f14f4SXin Li 		VorbisComment::VorbisComment():
869*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT), /*copy=*/false)
870*600f14f4SXin Li 		{ }
871*600f14f4SXin Li 
~VorbisComment()872*600f14f4SXin Li 		VorbisComment::~VorbisComment()
873*600f14f4SXin Li 		{ }
874*600f14f4SXin Li 
get_num_comments() const875*600f14f4SXin Li 		uint32_t VorbisComment::get_num_comments() const
876*600f14f4SXin Li 		{
877*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
878*600f14f4SXin Li 			return object_->data.vorbis_comment.num_comments;
879*600f14f4SXin Li 		}
880*600f14f4SXin Li 
get_vendor_string() const881*600f14f4SXin Li 		const FLAC__byte *VorbisComment::get_vendor_string() const
882*600f14f4SXin Li 		{
883*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
884*600f14f4SXin Li 			return object_->data.vorbis_comment.vendor_string.entry;
885*600f14f4SXin Li 		}
886*600f14f4SXin Li 
get_comment(uint32_t indx) const887*600f14f4SXin Li 		VorbisComment::Entry VorbisComment::get_comment(uint32_t indx) const
888*600f14f4SXin Li 		{
889*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
890*600f14f4SXin Li 			FLAC__ASSERT(indx < object_->data.vorbis_comment.num_comments);
891*600f14f4SXin Li 			return Entry(reinterpret_cast<const char *>(object_->data.vorbis_comment.comments[indx].entry), object_->data.vorbis_comment.comments[indx].length);
892*600f14f4SXin Li 		}
893*600f14f4SXin Li 
set_vendor_string(const FLAC__byte * string)894*600f14f4SXin Li 		bool VorbisComment::set_vendor_string(const FLAC__byte *string)
895*600f14f4SXin Li 		{
896*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
897*600f14f4SXin Li 			// vendor_string is a special kind of entry
898*600f14f4SXin Li 			const ::FLAC__StreamMetadata_VorbisComment_Entry vendor_string = { static_cast<FLAC__uint32>(std::strlen(reinterpret_cast<const char *>(string))), const_cast<FLAC__byte*>(string) }; // we can cheat on const-ness because we make a copy below:
899*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_vorbiscomment_set_vendor_string(object_, vendor_string, /*copy=*/true));
900*600f14f4SXin Li 		}
901*600f14f4SXin Li 
resize_comments(uint32_t new_num_comments)902*600f14f4SXin Li 		bool VorbisComment::resize_comments(uint32_t new_num_comments)
903*600f14f4SXin Li 		{
904*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
905*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_vorbiscomment_resize_comments(object_, new_num_comments));
906*600f14f4SXin Li 		}
907*600f14f4SXin Li 
set_comment(uint32_t indx,const VorbisComment::Entry & entry)908*600f14f4SXin Li 		bool VorbisComment::set_comment(uint32_t indx, const VorbisComment::Entry &entry)
909*600f14f4SXin Li 		{
910*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
911*600f14f4SXin Li 			FLAC__ASSERT(indx < object_->data.vorbis_comment.num_comments);
912*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_vorbiscomment_set_comment(object_, indx, entry.get_entry(), /*copy=*/true));
913*600f14f4SXin Li 		}
914*600f14f4SXin Li 
insert_comment(uint32_t indx,const VorbisComment::Entry & entry)915*600f14f4SXin Li 		bool VorbisComment::insert_comment(uint32_t indx, const VorbisComment::Entry &entry)
916*600f14f4SXin Li 		{
917*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
918*600f14f4SXin Li 			FLAC__ASSERT(indx <= object_->data.vorbis_comment.num_comments);
919*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_vorbiscomment_insert_comment(object_, indx, entry.get_entry(), /*copy=*/true));
920*600f14f4SXin Li 		}
921*600f14f4SXin Li 
append_comment(const VorbisComment::Entry & entry)922*600f14f4SXin Li 		bool VorbisComment::append_comment(const VorbisComment::Entry &entry)
923*600f14f4SXin Li 		{
924*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
925*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_vorbiscomment_append_comment(object_, entry.get_entry(), /*copy=*/true));
926*600f14f4SXin Li 		}
927*600f14f4SXin Li 
replace_comment(const VorbisComment::Entry & entry,bool all)928*600f14f4SXin Li 		bool VorbisComment::replace_comment(const VorbisComment::Entry &entry, bool all)
929*600f14f4SXin Li 		{
930*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
931*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_vorbiscomment_replace_comment(object_, entry.get_entry(), static_cast<FLAC__bool>(all), /*copy=*/true));
932*600f14f4SXin Li 		}
933*600f14f4SXin Li 
delete_comment(uint32_t indx)934*600f14f4SXin Li 		bool VorbisComment::delete_comment(uint32_t indx)
935*600f14f4SXin Li 		{
936*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
937*600f14f4SXin Li 			FLAC__ASSERT(indx < object_->data.vorbis_comment.num_comments);
938*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_vorbiscomment_delete_comment(object_, indx));
939*600f14f4SXin Li 		}
940*600f14f4SXin Li 
find_entry_from(uint32_t offset,const char * field_name)941*600f14f4SXin Li 		int VorbisComment::find_entry_from(uint32_t offset, const char *field_name)
942*600f14f4SXin Li 		{
943*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
944*600f14f4SXin Li 			return ::FLAC__metadata_object_vorbiscomment_find_entry_from(object_, offset, field_name);
945*600f14f4SXin Li 		}
946*600f14f4SXin Li 
remove_entry_matching(const char * field_name)947*600f14f4SXin Li 		int VorbisComment::remove_entry_matching(const char *field_name)
948*600f14f4SXin Li 		{
949*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
950*600f14f4SXin Li 			return ::FLAC__metadata_object_vorbiscomment_remove_entry_matching(object_, field_name);
951*600f14f4SXin Li 		}
952*600f14f4SXin Li 
remove_entries_matching(const char * field_name)953*600f14f4SXin Li 		int VorbisComment::remove_entries_matching(const char *field_name)
954*600f14f4SXin Li 		{
955*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
956*600f14f4SXin Li 			return ::FLAC__metadata_object_vorbiscomment_remove_entries_matching(object_, field_name);
957*600f14f4SXin Li 		}
958*600f14f4SXin Li 
959*600f14f4SXin Li 
960*600f14f4SXin Li 		//
961*600f14f4SXin Li 		// CueSheet::Track
962*600f14f4SXin Li 		//
963*600f14f4SXin Li 
Track()964*600f14f4SXin Li 		CueSheet::Track::Track():
965*600f14f4SXin Li 		object_(::FLAC__metadata_object_cuesheet_track_new())
966*600f14f4SXin Li 		{ }
967*600f14f4SXin Li 
Track(const::FLAC__StreamMetadata_CueSheet_Track * track)968*600f14f4SXin Li 		CueSheet::Track::Track(const ::FLAC__StreamMetadata_CueSheet_Track *track):
969*600f14f4SXin Li 		object_(::FLAC__metadata_object_cuesheet_track_clone(track))
970*600f14f4SXin Li 		{ }
971*600f14f4SXin Li 
Track(const Track & track)972*600f14f4SXin Li 		CueSheet::Track::Track(const Track &track):
973*600f14f4SXin Li 		object_(::FLAC__metadata_object_cuesheet_track_clone(track.object_))
974*600f14f4SXin Li 		{ }
975*600f14f4SXin Li 
operator =(const Track & track)976*600f14f4SXin Li 		CueSheet::Track &CueSheet::Track::operator=(const Track &track)
977*600f14f4SXin Li 		{
978*600f14f4SXin Li 			if(0 != object_)
979*600f14f4SXin Li 				::FLAC__metadata_object_cuesheet_track_delete(object_);
980*600f14f4SXin Li 			object_ = ::FLAC__metadata_object_cuesheet_track_clone(track.object_);
981*600f14f4SXin Li 			return *this;
982*600f14f4SXin Li 		}
983*600f14f4SXin Li 
~Track()984*600f14f4SXin Li 		CueSheet::Track::~Track()
985*600f14f4SXin Li 		{
986*600f14f4SXin Li 			if(0 != object_)
987*600f14f4SXin Li 				::FLAC__metadata_object_cuesheet_track_delete(object_);
988*600f14f4SXin Li 		}
989*600f14f4SXin Li 
is_valid() const990*600f14f4SXin Li 		bool CueSheet::Track::is_valid() const
991*600f14f4SXin Li 		{
992*600f14f4SXin Li 			return(0 != object_);
993*600f14f4SXin Li 		}
994*600f14f4SXin Li 
get_index(uint32_t i) const995*600f14f4SXin Li 		::FLAC__StreamMetadata_CueSheet_Index CueSheet::Track::get_index(uint32_t i) const
996*600f14f4SXin Li 		{
997*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
998*600f14f4SXin Li 			FLAC__ASSERT(i < object_->num_indices);
999*600f14f4SXin Li 			return object_->indices[i];
1000*600f14f4SXin Li 		}
1001*600f14f4SXin Li 
set_isrc(const char value[12])1002*600f14f4SXin Li 		void CueSheet::Track::set_isrc(const char value[12])
1003*600f14f4SXin Li 		{
1004*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1005*600f14f4SXin Li 			FLAC__ASSERT(0 != value);
1006*600f14f4SXin Li 			std::memcpy(object_->isrc, value, 12);
1007*600f14f4SXin Li 			object_->isrc[12] = '\0';
1008*600f14f4SXin Li 		}
1009*600f14f4SXin Li 
set_type(uint32_t value)1010*600f14f4SXin Li 		void CueSheet::Track::set_type(uint32_t value)
1011*600f14f4SXin Li 		{
1012*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1013*600f14f4SXin Li 			FLAC__ASSERT(value <= 1);
1014*600f14f4SXin Li 			object_->type = value;
1015*600f14f4SXin Li 		}
1016*600f14f4SXin Li 
set_index(uint32_t i,const::FLAC__StreamMetadata_CueSheet_Index & indx)1017*600f14f4SXin Li  		void CueSheet::Track::set_index(uint32_t i, const ::FLAC__StreamMetadata_CueSheet_Index &indx)
1018*600f14f4SXin Li  		{
1019*600f14f4SXin Li  			FLAC__ASSERT(is_valid());
1020*600f14f4SXin Li  			FLAC__ASSERT(i < object_->num_indices);
1021*600f14f4SXin Li  			object_->indices[i] = indx;
1022*600f14f4SXin Li  		}
1023*600f14f4SXin Li 
1024*600f14f4SXin Li 
1025*600f14f4SXin Li 		//
1026*600f14f4SXin Li 		// CueSheet
1027*600f14f4SXin Li 		//
1028*600f14f4SXin Li 
CueSheet()1029*600f14f4SXin Li 		CueSheet::CueSheet():
1030*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET), /*copy=*/false)
1031*600f14f4SXin Li 		{ }
1032*600f14f4SXin Li 
~CueSheet()1033*600f14f4SXin Li 		CueSheet::~CueSheet()
1034*600f14f4SXin Li 		{ }
1035*600f14f4SXin Li 
get_media_catalog_number() const1036*600f14f4SXin Li 		const char *CueSheet::get_media_catalog_number() const
1037*600f14f4SXin Li 		{
1038*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1039*600f14f4SXin Li 			return object_->data.cue_sheet.media_catalog_number;
1040*600f14f4SXin Li 		}
1041*600f14f4SXin Li 
get_lead_in() const1042*600f14f4SXin Li 		FLAC__uint64 CueSheet::get_lead_in() const
1043*600f14f4SXin Li 		{
1044*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1045*600f14f4SXin Li 			return object_->data.cue_sheet.lead_in;
1046*600f14f4SXin Li 		}
1047*600f14f4SXin Li 
get_is_cd() const1048*600f14f4SXin Li 		bool CueSheet::get_is_cd() const
1049*600f14f4SXin Li 		{
1050*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1051*600f14f4SXin Li 			return object_->data.cue_sheet.is_cd? true : false;
1052*600f14f4SXin Li 		}
1053*600f14f4SXin Li 
get_num_tracks() const1054*600f14f4SXin Li 		uint32_t CueSheet::get_num_tracks() const
1055*600f14f4SXin Li 		{
1056*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1057*600f14f4SXin Li 			return object_->data.cue_sheet.num_tracks;
1058*600f14f4SXin Li 		}
1059*600f14f4SXin Li 
get_track(uint32_t i) const1060*600f14f4SXin Li 		CueSheet::Track CueSheet::get_track(uint32_t i) const
1061*600f14f4SXin Li 		{
1062*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1063*600f14f4SXin Li 			FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
1064*600f14f4SXin Li 			return Track(object_->data.cue_sheet.tracks + i);
1065*600f14f4SXin Li 		}
1066*600f14f4SXin Li 
set_media_catalog_number(const char value[128])1067*600f14f4SXin Li 		void CueSheet::set_media_catalog_number(const char value[128])
1068*600f14f4SXin Li 		{
1069*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1070*600f14f4SXin Li 			FLAC__ASSERT(0 != value);
1071*600f14f4SXin Li 			std::memcpy(object_->data.cue_sheet.media_catalog_number, value, 128);
1072*600f14f4SXin Li 			object_->data.cue_sheet.media_catalog_number[128] = '\0';
1073*600f14f4SXin Li 		}
1074*600f14f4SXin Li 
set_lead_in(FLAC__uint64 value)1075*600f14f4SXin Li 		void CueSheet::set_lead_in(FLAC__uint64 value)
1076*600f14f4SXin Li 		{
1077*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1078*600f14f4SXin Li 			object_->data.cue_sheet.lead_in = value;
1079*600f14f4SXin Li 		}
1080*600f14f4SXin Li 
set_is_cd(bool value)1081*600f14f4SXin Li 		void CueSheet::set_is_cd(bool value)
1082*600f14f4SXin Li 		{
1083*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1084*600f14f4SXin Li 			object_->data.cue_sheet.is_cd = value;
1085*600f14f4SXin Li 		}
1086*600f14f4SXin Li 
set_index(uint32_t track_num,uint32_t index_num,const::FLAC__StreamMetadata_CueSheet_Index & indx)1087*600f14f4SXin Li 		void CueSheet::set_index(uint32_t track_num, uint32_t index_num, const ::FLAC__StreamMetadata_CueSheet_Index &indx)
1088*600f14f4SXin Li 		{
1089*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1090*600f14f4SXin Li 			FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
1091*600f14f4SXin Li 			FLAC__ASSERT(index_num < object_->data.cue_sheet.tracks[track_num].num_indices);
1092*600f14f4SXin Li 			object_->data.cue_sheet.tracks[track_num].indices[index_num] = indx;
1093*600f14f4SXin Li 		}
1094*600f14f4SXin Li 
resize_indices(uint32_t track_num,uint32_t new_num_indices)1095*600f14f4SXin Li 		bool CueSheet::resize_indices(uint32_t track_num, uint32_t new_num_indices)
1096*600f14f4SXin Li 		{
1097*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1098*600f14f4SXin Li 			FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
1099*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_track_resize_indices(object_, track_num, new_num_indices));
1100*600f14f4SXin Li 		}
1101*600f14f4SXin Li 
insert_index(uint32_t track_num,uint32_t index_num,const::FLAC__StreamMetadata_CueSheet_Index & indx)1102*600f14f4SXin Li 		bool CueSheet::insert_index(uint32_t track_num, uint32_t index_num, const ::FLAC__StreamMetadata_CueSheet_Index &indx)
1103*600f14f4SXin Li 		{
1104*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1105*600f14f4SXin Li 			FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
1106*600f14f4SXin Li 			FLAC__ASSERT(index_num <= object_->data.cue_sheet.tracks[track_num].num_indices);
1107*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_track_insert_index(object_, track_num, index_num, indx));
1108*600f14f4SXin Li 		}
1109*600f14f4SXin Li 
insert_blank_index(uint32_t track_num,uint32_t index_num)1110*600f14f4SXin Li 		bool CueSheet::insert_blank_index(uint32_t track_num, uint32_t index_num)
1111*600f14f4SXin Li 		{
1112*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1113*600f14f4SXin Li 			FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
1114*600f14f4SXin Li 			FLAC__ASSERT(index_num <= object_->data.cue_sheet.tracks[track_num].num_indices);
1115*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_track_insert_blank_index(object_, track_num, index_num));
1116*600f14f4SXin Li 		}
1117*600f14f4SXin Li 
delete_index(uint32_t track_num,uint32_t index_num)1118*600f14f4SXin Li 		bool CueSheet::delete_index(uint32_t track_num, uint32_t index_num)
1119*600f14f4SXin Li 		{
1120*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1121*600f14f4SXin Li 			FLAC__ASSERT(track_num < object_->data.cue_sheet.num_tracks);
1122*600f14f4SXin Li 			FLAC__ASSERT(index_num < object_->data.cue_sheet.tracks[track_num].num_indices);
1123*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_track_delete_index(object_, track_num, index_num));
1124*600f14f4SXin Li 		}
1125*600f14f4SXin Li 
resize_tracks(uint32_t new_num_tracks)1126*600f14f4SXin Li 		bool CueSheet::resize_tracks(uint32_t new_num_tracks)
1127*600f14f4SXin Li 		{
1128*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1129*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_resize_tracks(object_, new_num_tracks));
1130*600f14f4SXin Li 		}
1131*600f14f4SXin Li 
set_track(uint32_t i,const CueSheet::Track & track)1132*600f14f4SXin Li 		bool CueSheet::set_track(uint32_t i, const CueSheet::Track &track)
1133*600f14f4SXin Li 		{
1134*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1135*600f14f4SXin Li 			FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
1136*600f14f4SXin Li 			// We can safely const_cast since copy=true
1137*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_set_track(object_, i, const_cast< ::FLAC__StreamMetadata_CueSheet_Track*>(track.get_track()), /*copy=*/true));
1138*600f14f4SXin Li 		}
1139*600f14f4SXin Li 
insert_track(uint32_t i,const CueSheet::Track & track)1140*600f14f4SXin Li 		bool CueSheet::insert_track(uint32_t i, const CueSheet::Track &track)
1141*600f14f4SXin Li 		{
1142*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1143*600f14f4SXin Li 			FLAC__ASSERT(i <= object_->data.cue_sheet.num_tracks);
1144*600f14f4SXin Li 			// We can safely const_cast since copy=true
1145*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_insert_track(object_, i, const_cast< ::FLAC__StreamMetadata_CueSheet_Track*>(track.get_track()), /*copy=*/true));
1146*600f14f4SXin Li 		}
1147*600f14f4SXin Li 
insert_blank_track(uint32_t i)1148*600f14f4SXin Li 		bool CueSheet::insert_blank_track(uint32_t i)
1149*600f14f4SXin Li 		{
1150*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1151*600f14f4SXin Li 			FLAC__ASSERT(i <= object_->data.cue_sheet.num_tracks);
1152*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_insert_blank_track(object_, i));
1153*600f14f4SXin Li 		}
1154*600f14f4SXin Li 
delete_track(uint32_t i)1155*600f14f4SXin Li 		bool CueSheet::delete_track(uint32_t i)
1156*600f14f4SXin Li 		{
1157*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1158*600f14f4SXin Li 			FLAC__ASSERT(i < object_->data.cue_sheet.num_tracks);
1159*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_delete_track(object_, i));
1160*600f14f4SXin Li 		}
1161*600f14f4SXin Li 
is_legal(bool check_cd_da_subset,const char ** violation) const1162*600f14f4SXin Li 		bool CueSheet::is_legal(bool check_cd_da_subset, const char **violation) const
1163*600f14f4SXin Li 		{
1164*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1165*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_cuesheet_is_legal(object_, check_cd_da_subset, violation));
1166*600f14f4SXin Li 		}
1167*600f14f4SXin Li 
calculate_cddb_id() const1168*600f14f4SXin Li 		FLAC__uint32 CueSheet::calculate_cddb_id() const
1169*600f14f4SXin Li 		{
1170*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1171*600f14f4SXin Li 			return ::FLAC__metadata_object_cuesheet_calculate_cddb_id(object_);
1172*600f14f4SXin Li 		}
1173*600f14f4SXin Li 
1174*600f14f4SXin Li 
1175*600f14f4SXin Li 		//
1176*600f14f4SXin Li 		// Picture
1177*600f14f4SXin Li 		//
1178*600f14f4SXin Li 
Picture()1179*600f14f4SXin Li 		Picture::Picture():
1180*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE), /*copy=*/false)
1181*600f14f4SXin Li 		{ }
1182*600f14f4SXin Li 
~Picture()1183*600f14f4SXin Li 		Picture::~Picture()
1184*600f14f4SXin Li 		{ }
1185*600f14f4SXin Li 
get_type() const1186*600f14f4SXin Li 		::FLAC__StreamMetadata_Picture_Type Picture::get_type() const
1187*600f14f4SXin Li 		{
1188*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1189*600f14f4SXin Li 			return object_->data.picture.type;
1190*600f14f4SXin Li 		}
1191*600f14f4SXin Li 
get_mime_type() const1192*600f14f4SXin Li 		const char *Picture::get_mime_type() const
1193*600f14f4SXin Li 		{
1194*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1195*600f14f4SXin Li 			return object_->data.picture.mime_type;
1196*600f14f4SXin Li 		}
1197*600f14f4SXin Li 
get_description() const1198*600f14f4SXin Li 		const FLAC__byte *Picture::get_description() const
1199*600f14f4SXin Li 		{
1200*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1201*600f14f4SXin Li 			return object_->data.picture.description;
1202*600f14f4SXin Li 		}
1203*600f14f4SXin Li 
get_width() const1204*600f14f4SXin Li 		FLAC__uint32 Picture::get_width() const
1205*600f14f4SXin Li 		{
1206*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1207*600f14f4SXin Li 			return object_->data.picture.width;
1208*600f14f4SXin Li 		}
1209*600f14f4SXin Li 
get_height() const1210*600f14f4SXin Li 		FLAC__uint32 Picture::get_height() const
1211*600f14f4SXin Li 		{
1212*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1213*600f14f4SXin Li 			return object_->data.picture.height;
1214*600f14f4SXin Li 		}
1215*600f14f4SXin Li 
get_depth() const1216*600f14f4SXin Li 		FLAC__uint32 Picture::get_depth() const
1217*600f14f4SXin Li 		{
1218*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1219*600f14f4SXin Li 			return object_->data.picture.depth;
1220*600f14f4SXin Li 		}
1221*600f14f4SXin Li 
get_colors() const1222*600f14f4SXin Li 		FLAC__uint32 Picture::get_colors() const
1223*600f14f4SXin Li 		{
1224*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1225*600f14f4SXin Li 			return object_->data.picture.colors;
1226*600f14f4SXin Li 		}
1227*600f14f4SXin Li 
get_data_length() const1228*600f14f4SXin Li 		FLAC__uint32 Picture::get_data_length() const
1229*600f14f4SXin Li 		{
1230*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1231*600f14f4SXin Li 			return object_->data.picture.data_length;
1232*600f14f4SXin Li 		}
1233*600f14f4SXin Li 
get_data() const1234*600f14f4SXin Li 		const FLAC__byte *Picture::get_data() const
1235*600f14f4SXin Li 		{
1236*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1237*600f14f4SXin Li 			return object_->data.picture.data;
1238*600f14f4SXin Li 		}
1239*600f14f4SXin Li 
set_type(::FLAC__StreamMetadata_Picture_Type type)1240*600f14f4SXin Li 		void Picture::set_type(::FLAC__StreamMetadata_Picture_Type type)
1241*600f14f4SXin Li 		{
1242*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1243*600f14f4SXin Li 			object_->data.picture.type = type;
1244*600f14f4SXin Li 		}
1245*600f14f4SXin Li 
set_mime_type(const char * string)1246*600f14f4SXin Li 		bool Picture::set_mime_type(const char *string)
1247*600f14f4SXin Li 		{
1248*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1249*600f14f4SXin Li 			// We can safely const_cast since copy=true
1250*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_picture_set_mime_type(object_, const_cast<char*>(string), /*copy=*/true));
1251*600f14f4SXin Li 		}
1252*600f14f4SXin Li 
set_description(const FLAC__byte * string)1253*600f14f4SXin Li 		bool Picture::set_description(const FLAC__byte *string)
1254*600f14f4SXin Li 		{
1255*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1256*600f14f4SXin Li 			// We can safely const_cast since copy=true
1257*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_picture_set_description(object_, const_cast<FLAC__byte*>(string), /*copy=*/true));
1258*600f14f4SXin Li 		}
1259*600f14f4SXin Li 
set_width(FLAC__uint32 value) const1260*600f14f4SXin Li 		void Picture::set_width(FLAC__uint32 value) const
1261*600f14f4SXin Li 		{
1262*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1263*600f14f4SXin Li 			object_->data.picture.width = value;
1264*600f14f4SXin Li 		}
1265*600f14f4SXin Li 
set_height(FLAC__uint32 value) const1266*600f14f4SXin Li 		void Picture::set_height(FLAC__uint32 value) const
1267*600f14f4SXin Li 		{
1268*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1269*600f14f4SXin Li 			object_->data.picture.height = value;
1270*600f14f4SXin Li 		}
1271*600f14f4SXin Li 
set_depth(FLAC__uint32 value) const1272*600f14f4SXin Li 		void Picture::set_depth(FLAC__uint32 value) const
1273*600f14f4SXin Li 		{
1274*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1275*600f14f4SXin Li 			object_->data.picture.depth = value;
1276*600f14f4SXin Li 		}
1277*600f14f4SXin Li 
set_colors(FLAC__uint32 value) const1278*600f14f4SXin Li 		void Picture::set_colors(FLAC__uint32 value) const
1279*600f14f4SXin Li 		{
1280*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1281*600f14f4SXin Li 			object_->data.picture.colors = value;
1282*600f14f4SXin Li 		}
1283*600f14f4SXin Li 
set_data(const FLAC__byte * data,FLAC__uint32 data_length)1284*600f14f4SXin Li 		bool Picture::set_data(const FLAC__byte *data, FLAC__uint32 data_length)
1285*600f14f4SXin Li 		{
1286*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1287*600f14f4SXin Li 			// We can safely const_cast since copy=true
1288*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_picture_set_data(object_, const_cast<FLAC__byte*>(data), data_length, /*copy=*/true));
1289*600f14f4SXin Li 		}
1290*600f14f4SXin Li 
is_legal(const char ** violation)1291*600f14f4SXin Li 		bool Picture::is_legal(const char **violation)
1292*600f14f4SXin Li 		{
1293*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1294*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_picture_is_legal(object_, violation));
1295*600f14f4SXin Li 		}
1296*600f14f4SXin Li 
1297*600f14f4SXin Li 
1298*600f14f4SXin Li 		//
1299*600f14f4SXin Li 		// Unknown
1300*600f14f4SXin Li 		//
1301*600f14f4SXin Li 
Unknown()1302*600f14f4SXin Li 		Unknown::Unknown():
1303*600f14f4SXin Li 		Prototype(FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION), /*copy=*/false)
1304*600f14f4SXin Li 		{ }
1305*600f14f4SXin Li 
~Unknown()1306*600f14f4SXin Li 		Unknown::~Unknown()
1307*600f14f4SXin Li 		{ }
1308*600f14f4SXin Li 
get_data() const1309*600f14f4SXin Li 		const FLAC__byte *Unknown::get_data() const
1310*600f14f4SXin Li 		{
1311*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1312*600f14f4SXin Li 			return object_->data.application.data;
1313*600f14f4SXin Li 		}
1314*600f14f4SXin Li 
set_data(const FLAC__byte * data,uint32_t length)1315*600f14f4SXin Li 		bool Unknown::set_data(const FLAC__byte *data, uint32_t length)
1316*600f14f4SXin Li 		{
1317*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1318*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_application_set_data(object_, const_cast<FLAC__byte*>(data), length, true));
1319*600f14f4SXin Li 		}
1320*600f14f4SXin Li 
set_data(FLAC__byte * data,uint32_t length,bool copy)1321*600f14f4SXin Li 		bool Unknown::set_data(FLAC__byte *data, uint32_t length, bool copy)
1322*600f14f4SXin Li 		{
1323*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1324*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_object_application_set_data(object_, data, length, copy));
1325*600f14f4SXin Li 		}
1326*600f14f4SXin Li 
1327*600f14f4SXin Li 
1328*600f14f4SXin Li 		// ============================================================
1329*600f14f4SXin Li 		//
1330*600f14f4SXin Li 		//  Level 0
1331*600f14f4SXin Li 		//
1332*600f14f4SXin Li 		// ============================================================
1333*600f14f4SXin Li 
get_streaminfo(const char * filename,StreamInfo & streaminfo)1334*600f14f4SXin Li 		FLACPP_API bool get_streaminfo(const char *filename, StreamInfo &streaminfo)
1335*600f14f4SXin Li 		{
1336*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1337*600f14f4SXin Li 
1338*600f14f4SXin Li 			::FLAC__StreamMetadata object;
1339*600f14f4SXin Li 
1340*600f14f4SXin Li 			if(::FLAC__metadata_get_streaminfo(filename, &object)) {
1341*600f14f4SXin Li 				streaminfo = object;
1342*600f14f4SXin Li 				return true;
1343*600f14f4SXin Li 			}
1344*600f14f4SXin Li 			else
1345*600f14f4SXin Li 				return false;
1346*600f14f4SXin Li 		}
1347*600f14f4SXin Li 
get_tags(const char * filename,VorbisComment * & tags)1348*600f14f4SXin Li 		FLACPP_API bool get_tags(const char *filename, VorbisComment *&tags)
1349*600f14f4SXin Li 		{
1350*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1351*600f14f4SXin Li 
1352*600f14f4SXin Li 			::FLAC__StreamMetadata *object;
1353*600f14f4SXin Li 
1354*600f14f4SXin Li 			tags = 0;
1355*600f14f4SXin Li 
1356*600f14f4SXin Li 			if(::FLAC__metadata_get_tags(filename, &object)) {
1357*600f14f4SXin Li 				tags = new VorbisComment(object, /*copy=*/false);
1358*600f14f4SXin Li 				return true;
1359*600f14f4SXin Li 			}
1360*600f14f4SXin Li 			else
1361*600f14f4SXin Li 				return false;
1362*600f14f4SXin Li 		}
1363*600f14f4SXin Li 
get_tags(const char * filename,VorbisComment & tags)1364*600f14f4SXin Li 		FLACPP_API bool get_tags(const char *filename, VorbisComment &tags)
1365*600f14f4SXin Li 		{
1366*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1367*600f14f4SXin Li 
1368*600f14f4SXin Li 			::FLAC__StreamMetadata *object;
1369*600f14f4SXin Li 
1370*600f14f4SXin Li 			if(::FLAC__metadata_get_tags(filename, &object)) {
1371*600f14f4SXin Li 				tags.assign(object, /*copy=*/false);
1372*600f14f4SXin Li 				return true;
1373*600f14f4SXin Li 			}
1374*600f14f4SXin Li 			else
1375*600f14f4SXin Li 				return false;
1376*600f14f4SXin Li 		}
1377*600f14f4SXin Li 
get_cuesheet(const char * filename,CueSheet * & cuesheet)1378*600f14f4SXin Li 		FLACPP_API bool get_cuesheet(const char *filename, CueSheet *&cuesheet)
1379*600f14f4SXin Li 		{
1380*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1381*600f14f4SXin Li 
1382*600f14f4SXin Li 			::FLAC__StreamMetadata *object;
1383*600f14f4SXin Li 
1384*600f14f4SXin Li 			cuesheet = 0;
1385*600f14f4SXin Li 
1386*600f14f4SXin Li 			if(::FLAC__metadata_get_cuesheet(filename, &object)) {
1387*600f14f4SXin Li 				cuesheet = new CueSheet(object, /*copy=*/false);
1388*600f14f4SXin Li 				return true;
1389*600f14f4SXin Li 			}
1390*600f14f4SXin Li 			else
1391*600f14f4SXin Li 				return false;
1392*600f14f4SXin Li 		}
1393*600f14f4SXin Li 
get_cuesheet(const char * filename,CueSheet & cuesheet)1394*600f14f4SXin Li 		FLACPP_API bool get_cuesheet(const char *filename, CueSheet &cuesheet)
1395*600f14f4SXin Li 		{
1396*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1397*600f14f4SXin Li 
1398*600f14f4SXin Li 			::FLAC__StreamMetadata *object;
1399*600f14f4SXin Li 
1400*600f14f4SXin Li 			if(::FLAC__metadata_get_cuesheet(filename, &object)) {
1401*600f14f4SXin Li 				cuesheet.assign(object, /*copy=*/false);
1402*600f14f4SXin Li 				return true;
1403*600f14f4SXin Li 			}
1404*600f14f4SXin Li 			else
1405*600f14f4SXin Li 				return false;
1406*600f14f4SXin Li 		}
1407*600f14f4SXin Li 
get_picture(const char * filename,Picture * & picture,::FLAC__StreamMetadata_Picture_Type type,const char * mime_type,const FLAC__byte * description,uint32_t max_width,uint32_t max_height,uint32_t max_depth,uint32_t max_colors)1408*600f14f4SXin Li 		FLACPP_API bool get_picture(const char *filename, Picture *&picture, ::FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, uint32_t max_width, uint32_t max_height, uint32_t max_depth, uint32_t max_colors)
1409*600f14f4SXin Li 		{
1410*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1411*600f14f4SXin Li 
1412*600f14f4SXin Li 			::FLAC__StreamMetadata *object;
1413*600f14f4SXin Li 
1414*600f14f4SXin Li 			picture = 0;
1415*600f14f4SXin Li 
1416*600f14f4SXin Li 			if(::FLAC__metadata_get_picture(filename, &object, type, mime_type, description, max_width, max_height, max_depth, max_colors)) {
1417*600f14f4SXin Li 				picture = new Picture(object, /*copy=*/false);
1418*600f14f4SXin Li 				return true;
1419*600f14f4SXin Li 			}
1420*600f14f4SXin Li 			else
1421*600f14f4SXin Li 				return false;
1422*600f14f4SXin Li 		}
1423*600f14f4SXin Li 
get_picture(const char * filename,Picture & picture,::FLAC__StreamMetadata_Picture_Type type,const char * mime_type,const FLAC__byte * description,uint32_t max_width,uint32_t max_height,uint32_t max_depth,uint32_t max_colors)1424*600f14f4SXin Li 		FLACPP_API bool get_picture(const char *filename, Picture &picture, ::FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, uint32_t max_width, uint32_t max_height, uint32_t max_depth, uint32_t max_colors)
1425*600f14f4SXin Li 		{
1426*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1427*600f14f4SXin Li 
1428*600f14f4SXin Li 			::FLAC__StreamMetadata *object;
1429*600f14f4SXin Li 
1430*600f14f4SXin Li 			if(::FLAC__metadata_get_picture(filename, &object, type, mime_type, description, max_width, max_height, max_depth, max_colors)) {
1431*600f14f4SXin Li 				picture.assign(object, /*copy=*/false);
1432*600f14f4SXin Li 				return true;
1433*600f14f4SXin Li 			}
1434*600f14f4SXin Li 			else
1435*600f14f4SXin Li 				return false;
1436*600f14f4SXin Li 		}
1437*600f14f4SXin Li 
1438*600f14f4SXin Li 
1439*600f14f4SXin Li 		// ============================================================
1440*600f14f4SXin Li 		//
1441*600f14f4SXin Li 		//  Level 1
1442*600f14f4SXin Li 		//
1443*600f14f4SXin Li 		// ============================================================
1444*600f14f4SXin Li 
SimpleIterator()1445*600f14f4SXin Li 		SimpleIterator::SimpleIterator():
1446*600f14f4SXin Li 		iterator_(::FLAC__metadata_simple_iterator_new())
1447*600f14f4SXin Li 		{ }
1448*600f14f4SXin Li 
~SimpleIterator()1449*600f14f4SXin Li 		SimpleIterator::~SimpleIterator()
1450*600f14f4SXin Li 		{
1451*600f14f4SXin Li 			clear();
1452*600f14f4SXin Li 		}
1453*600f14f4SXin Li 
clear()1454*600f14f4SXin Li 		void SimpleIterator::clear()
1455*600f14f4SXin Li 		{
1456*600f14f4SXin Li 			if(0 != iterator_)
1457*600f14f4SXin Li 				FLAC__metadata_simple_iterator_delete(iterator_);
1458*600f14f4SXin Li 			iterator_ = 0;
1459*600f14f4SXin Li 		}
1460*600f14f4SXin Li 
init(const char * filename,bool read_only,bool preserve_file_stats)1461*600f14f4SXin Li 		bool SimpleIterator::init(const char *filename, bool read_only, bool preserve_file_stats)
1462*600f14f4SXin Li 		{
1463*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1464*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1465*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_init(iterator_, filename, read_only, preserve_file_stats));
1466*600f14f4SXin Li 		}
1467*600f14f4SXin Li 
is_valid() const1468*600f14f4SXin Li 		bool SimpleIterator::is_valid() const
1469*600f14f4SXin Li 		{
1470*600f14f4SXin Li 			return 0 != iterator_;
1471*600f14f4SXin Li 		}
1472*600f14f4SXin Li 
status()1473*600f14f4SXin Li 		SimpleIterator::Status SimpleIterator::status()
1474*600f14f4SXin Li 		{
1475*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1476*600f14f4SXin Li 			return Status(::FLAC__metadata_simple_iterator_status(iterator_));
1477*600f14f4SXin Li 		}
1478*600f14f4SXin Li 
is_writable() const1479*600f14f4SXin Li 		bool SimpleIterator::is_writable() const
1480*600f14f4SXin Li 		{
1481*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1482*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_is_writable(iterator_));
1483*600f14f4SXin Li 		}
1484*600f14f4SXin Li 
next()1485*600f14f4SXin Li 		bool SimpleIterator::next()
1486*600f14f4SXin Li 		{
1487*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1488*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_next(iterator_));
1489*600f14f4SXin Li 		}
1490*600f14f4SXin Li 
prev()1491*600f14f4SXin Li 		bool SimpleIterator::prev()
1492*600f14f4SXin Li 		{
1493*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1494*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_prev(iterator_));
1495*600f14f4SXin Li 		}
1496*600f14f4SXin Li 
1497*600f14f4SXin Li 		//@@@@ add to tests
is_last() const1498*600f14f4SXin Li 		bool SimpleIterator::is_last() const
1499*600f14f4SXin Li 		{
1500*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1501*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_is_last(iterator_));
1502*600f14f4SXin Li 		}
1503*600f14f4SXin Li 
1504*600f14f4SXin Li 		//@@@@ add to tests
get_block_offset() const1505*600f14f4SXin Li 		off_t SimpleIterator::get_block_offset() const
1506*600f14f4SXin Li 		{
1507*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1508*600f14f4SXin Li 			return ::FLAC__metadata_simple_iterator_get_block_offset(iterator_);
1509*600f14f4SXin Li 		}
1510*600f14f4SXin Li 
get_block_type() const1511*600f14f4SXin Li 		::FLAC__MetadataType SimpleIterator::get_block_type() const
1512*600f14f4SXin Li 		{
1513*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1514*600f14f4SXin Li 			return ::FLAC__metadata_simple_iterator_get_block_type(iterator_);
1515*600f14f4SXin Li 		}
1516*600f14f4SXin Li 
1517*600f14f4SXin Li 		//@@@@ add to tests
get_block_length() const1518*600f14f4SXin Li 		uint32_t SimpleIterator::get_block_length() const
1519*600f14f4SXin Li 		{
1520*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1521*600f14f4SXin Li 			return ::FLAC__metadata_simple_iterator_get_block_length(iterator_);
1522*600f14f4SXin Li 		}
1523*600f14f4SXin Li 
1524*600f14f4SXin Li 		//@@@@ add to tests
get_application_id(FLAC__byte * id)1525*600f14f4SXin Li 		bool SimpleIterator::get_application_id(FLAC__byte *id)
1526*600f14f4SXin Li 		{
1527*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1528*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_get_application_id(iterator_, id));
1529*600f14f4SXin Li 		}
1530*600f14f4SXin Li 
get_block()1531*600f14f4SXin Li 		Prototype *SimpleIterator::get_block()
1532*600f14f4SXin Li 		{
1533*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1534*600f14f4SXin Li 			return local::construct_block(::FLAC__metadata_simple_iterator_get_block(iterator_));
1535*600f14f4SXin Li 		}
1536*600f14f4SXin Li 
set_block(Prototype * block,bool use_padding)1537*600f14f4SXin Li 		bool SimpleIterator::set_block(Prototype *block, bool use_padding)
1538*600f14f4SXin Li 		{
1539*600f14f4SXin Li 			FLAC__ASSERT(0 != block);
1540*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1541*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_set_block(iterator_, block->object_, use_padding));
1542*600f14f4SXin Li 		}
1543*600f14f4SXin Li 
insert_block_after(Prototype * block,bool use_padding)1544*600f14f4SXin Li 		bool SimpleIterator::insert_block_after(Prototype *block, bool use_padding)
1545*600f14f4SXin Li 		{
1546*600f14f4SXin Li 			FLAC__ASSERT(0 != block);
1547*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1548*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_insert_block_after(iterator_, block->object_, use_padding));
1549*600f14f4SXin Li 		}
1550*600f14f4SXin Li 
delete_block(bool use_padding)1551*600f14f4SXin Li 		bool SimpleIterator::delete_block(bool use_padding)
1552*600f14f4SXin Li 		{
1553*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1554*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_simple_iterator_delete_block(iterator_, use_padding));
1555*600f14f4SXin Li 		}
1556*600f14f4SXin Li 
1557*600f14f4SXin Li 
1558*600f14f4SXin Li 		// ============================================================
1559*600f14f4SXin Li 		//
1560*600f14f4SXin Li 		//  Level 2
1561*600f14f4SXin Li 		//
1562*600f14f4SXin Li 		// ============================================================
1563*600f14f4SXin Li 
Chain()1564*600f14f4SXin Li 		Chain::Chain():
1565*600f14f4SXin Li 		chain_(::FLAC__metadata_chain_new())
1566*600f14f4SXin Li 		{ }
1567*600f14f4SXin Li 
~Chain()1568*600f14f4SXin Li 		Chain::~Chain()
1569*600f14f4SXin Li 		{
1570*600f14f4SXin Li 			clear();
1571*600f14f4SXin Li 		}
1572*600f14f4SXin Li 
clear()1573*600f14f4SXin Li 		void Chain::clear()
1574*600f14f4SXin Li 		{
1575*600f14f4SXin Li 			if(0 != chain_)
1576*600f14f4SXin Li 				FLAC__metadata_chain_delete(chain_);
1577*600f14f4SXin Li 			chain_ = 0;
1578*600f14f4SXin Li 		}
1579*600f14f4SXin Li 
is_valid() const1580*600f14f4SXin Li 		bool Chain::is_valid() const
1581*600f14f4SXin Li 		{
1582*600f14f4SXin Li 			return 0 != chain_;
1583*600f14f4SXin Li 		}
1584*600f14f4SXin Li 
status()1585*600f14f4SXin Li 		Chain::Status Chain::status()
1586*600f14f4SXin Li 		{
1587*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1588*600f14f4SXin Li 			return Status(::FLAC__metadata_chain_status(chain_));
1589*600f14f4SXin Li 		}
1590*600f14f4SXin Li 
read(const char * filename,bool is_ogg)1591*600f14f4SXin Li 		bool Chain::read(const char *filename, bool is_ogg)
1592*600f14f4SXin Li 		{
1593*600f14f4SXin Li 			FLAC__ASSERT(0 != filename);
1594*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1595*600f14f4SXin Li 			return is_ogg?
1596*600f14f4SXin Li 				static_cast<bool>(::FLAC__metadata_chain_read_ogg(chain_, filename)) :
1597*600f14f4SXin Li 				static_cast<bool>(::FLAC__metadata_chain_read(chain_, filename))
1598*600f14f4SXin Li 			;
1599*600f14f4SXin Li 		}
1600*600f14f4SXin Li 
read(FLAC__IOHandle handle,::FLAC__IOCallbacks callbacks,bool is_ogg)1601*600f14f4SXin Li 		bool Chain::read(FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks, bool is_ogg)
1602*600f14f4SXin Li 		{
1603*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1604*600f14f4SXin Li 			return is_ogg?
1605*600f14f4SXin Li 				static_cast<bool>(::FLAC__metadata_chain_read_ogg_with_callbacks(chain_, handle, callbacks)) :
1606*600f14f4SXin Li 				static_cast<bool>(::FLAC__metadata_chain_read_with_callbacks(chain_, handle, callbacks))
1607*600f14f4SXin Li 			;
1608*600f14f4SXin Li 		}
1609*600f14f4SXin Li 
check_if_tempfile_needed(bool use_padding)1610*600f14f4SXin Li 		bool Chain::check_if_tempfile_needed(bool use_padding)
1611*600f14f4SXin Li 		{
1612*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1613*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_chain_check_if_tempfile_needed(chain_, use_padding));
1614*600f14f4SXin Li 		}
1615*600f14f4SXin Li 
write(bool use_padding,bool preserve_file_stats)1616*600f14f4SXin Li 		bool Chain::write(bool use_padding, bool preserve_file_stats)
1617*600f14f4SXin Li 		{
1618*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1619*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_chain_write(chain_, use_padding, preserve_file_stats));
1620*600f14f4SXin Li 		}
1621*600f14f4SXin Li 
write(bool use_padding,::FLAC__IOHandle handle,::FLAC__IOCallbacks callbacks)1622*600f14f4SXin Li 		bool Chain::write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks)
1623*600f14f4SXin Li 		{
1624*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1625*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_chain_write_with_callbacks(chain_, use_padding, handle, callbacks));
1626*600f14f4SXin Li 		}
1627*600f14f4SXin Li 
write(bool use_padding,::FLAC__IOHandle handle,::FLAC__IOCallbacks callbacks,::FLAC__IOHandle temp_handle,::FLAC__IOCallbacks temp_callbacks)1628*600f14f4SXin Li 		bool Chain::write(bool use_padding, ::FLAC__IOHandle handle, ::FLAC__IOCallbacks callbacks, ::FLAC__IOHandle temp_handle, ::FLAC__IOCallbacks temp_callbacks)
1629*600f14f4SXin Li 		{
1630*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1631*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain_, use_padding, handle, callbacks, temp_handle, temp_callbacks));
1632*600f14f4SXin Li 		}
1633*600f14f4SXin Li 
merge_padding()1634*600f14f4SXin Li 		void Chain::merge_padding()
1635*600f14f4SXin Li 		{
1636*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1637*600f14f4SXin Li 			::FLAC__metadata_chain_merge_padding(chain_);
1638*600f14f4SXin Li 		}
1639*600f14f4SXin Li 
sort_padding()1640*600f14f4SXin Li 		void Chain::sort_padding()
1641*600f14f4SXin Li 		{
1642*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1643*600f14f4SXin Li 			::FLAC__metadata_chain_sort_padding(chain_);
1644*600f14f4SXin Li 		}
1645*600f14f4SXin Li 
1646*600f14f4SXin Li 
Iterator()1647*600f14f4SXin Li 		Iterator::Iterator():
1648*600f14f4SXin Li 		iterator_(::FLAC__metadata_iterator_new())
1649*600f14f4SXin Li 		{ }
1650*600f14f4SXin Li 
~Iterator()1651*600f14f4SXin Li 		Iterator::~Iterator()
1652*600f14f4SXin Li 		{
1653*600f14f4SXin Li 			clear();
1654*600f14f4SXin Li 		}
1655*600f14f4SXin Li 
clear()1656*600f14f4SXin Li 		void Iterator::clear()
1657*600f14f4SXin Li 		{
1658*600f14f4SXin Li 			if(0 != iterator_)
1659*600f14f4SXin Li 				FLAC__metadata_iterator_delete(iterator_);
1660*600f14f4SXin Li 			iterator_ = 0;
1661*600f14f4SXin Li 		}
1662*600f14f4SXin Li 
is_valid() const1663*600f14f4SXin Li 		bool Iterator::is_valid() const
1664*600f14f4SXin Li 		{
1665*600f14f4SXin Li 			return 0 != iterator_;
1666*600f14f4SXin Li 		}
1667*600f14f4SXin Li 
init(Chain & chain)1668*600f14f4SXin Li 		void Iterator::init(Chain &chain)
1669*600f14f4SXin Li 		{
1670*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1671*600f14f4SXin Li 			FLAC__ASSERT(chain.is_valid());
1672*600f14f4SXin Li 			::FLAC__metadata_iterator_init(iterator_, chain.chain_);
1673*600f14f4SXin Li 		}
1674*600f14f4SXin Li 
next()1675*600f14f4SXin Li 		bool Iterator::next()
1676*600f14f4SXin Li 		{
1677*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1678*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_iterator_next(iterator_));
1679*600f14f4SXin Li 		}
1680*600f14f4SXin Li 
prev()1681*600f14f4SXin Li 		bool Iterator::prev()
1682*600f14f4SXin Li 		{
1683*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1684*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_iterator_prev(iterator_));
1685*600f14f4SXin Li 		}
1686*600f14f4SXin Li 
get_block_type() const1687*600f14f4SXin Li 		::FLAC__MetadataType Iterator::get_block_type() const
1688*600f14f4SXin Li 		{
1689*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1690*600f14f4SXin Li 			return ::FLAC__metadata_iterator_get_block_type(iterator_);
1691*600f14f4SXin Li 		}
1692*600f14f4SXin Li 
get_block()1693*600f14f4SXin Li 		Prototype *Iterator::get_block()
1694*600f14f4SXin Li 		{
1695*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1696*600f14f4SXin Li 			Prototype *block = local::construct_block(::FLAC__metadata_iterator_get_block(iterator_));
1697*600f14f4SXin Li 			if(0 != block)
1698*600f14f4SXin Li 				block->set_reference(true);
1699*600f14f4SXin Li 			return block;
1700*600f14f4SXin Li 		}
1701*600f14f4SXin Li 
set_block(Prototype * block)1702*600f14f4SXin Li 		bool Iterator::set_block(Prototype *block)
1703*600f14f4SXin Li 		{
1704*600f14f4SXin Li 			FLAC__ASSERT(0 != block);
1705*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1706*600f14f4SXin Li 			bool ret = static_cast<bool>(::FLAC__metadata_iterator_set_block(iterator_, block->object_));
1707*600f14f4SXin Li 			if(ret) {
1708*600f14f4SXin Li 				block->set_reference(true);
1709*600f14f4SXin Li 				delete block;
1710*600f14f4SXin Li 			}
1711*600f14f4SXin Li 			return ret;
1712*600f14f4SXin Li 		}
1713*600f14f4SXin Li 
delete_block(bool replace_with_padding)1714*600f14f4SXin Li 		bool Iterator::delete_block(bool replace_with_padding)
1715*600f14f4SXin Li 		{
1716*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1717*600f14f4SXin Li 			return static_cast<bool>(::FLAC__metadata_iterator_delete_block(iterator_, replace_with_padding));
1718*600f14f4SXin Li 		}
1719*600f14f4SXin Li 
insert_block_before(Prototype * block)1720*600f14f4SXin Li 		bool Iterator::insert_block_before(Prototype *block)
1721*600f14f4SXin Li 		{
1722*600f14f4SXin Li 			FLAC__ASSERT(0 != block);
1723*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1724*600f14f4SXin Li 			bool ret = static_cast<bool>(::FLAC__metadata_iterator_insert_block_before(iterator_, block->object_));
1725*600f14f4SXin Li 			if(ret) {
1726*600f14f4SXin Li 				block->set_reference(true);
1727*600f14f4SXin Li 				delete block;
1728*600f14f4SXin Li 			}
1729*600f14f4SXin Li 			return ret;
1730*600f14f4SXin Li 		}
1731*600f14f4SXin Li 
insert_block_after(Prototype * block)1732*600f14f4SXin Li 		bool Iterator::insert_block_after(Prototype *block)
1733*600f14f4SXin Li 		{
1734*600f14f4SXin Li 			FLAC__ASSERT(0 != block);
1735*600f14f4SXin Li 			FLAC__ASSERT(is_valid());
1736*600f14f4SXin Li 			bool ret = static_cast<bool>(::FLAC__metadata_iterator_insert_block_after(iterator_, block->object_));
1737*600f14f4SXin Li 			if(ret) {
1738*600f14f4SXin Li 				block->set_reference(true);
1739*600f14f4SXin Li 				delete block;
1740*600f14f4SXin Li 			}
1741*600f14f4SXin Li 			return ret;
1742*600f14f4SXin Li 		}
1743*600f14f4SXin Li 
1744*600f14f4SXin Li 	} // namespace Metadata
1745*600f14f4SXin Li } // namespace FLAC
1746