hfd-0.0.2: src/OMsg.hs
-- | This module defines output messages, sent to player
module OMsg
(
OMsg(..),
binOMsg
)
where
import qualified Data.ByteString as BS
import Data.ByteString (ByteString, empty, pack, append)
import qualified Data.ByteString.Char8 as BSChar
import Data.Word (Word32, Word16)
import Data.Bits (shiftR)
-- | Messages that debugger can send to player
data OMsg
-- | 0F or 15
= OMsgContinue
-- | 11 or 17
| OMsgSetBreakpoint Word16 Word16
-- | 12 or 18
| OMsgClearBreakpoint Word16 Word16
-- | 13 or 19
| OMsgClearBreakpoints
-- | 14 or 20
| OMsgNext
-- | 15 or 21
| OMsgStep
-- | 16 or 22
| OMsgFinish
-- | 17 or 23
| OMsgProcessTag
-- | 19 or 25
| OMsgGetField Word32 String
-- | 1A or 26
| OMsgGetFunctionFrame Word32
-- | 1C or 28
| OMsgSetDebuggerOptions String String
deriving Show
-- | Convert `OMsg` to `ByteString`
binOMsg :: OMsg -> ByteString
binOMsg OMsgContinue = mkBin 15 empty
binOMsg (OMsgSetBreakpoint fl ln) = mkBin 17 (mkBinWord32 0 `append` mkBinWord16 fl `append` mkBinWord16 ln)
binOMsg (OMsgClearBreakpoint fl ln) = mkBin 18 (mkBinWord32 0 `append` mkBinWord16 fl `append` mkBinWord16 ln)
binOMsg OMsgClearBreakpoints = mkBin 19 empty
binOMsg OMsgNext = mkBin 20 empty
binOMsg OMsgStep = mkBin 21 empty
binOMsg OMsgFinish = mkBin 22 empty
binOMsg OMsgProcessTag = mkBin 23 empty
binOMsg (OMsgGetField addr name) = mkBin 25 (mkBinWord32 addr `append` s2bs name `append` pack [0] `append` mkBinWord32 15)
binOMsg (OMsgGetFunctionFrame depth) = mkBin 26 (mkBinWord32 depth)
binOMsg (OMsgSetDebuggerOptions n v) = mkBin 28 (s2bs n `append` pack [0] `append` s2bs v `append` pack [0])
-- | Make binary message
--
-- Format: length (4b) + message id (4b) + message
--
-- All data is little endian
mkBin :: Word32 -> ByteString -> ByteString
mkBin idi msg = BS.concat [l, i, msg]
where
i = mkBinWord32 idi
l = mkBinWord32 $ fromIntegral $ BS.length msg
-- | Convert `Word32` to `ByteString` using little endian encoding
mkBinWord32 :: Word32 -> ByteString
mkBinWord32 i = pack w
where
w =
[ fromIntegral i
, fromIntegral (i `shiftR` 8)
, fromIntegral (i `shiftR` 16)
, fromIntegral (i `shiftR` 24)
]
-- | Convert `Word16` to `ByteString` using little endian encoding
mkBinWord16 :: Word16 -> ByteString
mkBinWord16 i = pack w
where
w =
[ fromIntegral i
, fromIntegral (i `shiftR` 8)
]
-- | Convert `String` to `ByteString`
s2bs :: String -> ByteString
s2bs = BSChar.pack