Mercurial > hg > aim92
diff stitch/pullable.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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stitch/pullable.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,230 @@ +/* + pullable.c + ========== + + sources who's native operation is receive pull commands. + +*/ + +#include "stitch.h" +#include "source.h" + +#ifndef lint +static char *sccs_id = "@(#)pullable.c 1.3 John Holdsworth (MRC-APU) 6/6/91" ; +#endif + +#if 0 +#define DEBUG 1 +#endif + +/* + fill a users buffer from a process that returns it's own buffer + +*/ + +static Pointer fillFromPullable( source, bytes, buffer ) +struct _pullable_source *source ; +ByteCount *bytes ; +Pointer buffer ; +{ + Pointer input = source->parent.pull( source, bytes ) ; + + CopyArray( (char *) input, (char *) buffer, *bytes ) ; + + return ( buffer ) ; +} + +Source setPullableSource( source, puller, name ) +struct _pullable_source *source ; +Pointer (*puller)() ; +char *name ; +{ + return ( SetSource( source, puller, fillFromPullable, nonRoller, name ) ) ; +} + +Pointer deletePullableSource( source ) +struct _pullable_source *source ; +{ + return ( DeleteSource( source ) ) ; +} + +/* + simple slave source as example of derived source + +*/ + +typedef struct { struct _pullable_source parent ; Source master ; } *SlaveSource ; + +static Pointer slavePull( source, bytes ) +SlaveSource source ; +ByteCount *bytes ; +{ + register int last = *bytes == 0 ; + + if( !last ) + return ( _SPTR( source->master )->returned ) ; + else + return ( DeletePullableSource( source ) ) ; +} + +Source newSlaveSource( master ) +Source master ; +{ + DeclareNew( SlaveSource, source ) ; + + source->master = master ; + + return ( SetPullableSource( source, slavePull, "pullable.c slave" ) ) ; +} + +/* + the simplest Source is one direct from memory + +*/ + +typedef struct { + struct _pullable_source parent ; + Pointer next ; + } *StaticSource ; + +static Pointer staticPull( source, bytes ) +StaticSource source ; +ByteCount *bytes ; +{ + register int last = *bytes == 0 ; + register Pointer this = source->next ; + + if( !last ) { + + source->next += abs( *bytes ) ; + + return ( this ) ; + } + else + return ( DeletePullableSource( source ) ) ; +} + +Source newStaticSource( pointer ) +Pointer pointer ; +{ + DeclareNew( StaticSource, source ) ; + + source->next = pointer ; + + return ( SetPullableSource( source, staticPull, "pullable.c static" ) ) ; +} + +typedef struct { + struct _pullable_source parent ; + Source input ; Pointer buffer ; ByteCount retained ; +} *RetainingSource ; + +static Pointer retaining_callback( source, bytes ) +RetainingSource source ; +ByteCount *bytes ; +{ + register int last = *bytes == 0 ; + Pointer buffer = RollSome( source->input, bytes, source->retained ) ; + + if( !last ) + return ( buffer ) ; + else + return ( DeletePullableSource( source ) ) ; +} + +Source newRetainingSource( input, retained ) +Source input ; +ByteCount retained ; +{ + DeclareNew( RetainingSource, source ) ; + + source->retained = retained ; + + source->input = NewRollableSource( input ) ; + + return ( SetPullableSource( source, retaining_callback, "pullable.c retaining" ) ) ; +} + +typedef struct { + struct _pullable_source parent ; + Source input ; ByteCount delay ; + } *DelayingSource ; + +static Pointer delay_callback( source, bytes ) +DelayingSource source ; +ByteCount *bytes ; +{ + register int last = *bytes == 0 ; + Pointer delayed = PullSome( source->input, bytes ) - source->delay ; + + if( !last ) + return ( delayed ) ; + else + return ( DeletePullableSource( source ) ) ; +} + +Source newDelayingSource( input, delay ) +Source input ; +ByteCount delay ; +{ + DeclareNew( DelayingSource, source ) ; + + source->input = NewRetainingSource( input, delay ) ; + + source->delay = delay ; + + return ( SetPullableSource( source, delay_callback, "pullable.c delaying" ) ) ; +} + +typedef struct { + struct _pullable_source parent ; + Source input ; Pointer buffer, position, end ; ByteCount segment ; +} *BlockingSource ; + +static Pointer block_callback( source, bytes ) +BlockingSource source ; +ByteCount *bytes ; +{ + register int last = *bytes == 0 ; + ByteCount segment = source->segment ; + + if( source->position == source->end || last ) { + + if( segment < *bytes || last ) + segment = *bytes ; + + source->buffer = PullSome( source->input, &segment ) ; +#if DEBUG +printf( "pulled block at %x from %s\n", source->buffer, SourceName( source->input ) ) ; +#endif + source->end = source->buffer + segment ; + + source->position = source->buffer ; + } + + if( *bytes > source->end - source->position ) + *bytes = source->end - source->position ; + + source->position += *bytes ; + + if( !last ) + return ( source->position - *bytes ) ; + else + return ( DeletePullableSource( source ) ) ; +} + +Source newBlockingSource( input, segment ) +Source input ; +ByteCount segment ; +{ + DeclareNew( BlockingSource, source ) ; + + source->input = input ; + + source->position = source->end = (Pointer) 0 ; + + source->segment = segment ; + + return ( SetPullableSource( source, block_callback, "pullable.c blocking" ) ) ; +} +