-- | -- 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