{-# LANGUAGE CPP               #-}
{-# LANGUAGE FlexibleInstances #-}

module HaskellWorks.Data.Simd.Internal.ChunkString where

import Data.Word
import HaskellWorks.Data.ByteString
import HaskellWorks.Data.ByteString.Lazy

import qualified Data.ByteString              as BS
import qualified Data.ByteString.Lazy         as LBS
import qualified Data.Vector.Storable         as DVS
import qualified HaskellWorks.Data.ByteString as BS

newtype ChunkString = ChunkString
  { ChunkString -> [ByteString]
chunks :: [BS.ByteString]
  } deriving (ChunkString -> ChunkString -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ChunkString -> ChunkString -> Bool
$c/= :: ChunkString -> ChunkString -> Bool
== :: ChunkString -> ChunkString -> Bool
$c== :: ChunkString -> ChunkString -> Bool
Eq, Int -> ChunkString -> ShowS
[ChunkString] -> ShowS
ChunkString -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ChunkString] -> ShowS
$cshowList :: [ChunkString] -> ShowS
show :: ChunkString -> String
$cshow :: ChunkString -> String
showsPrec :: Int -> ChunkString -> ShowS
$cshowsPrec :: Int -> ChunkString -> ShowS
Show)

instance ToLazyByteString ChunkString where
  toLazyByteString :: ChunkString -> ByteString
toLazyByteString (ChunkString [ByteString]
cs) = [ByteString] -> ByteString
LBS.fromChunks [ByteString]
cs

instance ToByteStrings ChunkString where
  toByteStrings :: ChunkString -> [ByteString]
toByteStrings (ChunkString [ByteString]
bss) = [ByteString]
bss

class ToChunkString a where
  toChunkString :: a -> ChunkString

instance ToChunkString LBS.ByteString where
  toChunkString :: ByteString -> ChunkString
toChunkString = forall a. ToChunkString a => a -> ChunkString
toChunkString forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
LBS.toChunks

instance ToChunkString [BS.ByteString] where
  toChunkString :: [ByteString] -> ChunkString
toChunkString = [ByteString] -> ChunkString
ChunkString forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [ByteString] -> [ByteString]
BS.rechunk Int
chunkSize

instance ToChunkString [DVS.Vector Word8] where
  toChunkString :: [Vector Word8] -> ChunkString
toChunkString = forall a. ToChunkString a => a -> ChunkString
toChunkString forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. ToByteString a => a -> ByteString
toByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)

instance ToChunkString [DVS.Vector Word16] where
  toChunkString :: [Vector Word16] -> ChunkString
toChunkString = forall a. ToChunkString a => a -> ChunkString
toChunkString forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. ToByteString a => a -> ByteString
toByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)

instance ToChunkString [DVS.Vector Word32] where
  toChunkString :: [Vector Word32] -> ChunkString
toChunkString = forall a. ToChunkString a => a -> ChunkString
toChunkString forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. ToByteString a => a -> ByteString
toByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)

instance ToChunkString [DVS.Vector Word64] where
  toChunkString :: [Vector Word64] -> ChunkString
toChunkString = forall a. ToChunkString a => a -> ChunkString
toChunkString forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. ToByteString a => a -> ByteString
toByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)

instance ToChunkString (DVS.Vector Word8) where
  toChunkString :: Vector Word8 -> ChunkString
toChunkString Vector Word8
v = forall a. ToChunkString a => a -> ChunkString
toChunkString [forall a. ToByteString a => a -> ByteString
toByteString Vector Word8
v]

instance ToChunkString (DVS.Vector Word16) where
  toChunkString :: Vector Word16 -> ChunkString
toChunkString Vector Word16
v = forall a. ToChunkString a => a -> ChunkString
toChunkString [forall a. ToByteString a => a -> ByteString
toByteString Vector Word16
v]

instance ToChunkString (DVS.Vector Word32) where
  toChunkString :: Vector Word32 -> ChunkString
toChunkString Vector Word32
v = forall a. ToChunkString a => a -> ChunkString
toChunkString [forall a. ToByteString a => a -> ByteString
toByteString Vector Word32
v]

instance ToChunkString (DVS.Vector Word64) where
  toChunkString :: Vector Word64 -> ChunkString
toChunkString Vector Word64
v = forall a. ToChunkString a => a -> ChunkString
toChunkString [forall a. ToByteString a => a -> ByteString
toByteString Vector Word64
v]

#if 0
instance BitWise ChunkString where
  ChunkString (a:as) .&. ChunkString (b:bs) = ChunkString (c:cs)
    where len             = end a `min` end b
          c               = toByteString $ DVS.constructN (fromIntegral len) go
          ChunkString cs  = ChunkString as .&. ChunkString bs
          go u            = let ui = end u in (a !!! ui) .&. (b !!! ui)
  ChunkString _ .&. ChunkString _ = ChunkString []
  {-# INLINE (.&.) #-}

  ChunkString (a:as) .|. ChunkString (b:bs) = ChunkString (c:cs)
    where len             = end a `min` end b
          c               = toByteString $ DVS.constructN (fromIntegral len) go
          ChunkString cs  = ChunkString as .|. ChunkString bs
          go u            = let ui = end u in (a !!! ui) .&. (b !!! ui)
  ChunkString _ .|. ChunkString _ = ChunkString []
  {-# INLINE (.|.) #-}

  ChunkString (a:as) .^. ChunkString (b:bs) = ChunkString (c:cs)
    where len             = end a `min` end b
          c               = toByteString $ DVS.constructN (fromIntegral len) go
          ChunkString cs  = ChunkString as .^. ChunkString bs
          go u            = let ui = end u in (a !!! ui) .&. (b !!! ui)
  ChunkString _ .^. ChunkString _ = ChunkString []
  {-# INLINE (.^.) #-}

  comp (ChunkString (a:as)) = ChunkString (c:cs)
    where c               = toByteString $ DVS.constructN (fromIntegral (end a)) go
          ChunkString cs  = comp (ChunkString as)
          go u            = let ui = end u in comp (a !!! ui)
  comp (ChunkString _) = ChunkString []
  {-# INLINE comp #-}

  all0s = ChunkString $ repeat $ toByteString $ DVS.replicate chunkSize (0x00 :: Word8)
  {-# INLINE all0s #-}

  all1s = ChunkString $ repeat $ toByteString $ DVS.replicate chunkSize (0xff :: Word8)
  {-# INLINE all1s #-}
#endif

chunkSize :: Int
chunkSize :: Int
chunkSize = Int
32 forall a. Num a => a -> a -> a
* Int
1024 forall a. Num a => a -> a -> a
- Int
64
{-# INLINE chunkSize #-}