thrift-lib-0.1.0.1: Thrift/Protocol/Binary/Internal.hs
{-
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.
-}
{-# LANGUAGE CPP #-}
module Thrift.Protocol.Binary.Internal
( binaryFloat, binaryDouble, getBuffer
) where
#if __GLASGOW_HASKELL__ == 804
import Thrift.Binary.Parser (getWord32be)
#endif
import Thrift.Binary.Parser as P
import Data.ByteString (ByteString)
import Foreign.Marshal.Alloc
import Foreign.Storable as F
import Foreign.Ptr
import System.IO.Unsafe
{-# INLINE toFloat #-}
toFloat
:: (Floating f, Storable f, Storable a)
=> a
-> f
toFloat a =
unsafeDupablePerformIO $ alloca $ \ptr ->
poke ptr a >> F.peek (castPtr ptr)
{-# INLINE binaryFloat #-}
binaryFloat :: Parser Float
binaryFloat = toFloat <$> getWord32be
{-# INLINE binaryDouble #-}
binaryDouble :: Parser Double
binaryDouble = toFloat <$> getWord64be
{-# INLINE getBuffer #-}
-- | Parse a ByteString given a length parser and a copy function.
-- Note: The copy function *must* copy the input, otherwise this is unsafe
-- because the result is a slice of the input which may be a memory buffer that
-- is owned by C++. We also want to eliminate references to the input so that it
-- can get GC'd
getBuffer :: Integral len => Parser len -> (ByteString -> a) -> Parser a
getBuffer getLength copy = do
len <- getLength
buf <- P.getByteString $ fromIntegral len
return $! copy buf