> wonderful precompress_stream function that has virtual read, write and seek functions
I'd again suggest to consider the coroutine approach.
To me it seems much more convenient for codec libraries than ugly callback APIs,
and also coders based on it are faster (in my experience, and not comparing
to plain memory-to-memory though).
Example:
http://nishi.dreamhosters.com/u/newbrc_2.rar
The actual codec is hidden in process() here and works memory-to-memory.
But when it encounters buffer bounds (or for any other reason, like
seeking) it returns a corresponding status and resumes with the next
call of the same function.
\newbrc_2\src_1\coroproc.inc:
Code:
void processfile(
FILE* f, FILE* g,
byte* inpbuf,uint inpbufsize,
byte* outbuf,uint outbufsize
) {
init();
// add an output buffer in advance to store headers etc
addout( outbuf, outbufsize );
while( 1 ) {
int r = process();
if( r==0 ) break;
if( r==1 ) {
uint l = fread( inpbuf, 1, inpbufsize, f );
if( l==0 ) break;
// add input data for status=1
addinp( inpbuf, l );
} else if( r==2 ) {
fwrite( outbuf, 1, outbufsize, g );
// add an output buffer for status=2
addout( outbuf, outbufsize );
}
}
fwrite( outbuf, 1,outptr-outbuf, g ); // flush
}
Another example is http://nishi.dreamhosters.com/u/marc_v1.rar
(its more complex, but there's a newer coroutine class)
And a simple demo is this: http://nishi.dreamhosters.com/u/fibo_1.rar
(with symmetric coroutines, stack switching, and a faster custom setjmp replacement)
Code:
struct index : coroutine<index> {
void do_process( void ) {
uint a=1;
while(1) {
yield( a );
a++;
}
}
} F1;
struct fibonacci : coroutine<fibonacci> {
void do_process( void ) {
uint a=0,b=1;
while(1) {
yield( b );
b = b + a;
a = b - a;
}
}
} F2;
int main( int argc, char** argv ) {
for( int i=0; i<20; i++ ) {
printf( "%i:%i ", F1.call(), F2.call() );
} printf( "\n" );
return 0;
}