annotate 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
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 fillable.c
tomwalters@0 3 ==========
tomwalters@0 4
tomwalters@0 5 Sources whose native mode of operation is the fill entry point.
tomwalters@0 6 They may be pulled in which case a buffer is allocated.
tomwalters@0 7
tomwalters@0 8 */
tomwalters@0 9
tomwalters@0 10 #include "stitch.h"
tomwalters@0 11 #include "source.h"
tomwalters@0 12
tomwalters@0 13 #ifndef lint
tomwalters@0 14 static char *sccs_id = "@(#)fillable.c 1.2 John Holdsworth (MRC-APU) 11/8/90" ;
tomwalters@0 15 #endif
tomwalters@0 16
tomwalters@0 17 #if 0
tomwalters@0 18 #define DEBUG 1
tomwalters@0 19 #endif
tomwalters@0 20
tomwalters@0 21 Source SharingSource( source1, source2 )
tomwalters@0 22 struct _fillable_source *source1, *source2 ;
tomwalters@0 23 {
tomwalters@0 24 DeleteBuffer( source1->buffer ) ;
tomwalters@0 25
tomwalters@0 26 source1->buffer = SharedBuffer( source2->buffer ) ;
tomwalters@0 27
tomwalters@0 28 return ( (Source) source1 ) ;
tomwalters@0 29 }
tomwalters@0 30
tomwalters@0 31 /* converter of pull command to fill commands */
tomwalters@0 32
tomwalters@0 33 static Pointer pullFromFillable( source, bytes )
tomwalters@0 34 struct _fillable_source *source ;
tomwalters@0 35 ByteCount *bytes ;
tomwalters@0 36 {
tomwalters@0 37 #if DEBUG
tomwalters@0 38 printf( "buffering pulling from passive \"%s\", %d bytes\n", SourceName( source ), *bytes ) ;
tomwalters@0 39 #endif
tomwalters@0 40 #if 00
tomwalters@0 41 if( source->bsize < *bytes ) {
tomwalters@0 42
tomwalters@0 43 if( source->bsize != 0 )
tomwalters@0 44 Delete( source->buffer ) ;
tomwalters@0 45
tomwalters@0 46 source->buffer = Allocate( *bytes, "fillable.c for source buffer" ) ;
tomwalters@0 47
tomwalters@0 48 source->bsize = *bytes ;
tomwalters@0 49 }
tomwalters@0 50 #endif
tomwalters@0 51 return ( source->parent.fill( source, bytes, SizedBufferPointer( SourceBuffer( source ), *bytes ) ) ) ;
tomwalters@0 52 }
tomwalters@0 53
tomwalters@0 54 /* constructor for all pullable sources */
tomwalters@0 55
tomwalters@0 56 Source setFillableSource( source, filler, name )
tomwalters@0 57 struct _fillable_source *source ;
tomwalters@0 58 Pointer (*filler)() ;
tomwalters@0 59 char *name ;
tomwalters@0 60 {
tomwalters@0 61 source->buffer = NewBuffer( "pulling" ) ;
tomwalters@0 62
tomwalters@0 63 return ( SetSource( source, pullFromFillable, filler, nonRoller, name ) ) ;
tomwalters@0 64 }
tomwalters@0 65
tomwalters@0 66 Pointer deleteFillableSource( source )
tomwalters@0 67 struct _fillable_source *source ;
tomwalters@0 68 {
tomwalters@0 69 DeleteBuffer( source->buffer ) ;
tomwalters@0 70
tomwalters@0 71 return ( DeleteSource( source ) ) ;
tomwalters@0 72 }
tomwalters@0 73
tomwalters@0 74
tomwalters@0 75 /* derived fillable source */
tomwalters@0 76
tomwalters@0 77 typedef struct {
tomwalters@0 78 struct _fillable_source parent ;
tomwalters@0 79 Pointer data, end, ptr ;
tomwalters@0 80 } *RepeatingSource ;
tomwalters@0 81
tomwalters@0 82 static Pointer repeating_callback( source, bytes, buffer )
tomwalters@0 83 RepeatingSource source ;
tomwalters@0 84 ByteCount *bytes ;
tomwalters@0 85 Pointer buffer ;
tomwalters@0 86 {
tomwalters@0 87 register int last = *bytes == 0 ;
tomwalters@0 88 register Pointer bptr = buffer ;
tomwalters@0 89 register Pointer bend = buffer + *bytes ;
tomwalters@0 90 register ByteCount segment ;
tomwalters@0 91
tomwalters@0 92 if( !last ) {
tomwalters@0 93
tomwalters@0 94 while( bptr < bend ) {
tomwalters@0 95
tomwalters@0 96 segment = source->end - source->ptr ;
tomwalters@0 97 if( segment > bend - bptr )
tomwalters@0 98 segment = bend - bptr ;
tomwalters@0 99
tomwalters@0 100 CopyArray( (char *) source->ptr, (char *) bptr, segment ) ;
tomwalters@0 101
tomwalters@0 102 source->ptr += segment ;
tomwalters@0 103 bptr += segment ;
tomwalters@0 104
tomwalters@0 105 if( source->ptr == source->end )
tomwalters@0 106 source->ptr = source->data ;
tomwalters@0 107 }
tomwalters@0 108
tomwalters@0 109 return ( buffer ) ;
tomwalters@0 110 }
tomwalters@0 111 else
tomwalters@0 112 return ( DeleteFillableSource( source ) ) ;
tomwalters@0 113 }
tomwalters@0 114
tomwalters@0 115 Source newRepeatingSource( data, segment )
tomwalters@0 116 Pointer data ;
tomwalters@0 117 ByteCount segment ;
tomwalters@0 118 {
tomwalters@0 119 DeclareNew( RepeatingSource, source ) ;
tomwalters@0 120
tomwalters@0 121 source->data = data ;
tomwalters@0 122 source->end = data + segment ;
tomwalters@0 123
tomwalters@0 124 source->ptr = source->data ;
tomwalters@0 125
tomwalters@0 126 return ( SetFillableSource( source, repeating_callback, "fillable.c repeating" ) ) ;
tomwalters@0 127 }
tomwalters@0 128
tomwalters@0 129 typedef struct {
tomwalters@0 130 struct _fillable_source parent ;
tomwalters@0 131 Source input ; ByteCount segment ;
tomwalters@0 132 } *SegmentingSource ;
tomwalters@0 133
tomwalters@0 134 static Pointer segmenting_callback( source, bytes, buffer )
tomwalters@0 135 SegmentingSource source ;
tomwalters@0 136 ByteCount *bytes ;
tomwalters@0 137 Pointer buffer ;
tomwalters@0 138 {
tomwalters@0 139 register int last = *bytes == 0 ;
tomwalters@0 140 Pointer bptr = buffer ;
tomwalters@0 141 ByteCount segment ;
tomwalters@0 142
tomwalters@0 143 do {
tomwalters@0 144
tomwalters@0 145 segment = source->segment ;
tomwalters@0 146
tomwalters@0 147 if( segment > buffer + *bytes - bptr )
tomwalters@0 148 segment = buffer + *bytes - bptr ;
tomwalters@0 149
tomwalters@0 150 (void) FillSome( source->input, &segment, bptr ) ;
tomwalters@0 151
tomwalters@0 152 bptr += segment ;
tomwalters@0 153
tomwalters@0 154 } while ( bptr < buffer + *bytes ) ;
tomwalters@0 155
tomwalters@0 156 if( !last )
tomwalters@0 157 return ( buffer ) ;
tomwalters@0 158 else
tomwalters@0 159 return ( DeleteFillableSource( source ) ) ;
tomwalters@0 160 }
tomwalters@0 161
tomwalters@0 162 Source newSegmentingSource( input, segment )
tomwalters@0 163 Source input ;
tomwalters@0 164 ByteCount segment ;
tomwalters@0 165 {
tomwalters@0 166 DeclareNew( SegmentingSource, source ) ;
tomwalters@0 167
tomwalters@0 168 source->input = input ;
tomwalters@0 169
tomwalters@0 170 source->segment = segment ;
tomwalters@0 171
tomwalters@0 172 return ( SetFillableSource( source, segmenting_callback, "segmenting" ) ) ;
tomwalters@0 173 }
tomwalters@0 174
tomwalters@0 175
tomwalters@0 176
tomwalters@0 177 /* higher level methods to sources */
tomwalters@0 178
tomwalters@0 179
tomwalters@0 180 typedef struct _callback_source {
tomwalters@0 181 struct _fillable_source parent ;
tomwalters@0 182 Pointer state ;
tomwalters@0 183 void (*callback)(), (*close)() ;
tomwalters@0 184 } *CallbackSource ;
tomwalters@0 185
tomwalters@0 186 Source setCallbackSource( source, filler, state, callback, close, name )
tomwalters@0 187 CallbackSource source ;
tomwalters@0 188 Pointer (*filler)() ;
tomwalters@0 189 Pointer state ;
tomwalters@0 190 void (*callback)(), (*close)() ;
tomwalters@0 191 char *name ;
tomwalters@0 192 {
tomwalters@0 193 source->state = state ;
tomwalters@0 194 source->callback = callback ;
tomwalters@0 195 source->close = close ;
tomwalters@0 196
tomwalters@0 197 return ( SetFillableSource( source, filler, name ) ) ;
tomwalters@0 198 }
tomwalters@0 199
tomwalters@0 200 Source newCallbackSource( filler, state, callback, close, name )
tomwalters@0 201 Pointer (*filler)() ;
tomwalters@0 202 Pointer state ;
tomwalters@0 203 void (*callback)(), (*close)() ;
tomwalters@0 204 char *name ;
tomwalters@0 205 {
tomwalters@0 206 return ( setCallbackSource( New( CallbackSource ), filler, state, callback, close, name ) ) ;
tomwalters@0 207 }
tomwalters@0 208
tomwalters@0 209 static Pointer externalFiller( source, bytes, buffer )
tomwalters@0 210 CallbackSource source ;
tomwalters@0 211 ByteCount *bytes ;
tomwalters@0 212 Pointer buffer ;
tomwalters@0 213 {
tomwalters@0 214 register int last = *bytes == 0 ;
tomwalters@0 215
tomwalters@0 216 source->callback( source->state, bytes, buffer, buffer+*bytes ) ;
tomwalters@0 217
tomwalters@0 218 if( !last )
tomwalters@0 219 return ( buffer ) ;
tomwalters@0 220 else {
tomwalters@0 221 if( source->close != (void ( * )()) 0 )
tomwalters@0 222 source->close( source->state ) ;
tomwalters@0 223
tomwalters@0 224 return ( DeleteFillableSource( source ) ) ;
tomwalters@0 225 }
tomwalters@0 226 }
tomwalters@0 227
tomwalters@0 228 Source newExternalSource( state, callback, close, name )
tomwalters@0 229 Pointer state ;
tomwalters@0 230 void (*callback)(), (*close)() ;
tomwalters@0 231 char *name ;
tomwalters@0 232 {
tomwalters@0 233 return ( newCallbackSource( externalFiller, state, callback, close, name ) ) ;
tomwalters@0 234 }
tomwalters@0 235
tomwalters@0 236 typedef struct _through_source {
tomwalters@0 237 struct _callback_source parent ;
tomwalters@0 238 Source input ;
tomwalters@0 239 } *ThroughSource ;
tomwalters@0 240
tomwalters@0 241 static Source setThroughSource( source, filler, state, callback, close, input, name )
tomwalters@0 242 ThroughSource source ;
tomwalters@0 243 Pointer (*filler)() ;
tomwalters@0 244 Pointer state ;
tomwalters@0 245 void (*callback)(), (*close)() ;
tomwalters@0 246 Source input ;
tomwalters@0 247 char *name ;
tomwalters@0 248 {
tomwalters@0 249 source->input = input ;
tomwalters@0 250
tomwalters@0 251 return ( setCallbackSource( (CallbackSource) source, filler, state, callback, close, name ) ) ;
tomwalters@0 252 }
tomwalters@0 253
tomwalters@0 254 Source newThroughSource( filler, state, callback, close, input, name )
tomwalters@0 255 Pointer (*filler)(), state ;
tomwalters@0 256 void (*callback)(), (*close)() ;
tomwalters@0 257 Source input ;
tomwalters@0 258 char *name ;
tomwalters@0 259 {
tomwalters@0 260 return ( setThroughSource( New( ThroughSource ), filler, state, callback, close, input, name ) ) ;
tomwalters@0 261 }
tomwalters@0 262
tomwalters@0 263
tomwalters@0 264 static Pointer processingFiller( source, bytes, buffer )
tomwalters@0 265 ThroughSource source ;
tomwalters@0 266 ByteCount *bytes ;
tomwalters@0 267 Pointer buffer ;
tomwalters@0 268 {
tomwalters@0 269 register int last = *bytes == 0 ;
tomwalters@0 270
tomwalters@0 271 source->parent.callback( source->parent.state, bytes, buffer, buffer+*bytes, PullSome( source->input, bytes ) ) ;
tomwalters@0 272
tomwalters@0 273 if( !last )
tomwalters@0 274 return ( buffer ) ;
tomwalters@0 275 else {
tomwalters@0 276 if( source->parent.close != (void ( * )()) 0 )
tomwalters@0 277 source->parent.close( source->parent.state ) ;
tomwalters@0 278
tomwalters@0 279 return ( DeleteFillableSource( &source->parent ) ) ;
tomwalters@0 280 }
tomwalters@0 281 }
tomwalters@0 282
tomwalters@0 283 Source newProcessingSource( state, callback, close, input, name )
tomwalters@0 284 Pointer state ;
tomwalters@0 285 void (*callback)(), (*close)() ;
tomwalters@0 286 Source input ;
tomwalters@0 287 char *name ;
tomwalters@0 288 {
tomwalters@0 289 return ( newThroughSource( processingFiller, state, callback, close, input, name ) ) ;
tomwalters@0 290 }
tomwalters@0 291
tomwalters@0 292 Source newSimpleProcessingSource( callback, input, name )
tomwalters@0 293 void (*callback)() ;
tomwalters@0 294 Source input ;
tomwalters@0 295 char *name ;
tomwalters@0 296 {
tomwalters@0 297 return ( NewProcessingSource( (Pointer) 0, callback, (void ( * )()) 0, input, name ) ) ;
tomwalters@0 298 }
tomwalters@0 299
tomwalters@0 300 typedef struct {
tomwalters@0 301 struct _fillable_source parent ;
tomwalters@0 302 Pointer *states ;
tomwalters@0 303 int (*callback)() ;
tomwalters@0 304 void (*close)() ;
tomwalters@0 305 int channels ;
tomwalters@0 306 Source input ;
tomwalters@0 307 } *MultiplexedSource ;
tomwalters@0 308
tomwalters@0 309 static Pointer multiplexed_callback( source, bytes, buffer )
tomwalters@0 310 MultiplexedSource source ;
tomwalters@0 311 ByteCount *bytes ;
tomwalters@0 312 Pointer buffer ;
tomwalters@0 313 {
tomwalters@0 314 register int last = *bytes == 0 ;
tomwalters@0 315 Pointer iptr = PullSome( source->input, bytes ) ;
tomwalters@0 316 Pointer optr = buffer ;
tomwalters@0 317 Pointer end = buffer + *bytes ;
tomwalters@0 318 ByteCount data_size ;
tomwalters@0 319 int channel ;
tomwalters@0 320
tomwalters@0 321 for( channel=0 ; channel<source->channels ; channel++ ) {
tomwalters@0 322 data_size = source->callback( source->states[channel], optr, end, iptr, source->channels ) ;
tomwalters@0 323 iptr += data_size ;
tomwalters@0 324 optr += data_size ;
tomwalters@0 325 }
tomwalters@0 326
tomwalters@0 327 if( !last )
tomwalters@0 328 return ( buffer ) ;
tomwalters@0 329 else {
tomwalters@0 330 if( source->close != (void ( * )()) 0 )
tomwalters@0 331 for( channel=0 ; channel<source->channels ; channel++ )
tomwalters@0 332 source->close( source->states[channel] ) ;
tomwalters@0 333
tomwalters@0 334 Delete( source->states ) ;
tomwalters@0 335
tomwalters@0 336 return ( DeleteFillableSource( source ) ) ;
tomwalters@0 337 }
tomwalters@0 338 }
tomwalters@0 339
tomwalters@0 340 Source newMultiplexedSource( states, callback, close, channels, input, name )
tomwalters@0 341 Pointer *states ;
tomwalters@0 342 int (*callback)() ;
tomwalters@0 343 void (*close)() ;
tomwalters@0 344 int channels ;
tomwalters@0 345 Source input ;
tomwalters@0 346 char *name ;
tomwalters@0 347 {
tomwalters@0 348 DeclareNew( MultiplexedSource, source ) ;
tomwalters@0 349
tomwalters@0 350 source->states = states ;
tomwalters@0 351 source->callback = callback ;
tomwalters@0 352 source->close = close ;
tomwalters@0 353 source->channels = channels ;
tomwalters@0 354
tomwalters@0 355 source->input = input ;
tomwalters@0 356
tomwalters@0 357 return ( SetFillableSource( source, multiplexed_callback, name ) ) ;
tomwalters@0 358 }
tomwalters@0 359
tomwalters@0 360 typedef struct _merging_source {
tomwalters@0 361 struct _callback_source parent ; Source *inputs ;
tomwalters@0 362 } *MergingSource ;
tomwalters@0 363
tomwalters@0 364 static Pointer mergingFiller( source, bytes, buffer )
tomwalters@0 365 MergingSource source ;
tomwalters@0 366 ByteCount *bytes ;
tomwalters@0 367 Pointer buffer ;
tomwalters@0 368 {
tomwalters@0 369 register int last = *bytes == 0 ;
tomwalters@0 370 Pointer input1, input2 ;
tomwalters@0 371 int n ;
tomwalters@0 372
tomwalters@0 373 input1 = PullSome( source->inputs[0], bytes ) ;
tomwalters@0 374
tomwalters@0 375 for( n=1 ; _SPTR( source->inputs[n] ) != (struct _source *) 0 ; n++ ) {
tomwalters@0 376
tomwalters@0 377 input2 = PullSome( source->inputs[n], bytes ) ;
tomwalters@0 378
tomwalters@0 379 source->parent.callback( source->parent.state, bytes, buffer, buffer+*bytes, input1, input2 ) ;
tomwalters@0 380
tomwalters@0 381 input1 = buffer ;
tomwalters@0 382 }
tomwalters@0 383
tomwalters@0 384 if( !last )
tomwalters@0 385 return ( buffer ) ;
tomwalters@0 386 else {
tomwalters@0 387 Delete( source->inputs ) ;
tomwalters@0 388
tomwalters@0 389 return ( DeleteFillableSource( &source->parent ) ) ;
tomwalters@0 390 }
tomwalters@0 391 }
tomwalters@0 392
tomwalters@0 393 Source newMergingSource( state, callback, close, inputs, name )
tomwalters@0 394 Pointer state ;
tomwalters@0 395 void (*callback)(), (*close)() ;
tomwalters@0 396 Source *inputs ;
tomwalters@0 397 char *name ;
tomwalters@0 398 {
tomwalters@0 399 DeclareNew( MergingSource, source ) ;
tomwalters@0 400
tomwalters@0 401 source->inputs = inputs ;
tomwalters@0 402
tomwalters@0 403 return ( setCallbackSource( (CallbackSource) source, mergingFiller, state, callback, close, name ) ) ;
tomwalters@0 404 }
tomwalters@0 405