/*1reader: reading input data23copyright ?-2023 by the mpg123 project - free software under the terms of the LGPL 2.14see COPYING and AUTHORS files in distribution or http://mpg123.org5initially written by Thomas Orgis (after code from Michael Hipp)6*/78#ifndef MPG123_READER_H9#define MPG123_READER_H1011#ifndef MPG123_H_INTERN12#error "include internal mpg123 header first"13#endif1415#ifndef NO_FEEDER16struct buffy17{18unsigned char *data;19ptrdiff_t size;20ptrdiff_t realsize;21struct buffy *next;22};232425struct bufferchain26{27struct buffy* first; /* The beginning of the chain. */28struct buffy* last; /* The end... of the chain. */29ptrdiff_t size; /* Aggregated size of all buffies. */30/* These positions are relative to buffer chain beginning. */31ptrdiff_t pos; /* Position in whole chain. */32ptrdiff_t firstpos; /* The point of return on non-forget() */33/* The "real" filepos is fileoff + pos. */34int64_t fileoff; /* Beginning of chain is at this file offset. */35// Unsigned since no direct arithmetic with offsets. Overflow of overall36// size needs to be checked anyway.37size_t bufblock; /* Default (minimal) size of buffers. */38size_t pool_size; /* Keep that many buffers in storage. */39size_t pool_fill; /* That many buffers are there. */40/* A pool of buffers to re-use, if activated. It's a linked list that is worked on from the front. */41struct buffy *pool;42};4344/* Call this before any buffer chain use (even bc_init()). */45void INT123_bc_prepare(struct bufferchain *, size_t pool_size, size_t bufblock);46/* Free persistent data in the buffer chain, after bc_reset(). */47void INT123_bc_cleanup(struct bufferchain *);48/* Change pool size. This does not actually allocate/free anything on itself, just instructs later operations to free less / allocate more buffers. */49void INT123_bc_poolsize(struct bufferchain *, size_t pool_size, size_t bufblock);50/* Return available byte count in the buffer. */51size_t INT123_bc_fill(struct bufferchain *bc);5253#endif5455struct reader_data56{57int64_t filelen; /* total file length or total buffer size */58int64_t filepos; /* position in file or position in buffer chain */59/* Custom opaque I/O handle from the client. */60void *iohandle;61int flags;62// The one and only lowlevel reader wrapper, wrapping over all others.63// This is either libmpg123's wrapper or directly the user-supplied functions.64int (*r_read64) (void *, void *, size_t, size_t *);65int64_t (*r_lseek64)(void *, int64_t, int);66void (*cleanup_handle)(void *handle);67#ifndef NO_FEEDER68struct bufferchain buffer; /* Not dynamically allocated, these few struct bytes aren't worth the trouble. */69#endif70};7172/* start to use off_t to properly do LFS in future ... used to be long */73#ifdef __MORPHOS__74#undef tell /* unistd.h defines it as lseek(x, 0L, 1) */75#endif76struct reader77{78int (*init) (mpg123_handle *);79void (*close) (mpg123_handle *);80ptrdiff_t (*fullread) (mpg123_handle *, unsigned char *, ptrdiff_t);81int (*head_read) (mpg123_handle *, unsigned long *newhead); /* succ: TRUE, else <= 0 (FALSE or READER_MORE) */82int (*head_shift) (mpg123_handle *, unsigned long *head); /* succ: TRUE, else <= 0 (FALSE or READER_MORE) */83int64_t (*skip_bytes) (mpg123_handle *, int64_t len); /* succ: >=0, else error or READER_MORE */84int (*read_frame_body)(mpg123_handle *, unsigned char *, int size);85int (*back_bytes) (mpg123_handle *, int64_t bytes);86int (*seek_frame) (mpg123_handle *, int64_t num);87int64_t (*tell) (mpg123_handle *);88void (*rewind) (mpg123_handle *);89void (*forget) (mpg123_handle *);90};9192/* Open an external handle. */93int INT123_open_stream_handle(mpg123_handle *, void *iohandle);9495/* feed based operation has some specials */96int INT123_open_feed(mpg123_handle *);97/* externally called function, returns 0 on success, -1 on error */98int INT123_feed_more(mpg123_handle *fr, const unsigned char *in, size_t count);99void INT123_feed_forget(mpg123_handle *fr); /* forget the data that has been read (free some buffers) */100int64_t INT123_feed_set_pos(mpg123_handle *fr, int64_t pos); /* Set position (inside available data if possible), return wanted byte offset of next feed. */101102void INT123_open_bad(mpg123_handle *);103104#define READER_ID3TAG 0x2105#define READER_SEEKABLE 0x4106#define READER_BUFFERED 0x8107#define READER_NOSEEK 0x10108#define READER_HANDLEIO 0x40109#define READER_STREAM 0110#define READER_ICY_STREAM 1111#define READER_FEED 2112/* These two add a little buffering to enable small seeks for peek ahead. */113#define READER_BUF_STREAM 3114#define READER_BUF_ICY_STREAM 4115116#define READER_ERROR MPG123_ERR117#define READER_MORE MPG123_NEED_MORE118119#endif120121122