File: ByteString.hs

package info (click to toggle)
haskell-spool 0.1-5
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 64 kB
  • sloc: haskell: 81; makefile: 5
file content (36 lines) | stat: -rw-r--r-- 1,321 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-- | Convert between @ByteString@ and @Vector.Storable@
-- without copying.
module Data.Vector.Storable.ByteString
    ( -- | See also the caveats mentioned in the package's
      -- top-level documentation.
      byteStringToVector
    , vectorToByteString
    ) where

import qualified Data.ByteString          as BS
import qualified Data.ByteString.Internal as BS
import qualified Data.Vector.Storable     as V

import Foreign.Storable
import Foreign.ForeignPtr

sizeOfElem :: (Storable a) => V.Vector a -> Int
sizeOfElem vec = sizeOf (undefined `asTypeOf` V.head vec)

-- | Convert a @'BS.ByteString'@ to a @'V.Vector'@.
--
-- This function can produce @'Vector'@s which do not obey
-- architectural alignment requirements.  On @x86@ this should
-- not be an issue.
byteStringToVector :: (Storable a) => BS.ByteString -> V.Vector a
byteStringToVector bs = vec where
    vec = V.unsafeFromForeignPtr (castForeignPtr fptr) (scale off) (scale len)
    (fptr, off, len) = BS.toForeignPtr bs
    scale = (`div` sizeOfElem vec)

-- | Convert a @'V.Vector'@ to a @'BS.ByteString'@.
vectorToByteString :: (Storable a) => V.Vector a -> BS.ByteString
vectorToByteString vec
  = BS.fromForeignPtr (castForeignPtr fptr) (scale off) (scale len) where
    (fptr, off, len) = V.unsafeToForeignPtr vec
    scale = (* sizeOfElem vec)