Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1905 serge 1
/* TODO: Check all read calls (in loops, especially!) for return value 0 (EOF)! */
2
 
3
/*
4
	readers.c: reading input data
5
 
6
	copyright ?-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
7
	see COPYING and AUTHORS files in distribution or http://mpg123.org
8
	initially written by Michael Hipp
9
*/
10
 
11
#include "mpg123lib_intern.h"
12
#include 
13
#include 
14
#include 
15
/* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */
16
/* Including these here although it works without on my Linux install... curious about _why_. */
17
#ifdef HAVE_SYS_SELECT_H
18
#include 
19
#endif
20
#ifdef HAVE_SYS_TIME_H
21
#include 
22
#endif
23
#ifdef HAVE_SYS_TYPES_H
24
#include 
25
#endif
26
#ifdef HAVE_UNISTD_H
27
#include 
28
#endif
29
#ifdef _MSC_VER
30
#include 
31
#endif
32
 
33
#include "debug.h"
34
 
35
static int default_init(mpg123_handle *fr);
36
static off_t get_fileinfo(mpg123_handle *);
37
static ssize_t posix_read(int fd, void *buf, size_t count){ return read(fd, buf, count); }
38
static off_t   posix_lseek(int fd, off_t offset, int whence){ return lseek(fd, offset, whence); }
39
 
40
static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t count);
41
 
42
#ifndef NO_FEEDER
43
/* Bufferchain methods. */
44
static void bc_init(struct bufferchain *bc);
45
static void bc_reset(struct bufferchain *bc);
46
static int bc_append(struct bufferchain *bc, ssize_t size);
47
#if 0
48
static void bc_drop(struct bufferchain *bc);
49
#endif
50
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size);
51
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size);
52
static ssize_t bc_skip(struct bufferchain *bc, ssize_t count);
53
static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count);
54
static void bc_forget(struct bufferchain *bc);
55
#else
56
#define bc_init(a)
57
#define bc_reset(a)
58
#endif
59
 
60
/* A normal read and a read with timeout. */
61
static ssize_t plain_read(mpg123_handle *fr, void *buf, size_t count)
62
{
63
	ssize_t ret = fr->rdat.read(fr->rdat.filept, buf, count);
64
	if(VERBOSE3) debug2("read %li bytes of %li", (long)ret, (long)count);
65
	return ret;
66
}
67
 
68
#ifndef NO_ICY
69
/* stream based operation  with icy meta data*/
70
static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
71
{
72
	ssize_t ret,cnt;
73
	cnt = 0;
74
	if(fr->rdat.flags & READER_SEEKABLE)
75
	{
76
		if(NOQUIET) error("mpg123 programmer error: I don't do ICY on seekable streams.");
77
		return -1;
78
	}
79
	/*
80
		There used to be a check for expected file end here (length value or ID3 flag).
81
		This is not needed:
82
		1. EOF is indicated by fdread returning zero bytes anyway.
83
		2. We get false positives of EOF for either files that grew or
84
		3. ... files that have ID3v1 tags in between (stream with intro).
85
	*/
86
 
87
	while(cnt < count)
88
	{
89
		/* all icy code is inside this if block, everything else is the plain fullread we know */
90
		/* debug1("read: %li left", (long) count-cnt); */
91
		if(fr->icy.next < count-cnt)
92
		{
93
			unsigned char temp_buff;
94
			size_t meta_size;
95
			ssize_t cut_pos;
96
 
97
			/* we are near icy-metaint boundary, read up to the boundary */
98
			if(fr->icy.next > 0)
99
			{
100
				cut_pos = fr->icy.next;
101
				ret = fr->rdat.fdread(fr,buf,cut_pos);
102
				if(ret < 1)
103
				{
104
					if(ret == 0) break; /* Just EOF. */
105
					if(NOQUIET) error("icy boundary read");
106
 
107
					return READER_ERROR;
108
				}
109
				fr->rdat.filepos += ret;
110
				cnt += ret;
111
				fr->icy.next -= ret;
112
				if(fr->icy.next > 0)
113
				{
114
					debug1("another try... still %li left", (long)fr->icy.next);
115
					continue;
116
				}
117
			}
118
			/* now off to read icy data */
119
 
120
			/* one byte icy-meta size (must be multiplied by 16 to get icy-meta length) */
121
 
122
			ret = fr->rdat.fdread(fr,&temp_buff,1); /* Getting one single byte hast to suceed. */
123
			if(ret < 0){ if(NOQUIET) error("reading icy size"); return READER_ERROR; }
124
			if(ret == 0) break;
125
 
126
			debug2("got meta-size byte: %u, at filepos %li", temp_buff, (long)fr->rdat.filepos );
127
			if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret; /* 1... */
128
 
129
			if((meta_size = ((size_t) temp_buff) * 16))
130
			{
131
				/* we have got some metadata */
132
				char *meta_buff;
133
				meta_buff = malloc(meta_size+1);
134
				if(meta_buff != NULL)
135
				{
136
					ssize_t left = meta_size;
137
					while(left > 0)
138
					{
139
						ret = fr->rdat.fdread(fr,meta_buff+meta_size-left,left);
140
						/* 0 is error here, too... there _must_ be the ICY data, the server promised! */
141
						if(ret < 1){ if(NOQUIET) error("reading icy-meta"); return READER_ERROR; }
142
						left -= ret;
143
					}
144
					meta_buff[meta_size] = 0; /* string paranoia */
145
					if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
146
 
147
					if(fr->icy.data) free(fr->icy.data);
148
					fr->icy.data = meta_buff;
149
					fr->metaflags |= MPG123_NEW_ICY;
150
					debug2("icy-meta: %s size: %d bytes", fr->icy.data, (int)meta_size);
151
				}
152
				else
153
				{
154
					if(NOQUIET) error1("cannot allocate memory for meta_buff (%lu bytes) ... trying to skip the metadata!", (unsigned long)meta_size);
155
					fr->rd->skip_bytes(fr, meta_size);
156
				}
157
			}
158
			fr->icy.next = fr->icy.interval;
159
		}
160
 
161
		ret = plain_fullread(fr, buf+cnt, count-cnt);
162
		if(ret < 0){ if(NOQUIET) error1("reading the rest of %li", (long)(count-cnt)); return READER_ERROR; }
163
		if(ret == 0) break;
164
 
165
		cnt += ret;
166
		fr->icy.next -= ret;
167
	}
168
	/* debug1("done reading, got %li", (long)cnt); */
169
	return cnt;
170
}
171
#else
172
#define icy_fullread NULL
173
#endif /* NO_ICY */
174
 
