Carcigenicate
Carcigenicate

Reputation: 45826

How do I convert 4 bytes of a ByteString to an Int?

How can I convert a ByteString to an Int?

I have the following 4 bytes that I want to convert (it represents the size in bytes of a .bmp file):

"v\SOH\NUL\NUL"

which I know equals 374

Upvotes: 1

Views: 927

Answers (2)

ErikR
ErikR

Reputation: 52057

For binary parsing, have a look at the binary package - http://hackage.haskell.org/package/binary

It defines a Get monad, so you can write something like:

data Header { ftype :: ByteString, size_ :: Word32, reserved_ :: ByteString, offset_ :: Word32 } 
parseHeader = do
  ft <- getByteString 2
  size <- getWord32le
  reserved <- getByteString 4
  offset <- getWord32le
  return $ Header ft size reserved offset

and later:

main = do
  bytes <- hGetContents handle
  let header = runGet parseHeader bytes
  ...

Upvotes: 3

Carcigenicate
Carcigenicate

Reputation: 45826

I managed to get a small functions working that demonstrates the idea

import qualified Data.ByteString.Lazy.Char8 as B

lEBsToInt :: B.ByteString -> Int -- littleEndianByteStringToInt
lEBsToInt bs = let bsI = B.take 4 bs in -- 1.
    fst $ B.foldl (\(s,i) b -> let shiftBy = i * 8 in -- 2.
        (s + (ord b `shiftL` shiftBy), i + 1)) (0,0) bsI --3.
  1. Get the first 4 bytes of a ByteString
  2. Calculate the amount to shift by
  3. Fold over the ByteString, summing the result of shifting the current byte by the current offset

lEBsToInt "v\SOH\NUL\NUL" = 374

This could definitely be improved, but I was happy with it

Upvotes: 0

Related Questions