From 9bbbf151b5bdde3f0bead1886996f17764e85521 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Thu, 23 Aug 2018 12:23:39 -0400 Subject: 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. --- src/BTLS/BoringSSLPatterns.hs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src/BTLS/BoringSSLPatterns.hs') 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) -- cgit v1.2.3