175
/* stream based operation */
176
static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t count)
177
{
178
	ssize_t ret,cnt=0;
179
 
180
	/*
181
		There used to be a check for expected file end here (length value or ID3 flag).
182
		This is not needed:
183
		1. EOF is indicated by fdread returning zero bytes anyway.
184
		2. We get false positives of EOF for either files that grew or
185
		3. ... files that have ID3v1 tags in between (stream with intro).
186
	*/
187
	while(cnt < count)
188
	{
189
		ret = fr->rdat.fdread(fr,buf+cnt,count-cnt);
190
		if(ret < 0) return READER_ERROR;
191
		if(ret == 0) break;
192
		if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
193
		cnt += ret;
194
	}
195
	return cnt;
196
}
197
 
198
static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
199
{
200
	off_t ret;
201
	ret = fr->rdat.lseek(fr->rdat.filept, pos, whence);
202
	if (ret >= 0)	fr->rdat.filepos = ret;
203
	else
204
	{
205
		fr->err = MPG123_LSEEK_FAILED;
206
		ret = READER_ERROR; /* not the original value */
207
	}
208
	return ret;
209
}
210
 
211
static void stream_close(mpg123_handle *fr)
212
{
213
	if(fr->rdat.flags & READER_FD_OPENED) close(fr->rdat.filept);
214
	if(fr->rdat.flags & READER_BUFFERED)  bc_reset(&fr->rdat.buffer);
215
}
216
 
