on master help sign in
Add 'Hashable' instance and switch to network-info
4637838Antoine Latter
Data/UUID/Internal.hs+12−1
@@ -30,8 +30,9 @@ import Prelude hiding (null)
30
30
31import Control.Monad (liftM4)
31import Control.Monad (liftM4)
32import Data.Char
32import Data.Char
33−import Data.Maybe
34import Data.Bits
33import Data.Bits
34+import Data.Hashable
35+import Data.Maybe
35import Data.List (elemIndices)
36import Data.List (elemIndices)
36
37
37#if MIN_VERSION_base(4,0,0)
38#if MIN_VERSION_base(4,0,0)
@@ -273,6 +274,16 @@ instance ByteSource ThreeByte where
273 b2 = fromIntegral (w `shiftR` 8)
274 b2 = fromIntegral (w `shiftR` 8)
274 b3 = fromIntegral w
275 b3 = fromIntegral w
275
276
277+instance Hashable UUID where
278+ hash (UUID w0 w1 w2 w3) =
279+ hash w0 `hashWithSalt` w1
280+ `hashWithSalt` w2
281+ `hashWithSalt` w3
282+ hashWithSalt s (UUID w0 w1 w2 w3) =
283+ s `hashWithSalt` w0
284+ `hashWithSalt` w1
285+ `hashWithSalt` w2
286+ `hashWithSalt` w3
276
287
277instance Show UUID where
288instance Show UUID where
278 show = toString
289 show = toString
Data/UUID/V1.hs+15−14
@@ -25,9 +25,10 @@ generator with a psuedo-random number.
25module Data.UUID.V1(nextUUID)
25module Data.UUID.V1(nextUUID)
26where
26where
27
27
28−import Data.Time
29
28
30import Data.Bits
29import Data.Bits
30+import Data.Maybe
31+import Data.Time
31import Data.Word
32import Data.Word
32
33
33import Control.Applicative ((<$>),(<*>))
34import Control.Applicative ((<$>),(<*>))
@@ -36,8 +37,7 @@ import System.IO.Unsafe
36
37
37import qualified System.Random as R
38import qualified System.Random as R
38
39
39−import qualified System.Info.MAC as SysMAC
40+import Network.Info
40−import Data.MAC
41
41
42import Data.UUID.Builder
42import Data.UUID.Builder
43import Data.UUID.Internal
43import Data.UUID.Internal
@@ -52,13 +52,13 @@ nextUUID :: IO (Maybe UUID)
52nextUUID = do
52nextUUID = do
53 res <- stepTime
53 res <- stepTime
54 case res of
54 case res of
55− Just (mac, c, t) -> return $ Just $ makeUUID t c mac
55+ Just (mac', c, t) -> return $ Just $ makeUUID t c mac'
56 _ -> return Nothing
56 _ -> return Nothing
57
57
58
58
59makeUUID :: Word64 -> Word16 -> MAC -> UUID
59makeUUID :: Word64 -> Word16 -> MAC -> UUID
60−makeUUID time clock mac =
60+makeUUID time clock mac' =
61− buildFromBytes 1 /-/ tLow /-/ tMid /-/ tHigh /-/ clock /-/ (MACSource mac)
61+ buildFromBytes 1 /-/ tLow /-/ tMid /-/ tHigh /-/ clock /-/ (MACSource mac')
62 where tLow = (fromIntegral time) :: Word32
62 where tLow = (fromIntegral time) :: Word32
63 tMid = (fromIntegral (time `shiftR` 32)) :: Word16
63 tMid = (fromIntegral (time `shiftR` 32)) :: Word16
64 tHigh = (fromIntegral (time `shiftR` 48)) :: Word16
64 tHigh = (fromIntegral (time `shiftR` 48)) :: Word16
@@ -75,17 +75,17 @@ type instance ByteSink MACSource g = Takes3Bytes (Takes3Bytes g)
75stepTime :: IO (Maybe (MAC, Word16, Word64))
75stepTime :: IO (Maybe (MAC, Word16, Word64))
76stepTime = do
76stepTime = do
77 h1 <- fmap hundredsOfNanosSinceGregorianReform getCurrentTime
77 h1 <- fmap hundredsOfNanosSinceGregorianReform getCurrentTime
78− modifyMVar state $ \s@(State mac c0 h0) ->
78+ modifyMVar state $ \s@(State mac' c0 h0) ->
79 if h1 > h0
79 if h1 > h0
80 then
80 then
81− return (State mac c0 h1, Just (mac, c0, h1))
81+ return (State mac' c0 h1, Just (mac', c0, h1))
82 else
82 else
83 let
83 let
84 c1 = succ c0
84 c1 = succ c0
85 in if c1 <= 0x3fff -- when clock is initially randomized,
85 in if c1 <= 0x3fff -- when clock is initially randomized,
86 -- then this test will need to change
86 -- then this test will need to change
87 then
87 then
88− return (State mac c1 h1, Just (mac, c1, h1))
88+ return (State mac' c1 h1, Just (mac', c1, h1))
89 else
89 else
90 return (s, Nothing)
90 return (s, Nothing)
91
91
@@ -94,16 +94,17 @@ stepTime = do
94state :: MVar State
94state :: MVar State
95state = unsafePerformIO $ do
95state = unsafePerformIO $ do
96 h0 <- fmap hundredsOfNanosSinceGregorianReform getCurrentTime
96 h0 <- fmap hundredsOfNanosSinceGregorianReform getCurrentTime
97− mac <- getMac
97+ mac' <- getMac
98− newMVar $ State mac 0 h0 -- the 0 should be a random number
98+ newMVar $ State mac' 0 h0 -- the 0 should be a random number
99
99
100-- SysMAC.mac can fail on some machines.
100-- SysMAC.mac can fail on some machines.
101-- In those cases we fake it with a random
101-- In those cases we fake it with a random
102-- 6 bytes seed.
102-- 6 bytes seed.
103getMac :: IO MAC
103getMac :: IO MAC
104getMac =
104getMac =
105− SysMAC.mac >>= \macM ->
105+ getNetworkInterfaces >>=
106+ return . listToMaybe . filter (minBound /=) . map mac >>=
106− case macM of
107+ \macM -> case macM of
107 Just m -> return m
108 Just m -> return m
108 Nothing -> randomMac
109 Nothing -> randomMac
109
110
@@ -112,7 +113,7 @@ randomMac =
112 -- I'm too lazy to thread through
113 -- I'm too lazy to thread through
113 -- the random state ...
114 -- the random state ...
114 MAC
115 MAC
115− <$> R.randomIO
116+ <$> (R.randomIO >>= return . (1 .|.)) -- We must set the multicast bit to True. See section 4.5 of the RFC.
116 <*> R.randomIO
117 <*> R.randomIO
117 <*> R.randomIO
118 <*> R.randomIO
118 <*> R.randomIO
119 <*> R.randomIO
uuid.cabal+2−1
@@ -30,7 +30,8 @@ Library
30 binary >= 0.4 && < 0.8,
30 binary >= 0.4 && < 0.8,
31 bytestring >= 0.9 && < 1.1,
31 bytestring >= 0.9 && < 1.1,
32 cryptohash >= 0.7 && < 0.11,
32 cryptohash >= 0.7 && < 0.11,
33− maccatcher >= 1.0 && < 2.2,
33+ hashable == 1.2.*,
34+ network-info == 0.2.*,
34 random >= 1.0.1 && < 1.1,
35 random >= 1.0.1 && < 1.1,
35 time >= 1.1 && < 1.5
36 time >= 1.1 && < 1.5
36
37