tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

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)