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" ) ) ;
+}
+