aboutsummaryrefslogtreecommitdiff
path: root/src/BTLS/BoringSSLPatterns.hs
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@google.com>2018-08-23 12:23:39 -0400
committerGravatar Benjamin Barenblat <bbaren@google.com>2018-08-23 12:23:39 -0400
commit9bbbf151b5bdde3f0bead1886996f17764e85521 (patch)
tree9cb2f7e814d99626bc7f4d99dacce6b03fdb9b96 /src/BTLS/BoringSSLPatterns.hs
parentf7277a0fa46d97de4fa871d3744af948d258a334 (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.hs25
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)