+ CancelMsg i o l -> do putWord32be 13
+ putWord8 8
+ putWord32be (fromIntegral i)
+ putWord32be (fromIntegral o)
+ putWord32be (fromIntegral l)
+ PortMsg p -> do putWord32be 3
+ putWord8 9
+ putWord16be (fromIntegral p)
+ get = do
+ l <- getWord32be
+ id <- getWord8
+ case id of
+ 0 -> return ChokeMsg
+ 1 -> return UnChokeMsg
+ 2 -> return InterestedMsg
+ 3 -> return NotInterestedMsg
+ 4 -> liftM (HaveMsg . fromIntegral) getWord32be
+ 5 -> liftM (BitFieldMsg . pack) (replicateM (fromIntegral l - 1) getWord8)
+ 6 -> liftA3 RequestMsg getInteger getInteger getInteger
+ where getInteger = fromIntegral <$> getWord32be
+ 7 -> liftA3 PieceMsg getInteger getInteger (pack <$> replicateM (fromIntegral l - 9) getWord8)
+ where getInteger = fromIntegral <$> getWord32be
+ 8 -> liftA3 CancelMsg getInteger getInteger getInteger
+ where getInteger = fromIntegral <$> getWord32be
+ 9 -> liftM (PortMsg . fromIntegral) getWord16be
+ _ -> error "unknown message ID"