packages feed

uuid (empty) → 0.1.0

raw patch · 5 files changed

+348/−0 lines, 5 filesdep +basesetup-changed

Dependencies added: base

Files

+ Data/UUID.hs view
@@ -0,0 +1,225 @@+{-# INCLUDE <uuid/uuid.h> #-}+{-# INCLUDE <string.h> #-}+{-# LANGUAGE ForeignFunctionInterface #-}++-- |+-- Module      : Data.UUID+-- Copyright   : (c) 2008 Antoine Latter+--+-- License     : BSD-style+--+-- Maintainer  : aslatter@gmail.com+-- Stability   : experimental+-- Portability : portable+-- +-- Haskell bindings to /libuuid/.+-- The library /libuuid/ is available as a part of e2fsprogs:+-- <http://e2fsprogs.sourceforge.net/>.+--+-- This library is useful for creating, comparing, parsing and+-- printing Universally Unique Identifiers.+-- See <http://en.wikipedia.org/wiki/UUID> for the general idea.++module Data.UUID(UUID+                ,fromString+                ,toString+                ,toStringUpper+                ,toStringLower+                ,generate+                ,generateRandom+                ,generateTime+                ,null+                )+where++import Foreign.C.String+import Foreign.C+import Foreign.ForeignPtr+import Foreign++import Data.Typeable+import Data.Generics.Basics++import Prelude hiding (null)++import Data.UUID.Internal++instance Eq UUID where+    a == b = compare a b == EQ++instance Ord UUID where+    compare (U fp1) (U fp2) = unsafePerformIO $+        withForeignPtr fp1 $ \p1 ->+        withForeignPtr fp2 $ \p2 ->+        case c_compare p1 p2 of+           0     -> return EQ+           n|n<0 -> return LT+            |n>0 -> return GT++instance Show UUID where+    show = toString++instance Read UUID where+    readsPrec _ str = case fromString (take 36 str) of+      Nothing -> []+      Just u  -> [(u,drop 36 str)]++instance Typeable UUID where+    typeOf _ = mkTyConApp (mkTyCon "Data.UUID.UUID") []++instance Storable UUID where+    sizeOf _ = (16 *) $ alignment (undefined :: CChar)+    alignment _ = alignment (undefined :: CChar)++    peek psource = do+      fp <- mallocForeignPtrArray 16+      withForeignPtr fp $ \pdest ->+          memcpy pdest psource $ fromIntegral $ sizeOf (undefined :: UUID)+      return $ U fp++    poke pdest (U fp) = withForeignPtr fp $ \psource ->+          memcpy pdest psource $ fromIntegral $ sizeOf (undefined :: UUID)+++-- My goal with this instance was to make it work just enough to do what+-- I want when used with the HStringTemplate library.+instance Data UUID where+    toConstr uu  = mkConstr uuidType (show uu) [] (error "fixity")+    gunfold _ _  = error "gunfold"+    dataTypeOf _ = uuidType++uuidType =  mkNorepType "Data.UUID.UUID"+++-- |Creates a new 'UUID'.  If \/dev\/urandom is available, it will be used.+-- Otherwise a UUID will be generated based on the current time and the+-- hardware MAC address, if available.+generate :: IO UUID+generate = do+  fp <- mallocForeignPtrArray 16+  withForeignPtr fp $ \p -> c_generate p+  return $ U fp++-- |Create a new 'UUID'.  If \/dev\/urandom is available, it will be used.+-- Otherwise a psuedorandom generator will be used.+generateRandom :: IO UUID+generateRandom = do+  fp <- mallocForeignPtrArray 16+  withForeignPtr fp $ \p -> c_generate_random p+  return $ U fp++-- |Create a new 'UUID'.  The UUID will be  generated based on the+-- current time and the hardware MAC address, if available.+generateTime :: IO UUID+generateTime = do +  fp <- mallocForeignPtrArray 16+  withForeignPtr fp $ \p -> c_generate_time p+  return $ U fp++-- |Returns 'True' if the passed-in 'UUID' is the null UUID.+null :: UUID -> Bool+null (U fp) = unsafePerformIO $+              withForeignPtr fp $ \p ->+              return $ c_null p == 1++-- |If the passed in 'String' can be parsed as a 'UUID', it will be.+-- The hyphens may not be omitted.+-- Example:+--+-- @+--  fromString \"c2cc10e1-57d6-4b6f-9899-38d972112d8c\"+-- @+--+-- Hex digits may be upper or lower-case.+fromString :: String -> Maybe UUID+fromString s = unsafePerformIO $ do+  fp <- mallocForeignPtrArray 16+  res <- withCAString s $ \chars ->+      withForeignPtr fp $ \p ->+      c_read (castPtr chars) p+  case res of+    0 -> return . Just $ U fp+    _ -> return Nothing++-- |Returns a 'String' representation of the passed in 'UUID'.+-- Hex digits occuring in the output will be either upper or+-- lower-case depending on system defaults and locale.+toString :: UUID -> String+toString (U fp) = unsafePerformIO $ do+  chars <- mallocBytes 37+  withForeignPtr fp $ \p -> c_show p chars+  st <- peekCAString chars+  free chars+  return st++-- |Returns a 'String' representation of the passed in 'UUID'.+-- Hex digits occuring in the output will be lower-case.+toStringLower :: UUID -> String+toStringLower (U fp) = unsafePerformIO $ do+  chars <- mallocBytes 37+  withForeignPtr fp $ \p -> c_show_lower p chars+  st <- peekCAString chars+  free chars+  return st+  +-- |Returns a 'String' representation of the passed in 'UUID'.+-- Hex digits occuring in the output will be upper-case.+toStringUpper :: UUID -> String+toStringUpper (U fp) = unsafePerformIO $ do+  chars <- mallocBytes 37+  withForeignPtr fp $ \p -> c_show_upper p chars+  st <- peekCAString chars+  free chars+  return st+++-- FFI calls to do the work++type C_UUID = Ptr CChar++-- comparing UUIDs+foreign import ccall unsafe "uuid_compare"+  c_compare :: C_UUID -> C_UUID -> CInt++-- making random UUIDs+foreign import ccall unsafe "uuid_generate"+  c_generate :: C_UUID -> IO ()++foreign import ccall unsafe "uuid_generate_time"+  c_generate_time :: C_UUID -> IO ()++foreign import ccall unsafe "uuid_generate_random"+  c_generate_random :: C_UUID -> IO ()++-- Null check+foreign import ccall unsafe "uuid_is_null"+  c_null :: C_UUID -> CInt++-- Parsing+foreign import ccall unsafe "uuid_parse"+  c_read :: CString -> C_UUID ->IO CInt++-- Showing++foreign import ccall unsafe "uuid_unparse"+  c_show :: C_UUID -> CString -> IO ()++foreign import ccall unsafe "uuid_unparse_lower"+  c_show_lower :: C_UUID -> CString -> IO ()++foreign import ccall unsafe "uuid_unparse_upper"+  c_show_upper :: C_UUID -> CString -> IO ()+++-- Queries++foreign import ccall unsafe "uuid_type"+  c_type :: C_UUID -> CInt++foreign import ccall unsafe "uuid_variant"+  c_variant :: C_UUID -> CInt++-- Other++foreign import ccall unsafe "memcpy"+  memcpy :: Ptr a -> Ptr b -> CSize -> IO ()
+ Data/UUID/Internal.hs view
@@ -0,0 +1,59 @@+-- |+-- Module      : Data.UUID.Internal+-- Copyright   : (c) 2008 Antoine Latter+--+-- License     : BSD-style+--+-- Maintainer  : aslatter@gmail.com+-- Stability   : experimental+-- Portability : portable+-- +-- If the public interface in "Data.UUID" doesn't give you+-- the flexibility you need, you should be able to find+-- something here.++module Data.UUID.Internal(UUID(..)+                         ,toBytes+                         ,fromBytes+                         ,unsafeFromBytes+                         ,toForeignPtr+                         ,fromForeignPtr+                         ) where++import Foreign.ForeignPtr+import Foreign.C+import Foreign++-- |The UUID type.  Represents 128-bits of identification.+newtype UUID = U (ForeignPtr CChar)++-- |Returns the passed in UUID as a list of 16 bytes.+toBytes :: UUID -> [Word8]+toBytes (U fp) = unsafePerformIO $ withForeignPtr fp $ \p ->+                 peekArray 16 (castPtr p)++-- |Creates a UUID out of a list of bytes.+-- Will throw an error if the list is not of length 16.+fromBytes :: [Word8] -> UUID+fromBytes  xs = if length xs == 16+ then unsafeFromBytes xs+ else error "Data.UUID.Internal.fromBytes: passed in list of bytes must be of length 16."++-- |Creates a UUID out of a list of bytes.+-- Does not perform a length check.+-- Behavior is undefined for lists not of length 16.+unsafeFromBytes :: [Word8] -> UUID+unsafeFromBytes xs = U $ castForeignPtr $ unsafePerformIO $ do+   p <- mallocForeignPtrBytes 16+   withForeignPtr p $ flip pokeArray xs+   return p++-- |Given a UUID, returns a pointer to the 16 bytes+-- of memory that make up the UUID.+toForeignPtr :: UUID -> ForeignPtr CChar+toForeignPtr (U p) = p++-- |The passed in pointer is treated as if it were a pointer+-- to 16 bytes of memory.  You're in trouble if it isn't.+fromForeignPtr :: ForeignPtr CChar -> UUID+fromForeignPtr = U
+ LICENSE view
@@ -0,0 +1,28 @@+Copyright (c) 2008, Antoine Latter++All rights reserved.++Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met:++    * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer.+    * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution.+    * The names of the authors may not be used to endorse or promote +products derived from this software without specific prior written +permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,4 @@+import Distribution.Simple+main :: IO ()+main = defaultMain+
+ uuid.cabal view
@@ -0,0 +1,32 @@+Name: uuid+Version: 0.1.0+Copyright: 2008, Antoine Latter+Author: Antoine Latter+Maintainer: aslatter@gmail.com+License: BSD3+License-file: LICENSE++Category: Data+Build-Type: Simple+Cabal-Version: >= 1.2++Description:+ Haskell bindings to libuuid.+ The library libuuid is available as a part of e2fsprogs:+ <http://e2fsprogs.sourceforge.net/>.+++ This library is useful for creating, comparing, parsing and+ printing Universally Unique Identifiers.+ See <http://en.wikipedia.org/wiki/UUID> for the general idea. ++Library+ Build-Depends: base++ Exposed-Modules:+   Data.UUID,+   Data.UUID.Internal++ Extensions: ForeignFunctionInterface++ Extra-Libraries: uuid