1
+
2
+ {-# LANGUAGE AllowAmbiguousTypes #-}
1
3
{-# LANGUAGE CPP #-}
2
4
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3
5
{-# LANGUAGE PatternSynonyms #-}
4
6
{-# LANGUAGE ScopedTypeVariables #-}
7
+ {-# LANGUAGE TypeApplications #-}
5
8
6
9
module Network.Socket.Win32.Cmsg where
7
10
@@ -77,24 +80,27 @@ filterCmsg cid cmsgs = filter (\cmsg -> cmsgId cmsg == cid) cmsgs
77
80
78
81
-- | A class to encode and decode control message.
79
82
class Storable a => ControlMessage a where
80
- controlMessageId :: a -> CmsgId
83
+ controlMessageId :: CmsgId
81
84
82
- encodeCmsg :: ControlMessage a => a -> Cmsg
85
+ encodeCmsg :: forall a . ControlMessage a => a -> Cmsg
83
86
encodeCmsg x = unsafeDupablePerformIO $ do
84
87
bs <- create siz $ \ p0 -> do
85
88
let p = castPtr p0
86
89
poke p x
87
- return $ Cmsg (controlMessageId x) bs
90
+ let cmsid = controlMessageId @ a
91
+ return $ Cmsg cmsid bs
88
92
where
89
93
siz = sizeOf x
90
94
91
- decodeCmsg :: forall a . Storable a => Cmsg -> Maybe a
92
- decodeCmsg (Cmsg _ (PS fptr off len))
93
- | len < siz = Nothing
95
+ decodeCmsg :: forall a . (ControlMessage a , Storable a ) => Cmsg -> Maybe a
96
+ decodeCmsg (Cmsg cmsid (PS fptr off len))
97
+ | cid /= cmsid = Nothing
98
+ | len < siz = Nothing
94
99
| otherwise = unsafeDupablePerformIO $ withForeignPtr fptr $ \ p0 -> do
95
100
let p = castPtr (p0 `plusPtr` off)
96
101
Just <$> peek p
97
102
where
103
+ cid = controlMessageId @ a
98
104
siz = sizeOf (undefined :: a )
99
105
100
106
----------------------------------------------------------------
@@ -103,31 +109,31 @@ decodeCmsg (Cmsg _ (PS fptr off len))
103
109
newtype IPv4TTL = IPv4TTL DWORD deriving (Eq , Show , Storable )
104
110
105
111
instance ControlMessage IPv4TTL where
106
- controlMessageId _ = CmsgIdIPv4TTL
112
+ controlMessageId = CmsgIdIPv4TTL
107
113
108
114
----------------------------------------------------------------
109
115
110
116
-- | Hop limit of IPv6.
111
117
newtype IPv6HopLimit = IPv6HopLimit DWORD deriving (Eq , Show , Storable )
112
118
113
119
instance ControlMessage IPv6HopLimit where
114
- controlMessageId _ = CmsgIdIPv6HopLimit
120
+ controlMessageId = CmsgIdIPv6HopLimit
115
121
116
122
----------------------------------------------------------------
117
123
118
124
-- | TOS of IPv4.
119
125
newtype IPv4TOS = IPv4TOS DWORD deriving (Eq , Show , Storable )
120
126
121
127
instance ControlMessage IPv4TOS where
122
- controlMessageId _ = CmsgIdIPv4TOS
128
+ controlMessageId = CmsgIdIPv4TOS
123
129
124
130
----------------------------------------------------------------
125
131
126
132
-- | Traffic class of IPv6.
127
133
newtype IPv6TClass = IPv6TClass DWORD deriving (Eq , Show , Storable )
128
134
129
135
instance ControlMessage IPv6TClass where
130
- controlMessageId _ = CmsgIdIPv6TClass
136
+ controlMessageId = CmsgIdIPv6TClass
131
137
132
138
----------------------------------------------------------------
133
139
@@ -138,7 +144,7 @@ instance Show IPv4PktInfo where
138
144
show (IPv4PktInfo n ha) = " IPv4PktInfo " ++ show n ++ " " ++ show (hostAddressToTuple ha)
139
145
140
146
instance ControlMessage IPv4PktInfo where
141
- controlMessageId _ = CmsgIdIPv4PktInfo
147
+ controlMessageId = CmsgIdIPv4PktInfo
142
148
143
149
instance Storable IPv4PktInfo where
144
150
sizeOf = const # {size IN_PKTINFO }
@@ -160,7 +166,7 @@ instance Show IPv6PktInfo where
160
166
show (IPv6PktInfo n ha6) = " IPv6PktInfo " ++ show n ++ " " ++ show (hostAddress6ToTuple ha6)
161
167
162
168
instance ControlMessage IPv6PktInfo where
163
- controlMessageId _ = CmsgIdIPv6PktInfo
169
+ controlMessageId = CmsgIdIPv6PktInfo
164
170
165
171
instance Storable IPv6PktInfo where
166
172
sizeOf = const # {size IN6_PKTINFO }
0 commit comments