packages feed

byteslice-0.2.10.0: src/Data/Bytes/Internal/Show.hs

{-# language BangPatterns #-}

module Data.Bytes.Internal.Show
  ( showsSlice
  ) where

import Data.Bits ((.&.),unsafeShiftR)
import Data.Char (ord)
import Data.Primitive (ByteArray)
import Data.Word (Word8)
import GHC.Base (unsafeChr)

import qualified Data.Primitive as PM

showsSlice :: ByteArray -> Int -> Int -> String -> String
showsSlice arr off len s = if len == 0
  then showString "[]" s
  else showString "[0x"
     $ showHexDigitsWord8 (PM.indexByteArray arr off)
     $ showHexLoop (off + 1) (len - 1) arr
     $ showChar ']'
     $ s

showHexLoop :: Int -> Int -> ByteArray -> String -> String
showHexLoop !ix !len !arr s = if len > 0
  then ',':'0':'x':showHexDigitsWord8 (PM.indexByteArray arr ix) (showHexLoop (ix + 1) (len - 1) arr s)
  else s

showHexDigitsWord8 :: Word8 -> String -> String
showHexDigitsWord8 !w s = word4ToChar (unsafeShiftR w 4) : word4ToChar (0x0F .&. w) : s

word4ToChar :: Word8 -> Char
word4ToChar w = if w < 10
  then unsafeChr (ord '0' + fromIntegral w)
  else unsafeChr (ord 'a' + (fromIntegral w) - 10)