{-# LANGUAGE MagicHash #-}
module Basement.String.Encoding.ASCII7
( ASCII7(..)
, ASCII7_Invalid(..)
) where
import Basement.Compat.Base
import Basement.Compat.Primitive
import Basement.Types.OffsetSize
import Basement.Numerical.Additive
import Basement.Monad
import Basement.Bits
import GHC.Prim (int2Word#, ord#)
import GHC.Word
import GHC.Types
import Basement.UArray
import Basement.UArray.Mutable (MUArray)
import Basement.MutableBuilder
import Basement.String.Encoding.Encoding
isAscii :: Word8 -> Bool
isAscii :: Word8 -> Bool
isAscii Word8
w = (Word8
w forall bits. BitOps bits => bits -> bits -> bits
.&. Word8
0x80) forall a. Eq a => a -> a -> Bool
== Word8
0
{-# INLINE isAscii #-}
data ASCII7_Invalid
= ByteOutOfBound Word8
| CharNotAscii Char
deriving (Typeable, Int -> ASCII7_Invalid -> ShowS
[ASCII7_Invalid] -> ShowS
ASCII7_Invalid -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ASCII7_Invalid] -> ShowS
$cshowList :: [ASCII7_Invalid] -> ShowS
show :: ASCII7_Invalid -> String
$cshow :: ASCII7_Invalid -> String
showsPrec :: Int -> ASCII7_Invalid -> ShowS
$cshowsPrec :: Int -> ASCII7_Invalid -> ShowS
Show, ASCII7_Invalid -> ASCII7_Invalid -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ASCII7_Invalid -> ASCII7_Invalid -> Bool
$c/= :: ASCII7_Invalid -> ASCII7_Invalid -> Bool
== :: ASCII7_Invalid -> ASCII7_Invalid -> Bool
$c== :: ASCII7_Invalid -> ASCII7_Invalid -> Bool
Eq)
instance Exception ASCII7_Invalid
data ASCII7 = ASCII7
instance Encoding ASCII7 where
type Unit ASCII7 = Word8
type Error ASCII7 = ASCII7_Invalid
encodingNext :: ASCII7
-> (Offset (Unit ASCII7) -> Unit ASCII7)
-> Offset (Unit ASCII7)
-> Either (Error ASCII7) (Char, Offset (Unit ASCII7))
encodingNext ASCII7
_ = (Offset Word8 -> Word8)
-> Offset Word8 -> Either ASCII7_Invalid (Char, Offset Word8)
next
encodingWrite :: forall (st :: * -> *) err.
(PrimMonad st, Monad st) =>
ASCII7
-> Char
-> Builder
(UArray (Unit ASCII7))
(MUArray (Unit ASCII7))
(Unit ASCII7)
st
err
()
encodingWrite ASCII7
_ = forall (st :: * -> *) err.
(PrimMonad st, Monad st) =>
Char -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
write
next :: (Offset Word8 -> Word8)
-> Offset Word8
-> Either ASCII7_Invalid (Char, Offset Word8)
next :: (Offset Word8 -> Word8)
-> Offset Word8 -> Either ASCII7_Invalid (Char, Offset Word8)
next Offset Word8 -> Word8
getter Offset Word8
off
| Word8 -> Bool
isAscii Word8
w8 = forall a b. b -> Either a b
Right (Word8# -> Char
toChar Word8#
w, Offset Word8
off forall a. Additive a => a -> a -> a
+ Offset Word8
1)
| Bool
otherwise = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ Word8 -> ASCII7_Invalid
ByteOutOfBound Word8
w8
where
!w8 :: Word8
w8@(W8# Word8#
w) = Offset Word8 -> Word8
getter Offset Word8
off
toChar :: Word8# -> Char
toChar :: Word8# -> Char
toChar Word8#
a = Char# -> Char
C# (Word8# -> Char#
word8ToChar# Word8#
w)
write :: (PrimMonad st, Monad st)
=> Char
-> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
write :: forall (st :: * -> *) err.
(PrimMonad st, Monad st) =>
Char -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
write Char
c
| Char
c forall a. Ord a => a -> a -> Bool
< forall a. Enum a => Int -> a
toEnum Int
0x80 = forall ty (state :: * -> *) err.
(PrimType ty, PrimMonad state) =>
ty -> Builder (UArray ty) (MUArray ty) ty state err ()
builderAppend forall a b. (a -> b) -> a -> b
$ Char -> Word8
w8 Char
c
| Bool
otherwise = forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ Char -> ASCII7_Invalid
CharNotAscii Char
c
where
w8 :: Char -> Word8
w8 :: Char -> Word8
w8 (C# Char#
ch) = Word8# -> Word8
W8# (Word# -> Word8#
wordToWord8# (Int# -> Word#
int2Word# (Char# -> Int#
ord# Char#
ch)))