{-# 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 :: ByteArray -> Int -> Int -> String -> String
showsSlice ByteArray
arr Int
off Int
len String
s = if Int
len forall a. Eq a => a -> a -> Bool
== Int
0
  then String -> String -> String
showString String
"[]" String
s
  else String -> String -> String
showString String
"[0x"
     forall a b. (a -> b) -> a -> b
$ Word8 -> String -> String
showHexDigitsWord8 (forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
arr Int
off)
     forall a b. (a -> b) -> a -> b
$ Int -> Int -> ByteArray -> String -> String
showHexLoop (Int
off forall a. Num a => a -> a -> a
+ Int
1) (Int
len forall a. Num a => a -> a -> a
- Int
1) ByteArray
arr
     forall a b. (a -> b) -> a -> b
$ Char -> String -> String
showChar Char
']'
     forall a b. (a -> b) -> a -> b
$ String
s

showHexLoop :: Int -> Int -> ByteArray -> String -> String
showHexLoop :: Int -> Int -> ByteArray -> String -> String
showHexLoop !Int
ix !Int
len !ByteArray
arr String
s = if Int
len forall a. Ord a => a -> a -> Bool
> Int
0
  then Char
','forall a. a -> [a] -> [a]
:Char
'0'forall a. a -> [a] -> [a]
:Char
'x'forall a. a -> [a] -> [a]
:Word8 -> String -> String
showHexDigitsWord8 (forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
arr Int
ix) (Int -> Int -> ByteArray -> String -> String
showHexLoop (Int
ix forall a. Num a => a -> a -> a
+ Int
1) (Int
len forall a. Num a => a -> a -> a
- Int
1) ByteArray
arr String
s)
  else String
s

showHexDigitsWord8 :: Word8 -> String -> String
showHexDigitsWord8 :: Word8 -> String -> String
showHexDigitsWord8 !Word8
w String
s = Word8 -> Char
word4ToChar (forall a. Bits a => a -> Int -> a
unsafeShiftR Word8
w Int
4) forall a. a -> [a] -> [a]
: Word8 -> Char
word4ToChar (Word8
0x0F forall a. Bits a => a -> a -> a
.&. Word8
w) forall a. a -> [a] -> [a]
: String
s

word4ToChar :: Word8 -> Char
word4ToChar :: Word8 -> Char
word4ToChar Word8
w = if Word8
w forall a. Ord a => a -> a -> Bool
< Word8
10
  then Int -> Char
unsafeChr (Char -> Int
ord Char
'0' forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w)
  else Int -> Char
unsafeChr (Char -> Int
ord Char
'a' forall a. Num a => a -> a -> a
+ (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w) forall a. Num a => a -> a -> a
- Int
10)