1 \ *****************************************************************************
2 \ * Copyright (c) 2004, 2008 IBM Corporation
3 \ * All rights reserved.
4 \ * This program and the accompanying materials
5 \ * are made available under the terms of the BSD License
6 \ * which accompanies this distribution, and is available at
7 \ * http://www.opensource.org/licenses/bsd-license.php
10 \ * IBM Corporation - initial implementation
11 \ ****************************************************************************/
14 \ =============================================================================
15 \ =============================================================================
18 \ The deblocker. Allows block devices to be used as a (seekable) byte device.
20 s" deblocker" device-name
22 INSTANCE VARIABLE offset
23 INSTANCE VARIABLE block-size
24 INSTANCE VARIABLE max-transfer
25 INSTANCE VARIABLE my-block
28 INSTANCE VARIABLE fail-count
31 s" block-size" ['] $call-parent CATCH IF 2drop false EXIT THEN
33 s" max-transfer" ['] $call-parent CATCH IF 2drop false EXIT THEN
35 block-size @ alloc-mem my-block !
38 : close my-block @ block-size @ free-mem ;
40 : seek ( lo hi -- status ) \ XXX: perhaps we should fail if the underlying
41 \ device would fail at this offset
43 : block+remainder ( -- block# remainder ) offset @ block-size @ u/mod swap ;
44 : read-blocks ( addr block# #blocks -- actual ) s" read-blocks" $call-parent ;
45 : read ( addr len -- actual )
47 \ First, handle a partial block at the start.
48 block+remainder dup IF ( block# offset-in-block )
49 >r my-block @ swap 1 read-blocks drop
50 my-block @ r@ + adr @ block-size @ r> - len @ min dup >r move
51 r> dup negate len +! dup adr +! offset +! ELSE 2drop THEN
53 \ Now, in a loop read max. max-transfer sized runs of whole blocks.
55 BEGIN len @ block-size @ >= WHILE
56 adr @ block+remainder drop len @ max-transfer @ min block-size @ / read-blocks
59 fail-count @ 5 >= IF r> drop EXIT THEN
63 block-size @ * dup negate len +! dup adr +! offset +!
66 \ And lastly, handle a partial block at the end.
67 len @ IF my-block @ block+remainder drop 1 read-blocks drop
68 my-block @ adr @ len @ move THEN