worker.tri (1365B)
1 !import base as B 2 !import native_math as N 3 !import io as IO 4 !export hashFile 5 6 limitError = B.err ["invalid-bound" "filecheck/hash" "file exceeds byte limit" "none"] t 7 8 -- Read position comes from the file handle, keeping the loop free of a lazy 9 -- byte-count accumulator. A growing file can consume one excess chunk on error. 10 hashLoop reader digest limit = do IO.onOk 11 received <- IO.readSome reader 4096 12 position <- IO.filePosition reader 13 case N.lte position limit of 14 (t t) = case received of 15 ("eof", t) = do IO.onOk 16 hash <- IO.finishDigest digest 17 IO.pure (B.ok [position hash] t) 18 ("data", bytes) = do IO.onOk 19 IO.updateDigest digest bytes 20 hashLoop reader digest limit 21 _ = IO.fail "Invalid filecheck read reply" 22 _ = IO.pure limitError 23 24 hashFile path limit = IO.io <| do IO.onOk 25 status <- IO.statPath path 26 case status of 27 ["file" size] = case N.lte size limit of 28 (t t) = IO.scope (owner : do IO.onOk 29 reader <- IO.openReader owner path 30 size <- IO.fileSize reader 31 case N.lte size limit of 32 (t t) = do IO.onOk 33 digest <- IO.openDigest owner "sha256" 34 hashLoop reader digest limit 35 _ = IO.pure limitError) 36 _ = IO.pure limitError 37 _ = IO.pure (B.err ["invalid-argument" "filecheck/hash" "expected regular file" "none"] t)