on 5b263a5 help sign in
179 lines 4.9 kB history raw
1{-# INCLUDE <uuid/uuid.h> #-}
2{-# LANGUAGE ForeignFunctionInterface #-}
4-- |Haskell bindings to /libuuid/.
5-- The library /libuuid/ is available as a part of e2fsprogs:
6-- <http://e2fsprogs.sourceforge.net/>.
7--
8-- This library is useful for creating, comparing, parsing and
9-- printing Universally Unique Identifiers.
10-- See <http://en.wikipedia.org/wiki/UUID> for the general idea.
12module Data.UUID(UUID
13 ,fromString
14 ,toString
15 ,toStringUpper
16 ,toStringLower
17 ,generate
18 ,generateRandom
19 ,generateTime
20 ,null
21 )
22where
24import Foreign.C.String
25import Foreign.C
26import Foreign.ForeignPtr
27import Foreign
29import Prelude hiding (null)
31import Data.UUID.Internal
33instance Eq UUID where
34 a == b = compare a b == EQ
36instance Ord UUID where
37 compare (U fp1) (U fp2) = unsafePerformIO $
38 withForeignPtr fp1 $ \p1 ->
39 withForeignPtr fp2 $ \p2 ->
40 case c_compare p1 p2 of
41 0 -> return EQ
42 n|n<0 -> return LT
43 |n>0 -> return GT
45instance Show UUID where
46 show = toString
48instance Read UUID where
49 readsPrec _ str = case fromString (take 36 str) of
50 Nothing -> []
51 Just u -> [(u,drop 36 str)]
53-- |Creates a new 'UUID'. If \/dev\/urandom is available, it will be used.
54-- Otherwise a UUID will be generated based on the current time and the
55-- hardware MAC address, if available.
56generate :: IO UUID
57generate = do
58 fp <- mallocForeignPtrArray 16
59 withForeignPtr fp $ \p -> c_generate p
60 return $ U fp
62-- |Create a new 'UUID'. If \/dev\/urandom is available, it will be used.
63-- Otherwise a psuedorandom generator will be used.
64generateRandom :: IO UUID
65generateRandom = do
66 fp <- mallocForeignPtrArray 16
67 withForeignPtr fp $ \p -> c_generate_random p
68 return $ U fp
70-- |Create a new 'UUID'. The UUID will be generated based on the
71-- current time and the hardware MAC address, if available.
72generateTime :: IO UUID
73generateTime = do
74 fp <- mallocForeignPtrArray 16
75 withForeignPtr fp $ \p -> c_generate_time p
76 return $ U fp
78-- |Returns 'True' if the passed-in 'UUID' is the null UUID.
79null :: UUID -> Bool
80null (U fp) = unsafePerformIO $
81 withForeignPtr fp $ \p ->
82 return $ c_null p == 1
84-- |If the passed in 'String' can be parsed as a 'UUID', it will be.
85-- The hyphens may not be ommited.
86-- Example:
87--
88-- @
89-- fromString \"c2cc10e1-57d6-4b6f-9899-38d972112d8c\"
90-- @
91--
92-- Hex digits may be upper or lower-case.
93fromString :: String -> Maybe UUID
94fromString s = unsafePerformIO $ do
95 fp <- mallocForeignPtrArray 16
96 res <- withCString s $ \chars ->
97 withForeignPtr fp $ \p ->
98 c_read (castPtr chars) p
99 case res of
100 0 -> return . Just $ U fp
101 _ -> return Nothing
103-- |Returns a 'String' representation of the passed in UUID.
104-- Hex digits occuring in the output will be either upper or
105-- lower-case depending on system defaults and locale.
106toString :: UUID -> String
107toString (U fp) = unsafePerformIO $ do
108 chars <- mallocBytes 37
109 withForeignPtr fp $ \p -> c_show p chars
110 st <- peekCString chars
111 free chars
112 return st
114-- |Returns a 'String' representation of the passed in UUID.
115-- Hex digits occuring in the output will be lower-case.
116toStringLower :: UUID -> String
117toStringLower (U fp) = unsafePerformIO $ do
118 chars <- mallocBytes 37
119 withForeignPtr fp $ \p -> c_show_lower p chars
120 st <- peekCString chars
121 free chars
122 return st
124-- |Returns a 'String' representation of the passed in UUID.
125-- Hex digits occuring in the output will be upper-case.
126toStringUpper :: UUID -> String
127toStringUpper (U fp) = unsafePerformIO $ do
128 chars <- mallocBytes 37
129 withForeignPtr fp $ \p -> c_show_upper p chars
130 st <- peekCString chars
131 free chars
132 return st
135-- FFI calls to do the work
137type C_UUID = Ptr CChar
139-- comparing UUIDs
140foreign import ccall unsafe "uuid_compare"
141 c_compare :: C_UUID -> C_UUID -> CInt
143-- making random UUIDs
144foreign import ccall unsafe "uuid_generate"
145 c_generate :: C_UUID -> IO ()
147foreign import ccall unsafe "uuid_generate_time"
148 c_generate_time :: C_UUID -> IO ()
150foreign import ccall unsafe "uuid_generate_random"
151 c_generate_random :: C_UUID -> IO ()
153-- Null check
154foreign import ccall unsafe "uuid_is_null"
155 c_null :: C_UUID -> CInt
157-- Parsing
158foreign import ccall unsafe "uuid_parse"
159 c_read :: CString -> C_UUID ->IO CInt
161-- Showing
163foreign import ccall unsafe "uuid_unparse"
164 c_show :: C_UUID -> CString -> IO ()
166foreign import ccall unsafe "uuid_unparse_lower"
167 c_show_lower :: C_UUID -> CString -> IO ()
169foreign import ccall unsafe "uuid_unparse_upper"
170 c_show_upper :: C_UUID -> CString -> IO ()
173-- Queries
175foreign import ccall unsafe "uuid_type"
176 c_type :: C_UUID -> CInt
178foreign import ccall unsafe "uuid_variant"
179 c_variant :: C_UUID -> CInt