217
static int stream_seek_frame(mpg123_handle *fr, off_t newframe)
218
{
219
	debug2("seek_frame to %"OFF_P" (from %"OFF_P")", (off_p)newframe, (off_p)fr->num);
220
	/* Seekable streams can go backwards and jump forwards.
221
	   Non-seekable streams still can go forward, just not jump. */
222
	if((fr->rdat.flags & READER_SEEKABLE) || (newframe >= fr->num))
223
	{
224
		off_t preframe; /* a leading frame we jump to */
225
		off_t seek_to;  /* the byte offset we want to reach */
226
		off_t to_skip;  /* bytes to skip to get there (can be negative) */
227
		/*
228
			now seek to nearest leading index position and read from there until newframe is reached.
229
			We use skip_bytes, which handles seekable and non-seekable streams
230
			(the latter only for positive offset, which we ensured before entering here).
231
		*/
232
		seek_to = frame_index_find(fr, newframe, &preframe);
233
		/* No need to seek to index position if we are closer already.
234
		   But I am picky about fr->num == newframe, play safe by reading the frame again.
235
		   If you think that's stupid, don't call a seek to the current frame. */
236
		if(fr->num >= newframe || fr->num < preframe)
237
		{
238
			to_skip = seek_to - fr->rd->tell(fr);
239
			if(fr->rd->skip_bytes(fr, to_skip) != seek_to)
240
			return READER_ERROR;
241
 
242
			debug2("going to %lu; just got %lu", (long unsigned)newframe, (long unsigned)preframe);
243
			fr->num = preframe-1; /* Watch out! I am going to read preframe... fr->num should indicate the frame before! */
244
		}
245
		while(fr->num < newframe)
246
		{
247
			/* try to be non-fatal now... frameNum only gets advanced on success anyway */
248
			if(!read_frame(fr)) break;
249
		}
250
		/* Now the wanted frame should be ready for decoding. */
251
		debug1("arrived at %lu", (long unsigned)fr->num);
252
 
253
		return MPG123_OK;
254
	}
255
	else
256
	{
257
		fr->err = MPG123_NO_SEEK;
258
		return READER_ERROR; /* invalid, no seek happened */
259
	}
260
}
261
 
262
/* return FALSE on error, TRUE on success, READER_MORE on occasion */
263
static int generic_head_read(mpg123_handle *fr,unsigned long *newhead)
264
{
265
	unsigned char hbuf[4];
266
	int ret = fr->rd->fullread(fr,hbuf,4);
267
	if(ret == READER_MORE) return ret;
268
	if(ret != 4) return FALSE;
269
 
270
	*newhead = ((unsigned long) hbuf[0] << 24) |
271
	           ((unsigned long) hbuf[1] << 16) |
272
	           ((unsigned long) hbuf[2] << 8)  |
273
	            (unsigned long) hbuf[3];
274
 
275
	return TRUE;
276
}
277
 
278
/* return FALSE on error, TRUE on success, READER_MORE on occasion */
279
static int generic_head_shift(mpg123_handle *fr,unsigned long *head)
280
{
281
	unsigned char hbuf;
282
	int ret = fr->rd->fullread(fr,&hbuf,1);
283
	if(ret == READER_MORE) return ret;
284
	if(ret != 1) return FALSE;
285
 
286
	*head <<= 8;
287
	*head |= hbuf;
288
	*head &= 0xffffffff;
289
	return TRUE;
290
}
291
 
292
/* returns reached position... negative ones are bad... */
293
static off_t stream_skip_bytes(mpg123_handle *fr,off_t len)
294
{
295
	if(fr->rdat.flags & READER_SEEKABLE)
296
	{
297
		off_t ret = stream_lseek(fr, len, SEEK_CUR);
298
		return (ret < 0) ? READER_ERROR : ret;
299
	}
300
	else if(len >= 0)
301
	{
302
		unsigned char buf[1024]; /* ThOr: Compaq cxx complained and it makes sense to me... or should one do a cast? What for? */
303
		ssize_t ret;
304
		while (len > 0)
305
		{
306
			ssize_t num = len < (off_t)sizeof(buf) ? (ssize_t)len : (ssize_t)sizeof(buf);
307
			ret = fr->rd->fullread(fr, buf, num);
308
			if (ret < 0) return ret;
309
			else if(ret == 0) break; /* EOF... an error? interface defined to tell the actual position... */
310
			len -= ret;
311
		}
312
		return fr->rd->tell(fr);
313
	}
314
	else if(fr->rdat.flags & READER_BUFFERED)
315
	{ /* Perhaps we _can_ go a bit back. */
316
		if(fr->rdat.buffer.pos >= -len)
317
		{
318
			fr->rdat.buffer.pos += len;
319
			return fr->rd->tell(fr);
320
		}
321
		else
322
		{
323
			fr->err = MPG123_NO_SEEK;
324
			return READER_ERROR;
325
		}
326
	}
327
	else
328
	{
329
		fr->err = MPG123_NO_SEEK;
330
		return READER_ERROR;
331
	}
332
}
333
 
334
/* Return 0 on success... */
335
static int stream_back_bytes(mpg123_handle *fr, off_t bytes)
336
{
337
	off_t want = fr->rd->tell(fr)-bytes;
338
	if(want < 0) return READER_ERROR;
339
	if(stream_skip_bytes(fr,-bytes) != want) return READER_ERROR;
340
 
341
	return 0;
342
}
343
 
344
 
