rws-0.1.1.2: src/PadN.hs
{-# LANGUAGE CPP #-}
module PadN where
import Data.Binary.Put
import qualified Data.ByteString.Lazy as B
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Perm
import Util
import Packet
import Lexer
#ifdef HRWS_TEST
import Debug.Trace
import Test.QuickCheck hiding ((.&.))
import Test.Framework (Test)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Text.Printf
#endif
parsePadNPkt :: Parser Packet -> Parser PadNPkt
parsePadNPkt f = permute
(tuple <$?> (1, parseIntAttribute "code")
<|?> (0, try (parseIntAttribute "len"))
<|?> ([PPayload defaultPayload], parsePayload f))
where
tuple nh l = PadNPkt (PadN nh l)
padNDecl :: Parser Packet -> Parser Packet
padNDecl f = do
symbol "padn"
g <- parsePadNPkt f
return (PPadN g)
padNWriteHdr :: PadN -> Put
padNWriteHdr p = do
putWord8 $ padNCode p
putWord8 $ padNLen p
let bs = B.replicate (fromIntegral $ padNLen p) 0
putLazyByteString bs
padNWrite :: PadN -> Maybe Packet -> B.ByteString -> Put
padNWrite h _ bs = do
padNWriteHdr h
putLazyByteString bs
instance PacketWriteable PadNPkt where packetWrite p = padNWrite $ padNPktHeader p
#ifdef HRWS_TEST
{- Unit Tests -}
instance Arbitrary PadN where
arbitrary = do
c <- arbitrary
l <- arbitrary
return (PadN c l)
testValidParse :: String -> (PadN -> Bool) -> Bool
testValidParse str fn =
case parse (dummyParsePacket padNDecl) "packet parse" str of
Left err -> trace (show err) False
Right val -> fn $ testPadNPkt val
testPadNDefault :: () -> Bool
testPadNDefault _ = let cmp f = defaultPadN == f in
testValidParse "(padn)" cmp
testPadNPkt :: Packet -> PadN
testPadNPkt (PPadN f) = padNPktHeader f
testPadNPkt _ = error "Unexpected packet type"
testPadNPacket :: PadN -> Bool
testPadNPacket pkt =
let cmp p = pkt == p in
testValidParse (printf "(padn code=%d len=%d)" (padNCode pkt) (padNLen pkt)) cmp
testPadNWrite :: () -> Bool
testPadNWrite _ =
let expPkt = B.pack [0x01, 0x04, 0x00, 0x00, 0x00, 0x00] in
let cmp p = runPut (padNWrite p Nothing B.empty) == expPkt in
testValidParse "(padn len=4)" cmp
padNTests :: [Test]
padNTests = [
testProperty "GRE: Default Packet" testPadNDefault,
testProperty "GRE: Packet" testPadNPacket,
testProperty "GRE: Write" testPadNWrite
]
#endif