{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts #-}

module Gamgine.Image.PNG.Internal.LBS
    ( LBS(..)
    , unpack
    , unpackToString
    , splitAt
    , readFile
    , concat
    , pack
    , null
    , head
    , tail
    ) where

import Prelude hiding (splitAt, readFile, concat, null, head, tail)
import Text.Parsec.Prim (Stream(..))
import Data.Word
import Data.Int (Int64)
import qualified Data.ByteString.Lazy as LB
import qualified Data.ByteString.Lazy.Char8 as C
import Control.Applicative ((<$>))

newtype LBS = LBS { LBS -> ByteString
unLBS :: LB.ByteString } deriving (Int -> LBS -> ShowS
[LBS] -> ShowS
LBS -> String
(Int -> LBS -> ShowS)
-> (LBS -> String) -> ([LBS] -> ShowS) -> Show LBS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LBS -> ShowS
showsPrec :: Int -> LBS -> ShowS
$cshow :: LBS -> String
show :: LBS -> String
$cshowList :: [LBS] -> ShowS
showList :: [LBS] -> ShowS
Show)

instance (Monad m) => Stream LBS m Word8 where
    uncons :: LBS -> m (Maybe (Word8, LBS))
uncons = Maybe (Word8, LBS) -> m (Maybe (Word8, LBS))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Word8, LBS) -> m (Maybe (Word8, LBS)))
-> (LBS -> Maybe (Word8, LBS)) -> LBS -> m (Maybe (Word8, LBS))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LBS -> Maybe (Word8, LBS)
uncons'

uncons' :: LBS -> Maybe (Word8, LBS)
uncons' :: LBS -> Maybe (Word8, LBS)
uncons' (LBS ByteString
bs) = case ByteString -> Maybe (Word8, ByteString)
LB.uncons ByteString
bs of
    Just (Word8
w, ByteString
bs) -> (Word8, LBS) -> Maybe (Word8, LBS)
forall a. a -> Maybe a
Just (Word8
w, ByteString -> LBS
LBS ByteString
bs)
    Maybe (Word8, ByteString)
Nothing      -> Maybe (Word8, LBS)
forall a. Maybe a
Nothing

unpack :: LBS -> [Word8]
unpack :: LBS -> [Word8]
unpack = ByteString -> [Word8]
LB.unpack (ByteString -> [Word8]) -> (LBS -> ByteString) -> LBS -> [Word8]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LBS -> ByteString
unLBS

unpackToString :: LBS -> String
unpackToString :: LBS -> String
unpackToString = ByteString -> String
C.unpack (ByteString -> String) -> (LBS -> ByteString) -> LBS -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LBS -> ByteString
unLBS

splitAt :: Int64 -> LBS -> (LBS, LBS)
splitAt :: Int64 -> LBS -> (LBS, LBS)
splitAt Int64
idx (LBS ByteString
bs) =
    let (ByteString
bs1, ByteString
bs2) = Int64 -> ByteString -> (ByteString, ByteString)
LB.splitAt Int64
idx ByteString
bs
        in (ByteString -> LBS
LBS ByteString
bs1, ByteString -> LBS
LBS ByteString
bs2)

readFile :: FilePath -> IO LBS
readFile :: String -> IO LBS
readFile String
fp = ByteString -> LBS
LBS (ByteString -> LBS) -> IO ByteString -> IO LBS
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO ByteString
LB.readFile String
fp

concat :: [LBS] -> LBS
concat :: [LBS] -> LBS
concat = ByteString -> LBS
LBS (ByteString -> LBS) -> ([LBS] -> ByteString) -> [LBS] -> LBS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
LB.concat ([ByteString] -> ByteString)
-> ([LBS] -> [ByteString]) -> [LBS] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LBS -> ByteString) -> [LBS] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map LBS -> ByteString
unLBS

pack :: [Word8] -> LBS
pack :: [Word8] -> LBS
pack = ByteString -> LBS
LBS (ByteString -> LBS) -> ([Word8] -> ByteString) -> [Word8] -> LBS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
LB.pack

null :: LBS -> Bool
null :: LBS -> Bool
null = ByteString -> Bool
LB.null (ByteString -> Bool) -> (LBS -> ByteString) -> LBS -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LBS -> ByteString
unLBS

head :: LBS -> Word8
head :: LBS -> Word8
head = HasCallStack => ByteString -> Word8
ByteString -> Word8
LB.head (ByteString -> Word8) -> (LBS -> ByteString) -> LBS -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LBS -> ByteString
unLBS

tail :: LBS -> LBS
tail :: LBS -> LBS
tail = ByteString -> LBS
LBS (ByteString -> LBS) -> (LBS -> ByteString) -> LBS -> LBS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => ByteString -> ByteString
ByteString -> ByteString
LB.tail (ByteString -> ByteString)
-> (LBS -> ByteString) -> LBS -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LBS -> ByteString
unLBS