345
/* returns size on success... */
346
static int generic_read_frame_body(mpg123_handle *fr,unsigned char *buf, int size)
347
{
348
	long l;
349
 
350
	if((l=fr->rd->fullread(fr,buf,size)) != size)
351
	{
352
		long ll = l;
353
		if(ll <= 0) ll = 0;
354
 
355
		/* This allows partial frames at the end... do we really want to pad and decode these?! */
356
		memset(buf+ll,0,size-ll);
357
	}
358
	return l;
359
}
360
 
361
static off_t generic_tell(mpg123_handle *fr)
362
{
363
	if(fr->rdat.flags & READER_BUFFERED)
364
	fr->rdat.filepos = fr->rdat.buffer.fileoff+fr->rdat.buffer.pos;
365
 
366
	return fr->rdat.filepos;
367
}
368
 
369
/* This does not (fully) work for non-seekable streams... You have to check for that flag, pal! */
370
static void stream_rewind(mpg123_handle *fr)
371
{
372
	if(fr->rdat.flags & READER_SEEKABLE)
373
	fr->rdat.buffer.fileoff = fr->rdat.filepos = stream_lseek(fr,0,SEEK_SET);
374
	if(fr->rdat.flags & READER_BUFFERED)
375
	{
376
		fr->rdat.buffer.pos      = 0;
377
		fr->rdat.buffer.firstpos = 0;
378
		fr->rdat.filepos = fr->rdat.buffer.fileoff;
379
	}
380
}
381
 
382
/*
383
 * returns length of a file (if filept points to a file)
384
 * reads the last 128 bytes information into buffer
385
 * ... that is not totally safe...
386
 */
387
 
388
static off_t get_fileinfo(mpg123_handle *fr)
389
{
390
	off_t len;
391
 
392
	if((len=fr->rdat.lseek(fr->rdat.filept,0,SEEK_END)) < 0)	return -1;
393
 
394
	if(fr->rdat.lseek(fr->rdat.filept,-128,SEEK_END) < 0) return -1;
395
 
396
	if(fr->rd->fullread(fr,(unsigned char *)fr->id3buf,128) != 128)	return -1;
397
 
398
	if(!strncmp((char*)fr->id3buf,"TAG",3))	len -= 128;
399
 
400
	if(fr->rdat.lseek(fr->rdat.filept,0,SEEK_SET) < 0)	return -1;
401
 
402
	if(len <= 0)	return -1;
403
 
404
	return len;
405
}
406
 
407
#ifndef NO_FEEDER
408
/* Methods for the buffer chain, mainly used for feed reader, but not just that. */
409
 
410
static void bc_init(struct bufferchain *bc)
411
{
412
	bc->first = NULL;
413
	bc->last  = bc->first;
414
	bc->size  = 0;
415
	bc->pos   = 0;
416
	bc->firstpos = 0;
417
	bc->fileoff  = 0;
418
}
419
 
420
static void bc_reset(struct bufferchain *bc)
421
{
422
	/* free the buffer chain */
423
	struct buffy *b = bc->first;
424
	while(b != NULL)
425
	{
426
		struct buffy *n = b->next;
427
		free(b->data);
428
		free(b);
429
		b = n;
430
	}
431
	bc_init(bc);
432
}
433
 
434
/* Create a new buffy at the end to be filled. */
435
static int bc_append(struct bufferchain *bc, ssize_t size)
436
{
437
	struct buffy *newbuf;
438
	if(size < 1) return -1;
439
 
440
	newbuf = malloc(sizeof(struct buffy));
441
	if(newbuf == NULL) return -2;
442
 
443
	newbuf->data = malloc(size);
444
	if(newbuf->data == NULL)
445
	{
446
		free(newbuf);
447
		return -3;
448
	}
449
	newbuf->size = size;
450
	newbuf->next = NULL;
451
	if(bc->last != NULL)  bc->last->next = newbuf;
452
	else if(bc->first == NULL) bc->first = newbuf;
453
 
454
	bc->last  = newbuf;
455
	bc->size += size;
456
	return 0;
457
}
458
 
459
 
460
/* Append a new buffer and copy content to it. */
461
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
462
{
463
	int ret = 0;
464
	if((ret = bc_append(bc, size)) == 0)
465
	memcpy(bc->last->data, data, size);
466
 
467
	return ret;
468
}
469
 
