{-# LANGUAGE MagicHash #-} {-# LANGUAGE BangPatterns #-} module Basement.Types.Char7 ( Char7(..) , toChar , fromCharMask , fromChar , fromByteMask , fromByte -- * individual ASCII Characters , c7_LF , c7_CR , c7_minus , c7_a , c7_A , c7_z , c7_Z , c7_0 , c7_1 , c7_2 , c7_3 , c7_4 , c7_5 , c7_6 , c7_7 , c7_8 , c7_9 -- * Upper / Lower With ASCII , c7Upper , c7Lower ) where import GHC.Prim import GHC.Word import GHC.Types import Data.Bits import Data.Maybe import Basement.Compat.Base import Basement.Compat.Primitive -- | ASCII value between 0x0 and 0x7f newtype Char7 = Char7 { toByte :: Word8 } deriving (Show,Eq,Ord,Typeable) -- | Convert a 'Char7' to a unicode code point 'Char' toChar :: Char7 -> Char toChar !(Char7 (W8# w)) = C# (chr# (word2Int# (word8ToWord# w))) -- | Try to convert a 'Char' to a 'Char7' -- -- If the code point is non ascii, then Nothing is returned. fromChar :: Char -> Maybe Char7 fromChar !(C# c#) | bool# (ltChar# c# (chr# 0x80#)) = Just $ Char7 $ W8# (wordToWord8# (int2Word# (ord# c#))) | otherwise = Nothing -- | Try to convert 'Word8' to a 'Char7' -- -- If the byte got higher bit set, then Nothing is returned. fromByte :: Word8 -> Maybe Char7 fromByte !w | (w .&. 0x80) == 0 = Just $ Char7 w | otherwise = Nothing -- | Convert a 'Char' to a 'Char7' ignoring all higher bits fromCharMask :: Char -> Char7 fromCharMask !(C# c#) = Char7 $ W8# (wordToWord8# (and# (int2Word# (ord# c#)) 0x7f##)) -- | Convert a 'Byte' to a 'Char7' ignoring the higher bit fromByteMask :: Word8 -> Char7 fromByteMask !w = Char7 (w .&. 0x7f) c7_LF :: Char7 c7_LF = Char7 0xa c7_CR :: Char7 c7_CR = Char7 0xd c7_minus :: Char7 c7_minus = Char7 0x2d c7_a :: Char7 c7_a = Char7 0x61 c7_A :: Char7 c7_A = Char7 0x41 c7_z :: Char7 c7_z = Char7 0x7a c7_Z :: Char7 c7_Z = Char7 0x5a c7_0, c7_1, c7_2, c7_3, c7_4, c7_5, c7_6, c7_7, c7_8, c7_9 :: Char7 c7_0 = Char7 0x30 c7_1 = Char7 0x31 c7_2 = Char7 0x32 c7_3 = Char7 0x33 c7_4 = Char7 0x34 c7_5 = Char7 0x35 c7_6 = Char7 0x36 c7_7 = Char7 0x37 c7_8 = Char7 0x38 c7_9 = Char7 0x39 c7Lower :: Char7 -> Char7 c7Lower c@(Char7 w) | c < c7_A = c | c <= c7_Z = Char7 (w .|. 0x20) | otherwise = c c7Upper :: Char7 -> Char7 c7Upper c@(Char7 w) | c < c7_a = c | c <= c7_z = Char7 (w .&. 0xdf) | otherwise = c