diff options
author | Benjamin Barenblat <bbaren@google.com> | 2018-08-23 12:23:39 -0400 |
---|---|---|
committer | Benjamin Barenblat <bbaren@google.com> | 2018-08-23 12:23:39 -0400 |
commit | 9bbbf151b5bdde3f0bead1886996f17764e85521 (patch) | |
tree | 9cb2f7e814d99626bc7f4d99dacce6b03fdb9b96 /src/BTLS/BoringSSLPatterns.hs | |
parent | f7277a0fa46d97de4fa871d3744af948d258a334 (diff) |
Factor out common allocate-modify-read pattern
Many functions in BoringSSL accept a buffer and a pointer to size, write
data into the buffer, and mutate the size. Create a function
representing this pattern that also loads the result into a ByteString
for convenience.
Diffstat (limited to 'src/BTLS/BoringSSLPatterns.hs')
-rw-r--r-- | src/BTLS/BoringSSLPatterns.hs | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/src/BTLS/BoringSSLPatterns.hs b/src/BTLS/BoringSSLPatterns.hs index 4b08663..e77abcb 100644 --- a/src/BTLS/BoringSSLPatterns.hs +++ b/src/BTLS/BoringSSLPatterns.hs @@ -14,6 +14,7 @@ module BTLS.BoringSSLPatterns ( initUpdateFinalize + , onBufferOfMaxSize ) where import Data.ByteString (ByteString) @@ -49,14 +50,28 @@ initUpdateFinalize mallocCtx initialize update finalize bytes = do withForeignPtr ctxFP $ \ctx -> do initialize ctx mapM_ (updateBytes ctx) (ByteString.Lazy.toChunks bytes) - allocaArray evpMaxMDSize $ \rOut -> - alloca $ \pOutSize -> do - finalize ctx rOut pOutSize - outSize <- fromIntegral <$> peek pOutSize - ByteString.packCStringLen (rOut, outSize) + onBufferOfMaxSize evpMaxMDSize (finalize ctx) where updateBytes ctx chunk = -- The updater won't mutate its arguments, so the sharing inherent in -- 'ByteString.unsafeUseAsCStringLen' is fine. ByteString.unsafeUseAsCStringLen chunk $ \(buf, len) -> update ctx buf (fromIntegral len) + +-- | Allocates a buffer, runs a function 'f' to partially fill it, and packs the +-- filled data into a 'ByteString'. 'f' must write the size of the filled data, +-- in bytes and not including any trailing null, into its second argument. +-- +-- If 'f' is safe to use under 'unsafeLocalState', this whole function is safe +-- to use under 'unsafeLocalState'. +onBufferOfMaxSize :: + (Integral size, Storable size) + => Int + -> (Ptr CChar -> Ptr size -> IO ()) + -> IO ByteString +onBufferOfMaxSize maxSize f = + allocaArray maxSize $ \pOut -> + alloca $ \pOutLen -> do + f pOut pOutLen + outLen <- fromIntegral <$> peek pOutLen + ByteString.packCStringLen (pOut, outLen) |