470
/* Give some data, advancing position but not forgetting yet. */
471
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
472
{
473
	struct buffy *b = bc->first;
474
	ssize_t gotcount = 0;
475
	ssize_t offset = 0;
476
	if(bc->size - bc->pos < size)
477
	{
478
		debug3("hit end, back to beginning (%li - %li < %li)", (long)bc->size, (long)bc->pos, (long)size);
479
		/* go back to firstpos, undo the previous reads */
480
		bc->pos = bc->firstpos;
481
		return READER_MORE;
482
	}
483
	/* find the current buffer */
484
	while(b != NULL && (offset + b->size) <= bc->pos)
485
	{
486
		offset += b->size;
487
		b = b->next;
488
	}
489
	/* now start copying from there */
490
	while(gotcount < size && (b != NULL))
491
	{
492
		ssize_t loff = bc->pos - offset;
493
		ssize_t chunk = size - gotcount; /* amount of bytes to get from here... */
494
		if(chunk > b->size - loff) chunk = b->size - loff;
495
 
496
#ifdef EXTRA_DEBUG
497
		debug3("copying %liB from %p+%li",(long)chunk, b->data, (long)loff); */
498
#endif
499
 
500
		memcpy(out+gotcount, b->data+loff, chunk);
501
		gotcount += chunk;
502
		bc->pos  += chunk;
503
		offset += b->size;
504
		b = b->next;
505
	}
506
#ifdef EXTRA_DEBUG
507
	debug2("got %li bytes, pos advanced to %li", (long)gotcount, (long)bc->pos);
508
#endif
509
 
510
	return gotcount;
511
}
512
 
513
/* Skip some bytes and return the new position.
514
   The buffers are still there, just the read pointer is moved! */
515
static ssize_t bc_skip(struct bufferchain *bc, ssize_t count)
516
{
517
	if(count >= 0)
518
	{
519
		if(bc->size - bc->pos < count) return READER_MORE;
520
		else return bc->pos += count;
521
	}
522
	else return READER_ERROR;
523
}
524
 
525
static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count)
526
{
527
	if(count >= 0 && count <= bc->pos) return bc->pos -= count;
528
	else return READER_ERROR;
529
}
530
 
531
/* Throw away buffies that we passed. */
532
static void bc_forget(struct bufferchain *bc)
533
{
534
	struct buffy *b = bc->first;
535
	/* free all buffers that are def'n'tly outdated */
536
	/* we have buffers until filepos... delete all buffers fully below it */
537
#ifdef EXTRA_DEBUG
538
	if(b) debug2("bc_forget: block %lu pos %lu", (unsigned long)b->size, (unsigned long)bc->pos);
539
	else debug("forget with nothing there!");
540
#endif
541
	while(b != NULL && bc->pos >= b->size)
542
	{
543
		struct buffy *n = b->next; /* != NULL or this is indeed the end and the last cycle anyway */
544
		if(n == NULL) bc->last = NULL; /* Going to delete the last buffy... */
545
		bc->fileoff += b->size;
546
		bc->pos  -= b->size;
547
		bc->size -= b->size;
548
#ifdef EXTRA_DEBUG
549
		debug5("bc_forget: forgot %p with %lu, pos=%li, size=%li, fileoff=%li", (void*)b->data, (long)b->size, (long)bc->pos,  (long)bc->size, (long)bc->fileoff);
550
#endif
551
		free(b->data);
552
		free(b);
553
		b = n;
554
	}
555
	bc->first = b;
556
	bc->firstpos = bc->pos;
557
}
558
 
559
/* reader for input via manually provided buffers */
560
 
561
static int feed_init(mpg123_handle *fr)
562
{
563
	bc_init(&fr->rdat.buffer);
564
	fr->rdat.filelen = 0;
565
	fr->rdat.filepos = 0;
566
	fr->rdat.flags |= READER_BUFFERED;
567
	return 0;
568
}
569
 
570
/* externally called function, returns 0 on success, -1 on error */
571
int feed_more(mpg123_handle *fr, const unsigned char *in, long count)
572
{
573
	int ret = 0;
574
	if(VERBOSE3) debug("feed_more");
575
	if((ret = bc_add(&fr->rdat.buffer, in, count)) != 0)
576
	{
577
		ret = READER_ERROR;
578
		if(NOQUIET) error1("Failed to add buffer, return: %i", ret);
579
	}
580
	else /* Not talking about filelen... that stays at 0. */
581
 
582
	if(VERBOSE3) debug3("feed_more: %p %luB bufsize=%lu", fr->rdat.buffer.last->data,
583
		(unsigned long)fr->rdat.buffer.last->size, (unsigned long)fr->rdat.buffer.size);
584
	return ret;
585
}
586
 
