minor comments
[flac.git] / src / libOggFLAC / seekable_stream_decoder.c
1 /* libOggFLAC - Free Lossless Audio Codec + Ogg library
2  * Copyright (C) 2002,2003,2004  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include <stdlib.h> /* for calloc() */
33 #include "FLAC/assert.h"
34 #include "protected/seekable_stream_decoder.h"
35
36 /***********************************************************************
37  *
38  * Private class method prototypes
39  *
40  ***********************************************************************/
41
42 static void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder);
43 static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
44 static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
45 static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
46 static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
47 static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
48 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
49 static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
50 static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
51 static OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
52
53
54 /***********************************************************************
55  *
56  * Private class data
57  *
58  ***********************************************************************/
59
60 typedef struct OggFLAC__SeekableStreamDecoderPrivate {
61         OggFLAC__SeekableStreamDecoderReadCallback read_callback;
62         OggFLAC__SeekableStreamDecoderSeekCallback seek_callback;
63         OggFLAC__SeekableStreamDecoderTellCallback tell_callback;
64         OggFLAC__SeekableStreamDecoderLengthCallback length_callback;
65         OggFLAC__SeekableStreamDecoderEofCallback eof_callback;
66         OggFLAC__SeekableStreamDecoderWriteCallback write_callback;
67         OggFLAC__SeekableStreamDecoderMetadataCallback metadata_callback;
68         OggFLAC__SeekableStreamDecoderErrorCallback error_callback;
69         void *client_data;
70         FLAC__SeekableStreamDecoder *FLAC_seekable_stream_decoder;
71 } OggFLAC__SeekableStreamDecoderPrivate;
72
73 /***********************************************************************
74  *
75  * Public static class data
76  *
77  ***********************************************************************/
78
79 OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderStateString[] = {
80         "OggFLAC__SEEKABLE_STREAM_DECODER_OK",
81         "OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM",
82         "OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR",
83         "OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR",
84         "OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
85         "OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
86         "OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED",
87         "OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK",
88         "OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED"
89 };
90
91
92 /***********************************************************************
93  *
94  * Class constructor/destructor
95  *
96  ***********************************************************************/
97 OggFLAC_API OggFLAC__SeekableStreamDecoder *OggFLAC__seekable_stream_decoder_new()
98 {
99         OggFLAC__SeekableStreamDecoder *decoder;
100
101         decoder = (OggFLAC__SeekableStreamDecoder*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoder));
102         if(decoder == 0) {
103                 return 0;
104         }
105
106         decoder->protected_ = (OggFLAC__SeekableStreamDecoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoderProtected));
107         if(decoder->protected_ == 0) {
108                 free(decoder);
109                 return 0;
110         }
111
112         decoder->private_ = (OggFLAC__SeekableStreamDecoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoderPrivate));
113         if(decoder->private_ == 0) {
114                 free(decoder->protected_);
115                 free(decoder);
116                 return 0;
117         }
118
119         decoder->private_->FLAC_seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
120         if(0 == decoder->private_->FLAC_seekable_stream_decoder) {
121                 free(decoder->private_);
122                 free(decoder->protected_);
123                 free(decoder);
124                 return 0;
125         }
126
127         set_defaults_(decoder);
128
129         decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
130
131         return decoder;
132 }
133
134 OggFLAC_API void OggFLAC__seekable_stream_decoder_delete(OggFLAC__SeekableStreamDecoder *decoder)
135 {
136         FLAC__ASSERT(0 != decoder);
137         FLAC__ASSERT(0 != decoder->protected_);
138         FLAC__ASSERT(0 != decoder->private_);
139         FLAC__ASSERT(0 != decoder->private_->FLAC_seekable_stream_decoder);
140
141         OggFLAC__seekable_stream_decoder_finish(decoder);
142
143         FLAC__seekable_stream_decoder_delete(decoder->private_->FLAC_seekable_stream_decoder);
144
145         free(decoder->private_);
146         free(decoder->protected_);
147         free(decoder);
148 }
149
150 /***********************************************************************
151  *
152  * Public class methods
153  *
154  ***********************************************************************/
155
156 OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_init(OggFLAC__SeekableStreamDecoder *decoder)
157 {
158         FLAC__ASSERT(0 != decoder);
159
160         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
161                 return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED;
162
163         if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
164                 return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
165
166         if(!OggFLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
167                 return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR;
168
169         FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->FLAC_seekable_stream_decoder, read_callback_);
170         FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->FLAC_seekable_stream_decoder, seek_callback_);
171         FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->FLAC_seekable_stream_decoder, tell_callback_);
172         FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->FLAC_seekable_stream_decoder, length_callback_);
173         FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->FLAC_seekable_stream_decoder, eof_callback_);
174         FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->FLAC_seekable_stream_decoder, write_callback_);
175         FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->FLAC_seekable_stream_decoder, metadata_callback_);
176         FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->FLAC_seekable_stream_decoder, error_callback_);
177         FLAC__seekable_stream_decoder_set_client_data(decoder->private_->FLAC_seekable_stream_decoder, decoder);
178
179         if(FLAC__seekable_stream_decoder_init(decoder->private_->FLAC_seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
180                 return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
181
182         return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
183 }
184
185 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_finish(OggFLAC__SeekableStreamDecoder *decoder)
186 {
187         FLAC__bool ok;
188
189         FLAC__ASSERT(0 != decoder);
190         FLAC__ASSERT(0 != decoder->private_);
191         FLAC__ASSERT(0 != decoder->protected_);
192
193         if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
194                 return true;
195
196         FLAC__ASSERT(0 != decoder->private_->FLAC_seekable_stream_decoder);
197
198         ok = FLAC__seekable_stream_decoder_finish(decoder->private_->FLAC_seekable_stream_decoder);
199
200         OggFLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
201
202         set_defaults_(decoder);
203
204         decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
205
206         return ok;
207 }
208
209 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_md5_checking(OggFLAC__SeekableStreamDecoder *decoder, FLAC__bool value)
210 {
211         FLAC__ASSERT(0 != decoder);
212         FLAC__ASSERT(0 != decoder->private_);
213         FLAC__ASSERT(0 != decoder->protected_);
214         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
215                 return false;
216         return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->FLAC_seekable_stream_decoder, value);
217 }
218
219 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_read_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderReadCallback value)
220 {
221         FLAC__ASSERT(0 != decoder);
222         FLAC__ASSERT(0 != decoder->private_);
223         FLAC__ASSERT(0 != decoder->protected_);
224         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
225                 return false;
226         decoder->private_->read_callback = value;
227         return true;
228 }
229
230 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_seek_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderSeekCallback value)
231 {
232         FLAC__ASSERT(0 != decoder);
233         FLAC__ASSERT(0 != decoder->private_);
234         FLAC__ASSERT(0 != decoder->protected_);
235         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
236                 return false;
237         decoder->private_->seek_callback = value;
238         return true;
239 }
240
241 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_tell_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderTellCallback value)
242 {
243         FLAC__ASSERT(0 != decoder);
244         FLAC__ASSERT(0 != decoder->private_);
245         FLAC__ASSERT(0 != decoder->protected_);
246         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
247                 return false;
248         decoder->private_->tell_callback = value;
249         return true;
250 }
251
252 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_length_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderLengthCallback value)
253 {
254         FLAC__ASSERT(0 != decoder);
255         FLAC__ASSERT(0 != decoder->private_);
256         FLAC__ASSERT(0 != decoder->protected_);
257         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
258                 return false;
259         decoder->private_->length_callback = value;
260         return true;
261 }
262
263 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_eof_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderEofCallback value)
264 {
265         FLAC__ASSERT(0 != decoder);
266         FLAC__ASSERT(0 != decoder->private_);
267         FLAC__ASSERT(0 != decoder->protected_);
268         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
269                 return false;
270         decoder->private_->eof_callback = value;
271         return true;
272 }
273
274 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_write_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderWriteCallback value)
275 {
276         FLAC__ASSERT(0 != decoder);
277         FLAC__ASSERT(0 != decoder->private_);
278         FLAC__ASSERT(0 != decoder->protected_);
279         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
280                 return false;
281         decoder->private_->write_callback = value;
282         return true;
283 }
284
285 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderMetadataCallback value)
286 {
287         FLAC__ASSERT(0 != decoder);
288         FLAC__ASSERT(0 != decoder->private_);
289         FLAC__ASSERT(0 != decoder->protected_);
290         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
291                 return false;
292         decoder->private_->metadata_callback = value;
293         return true;
294 }
295
296 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_error_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderErrorCallback value)
297 {
298         FLAC__ASSERT(0 != decoder);
299         FLAC__ASSERT(0 != decoder->private_);
300         FLAC__ASSERT(0 != decoder->protected_);
301         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
302                 return false;
303         decoder->private_->error_callback = value;
304         return true;
305 }
306
307 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_client_data(OggFLAC__SeekableStreamDecoder *decoder, void *value)
308 {
309         FLAC__ASSERT(0 != decoder);
310         FLAC__ASSERT(0 != decoder->private_);
311         FLAC__ASSERT(0 != decoder->protected_);
312         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
313                 return false;
314         decoder->private_->client_data = value;
315         return true;
316 }
317
318 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_serial_number(OggFLAC__SeekableStreamDecoder *decoder, long value)
319 {
320         FLAC__ASSERT(0 != decoder);
321         FLAC__ASSERT(0 != decoder->private_);
322         FLAC__ASSERT(0 != decoder->protected_);
323         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
324                 return false;
325         OggFLAC__ogg_decoder_aspect_set_serial_number(&decoder->protected_->ogg_decoder_aspect, value);
326         return true;
327 }
328
329 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond(OggFLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
330 {
331         FLAC__ASSERT(0 != decoder);
332         FLAC__ASSERT(0 != decoder->private_);
333         FLAC__ASSERT(0 != decoder->protected_);
334         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
335                 return false;
336         return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->FLAC_seekable_stream_decoder, type);
337 }
338
339 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
340 {
341         FLAC__ASSERT(0 != decoder);
342         FLAC__ASSERT(0 != decoder->private_);
343         FLAC__ASSERT(0 != decoder->protected_);
344         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
345                 return false;
346         return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_seekable_stream_decoder, id);
347 }
348
349 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_all(OggFLAC__SeekableStreamDecoder *decoder)
350 {
351         FLAC__ASSERT(0 != decoder);
352         FLAC__ASSERT(0 != decoder->private_);
353         FLAC__ASSERT(0 != decoder->protected_);
354         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
355                 return false;
356         return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_seekable_stream_decoder);
357 }
358
359 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore(OggFLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
360 {
361         FLAC__ASSERT(0 != decoder);
362         FLAC__ASSERT(0 != decoder->private_);
363         FLAC__ASSERT(0 != decoder->protected_);
364         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
365                 return false;
366         return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->FLAC_seekable_stream_decoder, type);
367 }
368
369 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
370 {
371         FLAC__ASSERT(0 != decoder);
372         FLAC__ASSERT(0 != decoder->private_);
373         FLAC__ASSERT(0 != decoder->protected_);
374         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
375                 return false;
376         return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_seekable_stream_decoder, id);
377 }
378
379 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(OggFLAC__SeekableStreamDecoder *decoder)
380 {
381         FLAC__ASSERT(0 != decoder);
382         FLAC__ASSERT(0 != decoder->private_);
383         FLAC__ASSERT(0 != decoder->protected_);
384         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
385                 return false;
386         return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_seekable_stream_decoder);
387 }
388
389 OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_state(const OggFLAC__SeekableStreamDecoder *decoder)
390 {
391         FLAC__ASSERT(0 != decoder);
392         FLAC__ASSERT(0 != decoder->protected_);
393         return decoder->protected_->state;
394 }
395
396 OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
397 {
398         FLAC__ASSERT(0 != decoder);
399         FLAC__ASSERT(0 != decoder->private_);
400         return FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder);
401 }
402
403 OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
404 {
405         FLAC__ASSERT(0 != decoder);
406         FLAC__ASSERT(0 != decoder->private_);
407         return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->FLAC_seekable_stream_decoder);
408 }
409
410 OggFLAC_API const char *OggFLAC__seekable_stream_decoder_get_resolved_state_string(const OggFLAC__SeekableStreamDecoder *decoder)
411 {
412         if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR)
413                 return OggFLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
414         else
415                 return FLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->FLAC_seekable_stream_decoder);
416 }
417
418 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_md5_checking(const OggFLAC__SeekableStreamDecoder *decoder)
419 {
420         FLAC__ASSERT(0 != decoder);
421         FLAC__ASSERT(0 != decoder->private_);
422         return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->FLAC_seekable_stream_decoder);
423 }
424
425 OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_channels(const OggFLAC__SeekableStreamDecoder *decoder)
426 {
427         FLAC__ASSERT(0 != decoder);
428         FLAC__ASSERT(0 != decoder->private_);
429         return FLAC__seekable_stream_decoder_get_channels(decoder->private_->FLAC_seekable_stream_decoder);
430 }
431
432 OggFLAC_API FLAC__ChannelAssignment OggFLAC__seekable_stream_decoder_get_channel_assignment(const OggFLAC__SeekableStreamDecoder *decoder)
433 {
434         FLAC__ASSERT(0 != decoder);
435         FLAC__ASSERT(0 != decoder->private_);
436         return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->FLAC_seekable_stream_decoder);
437 }
438
439 OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_bits_per_sample(const OggFLAC__SeekableStreamDecoder *decoder)
440 {
441         FLAC__ASSERT(0 != decoder);
442         FLAC__ASSERT(0 != decoder->private_);
443         return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->FLAC_seekable_stream_decoder);
444 }
445
446 OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_sample_rate(const OggFLAC__SeekableStreamDecoder *decoder)
447 {
448         FLAC__ASSERT(0 != decoder);
449         FLAC__ASSERT(0 != decoder->private_);
450         return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->FLAC_seekable_stream_decoder);
451 }
452
453 OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_blocksize(const OggFLAC__SeekableStreamDecoder *decoder)
454 {
455         FLAC__ASSERT(0 != decoder);
456         FLAC__ASSERT(0 != decoder->private_);
457         return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->FLAC_seekable_stream_decoder);
458 }
459
460 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_decode_position(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position)
461 {
462         FLAC__ASSERT(0 != decoder);
463         FLAC__ASSERT(0 != decoder->private_);
464         return FLAC__seekable_stream_decoder_get_decode_position(decoder->private_->FLAC_seekable_stream_decoder, position);
465 }
466
467 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_flush(OggFLAC__SeekableStreamDecoder *decoder)
468 {
469         FLAC__ASSERT(0 != decoder);
470         FLAC__ASSERT(0 != decoder->private_);
471         FLAC__ASSERT(0 != decoder->protected_);
472
473         OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
474
475         if(!FLAC__seekable_stream_decoder_flush(decoder->private_->FLAC_seekable_stream_decoder)) {
476                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
477                 return false;
478         }
479
480         decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
481
482         return true;
483 }
484
485 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_reset(OggFLAC__SeekableStreamDecoder *decoder)
486 {
487         FLAC__ASSERT(0 != decoder);
488         FLAC__ASSERT(0 != decoder->private_);
489         FLAC__ASSERT(0 != decoder->protected_);
490
491         if(!OggFLAC__seekable_stream_decoder_flush(decoder)) {
492                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
493                 return false;
494         }
495
496         if(!FLAC__seekable_stream_decoder_reset(decoder->private_->FLAC_seekable_stream_decoder)) {
497                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
498                 return false;
499         }
500
501         decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
502
503         return true;
504 }
505
506 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_single(OggFLAC__SeekableStreamDecoder *decoder)
507 {
508         FLAC__bool ret;
509         FLAC__ASSERT(0 != decoder);
510
511         if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
512                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
513
514         if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
515                 return true;
516
517         FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
518
519         ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->FLAC_seekable_stream_decoder);
520         if(!ret)
521                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
522
523         return ret;
524 }
525
526 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(OggFLAC__SeekableStreamDecoder *decoder)
527 {
528         FLAC__bool ret;
529         FLAC__ASSERT(0 != decoder);
530
531         if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
532                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
533
534         if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
535                 return true;
536
537         FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
538
539         ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_seekable_stream_decoder);
540         if(!ret)
541                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
542
543         return ret;
544 }
545
546 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_stream(OggFLAC__SeekableStreamDecoder *decoder)
547 {
548         FLAC__bool ret;
549         FLAC__ASSERT(0 != decoder);
550
551         if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
552                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
553
554         if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
555                 return true;
556
557         FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
558
559         ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_seekable_stream_decoder);
560         if(!ret)
561                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
562
563         return ret;
564 }
565
566 OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_seek_absolute(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample)
567 {
568         FLAC__ASSERT(0 != decoder);
569         FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM);
570
571         if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->FLAC_seekable_stream_decoder, sample)) {
572                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
573                 return false;
574         }
575         else {
576                 decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
577                 return true;
578         }
579 }
580
581
582 /***********************************************************************
583  *
584  * Private class methods
585  *
586  ***********************************************************************/
587
588 void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder)
589 {
590         decoder->private_->read_callback = 0;
591         decoder->private_->seek_callback = 0;
592         decoder->private_->tell_callback = 0;
593         decoder->private_->length_callback = 0;
594         decoder->private_->eof_callback = 0;
595         decoder->private_->write_callback = 0;
596         decoder->private_->metadata_callback = 0;
597         decoder->private_->error_callback = 0;
598         decoder->private_->client_data = 0;
599         OggFLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
600 }
601
602 FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
603 {
604         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
605
606         (void)unused;
607
608         switch(OggFLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
609                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
610                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
611                 /* we don't really have a way to handle lost sync via read
612                  * callback so we'll let it pass and let the underlying
613                  * FLAC decoder catch the error
614                  */
615                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
616                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
617                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
618                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
619                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
620                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
621                         decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
622                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
623                 case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
624                         decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
625                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
626                 default:
627                         FLAC__ASSERT(0);
628                         /* double protection */
629                         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
630         }
631 }
632
633 FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 absolute_byte_offset, void *client_data)
634 {
635         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
636         (void)unused;
637
638         /* need to flush the Ogg state */
639         OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
640
641         return decoder->private_->seek_callback(decoder, absolute_byte_offset, decoder->private_->client_data);
642 }
643
644 FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 *absolute_byte_offset, void *client_data)
645 {
646         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
647         (void)unused;
648         return decoder->private_->tell_callback(decoder, absolute_byte_offset, decoder->private_->client_data);
649 }
650
651 FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 *stream_length, void *client_data)
652 {
653         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
654         (void)unused;
655         return decoder->private_->length_callback(decoder, stream_length, decoder->private_->client_data);
656 }
657
658 FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *unused, void *client_data)
659 {
660         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
661         (void)unused;
662         return decoder->private_->eof_callback(decoder, decoder->private_->client_data);
663 }
664
665 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
666 {
667         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
668         (void)unused;
669         return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
670 }
671
672 void metadata_callback_(const FLAC__SeekableStreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
673 {
674         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
675         (void)unused;
676         decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
677 }
678
679 void error_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
680 {
681         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
682         (void)unused;
683         decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
684 }
685
686 OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
687 {
688         OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)void_decoder;
689
690         switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
691                 case FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK:
692                         if (*bytes == 0)
693                                 return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
694                         else
695                                 return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
696                 case FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR:
697                         return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
698                 default:
699                         /* double protection: */
700                         FLAC__ASSERT(0);
701                         return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
702         }
703 }