diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd4a772..a8c9d93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: ./hlint/dist-newstyle ./ormolu/dist-newstyle ./cabal-fmt/dist-newstyle - key: ${{ env.V }}-${{ hashFiles('./hlint/cabal.project.freeze', './ormolu/cabal.project/freeze', './cabal-fmt/cabal.project.freeze') }} + key: ${{ env.V }}-${{ hashFiles('./cabal-fmt/cabal.project.freeze') }} restore-keys: ${{ env.V }}- - name: Install cabal-fmt working-directory: cabal-fmt @@ -114,3 +114,26 @@ jobs: run: | ~/.ghcup/bin/cabal update ~/.ghcup/bin/cabal build -w ~/.ghcup/bin/ghc + freebsd: + name: "Emulated: GHC ${{ matrix.ghc }} on FreeBSD" + runs-on: macos-10.15 + strategy: + matrix: + ghc: ['9.0.1'] # 8.10.7 is vulnerable to a bug, no 9.2.1 on FreeBSD yet + steps: + - name: Checkout base repo + uses: actions/checkout@v2.3.5 + - name: Build + uses: vmactions/freebsd-vm@v0.1.6 + with: + usesh: true + prepare: | + pkg install -y autotools gmp curl gmake ncurses libffi pkgconf + ln -s /lib/libffi.so.7 /lib/libffi.so.6 + curl -JL https://downloads.haskell.org/~ghcup/0.1.17.4/x86_64-freebsd13-ghcup-0.1.17.4 > ghcup + chmod +x ghcup + ./ghcup -v install ghc --set ${{ matrix.ghc }} + ./ghcup -v install cabal --set + run: | + ~/.ghcup/bin/cabal update + ~/.ghcup/bin/cabal build -w ~/.ghcup/bin/ghc diff --git a/README.md b/README.md index 368d832..7813f92 100644 --- a/README.md +++ b/README.md @@ -34,35 +34,32 @@ it to you. No surprises on upgrades either - _impeccable_ module Sample where -import Data.Word (Word8) +import Foreign.Marshal.Alloc (mallocBytes, free) +import Foreign.C.Types (CSize, CUChar) import Foreign.Ptr (Ptr) -import Foreign.Marshal.Alloc (mallocBytes) import Cryptography.BLAKE3.Bindings ( - blake3HasherAlloc, - blake3HasherInit, - blake3HasherUpdate, + blake3HasherSize, blake3OutLen, - blake3HasherFree + blake3HasherUpdate, + blake3HasherFinalize ) hashMeSomeData :: IO (Ptr Word8) hashMeSomeData = do - -- allocate and init a hasher - hasherPtr <- blake3HasherAlloc + -- allocate an initialize a hasher + hasherPtr <- mallocBytes . fromIntegral $ blake3HasherSize blake3HasherInit hasherPtr - -- allocate some data to hash - -- we'll assume you've set it all up somehow - (len, dataPtr) <- mkDataWithLen - -- hash the data - blake3HasherUpdate hasherPtr dataPtr len - -- allocate a buffer of the right size to store the result - outPtr :: Ptr Word8 <- mallocBytes . fromIntegral $ blake3OutLen - -- write out the hashed data + -- get some data to hash (we assume this is done in some user-specific way) + (dataLen :: CSize, dataPtr :: Ptr CUChar) <- mkSomeDataWithLength + -- feed the data into the hasher + blake3HasherUpdate hasherPtr dataPtr dataLen + -- make a place to fit the hash into + outPtr <- mallocBytes . fromIntegral $ blake3OutLen + -- output the hash blake3HasherFinalize hasherPtr outPtr blake3OutLen - -- release the hasher - blake3HasherFree hasherPtr - -- yield the answer - pure outPtr + -- deallocate the hasher, since we don't need it anymore + free hasherPtr + -- use the hash output however we please ``` ## What does this run on? diff --git a/include/sizes.h b/include/sizes.h new file mode 100644 index 0000000..8605f0c --- /dev/null +++ b/include/sizes.h @@ -0,0 +1,3 @@ +#include "blake3.h" + +const size_t blake3_hasher_size = sizeof(blake3_hasher); diff --git a/src/Cryptography/BLAKE3/Bindings.hs b/src/Cryptography/BLAKE3/Bindings.hs index 63c626e..ecadbbd 100644 --- a/src/Cryptography/BLAKE3/Bindings.hs +++ b/src/Cryptography/BLAKE3/Bindings.hs @@ -14,22 +14,20 @@ module Cryptography.BLAKE3.Bindings ( -- * Constants blake3VersionString, blake3OutLen, + blake3HasherSize, -- * Data types Blake3Hasher, -- * Functions - blake3HasherAlloc, blake3HasherInit, blake3HasherUpdate, blake3HasherFinalize, - blake3HasherFree, ) where import Data.Word (Word8) import Foreign.C.Types (CChar, CSize (CSize), CUChar) -import Foreign.Marshal.Alloc (free, mallocBytes) import Foreign.Ptr (Ptr) -- | Version C-string for the current BLAKE3 C binding. Currently "1.6.0". @@ -44,21 +42,20 @@ foreign import capi "blake3.h value BLAKE3_VERSION_STRING" foreign import capi "blake3.h value BLAKE3_OUT_LEN" blake3OutLen :: CSize --- | The 'running state' of a hashing process, containing the hash state. --- --- The only meaningful way to interact with this is to allocate one with --- 'blake3HasherAlloc', initialize it with 'blake3HasherInit', use it with the --- other functions in this module, then deallocate with 'blake3HasherFree'. +-- | The number of bytes needed for a 'Blake3Hasher'. -- -- @since 1.0 -data Blake3Hasher +foreign import capi "sizes.h value blake3_hasher_size" + blake3HasherSize :: CSize --- | Allocate enough space for a 'Blake3Hasher'. Ensure that you call --- 'blake3HasherInit' afterwards before you use it. +-- | The 'running state' of a hashing process, containing the hash state. +-- +-- This data is opaque to Haskell; the only way to meaningfully interact with a +-- 'Blake3Hasher' is to allocate one into a 'Foreign.ForeignPtr', initialize it +-- with 'blake3HasherInit', and use it with the other functions in this module. -- -- @since 1.0 -blake3HasherAlloc :: IO (Ptr Blake3Hasher) -blake3HasherAlloc = mallocBytes 3660 +data Blake3Hasher -- | Initialize the 'Blake3Hasher' passed in the first argument. Do this before -- you call 'blake3HasherUpdate' with it. @@ -106,14 +103,3 @@ foreign import capi "blake3.h blake3_hasher_finalize" CSize -> -- | No meaningful result IO () - --- | Deallocates a 'Blake3Hasher'. --- --- = Important note --- --- Do not try to pass a pointer to a deallocated 'Blake3Hasher' to any functions --- unless you enjoy your Haskell code segfaulting. --- --- @since 1.0 -blake3HasherFree :: Ptr Blake3Hasher -> IO () -blake3HasherFree = free