{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
module HaskellWorks.Data.Bits.FromBitTextByteString
( FromBitTextByteString(..)
) where
import Data.Word
import HaskellWorks.Data.Bits
import qualified Data.Bit as Bit
import qualified Data.Bit.ThreadSafe as BitTS
import qualified Data.ByteString as BS
import qualified Data.Vector.Storable as DVS
import qualified Data.Vector.Unboxed as DVU
class FromBitTextByteString a where
fromBitTextByteString :: BS.ByteString -> a
instance FromBitTextByteString (DVS.Vector Word8) where
fromBitTextByteString :: BS.ByteString -> DVS.Vector Word8
fromBitTextByteString bs = DVS.unfoldrN (BS.length bs `div` 8 + 1) gen bs
where gen :: BS.ByteString -> Maybe (Word8, BS.ByteString)
gen cs = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' 1 0 ds
Just (d, ds) | d == w1 -> gen' 1 1 ds
Just (_, ds) -> gen ds
Nothing -> Nothing
gen' :: Int -> Word8 -> BS.ByteString -> Maybe (Word8, BS.ByteString)
gen' n w cs
| n >= 8 = Just (w, cs)
| otherwise = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' (n + 1) (w .|. (0 .<. fromIntegral n)) ds
Just (d, ds) | d == w1 -> gen' (n + 1) (w .|. (1 .<. fromIntegral n)) ds
Just (_, ds) -> gen' n w ds
Nothing -> Just (w, cs)
instance FromBitTextByteString (DVS.Vector Word16) where
fromBitTextByteString :: BS.ByteString -> DVS.Vector Word16
fromBitTextByteString bs = DVS.unfoldrN (BS.length bs `div` 16 + 1) gen bs
where gen :: BS.ByteString -> Maybe (Word16, BS.ByteString)
gen cs = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' 1 0 ds
Just (d, ds) | d == w1 -> gen' 1 1 ds
Just (_, ds) -> gen ds
Nothing -> Nothing
gen' :: Int -> Word16 -> BS.ByteString -> Maybe (Word16, BS.ByteString)
gen' n w cs
| n >= 16 = Just (w, cs)
| otherwise = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' (n + 1) (w .|. (0 .<. fromIntegral n)) ds
Just (d, ds) | d == w1 -> gen' (n + 1) (w .|. (1 .<. fromIntegral n)) ds
Just (_, ds) -> gen' n w ds
Nothing -> Just (w, cs)
instance FromBitTextByteString (DVS.Vector Word32) where
fromBitTextByteString :: BS.ByteString -> DVS.Vector Word32
fromBitTextByteString bs = DVS.unfoldrN (BS.length bs `div` 32 + 1) gen bs
where gen :: BS.ByteString -> Maybe (Word32, BS.ByteString)
gen cs = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' 1 0 ds
Just (d, ds) | d == w1 -> gen' 1 1 ds
Just (_, ds) -> gen ds
Nothing -> Nothing
gen' :: Int -> Word32 -> BS.ByteString -> Maybe (Word32, BS.ByteString)
gen' n w cs
| n >= 32 = Just (w, cs)
| otherwise = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' (n + 1) (w .|. (0 .<. fromIntegral n)) ds
Just (d, ds) | d == w1 -> gen' (n + 1) (w .|. (1 .<. fromIntegral n)) ds
Just (_, ds) -> gen' n w ds
Nothing -> Just (w, cs)
instance FromBitTextByteString (DVS.Vector Word64) where
fromBitTextByteString :: BS.ByteString -> DVS.Vector Word64
fromBitTextByteString bs = DVS.unfoldrN (BS.length bs `div` 64 + 1) gen bs
where gen :: BS.ByteString -> Maybe (Word64, BS.ByteString)
gen cs = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' 1 0 ds
Just (d, ds) | d == w1 -> gen' 1 1 ds
Just (_, ds) -> gen ds
Nothing -> Nothing
gen' :: Int -> Word64 -> BS.ByteString -> Maybe (Word64, BS.ByteString)
gen' n w cs
| n >= 64 = Just (w, cs)
| otherwise = case BS.uncons cs of
Just (d, ds) | d == w0 -> gen' (n + 1) (w .|. (0 .<. fromIntegral n)) ds
Just (d, ds) | d == w1 -> gen' (n + 1) (w .|. (1 .<. fromIntegral n)) ds
Just (_, ds) -> gen' n w ds
Nothing -> Just (w, cs)
instance FromBitTextByteString (DVU.Vector Bit.Bit) where
fromBitTextByteString :: BS.ByteString -> DVU.Vector Bit.Bit
fromBitTextByteString bs = DVU.unfoldrN (BS.length bs) gen bs
where gen :: BS.ByteString -> Maybe (Bit.Bit, BS.ByteString)
gen cs = case BS.uncons cs of
Just (d, ds) | d == w0 -> Just (Bit.Bit False, ds)
Just (d, ds) | d == w1 -> Just (Bit.Bit True, ds)
Just (_, ds) -> gen ds
Nothing -> Nothing
instance FromBitTextByteString (DVU.Vector BitTS.Bit) where
fromBitTextByteString :: BS.ByteString -> DVU.Vector BitTS.Bit
fromBitTextByteString bs = DVU.unfoldrN (BS.length bs) gen bs
where gen :: BS.ByteString -> Maybe (BitTS.Bit, BS.ByteString)
gen cs = case BS.uncons cs of
Just (d, ds) | d == w0 -> Just (BitTS.Bit False, ds)
Just (d, ds) | d == w1 -> Just (BitTS.Bit True, ds)
Just (_, ds) -> gen ds
Nothing -> Nothing
w0 :: Word8
w0 = 48
w1 :: Word8
w1 = 49