@@ -358,3 +358,94 @@ pub fn buffer_new<BSIZE: u32>() -> Buffer<BSIZE> {
358
358
fn test_buffer_new () {
359
359
assert_eq (buffer_new < u32 :32 > (), Buffer { contents : u32 :0 , length : u32 :0 });
360
360
}
361
+
362
+ // Example use case
363
+ //
364
+ // The Buffer structure can be used to collect enough data that is required
365
+ // for the next steps to proceed. The next steps may consume variable or
366
+ // constant amount of data. In the simplest use-case scenario, one can use
367
+ // it to combine smaller transactions into bigger ones.
368
+
369
+ type Buffer64 = Buffer < 64 > ;
370
+
371
+ proc BufferExampleUsage {
372
+ input_r : chan < u32 > in ;
373
+ output_s : chan < u48 > out ;
374
+
375
+ config (
376
+ input_r : chan < u32 > in ,
377
+ output_s : chan < u48 > out
378
+ ) { (input_r , output_s ) }
379
+
380
+ init { Buffer64 { contents : u64 :0 , length : u32 :0 } }
381
+
382
+ next (tok : token , buffer : Buffer64 ) {
383
+ let (tok , recv_data ) = recv (tok , input_r );
384
+ let buffer = buffer_append < u32 :64 > (buffer , recv_data );
385
+
386
+ if buffer .length >= u32 :48 {
387
+ let (buffer , data_to_send ) = buffer_sized_pop < u32 :64 , u32 :48 > (buffer );
388
+ let tok = send (tok , output_s , data_to_send );
389
+ buffer
390
+ } else {
391
+ buffer
392
+ }
393
+ }
394
+ }
395
+
396
+ const NUMBER_OF_TESTED_TRANSACTIONS = u32 :30 ;
397
+
398
+ struct BufferExampleUsageTestState {
399
+ recv_count : u32 ,
400
+ send_count : u32
401
+ }
402
+
403
+ #[test_proc ]
404
+ proc BufferExampleUsageTest {
405
+ terminator : chan < bool > out ;
406
+ data32_s : chan < u32 > out ;
407
+ data48_r : chan < u48 > in ;
408
+
409
+ config (terminator : chan < bool > out ) {
410
+ let (data32_s , data32_r ) = chan < u32 > ;
411
+ let (data48_s , data48_r ) = chan < u48 > ;
412
+ spawn BufferExampleUsage (data32_r , data48_s );
413
+ (terminator , data32_s , data48_r )
414
+ }
415
+
416
+ init {
417
+ BufferExampleUsageTestState {
418
+ recv_count : u32 :0 ,
419
+ send_count : u32 :0
420
+ }
421
+ }
422
+
423
+ next (tok : token , state : BufferExampleUsageTestState ) {
424
+ let data_to_send = match state .send_count % u32 :3 {
425
+ u32 :0 = > u32 :0xDEADBEEF ,
426
+ u32 :1 = > u32 :0xBEEFCAFE ,
427
+ u32 :2 = > u32 :0xCAFEDEAD ,
428
+ _ = > fail !("impossible_case" , u32 :0 ),
429
+ };
430
+ let tok = send (tok , data32_s , data_to_send );
431
+ let send_count = state .send_count + u32 :1 ;
432
+
433
+ let (tok , received_data , valid ) = recv_non_blocking (tok , data48_r , u48 :0 );
434
+ let recv_count = if valid {
435
+ let recv_count = state .recv_count + u32 :1 ;
436
+ trace_fmt !("received data: {:#x}, recv_count {}, send_count {}" ,
437
+ received_data , recv_count , send_count );
438
+ assert_eq (received_data , u48 :0xCAFE _DEAD_BEEF );
439
+ recv_count
440
+ } else {
441
+ state .recv_count
442
+ };
443
+
444
+ assert_eq (u32 :32 * (send_count - u32 :1 ) / u32 :48 , recv_count );
445
+
446
+ let do_send = (state .send_count == NUMBER_OF_TESTED_TRANSACTIONS - u32 :1 );
447
+ send_if (tok , terminator , do_send , true);
448
+
449
+ BufferExampleUsageTestState { recv_count , send_count }
450
+ }
451
+ }
0 commit comments