@@ -1,86 +1,84 @@
2−{-# LANGUAGE DeriveDataTypeable #-}
1+{-# LANGUAGE DeriveDataTypeable, TypeFamilies, CPP #-}
3−{-# LANGUAGE TypeFamilies #-}
4−{-# LANGUAGE ViewPatterns #-}
5−{-# LANGUAGE Unsafe #-}
6−{-# LANGUAGE DeriveLift #-}
7−{-# LANGUAGE StandaloneDeriving #-}
8{-# OPTIONS_HADDOCK hide #-}
2{-# OPTIONS_HADDOCK hide #-}
11-- Module : Data.UUID.Types.Internal
5-- Module : Data.UUID.Types.Internal
12−-- Copyright : (c) 2017-2018 Herbert Valerio Riedel
13−-- (c) 2008-2009, 2012 Antoine Latter
6+-- Copyright : (c) 2008-2009, 2012 Antoine Latter
14-- (c) 2009 Mark Lentczner
7-- (c) 2009 Mark Lentczner
16-- License : BSD-style
9-- License : BSD-style
18−-- Maintainer : hvr@gnu.org
11+-- Maintainer : aslatter@gmail.com
12+-- Stability : experimental
19-- Portability : portable
13-- Portability : portable
21module Data.UUID.Types.Internal
15module Data.UUID.Types.Internal
22− ( UUID(..)
16+ (UUID(..)
25− , fromByteString
19+ ,fromByteString
26− , toByteString
20+ ,toByteString
27− , fromString
21+ ,fromString
28− , toString
22+ ,toString
31− , fromWords
23+ ,fromWords
32− , toWords
24+ ,toWords
36− , buildFromBytes
26+ ,buildFromBytes
37− , buildFromWords
27+ ,buildFromWords
38− , fromASCIIBytes
28+ ,fromASCIIBytes
39− , toASCIIBytes
29+ ,toASCIIBytes
40− , fromLazyASCIIBytes
30+ ,fromLazyASCIIBytes
41− , toLazyASCIIBytes
31+ ,toLazyASCIIBytes
42− , UnpackedUUID(..)
32+ ,UnpackedUUID(..)
47−import Prelude hiding (null)
37+import Prelude hiding (null)
39+import Control.Applicative ((<*>))
49−import Control.DeepSeq (NFData (..))
40+import Control.DeepSeq (NFData(..))
50−import Control.Monad (guard, liftM2)
41+import Control.Monad (liftM4, guard)
42+import Data.Functor ((<$>))
51−import Data.Bits
44+import Data.Bits
54−import Data.Hashable
45+import Data.Hashable
55−import Data.List (elemIndices)
46+import Data.List (elemIndices)
56−import Foreign.Ptr (Ptr)
47+import Foreign.Ptr (Ptr)
58−import Foreign.Storable
49+#if MIN_VERSION_base(4,0,0)
60−import Data.Binary
52+import Data.Generics.Basics
55+import Foreign.Storable
61−import Data.Binary.Get
57+import Data.Binary
62−import Data.Binary.Put
58+import Data.Binary.Put
59+import Data.Binary.Get
63−import qualified Data.ByteString as B
60+import qualified Data.ByteString as B
64−import qualified Data.ByteString.Internal as BI
61+import qualified Data.ByteString.Internal as BI
65−import qualified Data.ByteString.Lazy as BL
62+import qualified Data.ByteString.Lazy as BL
66−import qualified Data.ByteString.Unsafe as BU
63+import qualified Data.ByteString.Unsafe as BU
67−import Data.Text (Text)
64+
68−import qualified Data.Text.Encoding as T
70−import Data.UUID.Types.Internal.Builder
65+import Data.UUID.Types.Internal.Builder
72−import System.Random (Random (..), uniform)
67+import System.Random
73−import System.Random.Stateful (Uniform (..), uniformWord64)
68+
75−import Language.Haskell.TH.Syntax (Lift)
70+-- |The UUID type. A 'Random' instance is provided which produces
76−
71+-- version 4 UUIDs as specified in RFC 4122. The 'Storable' and
77−-- | Type representing <https://en.wikipedia.org/wiki/UUID Universally Unique Identifiers (UUID)> as specified in
72+-- 'Binary' instances are compatible with RFC 4122, storing the fields
78−-- <http://tools.ietf.org/html/rfc4122 RFC 4122>.
73+-- in network order as 16 bytes.
79−data UUID = UUID {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64
74+data UUID
76+ {-# UNPACK #-} !Word32
77+ {-# UNPACK #-} !Word32
78+ {-# UNPACK #-} !Word32
79+ {-# UNPACK #-} !Word32
80− deriving (Eq, Ord)
80+ deriving (Eq, Ord, Typeable)
82− Prior to uuid-types-1.0.4:
83− !Word32 !Word32 !Word32 !Word32
84 Other representations that we tried are:
82 Other representations that we tried are:
85 Mimic V1 structure: !Word32 !Word16 !Word16 !Word16
83 Mimic V1 structure: !Word32 !Word16 !Word16 !Word16
86 !Word8 !Word8 !Word8 !Word8 !Word8 !Word8
84 !Word8 !Word8 !Word8 !Word8 !Word8 !Word8
@@ -92,75 +90,40 @@ data UUID = UUID {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64
92 None was as fast, overall, as the representation used here.
90 None was as fast, overall, as the representation used here.
95−-- | Convert a 'UUID' into a sequence of 'Word32' values.
93+-- | Covert a 'UUID' into a sequence of 'Word32' values.
96-- Useful for when you need to serialize a UUID and
94-- Useful for when you need to serialize a UUID and
97-- neither 'Storable' nor 'Binary' are appropriate.
95-- neither 'Storable' nor 'Binary' are appropriate.
98−--
96+-- Introduced in version 1.2.2.
99−-- >>> toWords <$> fromString "550e8400-e29b-41d4-a716-446655440000"
100−-- Just (1427014656,3801825748,2803254374,1430519808)
102−-- See also 'toWords64'.
104−-- /Since: @uuid-1.2.2@/
107toWords :: UUID -> (Word32, Word32, Word32, Word32)
97toWords :: UUID -> (Word32, Word32, Word32, Word32)
108−toWords (UUID w12 w34) = (w1, w2, w3, w4)
98+toWords (UUID w1 w2 w3 w4) = (w1, w2, w3, w4)
110− w1 = fromIntegral (w12 `unsafeShiftR` 32)
111− w2 = fromIntegral w12
112− w3 = fromIntegral (w34 `unsafeShiftR` 32)
113− w4 = fromIntegral w34
115-- | Create a 'UUID' from a sequence of 'Word32'. The
100-- | Create a 'UUID' from a sequence of 'Word32'. The
116−-- inverse of 'toWords'. Useful when you need a total
101+-- opposite of 'toWords'. Useful when you need a total
117-- function for constructing 'UUID' values.
102-- function for constructing 'UUID' values.
118−--
103+-- Introduced in version 1.2.2.
119−-- See also 'fromWords64'.
121−-- /Since: @uuid-1.2.2@/
124fromWords :: Word32 -> Word32 -> Word32 -> Word32 -> UUID
104fromWords :: Word32 -> Word32 -> Word32 -> Word32 -> UUID
125−fromWords w1 w2 w3 w4 = UUID (w32to64 w1 w2) (w32to64 w3 w4)
105+fromWords = UUID
127−-- | Convert a 'UUID' into a pair of 'Word64's.
129−-- >>> toWords64 <$> fromString "550e8400-e29b-41d4-a716-446655440000"
130−-- Just (6128981282234515924,12039885860129472512)
132−-- See also 'toWords'.
135−toWords64 :: UUID -> (Word64, Word64)
136−toWords64 (UUID w12 w34) = (w12,w34)
138−-- | Create a 'UUID' from a pair of 'Word64's.
140−-- Inverse of 'toWords64'. See also 'fromWords'.
143−fromWords64 :: Word64 -> Word64 -> UUID
146data UnpackedUUID =
107data UnpackedUUID =
147 UnpackedUUID {
108 UnpackedUUID {
148− time_low :: Word32 -- 0-3
109+ time_low :: Word32 -- 0-3
149− , time_mid :: Word16 -- 4-5
110+ , time_mid :: Word16 -- 4-5
150 , time_hi_and_version :: Word16 -- 6-7
111 , time_hi_and_version :: Word16 -- 6-7
151− , clock_seq_hi_res :: Word8 -- 8
112+ , clock_seq_hi_res :: Word8 -- 8
152− , clock_seq_low :: Word8 -- 9
113+ , clock_seq_low :: Word8 -- 9
153− , node_0 :: Word8
114+ , node_0 :: Word8
154− , node_1 :: Word8
115+ , node_1 :: Word8
155− , node_2 :: Word8
116+ , node_2 :: Word8
156− , node_3 :: Word8
117+ , node_3 :: Word8
157− , node_4 :: Word8
118+ , node_4 :: Word8
158− , node_5 :: Word8
119+ , node_5 :: Word8
160 deriving (Read, Show, Eq, Ord)
121 deriving (Read, Show, Eq, Ord)
162unpack :: UUID -> UnpackedUUID
123unpack :: UUID -> UnpackedUUID
163−unpack (UUID w0 w1) = build /-/ w0 /-/ w1
124+unpack (UUID w0 w1 w2 w3) =
125+ build /-/ w0 /-/ w1 /-/ w2 /-/ w3
165 build x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF =
128 build x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF =
166 UnpackedUUID {
129 UnpackedUUID {
@@ -195,26 +158,23 @@ pack unpacked =
196-- |Build a Word32 from four Word8 values, presented in big-endian order
159-- |Build a Word32 from four Word8 values, presented in big-endian order
197word :: Word8 -> Word8 -> Word8 -> Word8 -> Word32
160word :: Word8 -> Word8 -> Word8 -> Word8 -> Word32
198−word a b c d = (fromIntegral a `unsafeShiftL` 24)
161+word a b c d = (fromIntegral a `shiftL` 24)
199− .|. (fromIntegral b `unsafeShiftL` 16)
162+ .|. (fromIntegral b `shiftL` 16)
200− .|. (fromIntegral c `unsafeShiftL` 8)
163+ .|. (fromIntegral c `shiftL` 8)
201− .|. (fromIntegral d )
164+ .|. (fromIntegral d )
203−-- |Extract a Word8 from a Word64. Bytes, high to low, are numbered from 7 to 0,
166+-- |Extract a Word8 from a Word32. Bytes, high to low, are numbered from 3 to 0,
204−byte :: Int -> Word64 -> Word8
167+byte :: Int -> Word32 -> Word8
205byte i w = fromIntegral (w `shiftR` (i * 8))
168byte i w = fromIntegral (w `shiftR` (i * 8))
207-- |Build a Word16 from two Word8 values, presented in big-endian order.
170-- |Build a Word16 from two Word8 values, presented in big-endian order.
208w8to16 :: Word8 -> Word8 -> Word16
171w8to16 :: Word8 -> Word8 -> Word16
209w8to16 w0s w1s =
172w8to16 w0s w1s =
210− (w0 `unsafeShiftL` 8) .|. w1
173+ (w0 `shiftL` 8) .|. w1
212 w0 = fromIntegral w0s
175 w0 = fromIntegral w0s
213 w1 = fromIntegral w1s
176 w1 = fromIntegral w1s
215−-- | Construct 'Word64' from low/high 'Word32's
216−w32to64 :: Word32 -> Word32 -> Word64
217−w32to64 w0 w1 = (fromIntegral w0 `unsafeShiftL` 32) .|. (fromIntegral w1)
219-- |Make a UUID from sixteen Word8 values
179-- |Make a UUID from sixteen Word8 values
220makeFromBytes :: Word8 -> Word8 -> Word8 -> Word8
180makeFromBytes :: Word8 -> Word8 -> Word8 -> Word8
@@ -223,12 +183,16 @@ makeFromBytes :: Word8 -> Word8 -> Word8 -> Word8
223 -> Word8 -> Word8 -> Word8 -> Word8
183 -> Word8 -> Word8 -> Word8 -> Word8
225makeFromBytes b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf
185makeFromBytes b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf
226− = fromWords w0 w1 w2 w3
186+ = UUID w0 w1 w2 w3
227 where w0 = word b0 b1 b2 b3
187 where w0 = word b0 b1 b2 b3
228 w1 = word b4 b5 b6 b7
188 w1 = word b4 b5 b6 b7
229 w2 = word b8 b9 ba bb
189 w2 = word b8 b9 ba bb
230 w3 = word bc bd be bf
190 w3 = word bc bd be bf
192+-- |Make a UUID from four Word32 values
193+makeFromWords :: Word32 -> Word32 -> Word32 -> Word32 -> UUID
232-- |A Builder for constructing a UUID of a given version.
196-- |A Builder for constructing a UUID of a given version.
233buildFromBytes :: Word8
197buildFromBytes :: Word8
234 -> Word8 -> Word8 -> Word8 -> Word8
198 -> Word8 -> Word8 -> Word8 -> Word8
@@ -241,20 +205,20 @@ buildFromBytes v b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf =
241 where b6' = b6 .&. 0x0f .|. (v `shiftL` 4)
205 where b6' = b6 .&. 0x0f .|. (v `shiftL` 4)
242 b8' = b8 .&. 0x3f .|. 0x80
206 b8' = b8 .&. 0x3f .|. 0x80
244−-- |Build a UUID of a given version from 'Word32' values.
208+-- |Build a UUID of a given version from Word32 values.
245buildFromWords :: Word8 -> Word32 -> Word32 -> Word32 -> Word32 -> UUID
209buildFromWords :: Word8 -> Word32 -> Word32 -> Word32 -> Word32 -> UUID
246−buildFromWords v w0 w1 w2 w3 = fromWords w0 w1' w2' w3
210+buildFromWords v w0 w1 w2 w3 = makeFromWords w0 w1' w2' w3
247 where w1' = w1 .&. 0xffff0fff .|. ((fromIntegral v) `shiftL` 12)
211 where w1' = w1 .&. 0xffff0fff .|. ((fromIntegral v) `shiftL` 12)
248 w2' = w2 .&. 0x3fffffff .|. 0x80000000
212 w2' = w2 .&. 0x3fffffff .|. 0x80000000
251-- |Return the bytes that make up the UUID
215-- |Return the bytes that make up the UUID
252toList :: UUID -> [Word8]
216toList :: UUID -> [Word8]
253−toList (UUID w0 w1) =
217+toList (UUID w0 w1 w2 w3) =
254− [byte 7 w0, byte 6 w0, byte 5 w0, byte 4 w0,
218+ [byte 3 w0, byte 2 w0, byte 1 w0, byte 0 w0,
255− byte 3 w0, byte 2 w0, byte 1 w0, byte 0 w0,
219+ byte 3 w1, byte 2 w1, byte 1 w1, byte 0 w1,
256− byte 7 w1, byte 6 w1, byte 5 w1, byte 4 w1,
220+ byte 3 w2, byte 2 w2, byte 1 w2, byte 0 w2,
257− byte 3 w1, byte 2 w1, byte 1 w1, byte 0 w1]
221+ byte 3 w3, byte 2 w3, byte 1 w3, byte 0 w3]
259-- |Construct a UUID from a list of Word8. Returns Nothing if the list isn't
223-- |Construct a UUID from a list of Word8. Returns Nothing if the list isn't
260-- exactly sixteen bytes long
224-- exactly sixteen bytes long
@@ -275,10 +239,10 @@ null = (== nil)
275 -- null (UUID 0 0 0 0) = True
239 -- null (UUID 0 0 0 0) = True
276 -- null _ = False
240 -- null _ = False
278−-- |The 'nil' UUID, as defined in <http://tools.ietf.org/html/rfc4122 RFC 4122>.
242+-- |The nil UUID, as defined in RFC 4122.
279−-- It is a UUID of all zeros. @'null' u@ /iff/ @'u' == 'nil'@.
243+-- It is a UUID of all zeros. @'null' u@ iff @'u' == 'nil'@.
280nil :: UUID
244nil :: UUID
281−nil = UUID 0 0
245+nil = UUID 0 0 0 0
283-- |Extract a UUID from a 'ByteString' in network byte order.
247-- |Extract a UUID from a 'ByteString' in network byte order.
284-- The argument must be 16 bytes long, otherwise 'Nothing' is returned.
248-- The argument must be 16 bytes long, otherwise 'Nothing' is returned.
@@ -286,8 +250,6 @@ fromByteString :: BL.ByteString -> Maybe UUID
286fromByteString = fromList . BL.unpack
250fromByteString = fromList . BL.unpack
288-- |Encode a UUID into a 'ByteString' in network order.
252-- |Encode a UUID into a 'ByteString' in network order.
290−-- This uses the same encoding as the 'Binary' instance.
291toByteString :: UUID -> BL.ByteString
253toByteString :: UUID -> BL.ByteString
292toByteString = BL.pack . toList
254toByteString = BL.pack . toList
@@ -295,8 +257,9 @@ toByteString = BL.pack . toList
295-- The hyphens may not be omitted.
257-- The hyphens may not be omitted.
296-- Example:
258-- Example:
298−-- >>> fromString "c2cc10e1-57d6-4b6f-9899-38d972112d8c"
261+-- fromString \"c2cc10e1-57d6-4b6f-9899-38d972112d8c\"
299−-- Just c2cc10e1-57d6-4b6f-9899-38d972112d8c
262+-- @
301-- Hex digits may be upper or lower-case.
264-- Hex digits may be upper or lower-case.
302fromString :: String -> Maybe UUID
265fromString :: String -> Maybe UUID
@@ -311,7 +274,7 @@ fromString' s0 = do
311 (w2, s3) <- hexWord s2
274 (w2, s3) <- hexWord s2
312 (w3, s4) <- hexWord s3
275 (w3, s4) <- hexWord s3
313 if s4 /= "" then Nothing
276 if s4 /= "" then Nothing
314− else Just $ fromWords w0 w1 w2 w3
277+ else Just $ UUID w0 w1 w2 w3
315 where hexWord :: String -> Maybe (Word32, String)
278 where hexWord :: String -> Maybe (Word32, String)
316 hexWord s = Just (0, s) >>= hexByte >>= hexByte
279 hexWord s = Just (0, s) >>= hexByte >>= hexByte
317 >>= hexByte >>= hexByte
280 >>= hexByte >>= hexByte
@@ -328,39 +291,21 @@ fromString' s0 = do
328-- | Convert a UUID into a hypenated string using lower-case letters.
291-- | Convert a UUID into a hypenated string using lower-case letters.
329-- Example:
292-- Example:
331−-- >>> toString <$> fromString "550e8400-e29b-41d4-a716-446655440000"
295+-- toString \<$\> fromString \"550e8400-e29b-41d4-a716-446655440000\"
332−-- Just "550e8400-e29b-41d4-a716-446655440000"
296+-- @
335toString :: UUID -> String
297toString :: UUID -> String
336−toString uuid = hexw0 w0 $ hexw1 w1 ""
298+toString (UUID w0 w1 w2 w3) = hexw w0 $ hexw' w1 $ hexw' w2 $ hexw w3 ""
337− where hexw0 :: Word64 -> String -> String
299+ where hexw :: Word32 -> String -> String
338− hexw0 w s = hexn w 60 : hexn w 56 : hexn w 52 : hexn w 48
339− : hexn w 44 : hexn w 40 : hexn w 36 : hexn w 32
340− : '-' : hexn w 28 : hexn w 24 : hexn w 20 : hexn w 16
300+ hexw w s = hexn w 28 : hexn w 24 : hexn w 20 : hexn w 16
341− : '-' : hexn w 12 : hexn w 8 : hexn w 4 : hexn w 0
301+ : hexn w 12 : hexn w 8 : hexn w 4 : hexn w 0 : s
344− hexw1 :: Word64 -> String -> String
345− hexw1 w s = '-' : hexn w 60 : hexn w 56 : hexn w 52 : hexn w 48
346− : '-' : hexn w 44 : hexn w 40 : hexn w 36 : hexn w 32
347− : hexn w 28 : hexn w 24 : hexn w 20 : hexn w 16
348− : hexn w 12 : hexn w 8 : hexn w 4 : hexn w 0
351− hexn :: Word64 -> Int -> Char
352− hexn w r = intToDigit $ fromIntegral ((w `shiftR` r) .&. 0xf)
354− (w0,w1) = toWords64 uuid
303+ hexw' :: Word32 -> String -> String
355−
304+ hexw' w s = '-' : hexn w 28 : hexn w 24 : hexn w 20 : hexn w 16
356−-- | If the passed in `Text` can be parsed as an ASCII representation of
305+ : '-' : hexn w 12 : hexn w 8 : hexn w 4 : hexn w 0 : s
357−-- a `UUID`, it will be. The hyphens may not be omitted.
358−fromText :: Text -> Maybe UUID
359−fromText = fromASCIIBytes . T.encodeUtf8
361−-- | Convert a UUID into a hyphentated string using lower-case letters.
307+ hexn :: Word32 -> Int -> Char
362−toText :: UUID -> Text
308+ hexn w r = intToDigit $ fromIntegral ((w `shiftR` r) .&. 0xf)
363−toText = T.decodeLatin1 . toASCIIBytes
365-- | Convert a UUID into a hyphentated string using lower-case letters, packed
310-- | Convert a UUID into a hyphentated string using lower-case letters, packed
366-- as ASCII bytes into `B.ByteString`.
311-- as ASCII bytes into `B.ByteString`.
@@ -455,30 +400,49 @@ fromASCIIBytes bs = do
455-- | Similar to `toASCIIBytes` except we produce a lazy `BL.ByteString`.
400-- | Similar to `toASCIIBytes` except we produce a lazy `BL.ByteString`.
456toLazyASCIIBytes :: UUID -> BL.ByteString
401toLazyASCIIBytes :: UUID -> BL.ByteString
457toLazyASCIIBytes =
402toLazyASCIIBytes =
403+#if MIN_VERSION_bytestring(0,10,0)
458 BL.fromStrict
404 BL.fromStrict
406+ BL.fromChunks . return
459 . toASCIIBytes
408 . toASCIIBytes
461-- | Similar to `fromASCIIBytes` except parses from a lazy `BL.ByteString`.
410-- | Similar to `fromASCIIBytes` except parses from a lazy `BL.ByteString`.
462fromLazyASCIIBytes :: BL.ByteString -> Maybe UUID
411fromLazyASCIIBytes :: BL.ByteString -> Maybe UUID
463fromLazyASCIIBytes bs =
412fromLazyASCIIBytes bs =
464− if BL.length bs == 36 then fromASCIIBytes (BL.toStrict bs) else Nothing
413+ if BL.length bs == 36 then fromASCIIBytes (
414+#if MIN_VERSION_bytestring(0,10,0)
417+ B.concat $ BL.toChunks bs
467-- Class Instances
422-- Class Instances
470−-- | This 'Random' instance produces __insecure__ version 4 UUIDs as
471−-- specified in <http://tools.ietf.org/html/rfc4122 RFC 4122>.
472instance Random UUID where
425instance Random UUID where
473− random = uniform
426+ random g = (fromGenNext w0 w1 w2 w3 w4, g4)
427+ where (w0, g0) = next g
474 randomR _ = random -- range is ignored
432 randomR _ = random -- range is ignored
476−-- @since 1.0.4
434+-- |Build a UUID from the results of five calls to next on a StdGen.
477−instance Uniform UUID where
435+-- While next on StdGet returns an Int, it doesn't provide 32 bits of
478− uniformM gen = do
436+-- randomness. This code relies on at last 28 bits of randomness in the
479− w0 <- uniformWord64 gen
437+-- and optimizes its use so as to make only five random values, not six.
480− w1 <- uniformWord64 gen
438+fromGenNext :: Int -> Int -> Int -> Int -> Int -> UUID
439+fromGenNext w0 w1 w2 w3 w4 =
481− pure $ buildFromBytes 4 /-/ w0 /-/ w1
440+ buildFromBytes 4 /-/ (ThreeByte w0)
442+ /-/ w2 -- use all 4 bytes because we know the version
443+ -- field will "cover" the upper, non-random bits
483-- |A ByteSource to extract only three bytes from an Int, since next on StdGet
447-- |A ByteSource to extract only three bytes from an Int, since next on StdGet
484-- only returns 31 bits of randomness.
448-- only returns 31 bits of randomness.
@@ -486,29 +450,24 @@ type instance ByteSink ThreeByte g = Takes3Bytes g
486newtype ThreeByte = ThreeByte Int
450newtype ThreeByte = ThreeByte Int
487instance ByteSource ThreeByte where
451instance ByteSource ThreeByte where
488 f /-/ (ThreeByte w) = f b1 b2 b3
452 f /-/ (ThreeByte w) = f b1 b2 b3
489− where b1 = fromIntegral (w `unsafeShiftR` 16)
453+ where b1 = fromIntegral (w `shiftR` 16)
490− b2 = fromIntegral (w `unsafeShiftR` 8)
454+ b2 = fromIntegral (w `shiftR` 8)
491 b3 = fromIntegral w
455 b3 = fromIntegral w
493instance NFData UUID where
457instance NFData UUID where
494− rnf = flip seq ()
458+ rnf = rnf . toWords
496instance Hashable UUID where
460instance Hashable UUID where
497− hash (toWords -> (w0,w1,w2,w3)) =
461+ hash (UUID w0 w1 w2 w3) =
498 hash w0 `hashWithSalt` w1
462 hash w0 `hashWithSalt` w1
499 `hashWithSalt` w2
463 `hashWithSalt` w2
500 `hashWithSalt` w3
464 `hashWithSalt` w3
501− hashWithSalt s (toWords -> (w0,w1,w2,w3)) =
465+ hashWithSalt s (UUID w0 w1 w2 w3) =
502 s `hashWithSalt` w0
466 s `hashWithSalt` w0
503 `hashWithSalt` w1
467 `hashWithSalt` w1
504 `hashWithSalt` w2
468 `hashWithSalt` w2
505 `hashWithSalt` w3
469 `hashWithSalt` w3
507−-- | Pretty prints a 'UUID' (without quotation marks). See also 'toString'.
510−-- "00000000-0000-0000-0000-000000000000"
512instance Show UUID where
471instance Show UUID where
513 show = toString
472 show = toString
@@ -519,7 +478,7 @@ instance Read UUID where
519 Nothing -> []
478 Nothing -> []
520 Just u -> [(u,drop 36 noSpaces)]
479 Just u -> [(u,drop 36 noSpaces)]
522−-- | This 'Storable' instance uses the memory layout as described in <http://tools.ietf.org/html/rfc4122 RFC 4122>, but in contrast to the 'Binary' instance, __the fields are stored in host byte order__.
481+
523instance Storable UUID where
482instance Storable UUID where
524 sizeOf _ = 16
483 sizeOf _ = 16
525 alignment _ = 4
484 alignment _ = 4
@@ -556,10 +515,10 @@ instance Storable UUID where
556 pokeByteOff p (off+14) x9
515 pokeByteOff p (off+14) x9
557 pokeByteOff p (off+15) x10
516 pokeByteOff p (off+15) x10
559−-- | This 'Binary' instance is compatible with <http://tools.ietf.org/html/rfc4122 RFC 4122>, storing the fields in network order as 16 bytes.
560instance Binary UUID where
518instance Binary UUID where
561− put (UUID w0 w1) = putWord64be w0 >> putWord64be w1
519+ put (UUID w0 w1 w2 w3) =
562− get = liftM2 UUID getWord64be getWord64be
520+ putWord32be w0 >> putWord32be w1 >> putWord32be w2 >> putWord32be w3
521+ get = liftM4 UUID getWord32be getWord32be getWord32be getWord32be
565-- My goal with this instance was to make it work just enough to do what
524-- My goal with this instance was to make it work just enough to do what
@@ -572,4 +531,7 @@ instance Data UUID where
572uuidType :: DataType
531uuidType :: DataType
573uuidType = mkNoRepType "Data.UUID.Types.UUID"
532uuidType = mkNoRepType "Data.UUID.Types.UUID"
575−deriving instance Lift UUID
534+#if !(MIN_VERSION_base(4,2,0))
535+mkNoRepType :: String -> DataType
536+mkNoRepType = mkNorepType