RnMss
RnMss

Reputation: 3833

Haskell: Efficient way to bitwise cast String to Integer?

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

Answers (1)

Michael Snoyman
Michael Snoyman

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

Related Questions