{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Data.Sequence.Word8 (

	-- * FROM/TO BITS

	fromBits, fromBits', toBits, toBits', fromBitsBE', toBitsBE

	) where

import Data.Bits
import Data.Bits.ToolsYj
import Data.Bool
import Data.Word
import Data.Sequence qualified as Seq
import Data.Sequence.ToolsYj qualified as Seq

fromBits :: Bits b => b -> Seq.Seq Word8
fromBits :: forall b. Bits b => b -> Seq Word8
fromBits = (b -> Maybe (Word8, b)) -> b -> Seq Word8
forall b a. (b -> Maybe (a, b)) -> b -> Seq a
Seq.unfoldr \b
b ->
	Maybe (Word8, b) -> Maybe (Word8, b) -> Bool -> Maybe (Word8, b)
forall a. a -> a -> Bool -> a
bool Maybe (Word8, b)
forall a. Maybe a
Nothing ((Word8, b) -> Maybe (Word8, b)
forall a. a -> Maybe a
Just (Int -> b -> Word8
forall a b. (Bits a, Bits b) => Int -> a -> b
bitsToBits Int
8 b
b, b
b b -> Int -> b
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)) (b
b b -> b -> Bool
forall a. Eq a => a -> a -> Bool
/= b
forall a. Bits a => a
zeroBits)

fromBits' :: FiniteBits b => b -> Seq.Seq Word8
fromBits' :: forall b. FiniteBits b => b -> Seq Word8
fromBits' b
b0 = Int -> b -> Seq Word8
forall {t} {t} {a}.
(Num t, Bits t, Bits a, Eq t) =>
t -> t -> Seq a
go (b -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize b
b0 Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8) b
b0
	where
	go :: t -> t -> Seq a
go t
0 t
_ = Seq a
forall a. Seq a
Seq.Empty
	go t
n t
b = Int -> t -> a
forall a b. (Bits a, Bits b) => Int -> a -> b
bitsToBits Int
8 t
b a -> Seq a -> Seq a
forall a. a -> Seq a -> Seq a
`Seq.cons` t -> t -> Seq a
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1) (t
b t -> Int -> t
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)

toBits :: Bits b => Seq.Seq Word8 -> b
toBits :: forall b. Bits b => Seq Word8 -> b
toBits = (Word8 -> b -> b) -> b -> Seq Word8 -> b
forall a b. (a -> b -> b) -> b -> Seq a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Word8
b b
s -> Int -> Word8 -> b
forall a b. (Bits a, Bits b) => Int -> a -> b
bitsToBits Int
8 Word8
b b -> b -> b
forall a. Bits a => a -> a -> a
.|. b
s b -> Int -> b
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) b
forall a. Bits a => a
zeroBits

toBits' :: forall b . FiniteBits b => Seq.Seq Word8 -> Maybe b
toBits' :: forall b. FiniteBits b => Seq Word8 -> Maybe b
toBits' Seq Word8
bs = Maybe b -> Maybe b -> Bool -> Maybe b
forall a. a -> a -> Bool -> a
bool
	Maybe b
forall a. Maybe a
Nothing
	(b -> Maybe b
forall a. a -> Maybe a
Just (b -> Maybe b) -> b -> Maybe b
forall a b. (a -> b) -> a -> b
$ (Word8 -> b -> b) -> b -> Seq Word8 -> b
forall a b. (a -> b -> b) -> b -> Seq a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Word8
b b
s -> Int -> Word8 -> b
forall a b. (Bits a, Bits b) => Int -> a -> b
bitsToBits Int
8 Word8
b b -> b -> b
forall a. Bits a => a -> a -> a
.|. b
s b -> Int -> b
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) b
forall a. Bits a => a
zeroBits Seq Word8
bs)
	(Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Seq Word8 -> Int
forall a. Seq a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Seq Word8
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= forall b. FiniteBits b => b -> Int
finiteBitSize @b b
forall a. HasCallStack => a
undefined)

fromBitsBE' :: FiniteBits b => b -> Seq.Seq Word8
fromBitsBE' :: forall b. FiniteBits b => b -> Seq Word8
fromBitsBE' b
b0 = Int -> b -> Seq Word8
forall {t} {t} {a}.
(Num t, Bits t, Bits a, Eq t) =>
t -> t -> Seq a
go (b -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize b
b0 Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8) b
b0
	where
	go :: t -> a -> Seq a
go t
0 a
_ = Seq a
forall a. Seq a
Seq.Empty
	go t
n a
b = t -> a -> Seq a
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1) (a
b a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftR` Int
8) Seq a -> a -> Seq a
forall a. Seq a -> a -> Seq a
`Seq.snoc` Int -> a -> a
forall a b. (Bits a, Bits b) => Int -> a -> b
bitsToBits Int
8 a
b

toBitsBE :: Bits b => Seq.Seq Word8 -> b
toBitsBE :: forall b. Bits b => Seq Word8 -> b
toBitsBE = (b -> Word8 -> b) -> b -> Seq Word8 -> b
forall b a. (b -> a -> b) -> b -> Seq a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\b
s Word8
b -> Int -> Word8 -> b
forall a b. (Bits a, Bits b) => Int -> a -> b
bitsToBits Int
8 Word8
b b -> b -> b
forall a. Bits a => a -> a -> a
.|. b
s b -> Int -> b
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) b
forall a. Bits a => a
zeroBits