{-# LANGUAGE TypeFamilies #-} module Data.UUID.Util ( UnpackedUUID(..) , unpack, pack , version , extractMac , extractTime , setTime ) where import Prelude hiding (null) import Data.Word import Data.Word.Util import Data.Bits import Data.UUID.Internal import Network.Info import Data.Int (Int64) version :: UUID -> Int version uuid = fromEnum ((time_hi_and_version unpacked `shiftR` 12) .&. 0xF) where unpacked = unpack uuid -- Note UUID time is in 10^-7 seconds. setTime :: (Integral a, Bits a) => UUID -> a -> Maybe UUID setTime uuid t = if version uuid == 1 then Just $ pack $ (unpack uuid){time_low = new_low_bits, time_mid = new_mid_bits, time_hi_and_version = new_hi_and_version_bits} else Nothing where new_low_bits = fromIntegral $ t .&. 0xFFFFFFFF new_mid_bits = fromIntegral $ (t `shiftR` 32) .&. 0xFFFF new_hi_and_version_bits = fromIntegral $ 0x1000 .|. ((t `shiftR` 48) .&. 0x0FFF) extractTime :: UUID -> Maybe Int64 extractTime uuid = if version uuid == 1 then Just $ fromIntegral $ w32to64 (w16to32 (timeAndVersionToTime $ time_hi_and_version unpacked) $ time_mid unpacked) (time_low unpacked) else Nothing where unpacked = unpack uuid timeAndVersionToTime :: Word16 -> Word16 timeAndVersionToTime tv = tv .&. 0x0FFF extractMac :: UUID -> Maybe MAC extractMac uuid = if version uuid == 1 then Just $ MAC (node_0 unpacked) (node_1 unpacked) (node_2 unpacked) (node_3 unpacked) (node_4 unpacked) (node_5 unpacked) else Nothing where unpacked = unpack uuid