comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:5242703e91d3
1 /*
2 pullable.c
3 ==========
4
5 sources who's native operation is receive pull commands.
6
7 */
8
9 #include "stitch.h"
10 #include "source.h"
11
12 #ifndef lint
13 static char *sccs_id = "@(#)pullable.c 1.3 John Holdsworth (MRC-APU) 6/6/91" ;
14 #endif
15
16 #if 0
17 #define DEBUG 1
18 #endif
19
20 /*
21 fill a users buffer from a process that returns it's own buffer
22
23 */
24
25 static Pointer fillFromPullable( source, bytes, buffer )
26 struct _pullable_source *source ;
27 ByteCount *bytes ;
28 Pointer buffer ;
29 {
30 Pointer input = source->parent.pull( source, bytes ) ;
31
32 CopyArray( (char *) input, (char *) buffer, *bytes ) ;
33
34 return ( buffer ) ;
35 }
36
37 Source setPullableSource( source, puller, name )
38 struct _pullable_source *source ;
39 Pointer (*puller)() ;
40 char *name ;
41 {
42 return ( SetSource( source, puller, fillFromPullable, nonRoller, name ) ) ;
43 }
44
45 Pointer deletePullableSource( source )
46 struct _pullable_source *source ;
47 {
48 return ( DeleteSource( source ) ) ;
49 }
50
51 /*
52 simple slave source as example of derived source
53
54 */
55
56 typedef struct { struct _pullable_source parent ; Source master ; } *SlaveSource ;
57
58 static Pointer slavePull( source, bytes )
59 SlaveSource source ;
60 ByteCount *bytes ;
61 {
62 register int last = *bytes == 0 ;
63
64 if( !last )
65 return ( _SPTR( source->master )->returned ) ;
66 else
67 return ( DeletePullableSource( source ) ) ;
68 }
69
70 Source newSlaveSource( master )
71 Source master ;
72 {
73 DeclareNew( SlaveSource, source ) ;
74
75 source->master = master ;
76
77 return ( SetPullableSource( source, slavePull, "pullable.c slave" ) ) ;
78 }
79
80 /*
81 the simplest Source is one direct from memory
82
83 */
84
85 typedef struct {
86 struct _pullable_source parent ;
87 Pointer next ;
88 } *StaticSource ;
89
90 static Pointer staticPull( source, bytes )
91 StaticSource source ;
92 ByteCount *bytes ;
93 {
94 register int last = *bytes == 0 ;
95 register Pointer this = source->next ;
96
97 if( !last ) {
98
99 source->next += abs( *bytes ) ;
100
101 return ( this ) ;
102 }
103 else
104 return ( DeletePullableSource( source ) ) ;
105 }
106
107 Source newStaticSource( pointer )
108 Pointer pointer ;
109 {
110 DeclareNew( StaticSource, source ) ;
111
112 source->next = pointer ;
113
114 return ( SetPullableSource( source, staticPull, "pullable.c static" ) ) ;
115 }
116
117 typedef struct {
118 struct _pullable_source parent ;
119 Source input ; Pointer buffer ; ByteCount retained ;
120 } *RetainingSource ;
121
122 static Pointer retaining_callback( source, bytes )
123 RetainingSource source ;
124 ByteCount *bytes ;
125 {
126 register int last = *bytes == 0 ;
127 Pointer buffer = RollSome( source->input, bytes, source->retained ) ;
128
129 if( !last )
130 return ( buffer ) ;
131 else
132 return ( DeletePullableSource( source ) ) ;
133 }
134
135 Source newRetainingSource( input, retained )
136 Source input ;
137 ByteCount retained ;
138 {
139 DeclareNew( RetainingSource, source ) ;
140
141 source->retained = retained ;
142
143 source->input = NewRollableSource( input ) ;
144
145 return ( SetPullableSource( source, retaining_callback, "pullable.c retaining" ) ) ;
146 }
147
148 typedef struct {
149 struct _pullable_source parent ;
150 Source input ; ByteCount delay ;
151 } *DelayingSource ;
152
153 static Pointer delay_callback( source, bytes )
154 DelayingSource source ;
155 ByteCount *bytes ;
156 {
157 register int last = *bytes == 0 ;
158 Pointer delayed = PullSome( source->input, bytes ) - source->delay ;
159
160 if( !last )
161 return ( delayed ) ;
162 else
163 return ( DeletePullableSource( source ) ) ;
164 }
165
166 Source newDelayingSource( input, delay )
167 Source input ;
168 ByteCount delay ;
169 {
170 DeclareNew( DelayingSource, source ) ;
171
172 source->input = NewRetainingSource( input, delay ) ;
173
174 source->delay = delay ;
175
176 return ( SetPullableSource( source, delay_callback, "pullable.c delaying" ) ) ;
177 }
178
179 typedef struct {
180 struct _pullable_source parent ;
181 Source input ; Pointer buffer, position, end ; ByteCount segment ;
182 } *BlockingSource ;
183
184 static Pointer block_callback( source, bytes )
185 BlockingSource source ;
186 ByteCount *bytes ;
187 {
188 register int last = *bytes == 0 ;
189 ByteCount segment = source->segment ;
190
191 if( source->position == source->end || last ) {
192
193 if( segment < *bytes || last )
194 segment = *bytes ;
195
196 source->buffer = PullSome( source->input, &segment ) ;
197 #if DEBUG
198 printf( "pulled block at %x from %s\n", source->buffer, SourceName( source->input ) ) ;
199 #endif
200 source->end = source->buffer + segment ;
201
202 source->position = source->buffer ;
203 }
204
205 if( *bytes > source->end - source->position )
206 *bytes = source->end - source->position ;
207
208 source->position += *bytes ;
209
210 if( !last )
211 return ( source->position - *bytes ) ;
212 else
213 return ( DeletePullableSource( source ) ) ;
214 }
215
216 Source newBlockingSource( input, segment )
217 Source input ;
218 ByteCount segment ;
219 {
220 DeclareNew( BlockingSource, source ) ;
221
222 source->input = input ;
223
224 source->position = source->end = (Pointer) 0 ;
225
226 source->segment = segment ;
227
228 return ( SetPullableSource( source, block_callback, "pullable.c blocking" ) ) ;
229 }
230