{-# LANGUAGE TypeSynonymInstances #-}
module Network.BufferType
(
BufferType(..)
, BufferOp(..)
, strictBufferOp
, lazyBufferOp
, stringBufferOp
) where
import qualified Data.ByteString as Strict hiding ( unpack, pack, span )
import qualified Data.ByteString.Char8 as Strict ( unpack, pack, span )
import qualified Data.ByteString.Lazy as Lazy hiding ( pack, unpack,span )
import qualified Data.ByteString.Lazy.Char8 as Lazy ( pack, unpack, span )
import System.IO ( Handle )
import Data.Word ( Word8 )
import Network.HTTP.Utils ( crlf, lf )
class BufferType bufType where
bufferOps :: BufferOp bufType
instance BufferType Lazy.ByteString where
bufferOps :: BufferOp ByteString
bufferOps = BufferOp ByteString
lazyBufferOp
instance BufferType Strict.ByteString where
bufferOps :: BufferOp ByteString
bufferOps = BufferOp ByteString
strictBufferOp
instance BufferType String where
bufferOps :: BufferOp String
bufferOps = BufferOp String
stringBufferOp
data BufferOp a
= BufferOp
{ BufferOp a -> Handle -> Int -> IO a
buf_hGet :: Handle -> Int -> IO a
, BufferOp a -> Handle -> IO a
buf_hGetContents :: Handle -> IO a
, BufferOp a -> Handle -> a -> IO ()
buf_hPut :: Handle -> a -> IO ()
, BufferOp a -> Handle -> IO a
buf_hGetLine :: Handle -> IO a
, BufferOp a -> a
buf_empty :: a
, BufferOp a -> a -> a -> a
buf_append :: a -> a -> a
, BufferOp a -> [a] -> a
buf_concat :: [a] -> a
, BufferOp a -> String -> a
buf_fromStr :: String -> a
, BufferOp a -> a -> String
buf_toStr :: a -> String
, BufferOp a -> a -> Word8 -> a
buf_snoc :: a -> Word8 -> a
, BufferOp a -> Int -> a -> (a, a)
buf_splitAt :: Int -> a -> (a,a)
, BufferOp a -> (Char -> Bool) -> a -> (a, a)
buf_span :: (Char -> Bool) -> a -> (a,a)
, BufferOp a -> a -> Bool
buf_isLineTerm :: a -> Bool
, BufferOp a -> a -> Bool
buf_isEmpty :: a -> Bool
}
instance Eq (BufferOp a) where
BufferOp a
_ == :: BufferOp a -> BufferOp a -> Bool
== BufferOp a
_ = Bool
False
strictBufferOp :: BufferOp Strict.ByteString
strictBufferOp :: BufferOp ByteString
strictBufferOp =
BufferOp :: forall a.
(Handle -> Int -> IO a)
-> (Handle -> IO a)
-> (Handle -> a -> IO ())
-> (Handle -> IO a)
-> a
-> (a -> a -> a)
-> ([a] -> a)
-> (String -> a)
-> (a -> String)
-> (a -> Word8 -> a)
-> (Int -> a -> (a, a))
-> ((Char -> Bool) -> a -> (a, a))
-> (a -> Bool)
-> (a -> Bool)
-> BufferOp a
BufferOp
{ buf_hGet :: Handle -> Int -> IO ByteString
buf_hGet = Handle -> Int -> IO ByteString
Strict.hGet
, buf_hGetContents :: Handle -> IO ByteString
buf_hGetContents = Handle -> IO ByteString
Strict.hGetContents
, buf_hPut :: Handle -> ByteString -> IO ()
buf_hPut = Handle -> ByteString -> IO ()
Strict.hPut
, buf_hGetLine :: Handle -> IO ByteString
buf_hGetLine = Handle -> IO ByteString
Strict.hGetLine
, buf_append :: ByteString -> ByteString -> ByteString
buf_append = ByteString -> ByteString -> ByteString
Strict.append
, buf_concat :: [ByteString] -> ByteString
buf_concat = [ByteString] -> ByteString
Strict.concat
, buf_fromStr :: String -> ByteString
buf_fromStr = String -> ByteString
Strict.pack
, buf_toStr :: ByteString -> String
buf_toStr = ByteString -> String
Strict.unpack
, buf_snoc :: ByteString -> Word8 -> ByteString
buf_snoc = ByteString -> Word8 -> ByteString
Strict.snoc
, buf_splitAt :: Int -> ByteString -> (ByteString, ByteString)
buf_splitAt = Int -> ByteString -> (ByteString, ByteString)
Strict.splitAt
, buf_span :: (Char -> Bool) -> ByteString -> (ByteString, ByteString)
buf_span = (Char -> Bool) -> ByteString -> (ByteString, ByteString)
Strict.span
, buf_empty :: ByteString
buf_empty = ByteString
Strict.empty
, buf_isLineTerm :: ByteString -> Bool
buf_isLineTerm = \ ByteString
b -> ByteString -> Int
Strict.length ByteString
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 Bool -> Bool -> Bool
&& ByteString
p_crlf ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
b Bool -> Bool -> Bool
||
ByteString -> Int
Strict.length ByteString
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&& ByteString
p_lf ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
b
, buf_isEmpty :: ByteString -> Bool
buf_isEmpty = ByteString -> Bool
Strict.null
}
where
p_crlf :: ByteString
p_crlf = String -> ByteString
Strict.pack String
crlf
p_lf :: ByteString
p_lf = String -> ByteString
Strict.pack String
lf
lazyBufferOp :: BufferOp Lazy.ByteString
lazyBufferOp :: BufferOp ByteString
lazyBufferOp =
BufferOp :: forall a.
(Handle -> Int -> IO a)
-> (Handle -> IO a)
-> (Handle -> a -> IO ())
-> (Handle -> IO a)
-> a
-> (a -> a -> a)
-> ([a] -> a)
-> (String -> a)
-> (a -> String)
-> (a -> Word8 -> a)
-> (Int -> a -> (a, a))
-> ((Char -> Bool) -> a -> (a, a))
-> (a -> Bool)
-> (a -> Bool)
-> BufferOp a
BufferOp
{ buf_hGet :: Handle -> Int -> IO ByteString
buf_hGet = Handle -> Int -> IO ByteString
Lazy.hGet
, buf_hGetContents :: Handle -> IO ByteString
buf_hGetContents = Handle -> IO ByteString
Lazy.hGetContents
, buf_hPut :: Handle -> ByteString -> IO ()
buf_hPut = Handle -> ByteString -> IO ()
Lazy.hPut
, buf_hGetLine :: Handle -> IO ByteString
buf_hGetLine = \ Handle
h -> Handle -> IO ByteString
Strict.hGetLine Handle
h IO ByteString -> (ByteString -> IO ByteString) -> IO ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ ByteString
l -> ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> ByteString
Lazy.fromChunks [ByteString
l])
, buf_append :: ByteString -> ByteString -> ByteString
buf_append = ByteString -> ByteString -> ByteString
Lazy.append
, buf_concat :: [ByteString] -> ByteString
buf_concat = [ByteString] -> ByteString
Lazy.concat
, buf_fromStr :: String -> ByteString
buf_fromStr = String -> ByteString
Lazy.pack
, buf_toStr :: ByteString -> String
buf_toStr = ByteString -> String
Lazy.unpack
, buf_snoc :: ByteString -> Word8 -> ByteString
buf_snoc = ByteString -> Word8 -> ByteString
Lazy.snoc
, buf_splitAt :: Int -> ByteString -> (ByteString, ByteString)
buf_splitAt = \ Int
i ByteString
x -> Int64 -> ByteString -> (ByteString, ByteString)
Lazy.splitAt (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i) ByteString
x
, buf_span :: (Char -> Bool) -> ByteString -> (ByteString, ByteString)
buf_span = (Char -> Bool) -> ByteString -> (ByteString, ByteString)
Lazy.span
, buf_empty :: ByteString
buf_empty = ByteString
Lazy.empty
, buf_isLineTerm :: ByteString -> Bool
buf_isLineTerm = \ ByteString
b -> ByteString -> Int64
Lazy.length ByteString
b Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
== Int64
2 Bool -> Bool -> Bool
&& ByteString
p_crlf ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
b Bool -> Bool -> Bool
||
ByteString -> Int64
Lazy.length ByteString
b Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
== Int64
1 Bool -> Bool -> Bool
&& ByteString
p_lf ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
b
, buf_isEmpty :: ByteString -> Bool
buf_isEmpty = ByteString -> Bool
Lazy.null
}
where
p_crlf :: ByteString
p_crlf = String -> ByteString
Lazy.pack String
crlf
p_lf :: ByteString
p_lf = String -> ByteString
Lazy.pack String
lf
stringBufferOp :: BufferOp String
stringBufferOp :: BufferOp String
stringBufferOp =BufferOp :: forall a.
(Handle -> Int -> IO a)
-> (Handle -> IO a)
-> (Handle -> a -> IO ())
-> (Handle -> IO a)
-> a
-> (a -> a -> a)
-> ([a] -> a)
-> (String -> a)
-> (a -> String)
-> (a -> Word8 -> a)
-> (Int -> a -> (a, a))
-> ((Char -> Bool) -> a -> (a, a))
-> (a -> Bool)
-> (a -> Bool)
-> BufferOp a
BufferOp
{ buf_hGet :: Handle -> Int -> IO String
buf_hGet = \ Handle
h Int
n -> BufferOp ByteString -> Handle -> Int -> IO ByteString
forall a. BufferOp a -> Handle -> Int -> IO a
buf_hGet BufferOp ByteString
strictBufferOp Handle
h Int
n IO ByteString -> (ByteString -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String)
-> (ByteString -> String) -> ByteString -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
Strict.unpack
, buf_hGetContents :: Handle -> IO String
buf_hGetContents = \ Handle
h -> BufferOp ByteString -> Handle -> IO ByteString
forall a. BufferOp a -> Handle -> IO a
buf_hGetContents BufferOp ByteString
strictBufferOp Handle
h IO ByteString -> (ByteString -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String)
-> (ByteString -> String) -> ByteString -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
Strict.unpack
, buf_hPut :: Handle -> String -> IO ()
buf_hPut = \ Handle
h String
s -> BufferOp ByteString -> Handle -> ByteString -> IO ()
forall a. BufferOp a -> Handle -> a -> IO ()
buf_hPut BufferOp ByteString
strictBufferOp Handle
h (String -> ByteString
Strict.pack String
s)
, buf_hGetLine :: Handle -> IO String
buf_hGetLine = \ Handle
h -> BufferOp ByteString -> Handle -> IO ByteString
forall a. BufferOp a -> Handle -> IO a
buf_hGetLine BufferOp ByteString
strictBufferOp Handle
h IO ByteString -> (ByteString -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String)
-> (ByteString -> String) -> ByteString -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
Strict.unpack
, buf_append :: String -> String -> String
buf_append = String -> String -> String
forall a. [a] -> [a] -> [a]
(++)
, buf_concat :: [String] -> String
buf_concat = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
, buf_fromStr :: String -> String
buf_fromStr = String -> String
forall a. a -> a
id
, buf_toStr :: String -> String
buf_toStr = String -> String
forall a. a -> a
id
, buf_snoc :: String -> Word8 -> String
buf_snoc = \ String
a Word8
x -> String
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Int -> Char
forall a. Enum a => Int -> a
toEnum (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x)]
, buf_splitAt :: Int -> String -> (String, String)
buf_splitAt = Int -> String -> (String, String)
forall a. Int -> [a] -> ([a], [a])
splitAt
, buf_span :: (Char -> Bool) -> String -> (String, String)
buf_span = \ Char -> Bool
p String
a ->
case (Char -> Bool) -> ByteString -> (ByteString, ByteString)
Strict.span Char -> Bool
p (String -> ByteString
Strict.pack String
a) of
(ByteString
x,ByteString
y) -> (ByteString -> String
Strict.unpack ByteString
x, ByteString -> String
Strict.unpack ByteString
y)
, buf_empty :: String
buf_empty = []
, buf_isLineTerm :: String -> Bool
buf_isLineTerm = \ String
b -> String
b String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
crlf Bool -> Bool -> Bool
|| String
b String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
lf
, buf_isEmpty :: String -> Bool
buf_isEmpty = String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null
}