Mercurial > hg > aim92
view stitch/fillable.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
line wrap: on
line source
/* fillable.c ========== Sources whose native mode of operation is the fill entry point. They may be pulled in which case a buffer is allocated. */ #include "stitch.h" #include "source.h" #ifndef lint static char *sccs_id = "@(#)fillable.c 1.2 John Holdsworth (MRC-APU) 11/8/90" ; #endif #if 0 #define DEBUG 1 #endif Source SharingSource( source1, source2 ) struct _fillable_source *source1, *source2 ; { DeleteBuffer( source1->buffer ) ; source1->buffer = SharedBuffer( source2->buffer ) ; return ( (Source) source1 ) ; } /* converter of pull command to fill commands */ static Pointer pullFromFillable( source, bytes ) struct _fillable_source *source ; ByteCount *bytes ; { #if DEBUG printf( "buffering pulling from passive \"%s\", %d bytes\n", SourceName( source ), *bytes ) ; #endif #if 00 if( source->bsize < *bytes ) { if( source->bsize != 0 ) Delete( source->buffer ) ; source->buffer = Allocate( *bytes, "fillable.c for source buffer" ) ; source->bsize = *bytes ; } #endif return ( source->parent.fill( source, bytes, SizedBufferPointer( SourceBuffer( source ), *bytes ) ) ) ; } /* constructor for all pullable sources */ Source setFillableSource( source, filler, name ) struct _fillable_source *source ; Pointer (*filler)() ; char *name ; { source->buffer = NewBuffer( "pulling" ) ; return ( SetSource( source, pullFromFillable, filler, nonRoller, name ) ) ; } Pointer deleteFillableSource( source ) struct _fillable_source *source ; { DeleteBuffer( source->buffer ) ; return ( DeleteSource( source ) ) ; } /* derived fillable source */ typedef struct { struct _fillable_source parent ; Pointer data, end, ptr ; } *RepeatingSource ; static Pointer repeating_callback( source, bytes, buffer ) RepeatingSource source ; ByteCount *bytes ; Pointer buffer ; { register int last = *bytes == 0 ; register Pointer bptr = buffer ; register Pointer bend = buffer + *bytes ; register ByteCount segment ; if( !last ) { while( bptr < bend ) { segment = source->end - source->ptr ; if( segment > bend - bptr ) segment = bend - bptr ; CopyArray( (char *) source->ptr, (char *) bptr, segment ) ; source->ptr += segment ; bptr += segment ; if( source->ptr == source->end ) source->ptr = source->data ; } return ( buffer ) ; } else return ( DeleteFillableSource( source ) ) ; } Source newRepeatingSource( data, segment ) Pointer data ; ByteCount segment ; { DeclareNew( RepeatingSource, source ) ; source->data = data ; source->end = data + segment ; source->ptr = source->data ; return ( SetFillableSource( source, repeating_callback, "fillable.c repeating" ) ) ; } typedef struct { struct _fillable_source parent ; Source input ; ByteCount segment ; } *SegmentingSource ; static Pointer segmenting_callback( source, bytes, buffer ) SegmentingSource source ; ByteCount *bytes ; Pointer buffer ; { register int last = *bytes == 0 ; Pointer bptr = buffer ; ByteCount segment ; do { segment = source->segment ; if( segment > buffer + *bytes - bptr ) segment = buffer + *bytes - bptr ; (void) FillSome( source->input, &segment, bptr ) ; bptr += segment ; } while ( bptr < buffer + *bytes ) ; if( !last ) return ( buffer ) ; else return ( DeleteFillableSource( source ) ) ; } Source newSegmentingSource( input, segment ) Source input ; ByteCount segment ; { DeclareNew( SegmentingSource, source ) ; source->input = input ; source->segment = segment ; return ( SetFillableSource( source, segmenting_callback, "segmenting" ) ) ; } /* higher level methods to sources */ typedef struct _callback_source { struct _fillable_source parent ; Pointer state ; void (*callback)(), (*close)() ; } *CallbackSource ; Source setCallbackSource( source, filler, state, callback, close, name ) CallbackSource source ; Pointer (*filler)() ; Pointer state ; void (*callback)(), (*close)() ; char *name ; { source->state = state ; source->callback = callback ; source->close = close ; return ( SetFillableSource( source, filler, name ) ) ; } Source newCallbackSource( filler, state, callback, close, name ) Pointer (*filler)() ; Pointer state ; void (*callback)(), (*close)() ; char *name ; { return ( setCallbackSource( New( CallbackSource ), filler, state, callback, close, name ) ) ; } static Pointer externalFiller( source, bytes, buffer ) CallbackSource source ; ByteCount *bytes ; Pointer buffer ; { register int last = *bytes == 0 ; source->callback( source->state, bytes, buffer, buffer+*bytes ) ; if( !last ) return ( buffer ) ; else { if( source->close != (void ( * )()) 0 ) source->close( source->state ) ; return ( DeleteFillableSource( source ) ) ; } } Source newExternalSource( state, callback, close, name ) Pointer state ; void (*callback)(), (*close)() ; char *name ; { return ( newCallbackSource( externalFiller, state, callback, close, name ) ) ; } typedef struct _through_source { struct _callback_source parent ; Source input ; } *ThroughSource ; static Source setThroughSource( source, filler, state, callback, close, input, name ) ThroughSource source ; Pointer (*filler)() ; Pointer state ; void (*callback)(), (*close)() ; Source input ; char *name ; { source->input = input ; return ( setCallbackSource( (CallbackSource) source, filler, state, callback, close, name ) ) ; } Source newThroughSource( filler, state, callback, close, input, name ) Pointer (*filler)(), state ; void (*callback)(), (*close)() ; Source input ; char *name ; { return ( setThroughSource( New( ThroughSource ), filler, state, callback, close, input, name ) ) ; } static Pointer processingFiller( source, bytes, buffer ) ThroughSource source ; ByteCount *bytes ; Pointer buffer ; { register int last = *bytes == 0 ; source->parent.callback( source->parent.state, bytes, buffer, buffer+*bytes, PullSome( source->input, bytes ) ) ; if( !last ) return ( buffer ) ; else { if( source->parent.close != (void ( * )()) 0 ) source->parent.close( source->parent.state ) ; return ( DeleteFillableSource( &source->parent ) ) ; } } Source newProcessingSource( state, callback, close, input, name ) Pointer state ; void (*callback)(), (*close)() ; Source input ; char *name ; { return ( newThroughSource( processingFiller, state, callback, close, input, name ) ) ; } Source newSimpleProcessingSource( callback, input, name ) void (*callback)() ; Source input ; char *name ; { return ( NewProcessingSource( (Pointer) 0, callback, (void ( * )()) 0, input, name ) ) ; } typedef struct { struct _fillable_source parent ; Pointer *states ; int (*callback)() ; void (*close)() ; int channels ; Source input ; } *MultiplexedSource ; static Pointer multiplexed_callback( source, bytes, buffer ) MultiplexedSource source ; ByteCount *bytes ; Pointer buffer ; { register int last = *bytes == 0 ; Pointer iptr = PullSome( source->input, bytes ) ; Pointer optr = buffer ; Pointer end = buffer + *bytes ; ByteCount data_size ; int channel ; for( channel=0 ; channel<source->channels ; channel++ ) { data_size = source->callback( source->states[channel], optr, end, iptr, source->channels ) ; iptr += data_size ; optr += data_size ; } if( !last ) return ( buffer ) ; else { if( source->close != (void ( * )()) 0 ) for( channel=0 ; channel<source->channels ; channel++ ) source->close( source->states[channel] ) ; Delete( source->states ) ; return ( DeleteFillableSource( source ) ) ; } } Source newMultiplexedSource( states, callback, close, channels, input, name ) Pointer *states ; int (*callback)() ; void (*close)() ; int channels ; Source input ; char *name ; { DeclareNew( MultiplexedSource, source ) ; source->states = states ; source->callback = callback ; source->close = close ; source->channels = channels ; source->input = input ; return ( SetFillableSource( source, multiplexed_callback, name ) ) ; } typedef struct _merging_source { struct _callback_source parent ; Source *inputs ; } *MergingSource ; static Pointer mergingFiller( source, bytes, buffer ) MergingSource source ; ByteCount *bytes ; Pointer buffer ; { register int last = *bytes == 0 ; Pointer input1, input2 ; int n ; input1 = PullSome( source->inputs[0], bytes ) ; for( n=1 ; _SPTR( source->inputs[n] ) != (struct _source *) 0 ; n++ ) { input2 = PullSome( source->inputs[n], bytes ) ; source->parent.callback( source->parent.state, bytes, buffer, buffer+*bytes, input1, input2 ) ; input1 = buffer ; } if( !last ) return ( buffer ) ; else { Delete( source->inputs ) ; return ( DeleteFillableSource( &source->parent ) ) ; } } Source newMergingSource( state, callback, close, inputs, name ) Pointer state ; void (*callback)(), (*close)() ; Source *inputs ; char *name ; { DeclareNew( MergingSource, source ) ; source->inputs = inputs ; return ( setCallbackSource( (CallbackSource) source, mergingFiller, state, callback, close, name ) ) ; }