-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpcapParser.hs
More file actions
113 lines (95 loc) · 3.69 KB
/
pcapParser.hs
File metadata and controls
113 lines (95 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import Control.Monad
import Data.Binary
import Data.Binary.Get
import qualified Data.ByteString as Strict
import qualified Data.ByteString.Char8 as CS
import qualified Data.ByteString.Lazy.Char8 as Lazy
import qualified Data.ByteString.Lazy.Internal as LI
import qualified Data.ByteString.Lazy as L
data Header = Header { magic :: Strict.ByteString
, version :: Strict.ByteString
, timezone :: Strict.ByteString
, accuracy :: Strict.ByteString
, snapshot :: Strict.ByteString
, linklayer :: Strict.ByteString
} deriving (Show)
data Bids = Bids
{priceBid :: !Strict.ByteString, qtyBid :: !Strict.ByteString}
deriving (Show)
data TradeJoe = Nada | TradeJoe
{ packetTime :: !Int
, quoteAccept :: !Strict.ByteString
, issueCode :: !Strict.ByteString
, bids :: ![Bids]
, asks :: ![Bids]
} deriving (Show)
data TradeJoe3 = Nil | TradeJoe3
{ packetLen :: !Int
} deriving (Show)
getHeader = do
magic <- getByteString 4
version <- getByteString 4
timezone <- getByteString 4
accuracy <- getByteString 4
snapshot <- getByteString 4
linklayer <- getByteString 4
rest <- getRemainingLazyByteString
return (Header magic version timezone accuracy snapshot linklayer,rest)
getTestByteString = do
test <- getByteString (58+212+58+215+58+215+58+215+58+258)
rest <- getRemainingLazyByteString
return (test,rest)
getTradeJoe3 = do
secondsFrom <- (fromIntegral <$> getWord32le) -- the number of seconds since unix time.
microSecs <- (fromIntegral <$> getWord32le) -- followed by microseconds
skip 4 --skip the first 4 from the pre packet part, (pre packet is 58 in length)
packetLen <- (fromIntegral <$> getWord32le) --getting the packet size(<$>) :: Functor f => (a->b) -> f a -> f b
skip (58-12-4)
if ((packetLen-42) == 215)
then do
skip 5 -- skip the packet header, ascii B6xxx
issueCode <- getByteString 12 -- issue code
skip 12
bids <- replicateM 5 getX
skip 7
asks <- replicateM 5 getX
skip (5 + 5*4 + 5 + 5*4)
quoteAccept <- (getByteString 8)
skip 1
return $! TradeJoe secondsFrom quoteAccept issueCode bids asks
--return $! Nil
--return $! TradeJoe3 packetLen
else do
skip (packetLen-42)
return $! Nada
--return $! TradeJoe3 packetLen
getX = do
priceX <- getByteString 5
qtyX <- getByteString 7
return (Bids priceX qtyX)
incrementalExampleJoe3 :: Lazy.ByteString -> [TradeJoe]
incrementalExampleJoe3 input0 = gojo decoder input0
where
decoder = runGetIncremental getTradeJoe3
gojo :: Decoder TradeJoe -> Lazy.ByteString -> [TradeJoe]
gojo (Done leftover _consumed trade) input = trade : gojo decoder (LI.chunk leftover input)
gojo (Partial k) input = gojo (k . takeHeadChunk $ input) (dropHeadChunk input)
gojo (Fail leftover _consumed msg) input = error msg
takeHeadChunk :: LI.ByteString -> Maybe CS.ByteString
takeHeadChunk lbs =
case lbs of
(LI.Chunk bs _) -> Just bs
_ -> Nothing
dropHeadChunk :: LI.ByteString -> LI.ByteString
dropHeadChunk lbs =
case lbs of
(LI.Chunk _ lbs') -> lbs'
_ -> Lazy.empty
main :: IO ()
main = do
src <- Lazy.readFile ("mdf-kospi200.20110216-0.pcap")
let (header,rest) = runGet getHeader src
--let (test,rest') = runGet getTestByteString rest
--let joe3 = incrementalExampleJoe rest
let joeTrade3 = incrementalExampleJoe3 rest
print (joeTrade3)