{-# LANGUAGE ScopedTypeVariables #-}
module Network.ADB.Transport where
import Control.Exception
import Control.Monad.Error
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as C
import Data.Monoid
import Network.Socket.ByteString
import System.IO.Error (IOError(..))
import Prelude hiding (read)
data Transport m = Transport {
write :: ByteString -> m (),
read :: Int -> m ByteString,
close :: m ()
}
data TransportError = ADBFailure String
| SocketFailure IOError
| ConnectionFailure ByteString
| ClosedByPeer
| IllegalData
deriving Show
instance Error TransportError where
noMsg = IllegalData
strMsg _ = IllegalData
readFully :: Monad m => Transport m -> Int -> m ByteString
readFully rem n = doRecv C.empty
where
doRecv sofar | C.length sofar == n = return sofar
doRecv sofar = do
blk <- read rem (n - C.length sofar)
doRecv (sofar `mappend` blk)