Skip to content

Commit

Permalink
Modify API to be friendlier to ForeignPtr
Browse files Browse the repository at this point in the history
  • Loading branch information
kozross committed Jan 27, 2022
1 parent 1c68411 commit 2cbad71
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 44 deletions.
37 changes: 17 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
1 change: 1 addition & 0 deletions cryptography-blake3-bindings.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extra-source-files:
CHANGELOG.md
include/blake3.h
include/blake3_impl.h
include/sizes.h
LICENSE
README.md

Expand Down
3 changes: 3 additions & 0 deletions include/sizes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "blake3.h"

const size_t blake3_hasher_size = sizeof(blake3_hasher);
34 changes: 10 additions & 24 deletions src/Cryptography/BLAKE3/Bindings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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".
Expand All @@ -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.
Expand Down Expand Up @@ -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

0 comments on commit 2cbad71

Please sign in to comment.