@@ -10,24 +10,21 @@ import Web.SocketIO.Types
10
10
--------------------------------------------------------------------------------
11
11
import Control.Applicative ((<$>) , (<*>) )
12
12
import Data.Aeson
13
- import qualified Data.ByteString.Lazy as B
14
13
import qualified Data.ByteString.Lazy as BL
15
14
-- import Text.Parsec
16
15
-- import Text.Parsec.ByteString.Lazy
17
16
import Data.Attoparsec.ByteString.Lazy
17
+ import Data.Attoparsec.ByteString.Char8 (digit , decimal )
18
18
import Prelude hiding (take )
19
19
20
-
21
- parseMessage = undefined
22
- -- parsePath = undefined
23
20
--------------------------------------------------------------------------------
24
21
-- | Parse raw ByteString to Messages
25
22
parseFramedMessage :: BL. ByteString -> Framed Message
26
23
parseFramedMessage input = if isSingleton
27
24
then Framed $ [parseMessage' input]
28
25
else Framed $ map parseMessage' splitted
29
26
where splitted = split input
30
- parseMessage' x = case (eitherResult . parse parseMessage ) x of
27
+ parseMessage' x = case (eitherResult . parse messageParser ) x of
31
28
Left _ -> MsgNoop
32
29
Right a -> a
33
30
isSingleton = not (BL. null input) && BL. head input /= 239
@@ -44,114 +41,74 @@ split str = map (BL.drop 2) . skipOddIndexed True . filter isDelimiter . BL.spli
44
41
45
42
----------------------------------------------------------------------------------
46
43
---- | Message, not framed
47
- -- parseMessage :: Parser Message
48
- -- parseMessage = do
49
- -- n <- digit
50
- -- case n of
51
- -- '0' -> (parseID >> parseEndpoint >>= return . MsgDisconnect)
52
- -- <|> ( return $ MsgDisconnect NoEndpoint)
53
- -- '1' -> (parseID >> parseEndpoint >>= return . MsgConnect)
54
- -- <|> ( return $ MsgConnect NoEndpoint)
55
- -- '2' -> return MsgHeartbeat
56
- -- '3' -> parseRegularMessage Msg
57
- -- '4' -> parseRegularMessage MsgJSON
58
- -- '5' -> MsgEvent <$> parseID
59
- -- <*> parseEndpoint
60
- -- <*> parseEvent
61
- -- '6' -> try (do
62
- -- string ":::"
63
- -- n' <- read <$> number
64
- -- char '+'
65
- -- d <- fromString <$> text
66
- -- return $ MsgACK (ID n') (Data d)
67
- -- ) <|> (do
68
- -- string ":::"
69
- -- n' <- read <$> number
70
- -- return $ MsgACK (ID n') NoData
71
- -- )
72
- -- '7' -> colon >> MsgError <$> parseEndpoint <*> parseData
73
- -- '8' -> return $ MsgNoop
74
- -- _ -> return $ MsgNoop
75
- -- where parseRegularMessage ctr = ctr <$> parseID
76
- -- <*> parseEndpoint
77
- -- <*> parseData
78
-
79
- ----------------------------------------------------------------------------------
80
- -- endpoint :: Parser String
81
- -- endpoint = many1 $ satisfy (/= ':')
82
-
83
- ----------------------------------------------------------------------------------
84
- -- number :: Parser String
85
- -- number = many1 digit
86
-
87
- ----------------------------------------------------------------------------------
88
- -- colon :: Parser Char
89
- -- colon = char ':'
90
-
91
- ----------------------------------------------------------------------------------
92
- -- parseID :: Parser ID
93
- -- parseID = try (colon >> number >>= plus >>= return . IDPlus . read)
94
- -- <|> try (colon >> number >>= return . ID . read)
95
- -- <|> (colon >> return NoID)
96
- -- where plus n = char '+' >> return n
97
-
98
- ----------------------------------------------------------------------------------
99
- -- parseEndpoint :: Parser Endpoint
100
- -- parseEndpoint = try (colon >> fromString <$> endpoint >>= return . Endpoint)
101
- -- <|> (colon >> return NoEndpoint)
102
-
103
- ----------------------------------------------------------------------------------
104
- -- parseData :: Parser Data
105
- -- parseData = try (colon >> text >>= return . Data . fromString)
106
- -- <|> (colon >> return NoData)
107
-
108
- ----------------------------------------------------------------------------------
109
- -- parseEvent :: Parser Event
110
- -- parseEvent = try (do
111
- -- colon
112
- -- t <- text
113
- -- case decode (fromString t) of
114
- -- Just e -> return e
115
- -- Nothing -> return NoEvent
116
- -- )
117
- -- <|> (colon >> return NoEvent)
118
-
119
-
120
- ----------------------------------------------------------------------------------
121
- ---- | Slashes as delimiters
122
- -- textWithoutSlash :: Parser String
123
- -- textWithoutSlash = many1 $ satisfy (/= '/')
44
+ messageParser :: Parser Message
45
+ messageParser = do
46
+ n <- digit
47
+ case n of
48
+ ' 0' -> choice
49
+ [ idParser >> endpointParser >>= return . MsgDisconnect
50
+ , return $ MsgDisconnect NoEndpoint
51
+ ]
52
+ ' 1' -> choice
53
+ [ idParser >> endpointParser >>= return . MsgConnect
54
+ , return $ MsgConnect NoEndpoint
55
+ ]
56
+ ' 2' -> return MsgHeartbeat
57
+ ' 3' -> Msg <$> idParser
58
+ <*> endpointParser
59
+ <*> dataParser
60
+ ' 4' -> MsgJSON <$> idParser
61
+ <*> endpointParser
62
+ <*> dataParser
63
+ ' 5' -> MsgEvent <$> idParser
64
+ <*> endpointParser
65
+ <*> eventParser
66
+ ' 6' -> choice
67
+ [ do string " :::"
68
+ d <- decimal
69
+ x <- takeTillEnd
70
+ return $ MsgACK (ID d) (Data x)
71
+ , do string " :::"
72
+ d <- decimal
73
+ return $ MsgACK (ID d) NoData
74
+ ]
75
+ ' 7' -> string " :" >> MsgError <$> endpointParser <*> dataParser
76
+ ' 8' -> return MsgNoop
77
+ _ -> return MsgNoop
78
+
79
+ idParser :: Parser ID
80
+ idParser = choice
81
+ [ string " :" >> decimal >>= plus >>= return . IDPlus
82
+ , string " :" >> decimal >>= return . ID
83
+ , string " :" >> return NoID
84
+ ]
85
+ where plus n = string " +" >> return n
124
86
125
- -- slash :: Parser Char
126
- -- slash = char '/'
87
+ endpointParser :: Parser Endpoint
88
+ endpointParser = do
89
+ string " :"
90
+ option NoEndpoint (takeWhile1 (/= 58 ) >>= return . Endpoint )
127
91
128
- ----------------------------------------------------------------------------------
129
- ---- | Non-empty text
130
- -- text :: Parser String
131
- -- text = many1 anyChar
92
+ dataParser :: Parser Data
93
+ dataParser = do
94
+ string " : "
95
+ option NoData (takeWhile1 ( /= 58 ) >>= return . Data )
132
96
133
- a :: ByteString
134
- a = " :{\" name\" :\" hey\" ,\" args\" :[\" haha\" ]}"
135
97
eventParser :: Parser Event
136
98
eventParser = do
137
99
string " :"
138
- t <- takeTill ( == 32 )
100
+ t <- takeTillEnd
139
101
case decode (serialize t) of
140
102
Just e -> return e
141
103
Nothing -> return NoEvent
142
104
143
-
144
- test p = parseOnly p
145
-
146
105
------------------------------------------------------------------------------
147
106
-- | Parse given HTTP request
148
107
parsePath :: ByteString -> Path
149
108
parsePath p = case parseOnly pathParser p of
150
109
Left _ -> WithoutSession " " " "
151
110
Right x -> x
152
111
153
- ------------------------------------------------------------------------------
154
- -- | "/:namespace/:protocol/[:transport/:sessionID]" -> Path
155
112
pathParser :: Parser Path
156
113
pathParser = do
157
114
string " /"
0 commit comments