587
static ssize_t feed_read(mpg123_handle *fr, unsigned char *out, ssize_t count)
588
{
589
	ssize_t gotcount = bc_give(&fr->rdat.buffer, out, count);
590
	if(gotcount >= 0 && gotcount != count) return READER_ERROR;
591
	else return gotcount;
592
}
593
 
594
/* returns reached position... negative ones are bad... */
595
static off_t feed_skip_bytes(mpg123_handle *fr,off_t len)
596
{
597
	return fr->rdat.buffer.fileoff+bc_skip(&fr->rdat.buffer, (ssize_t)len);
598
}
599
 
600
static int feed_back_bytes(mpg123_handle *fr, off_t bytes)
601
{
602
	if(bytes >=0)
603
	return bc_seekback(&fr->rdat.buffer, (ssize_t)bytes) >= 0 ? 0 : READER_ERROR;
604
	else
605
	return feed_skip_bytes(fr, -bytes) >= 0 ? 0 : READER_ERROR;
606
}
607
 
608
static int feed_seek_frame(mpg123_handle *fr, off_t num){ return READER_ERROR; }
609
 
610
/* Not just for feed reader, also for self-feeding buffered reader. */
611
static void buffered_forget(mpg123_handle *fr)
612
{
613
	bc_forget(&fr->rdat.buffer);
614
	fr->rdat.filepos = fr->rdat.buffer.fileoff + fr->rdat.buffer.pos;
615
}
616
 
617
off_t feed_set_pos(mpg123_handle *fr, off_t pos)
618
{
619
	struct bufferchain *bc = &fr->rdat.buffer;
620
	if(pos >= bc->fileoff && pos-bc->fileoff < bc->size)
621
	{ /* We have the position! */
622
		bc->pos = (ssize_t)(pos - bc->fileoff);
623
		return pos+bc->size; /* Next input after end of buffer... */
624
	}
625
	else
626
	{ /* I expect to get the specific position on next feed. Forget what I have now. */
627
		bc_reset(bc);
628
		bc->fileoff = pos;
629
		return pos; /* Next input from exactly that position. */
630
	}
631
}
632
 
633
/* The specific stuff for buffered stream reader. */
634
 
635
/* Let's work in nice 4K blocks, that may be nicely reusable (by malloc(), even). */
636
#define BUFFBLOCK 4096
637
static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t count)
638
{
639
	struct bufferchain *bc = &fr->rdat.buffer;
640
	ssize_t gotcount;
641
	if(bc->size - bc->pos < count)
642
	{ /* Add more stuff to buffer. If hitting end of file, adjust count. */
643
		unsigned char readbuf[BUFFBLOCK];
644
		ssize_t need = count - (bc->size-bc->pos);
645
		while(need>0)
646
		{
647
			int ret;
648
			ssize_t got = fr->rdat.fullread(fr, readbuf, BUFFBLOCK);
649
			if(got < 0)
650
			{
651
				if(NOQUIET) error("buffer reading");
652
				return READER_ERROR;
653
			}
654
 
655
			if(VERBOSE3) debug1("buffered_fullread: buffering %li bytes from stream (if > 0)", (long)got);
656
			if(got > 0 && (ret=bc_add(bc, readbuf, got)) != 0)
657
			{
658
				if(NOQUIET) error1("unable to add to chain, return: %i", ret);
659
				return READER_ERROR;
660
			}
661
 
662
			need -= got; /* May underflow here... */
663
			if(got < BUFFBLOCK) /* That naturally catches got == 0, too. */
664
			{
665
				if(VERBOSE3) fprintf(stderr, "Note: Input data end.\n");
666
				break; /* End. */
667
			}
668
		}
669
		if(bc->size - bc->pos < count)
670
		count = bc->size - bc->pos; /* We want only what we got. */
671
	}
672
	gotcount = bc_give(bc, out, count);
673
 
674
	if(VERBOSE3) debug2("wanted %li, got %li", (long)count, (long)gotcount);
675
 
676
	if(gotcount != count){ if(NOQUIET) error("gotcount != count"); return READER_ERROR; }
677
	else return gotcount;
678
}
679
#else
680
int feed_more(mpg123_handle *fr, const unsigned char *in, long count)
681
{
682
	fr->err = MPG123_MISSING_FEATURE;
683
	return -1;
684
}
685
off_t feed_set_pos(mpg123_handle *fr, off_t pos)
686
{
687
	fr->err = MPG123_MISSING_FEATURE;
688
	return -1;
689
}
690
#endif /* NO_FEEDER */
691
 
692
/*****************************************************************
693
 * read frame helper
694
 */
