Mercurial > hg > aim92
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 |