blob: b8feea1a92d0b92075ff9b4f319115b8606dc3cb [file] [log] [blame]
\ See license at end of file
\ opening, seeking and reading the contents of an existing file.
\ 10/2/90 cpt: revised for reading continuous clusters in 1 shot.
private
: to-first-cluster ( -- )
0 fh_logicalcl l!
fh_first l@ fh_physicalcl l!
0 fh_prevphyscl l!
;
: last-cluster? ( -- flag )
fh_physicalcl l@ fat-end? fh_physicalcl l@ 0= or ;
: to-next-cluster ( -- )
fh_physicalcl l@ dup fh_prevphyscl l! ( previous-physical-cluster# )
cluster@ fh_physicalcl l!
fh_logicalcl l@ 1+ fh_logicalcl l!
;
: to-last-cluster ( -- )
begin last-cluster? 0= while to-next-cluster repeat
;
: dos-seek ( byte# fh -- error? )
fh ! ( byte# )
fh_dev @ set-device
fh_clshift w@ >> ( target-cl )
\ Bail out early if we're already on the right cluster
dup fh_logicalcl l@ = if drop false exit then
\ If we are seeking forward, start at the current position. Otherwise
\ start at the beginning of the file.
dup fh_logicalcl l@ <= if to-first-cluster then
\ Advance to the desired cluster, if it exists.
begin dup fh_logicalcl l@ <> while ( target-cluster# )
last-cluster? if drop true exit then \ End of file?
to-next-cluster
repeat ( target-cluster# )
drop false
;
: log2 ( n -- log2-of-n )
-1 swap bits/cell 0 do
1 >> dup 0= if nip i swap leave then
loop ( log n' )
drop
;
: fh-open ( 'dirent -- fh false | true )
dirent !
allocate-fh if fh ! else true exit then
fh_isopen
de_attributes c@ at_rdonly and 0= if fh_writeable or then
fh_flags w!
current-device @ fh_dev !
dir-cl @ fh_dircl ! \ Cluster containing the directory entry
dirent @ dir-buf - fh_diroff w! \ Location of directory entry in its cluster
( fh_dircl ? ) ( fh_diroff ? )
file-cluster@ fh_first l!
de_length lel@ fh_length l!
to-first-cluster
/cluster log2 fh_clshift w!
fh @ false
;
: name-open ( adr len mode -- fh false | true )
\ If the mode specifies writing, look for writeable normal files
\ If mode is "read" (0), also find read-only files and subdirectories
1 >= if 0 else at_rdonly then
at_system or at_hidden or ( adr len file-types )
find-first if dirent @ fh-open else -1 then
;
variable remaining \ bytes
variable requested \ bytes
variable bufadr
VARIABLE 1st-cl# \ marks 1st of an allocated cotinuous cluster range
VARIABLE #cont-cls \ marks # of clusters in the ---- " --------
VARIABLE next-cl# \ marks next 1st cluster of non-continuous cluster range
\ (for read its used as a flag only)
: current-position ( -- n ) fh_logicalcl l@ fh_clshift w@ << ;
: cl#-valid? ( cl# -- flag ) 2 max-cl# l@ between ;
: dos-read ( adr count 'fh -- #read false | true )
fh ! fh_dev @ set-device ( adr count )
dup remaining ! dup requested ! swap bufadr ! ( count )
bytes>clusters ( #cls-to-read )
fh_physicalcl l@ dup 1st-cl# ! 1 #cont-cls ! ( #cls phys-cl# )
cl#-valid? 0= next-cl# ! \ set if not in valid range!
( #cls-to-read )
begin
dup 0>
remaining @ 0> and
current-position fh_length l@ u< and
last-cluster? 0= and
while ( #cls-remaining )
to-next-cluster
1st-cl# @ #cont-cls @ + fh_physicalcl l@ = if
\ increment counter only if not first loop
next-cl# @ if next-cl# off else #cont-cls 1+! then
else
next-cl# @ 0= if
1st-cl# @ #cont-cls @ bufadr @ read-clusters if
drop true exit
then
#cont-cls @ /cluster * dup bufadr +! negate remaining +!
then
fh_physicalcl l@ 1st-cl# ! 1 #cont-cls ! next-cl# off
then
1- ( #cls-to-read-1 )
repeat drop
remaining @ 0> next-cl# @ 0= and 1st-cl# @ cl#-valid? and if
\ We did loop & there is real data
remaining @ bytes>clusters ( #clusters-left )
1st-cl# @ over bufadr @ read-clusters if drop true exit then
/cluster * negate remaining +!
then
requested @ remaining @ - ( bytes-tranferred )
\ If the last cluster of the file has been read, account for the
\ true length of the file
current-position fh_length l@ u> if ( bytes-tranferred )
current-position fh_length l@ - - ( bytes-valid )
then ( bytes-valid )
false
;
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\
\ Permission is hereby granted, free of charge, to any person obtaining
\ a copy of this software and associated documentation files (the
\ "Software"), to deal in the Software without restriction, including
\ without limitation the rights to use, copy, modify, merge, publish,
\ distribute, sublicense, and/or sell copies of the Software, and to
\ permit persons to whom the Software is furnished to do so, subject to
\ the following conditions:
\
\ The above copyright notice and this permission notice shall be
\ included in all copies or substantial portions of the Software.
\
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\
\ LICENSE_END