rws-0.1.1.2: src/HexPayload.hs
{-# LANGUAGE CPP #-}
module HexPayload where
import Data.Binary.Put
import Data.Bits
import Data.Char
import Data.Word
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Perm
import Packet
import Lexer
#ifdef HRWS_TEST
import qualified Data.ByteString.Lazy as B
import Debug.Trace
import Test.QuickCheck hiding ((.&.))
import Test.Framework (Test)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Text.Printf
import Util
#endif
hexByte :: Parser Word8
hexByte = do
h1 <- hexDigit
h2 <- hexDigit
let w = digitToInt h1 `shiftL` 4 .|. digitToInt h2
return (fromIntegral w)
parseHexData :: Parser [Word8]
parseHexData = do
symbol "data"
symbol "="
many hexByte
hexPayloadPkt :: Parser Packet -> Parser HexPayload
hexPayloadPkt _ = permute
(tuple <$?> (replicate 64 0, parseHexData))
where
tuple = HexPayload
hexPayloadDecl :: Parser Packet -> Parser Packet
hexPayloadDecl f = do
symbol "hex"
p <- hexPayloadPkt f
return (PHexPayload p)
hexPayloadWrite :: HexPayload -> Put
hexPayloadWrite p =
mapM_ putWord8 (hexPayloadData p)
instance PacketWriteable HexPayload where packetWrite p _ _= hexPayloadWrite p
#ifdef HRWS_TEST
{- Unit Tests -}
instance Arbitrary HexPayload where
arbitrary = do
d <- arbitrary
l <- choose (1, 16)
return (HexPayload (replicate (2*l) d))
testHexPayloadString :: HexPayload -> String
testHexPayloadString h =
concatMap (printf "%02x") (hexPayloadData h)
testValidParse :: String -> (HexPayload -> Bool) -> Bool
testValidParse str fn =
case parse (dummyParsePacket hexPayloadDecl) "packet parse" str of
Left err -> trace (show err) False
Right val -> fn $ testHexPayloadPkt val
testHexPayloadPkt :: Packet -> HexPayload
testHexPayloadPkt (PHexPayload p) = p
testHexPayloadPkt _ = error "Unexpected packet type"
testHexPayloadDefault :: () -> Bool
testHexPayloadDefault _ =
let cmp p = defaultHexPayload == p in
testValidParse "(hex)" cmp
testHexPayloadPacket :: HexPayload -> Bool
testHexPayloadPacket pkt =
let cmp p = pkt == p in
testValidParse (printf "(hex data=%s)" (testHexPayloadString pkt)) cmp
testHexPayloadWrite :: () -> Bool
testHexPayloadWrite _ =
let expPkt = B.pack [0x80, 0x00, 0xb1, 0x4c, 0xca, 0xfe, 0xba, 0xbe] in
let cmp p = runPut (hexPayloadWrite p) == expPkt in
testValidParse "(hex data=8000b14ccafebabe)" cmp
hexPayloadTests :: [Test]
hexPayloadTests = [
testProperty "HexPayload: Default" testHexPayloadDefault,
testProperty "HexPayload: Packet" testHexPayloadPacket,
testProperty "HexPayload: Write" testHexPayloadWrite
]
#endif