Reputation: 3833
What's the most efficient way to cast String
(or ByteString
) to an integral type bitwise, for example:
smallEndianStringToInt32 :: ByteString -> Int32
smallEndianStringToInt32 str =
case str of
[a,b,c,d] -> shiftL d 24 .|. shiftL c 16 .|. shiftL b 8 .|. a
_ -> 0
In C we can simply do it like this, really low-cost:
char* some_string = "....";
int32_t x = *(int32_t*)some_string;
But the former implementation (smallEndianStringToInt32
) doesn't look as fast as the C code.
How can this be done? (Or it actually IS as fast?)
Upvotes: 0
Views: 123
Reputation: 31305
I think this does what you're looking for, but like the other commenters, I'd recommend you clarify what you're actually trying to do, as this is very non-idiomatic Haskell:
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Internal
import Foreign.Storable
import Foreign.ForeignPtr
import Foreign.Ptr
import Data.Word (Word32)
main :: IO ()
main = withForeignPtr fptr $ \ptr -> do
i <- peek $ castPtr (ptr `plusPtr` off)
print (i :: Word32)
where
PS fptr off len = "A\0\0\0"
As should be painfully obvious, this code is quite susceptible to segfaults, for example.
Upvotes: 3