@@ -0,0 +1,170 @@
1+{-# INCLUDE "cbits.h" #-}
2+{-# LANGUAGE ForeignFunctionInterface, CPP #-}
16+import Foreign.C.String
22+import Prelude hiding (null)
24+#if defined(__GLASGOW_HASKELL__)
25+import GHC.Base (unsafeChr)
28+newtype UUID = U C_UUID
32+instance Eq UUID where
33+ (U a) == (U b) = c_compare a b == 0
35+instance Ord UUID where
36+ compare (U p1) (U p2) =
37+ case c_compare p1 p2 of
42+instance Show UUID where
51+generateRandom :: IO UUID
57+generateTime :: IO UUID
64+null (U p) = c_null p /= 0
66+fromString :: String -> Maybe UUID
67+fromString s = unsafePerformIO $ do
69+ chars <- mallocBytes 37
71+ res <- c_read p (castPtr chars)
73+ 0 -> return . Just $ U p
76+pack :: Int -> String -> Ptr Word8 -> IO ()
77+pack 37 _ p = pokeByteOff p 37 (0 :: Word8)
79+ pokeByteOff p n (c2w c)
81+pack n [] p = pokeByteOff p n (0 :: Word8)
83+unpack :: Ptr Word8 -> Int -> IO String
84+unpack p 37 = return []
91+ return $ (w2c c) : cs
93+toString :: UUID -> String
94+toString (U p) = unsafePerformIO $ do
95+ chars <- mallocBytes 37
97+ unpack (castPtr chars) 0
99+toStringLower :: UUID -> String
100+toStringLower (U p) = unsafePerformIO $ do
101+ chars <- mallocBytes 37
102+ c_show_lower p chars
103+ unpack (castPtr chars) 0
105+toStringUpper :: UUID -> String
106+toStringUpper (U p) = unsafePerformIO $ do
107+ chars <- mallocBytes 37
108+ c_show_upper p chars
109+ unpack (castPtr chars) 0
111+-- | Conversion between 'Word8' and 'Char'. Should compile to a no-op.
112+-- Shamelessly stolen from the 'bytestring' package.
114+#if !defined(__GLASGOW_HASKELL__)
115+w2c = chr . fromIntegral
117+w2c = unsafeChr . fromIntegral
121+-- | Unsafe conversion between 'Char' and 'Word8'. This is a no-op and
122+-- silently truncates to 8 bits Chars > '\255'. It is provided as
123+-- convenience for ByteString construction.
124+-- Shamelessly stolen from the 'bytestring' package.
126+c2w = fromIntegral . ord
130+foreign import ccall unsafe "c_compare"
131+ c_compare :: C_UUID -> C_UUID -> CInt
133+-- making random UUIDs
134+foreign import ccall unsafe "c_generate"
135+ c_generate :: C_UUID -> IO ()
137+foreign import ccall unsafe "c_generate_time"
138+ c_generate_time :: C_UUID -> IO ()
140+foreign import ccall unsafe "c_generate_random"
141+ c_generate_random :: C_UUID -> IO ()
144+foreign import ccall unsafe "c_null"
145+ c_null :: C_UUID -> CInt
149+foreign import ccall unsafe "c_read"
150+ c_read :: C_UUID -> CString ->IO CInt
154+foreign import ccall unsafe "c_show"
155+ c_show :: C_UUID -> CString -> IO ()
157+foreign import ccall unsafe "c_show_lower"
158+ c_show_lower :: C_UUID -> CString -> IO ()
160+foreign import ccall unsafe "c_show_upper"
161+ c_show_upper :: C_UUID -> CString -> IO ()
166+foreign import ccall unsafe "c_type"
167+ c_type :: C_UUID -> CInt
169+foreign import ccall unsafe "c_variant"
170+ c_variant :: C_UUID -> CInt