695
 
696
#define bugger_off { mh->err = MPG123_NO_READER; return MPG123_ERR; }
697
int bad_init(mpg123_handle *mh) bugger_off
698
void bad_close(mpg123_handle *mh){}
699
ssize_t bad_fullread(mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_off
700
int bad_head_read(mpg123_handle *mh, unsigned long *newhead) bugger_off
701
int bad_head_shift(mpg123_handle *mh, unsigned long *head) bugger_off
702
off_t bad_skip_bytes(mpg123_handle *mh, off_t len) bugger_off
703
int bad_read_frame_body(mpg123_handle *mh, unsigned char *data, int size) bugger_off
704
int bad_back_bytes(mpg123_handle *mh, off_t bytes) bugger_off
705
int bad_seek_frame(mpg123_handle *mh, off_t num) bugger_off
706
off_t bad_tell(mpg123_handle *mh) bugger_off
707
void bad_rewind(mpg123_handle *mh){}
708
#undef bugger_off
709
 
710
#define READER_STREAM 0
711
#define READER_ICY_STREAM 1
712
#define READER_FEED       2
713
#define READER_BUF_STREAM 3
714
#define READER_BUF_ICY_STREAM 4
715
struct reader readers[] =
716
{
717
	{ /* READER_STREAM */
718
		default_init,
719
		stream_close,
720
		plain_fullread,
721
		generic_head_read,
722
		generic_head_shift,
723
		stream_skip_bytes,
724
		generic_read_frame_body,
725
		stream_back_bytes,
726
		stream_seek_frame,
727
		generic_tell,
728
		stream_rewind,
729
		NULL
730
	} ,
731
	{ /* READER_ICY_STREAM */
732
		default_init,
733
		stream_close,
734
		icy_fullread,
735
		generic_head_read,
736
		generic_head_shift,
737
		stream_skip_bytes,
738
		generic_read_frame_body,
739
		stream_back_bytes,
740
		stream_seek_frame,
741
		generic_tell,
742
		stream_rewind,
743
		NULL
744
	},
745
#ifdef NO_FEEDER
746
#define feed_init NULL
747
#define feed_read NULL
748
#define buffered_fullread NULL
749
#define feed_seek_frame NULL
750
#define feed_back_bytes NULL
751
#define feed_skip_bytes NULL
752
#define buffered_forget NULL
753
#endif
754
	{ /* READER_FEED */
755
		feed_init,
756
		stream_close,
757
		feed_read,
758
		generic_head_read,
759
		generic_head_shift,
760
		feed_skip_bytes,
761
		generic_read_frame_body,
762
		feed_back_bytes,
763
		feed_seek_frame,
764
		generic_tell,
765
		stream_rewind,
766
		buffered_forget
767
	},
768
	{ /* READER_BUF_STREAM */
769
		default_init,
770
		stream_close,
771
		buffered_fullread,
772
		generic_head_read,
773
		generic_head_shift,
774
		stream_skip_bytes,
775
		generic_read_frame_body,
776
		stream_back_bytes,
777
		stream_seek_frame,
778
		generic_tell,
779
		stream_rewind,
780
		buffered_forget
781
	} ,
782
	{ /* READER_BUF_ICY_STREAM */
783
		default_init,
784
		stream_close,
785
		buffered_fullread,
786
		generic_head_read,
787
		generic_head_shift,
788
		stream_skip_bytes,
789
		generic_read_frame_body,
790
		stream_back_bytes,
791
		stream_seek_frame,
792
		generic_tell,
793
		stream_rewind,
794
		buffered_forget
795
	},
796
#ifdef READ_SYSTEM
797
	,{
798
		system_init,
799
		NULL,	/* filled in by system_init() */
800
		fullread,
801
		NULL,
802
		NULL,
803
		NULL,
804
		NULL,
805
		NULL,
806
		NULL,
807
		NULL,
808
		NULL,
809
		NULL,
810
	}
811
#endif
812
};
813
 
814
struct reader bad_reader =
815
{
816
	bad_init,
817
	bad_close,
818
	bad_fullread,
819
	bad_head_read,
820
	bad_head_shift,
821
	bad_skip_bytes,
822
	bad_read_frame_body,
823
	bad_back_bytes,
824
	bad_seek_frame,
825
	bad_tell,
826
	bad_rewind,
827
	NULL
828
};
829
 
830
static int default_init(mpg123_handle *fr)
831
{
832
    fr->rdat.fdread = plain_read;
833
 
834
	fr->rdat.read  = fr->rdat.r_read  != NULL ? fr->rdat.r_read  : posix_read;
835
	fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : posix_lseek;
836
	fr->rdat.filelen = get_fileinfo(fr);
837
	fr->rdat.filepos = 0;
838
	if(fr->rdat.filelen >= 0)
839
	{
840
		fr->rdat.flags |= READER_SEEKABLE;
841
		if(!strncmp((char*)fr->id3buf,"TAG",3))
842
		{
843
			fr->rdat.flags |= READER_ID3TAG;
844
			fr->metaflags  |= MPG123_NEW_ID3;
845
		}
846
	}
847
	/* Switch reader to a buffered one, if allowed. */
848
	else if(fr->p.flags & MPG123_SEEKBUFFER)
849
	{
850
#ifdef NO_FEEDER
851
		error("Buffered readers not supported in this build.");
852
		fr->err = MPG123_MISSING_FEATURE;
853
		return -1;
854
#else
855
		if     (fr->rd == &readers[READER_STREAM])
856
		{
857
			fr->rd = &readers[READER_BUF_STREAM];
858
			fr->rdat.fullread = plain_fullread;
859
		}
860
#ifndef NO_ICY
861
		else if(fr->rd == &readers[READER_ICY_STREAM])
862
		{
863
			fr->rd = &readers[READER_BUF_ICY_STREAM];
864
			fr->rdat.fullread = icy_fullread;
865
		}
866
#endif
867
		else
868
		{
869
			if(NOQUIET) error("mpg123 Programmer's fault: invalid reader");
870
			return -1;
871
		}
872
		bc_init(&fr->rdat.buffer);
873
		fr->rdat.filelen = 0; /* We carry the offset, but never know how big the stream is. */
874
		fr->rdat.flags |= READER_BUFFERED;
875
#endif /* NO_FEEDER */
876
	}
877
	return 0;
878
}
879
 
880
 
881
void open_bad(mpg123_handle *mh)
882
{
883
#ifndef NO_ICY
884
	clear_icy(&mh->icy);
885
#endif
886
	mh->rd = &bad_reader;
887
	mh->rdat.flags = 0;
888
	bc_init(&mh->rdat.buffer);
889
}
890
 
891
int open_feed(mpg123_handle *fr)
892
{
893
	debug("feed reader");
894
#ifdef NO_FEEDER
895
	error("Buffered readers not supported in this build.");
896
	fr->err = MPG123_MISSING_FEATURE;
897
	return -1;
898
#else
899
#ifndef NO_ICY
900
	if(fr->p.icy_interval > 0)
901
	{
902
		if(NOQUIET) error("Feed reader cannot do ICY parsing!");
903
 
904
		return -1;
905
	}
906
	clear_icy(&fr->icy);
907
#endif
908
	fr->rd = &readers[READER_FEED];
909
	fr->rdat.flags = 0;
910
	if(fr->rd->init(fr) < 0) return -1;
911
	return 0;
912
#endif /* NO_FEEDER */
913
}
914
 
915
int open_stream(mpg123_handle *fr, const char *bs_filenam, int fd)
916
{
917
	int filept_opened = 1;
918
	int filept; /* descriptor of opened file/stream */
919
 
920
	clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
921
	if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
922
	{
923
		filept = fd;
924
		filept_opened = 0; /* and don't try to close it... */
925
	}
926
	#ifndef O_BINARY
927
	#define O_BINARY (0)
928
	#endif
929
	else if((filept = open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */
930
	{
931
		if(NOQUIET) error2("Cannot open file %s: %s", bs_filenam, strerror(errno));
932
		fr->err = MPG123_BAD_FILE;
933
		return MPG123_ERR; /* error... */
934
	}
935
 
936
	/* now we have something behind filept and can init the reader */
937
	fr->rdat.filelen = -1;
938
	fr->rdat.filept  = filept;
939
	fr->rdat.flags = 0;
940
	if(filept_opened)	fr->rdat.flags |= READER_FD_OPENED;
941
 
942
#ifndef NO_ICY
943
	if(fr->p.icy_interval > 0)
944
	{
945
		debug("ICY reader");
946
		fr->icy.interval = fr->p.icy_interval;
947
		fr->icy.next = fr->icy.interval;
948
		fr->rd = &readers[READER_ICY_STREAM];
949
	}
950
	else
951
#endif
952
	{
953
		fr->rd = &readers[READER_STREAM];
954
		debug("stream reader");
955
	}
956
 
957
	if(fr->rd->init(fr) < 0) return -1;
958
 
959
	return MPG123_OK;
960
}