File: ByteString.hs

package info (click to toggle)
haskell-http2 5.3.10-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 55,120 kB
  • sloc: haskell: 7,911; makefile: 3
file content (50 lines) | stat: -rw-r--r-- 1,367 bytes parent folder | download | duplicates (2)
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{-# LANGUAGE ForeignFunctionInterface #-}

module Network.HPACK.Huffman.ByteString (
    unpack4bits,
    copy,
) where

import Foreign.C.Types (CSize (..))
import Foreign.Ptr (Ptr, plusPtr)
import Foreign.Storable (peek)
import System.IO.Unsafe (unsafeDupablePerformIO)

import Imports

-- $setup
-- >>> import qualified Data.ByteString as BS

-- |
--
-- >>> let bs = BS.pack [0x12,0x34,0xf3,0xab]
-- >>> unpack4bits bs
-- [1,2,3,4,15,3,10,11]
-- >>> unpack4bits $ BS.tail bs
-- [3,4,15,3,10,11]
unpack4bits :: ByteString -> [Word8]
unpack4bits (PS fptr off len) = unsafeDupablePerformIO $
    withForeignPtr fptr $ \ptr -> do
        let lim = ptr `plusPtr` (off - 1)
            end = ptr `plusPtr` (off + len - 1)
        go lim end []
  where
    go lim p ws
        | lim == p = return ws
        | otherwise = do
            w <- peek p
            let w0 = w `shiftR` 4
                w1 = w .&. 0xf
            go lim (p `plusPtr` (-1)) (w0 : w1 : ws)

copy :: Ptr Word8 -> ByteString -> IO ()
copy dst (PS fptr off len) = withForeignPtr fptr $ \ptr -> do
    let beg = ptr `plusPtr` off
    memcpy dst beg (fromIntegral len)

foreign import ccall unsafe "string.h memcpy"
    c_memcpy
        :: Ptr Word8 -> Ptr Word8 -> CSize -> IO (Ptr Word8)

memcpy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
memcpy dst src s = void $ c_memcpy dst src (fromIntegral s)