-- |
-- Module      : Basement.String.Encoding.UTF32
-- License     : BSD-style
-- Maintainer  : Foundation
-- Stability   : experimental
-- Portability : portable
--
{-# LANGUAGE MagicHash #-}
module Basement.String.Encoding.UTF32
    ( UTF32(..)
    , UTF32_Invalid
    ) where

import GHC.Prim
import GHC.Word
import GHC.Types
import Basement.Compat.Base
import Basement.Compat.Primitive
import Basement.Types.OffsetSize
import Basement.Monad
import Basement.Numerical.Additive
import Basement.UArray
import Basement.UArray.Mutable (MUArray)
import Basement.MutableBuilder

import Basement.String.Encoding.Encoding

data UTF32 = UTF32

data UTF32_Invalid = UTF32_Invalid
  deriving (Typeable, Int -> UTF32_Invalid -> ShowS
[UTF32_Invalid] -> ShowS
UTF32_Invalid -> String
(Int -> UTF32_Invalid -> ShowS)
-> (UTF32_Invalid -> String)
-> ([UTF32_Invalid] -> ShowS)
-> Show UTF32_Invalid
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UTF32_Invalid -> ShowS
showsPrec :: Int -> UTF32_Invalid -> ShowS
$cshow :: UTF32_Invalid -> String
show :: UTF32_Invalid -> String
$cshowList :: [UTF32_Invalid] -> ShowS
showList :: [UTF32_Invalid] -> ShowS
Show, UTF32_Invalid -> UTF32_Invalid -> Bool
(UTF32_Invalid -> UTF32_Invalid -> Bool)
-> (UTF32_Invalid -> UTF32_Invalid -> Bool) -> Eq UTF32_Invalid
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UTF32_Invalid -> UTF32_Invalid -> Bool
== :: UTF32_Invalid -> UTF32_Invalid -> Bool
$c/= :: UTF32_Invalid -> UTF32_Invalid -> Bool
/= :: UTF32_Invalid -> UTF32_Invalid -> Bool
Eq, Eq UTF32_Invalid
Eq UTF32_Invalid =>
(UTF32_Invalid -> UTF32_Invalid -> Ordering)
-> (UTF32_Invalid -> UTF32_Invalid -> Bool)
-> (UTF32_Invalid -> UTF32_Invalid -> Bool)
-> (UTF32_Invalid -> UTF32_Invalid -> Bool)
-> (UTF32_Invalid -> UTF32_Invalid -> Bool)
-> (UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid)
-> (UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid)
-> Ord UTF32_Invalid
UTF32_Invalid -> UTF32_Invalid -> Bool
UTF32_Invalid -> UTF32_Invalid -> Ordering
UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UTF32_Invalid -> UTF32_Invalid -> Ordering
compare :: UTF32_Invalid -> UTF32_Invalid -> Ordering
$c< :: UTF32_Invalid -> UTF32_Invalid -> Bool
< :: UTF32_Invalid -> UTF32_Invalid -> Bool
$c<= :: UTF32_Invalid -> UTF32_Invalid -> Bool
<= :: UTF32_Invalid -> UTF32_Invalid -> Bool
$c> :: UTF32_Invalid -> UTF32_Invalid -> Bool
> :: UTF32_Invalid -> UTF32_Invalid -> Bool
$c>= :: UTF32_Invalid -> UTF32_Invalid -> Bool
>= :: UTF32_Invalid -> UTF32_Invalid -> Bool
$cmax :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
max :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
$cmin :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
min :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
Ord, Int -> UTF32_Invalid
UTF32_Invalid -> Int
UTF32_Invalid -> [UTF32_Invalid]
UTF32_Invalid -> UTF32_Invalid
UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
(UTF32_Invalid -> UTF32_Invalid)
-> (UTF32_Invalid -> UTF32_Invalid)
-> (Int -> UTF32_Invalid)
-> (UTF32_Invalid -> Int)
-> (UTF32_Invalid -> [UTF32_Invalid])
-> (UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid])
-> (UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid])
-> (UTF32_Invalid
    -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid])
-> Enum UTF32_Invalid
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: UTF32_Invalid -> UTF32_Invalid
succ :: UTF32_Invalid -> UTF32_Invalid
$cpred :: UTF32_Invalid -> UTF32_Invalid
pred :: UTF32_Invalid -> UTF32_Invalid
$ctoEnum :: Int -> UTF32_Invalid
toEnum :: Int -> UTF32_Invalid
$cfromEnum :: UTF32_Invalid -> Int
fromEnum :: UTF32_Invalid -> Int
$cenumFrom :: UTF32_Invalid -> [UTF32_Invalid]
enumFrom :: UTF32_Invalid -> [UTF32_Invalid]
$cenumFromThen :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
enumFromThen :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
$cenumFromTo :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
enumFromTo :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
$cenumFromThenTo :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
enumFromThenTo :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
Enum, UTF32_Invalid
UTF32_Invalid -> UTF32_Invalid -> Bounded UTF32_Invalid
forall a. a -> a -> Bounded a
$cminBound :: UTF32_Invalid
minBound :: UTF32_Invalid
$cmaxBound :: UTF32_Invalid
maxBound :: UTF32_Invalid
Bounded)
instance Exception UTF32_Invalid

instance Encoding UTF32 where
    type Unit UTF32 = Word32
    type Error UTF32 = UTF32_Invalid
    encodingNext :: UTF32
-> (Offset (Unit UTF32) -> Unit UTF32)
-> Offset (Unit UTF32)
-> Either (Error UTF32) (Char, Offset (Unit UTF32))
encodingNext  UTF32
_ = (Offset Word32 -> Word32)
-> Offset Word32 -> Either UTF32_Invalid (Char, Offset Word32)
(Offset (Unit UTF32) -> Unit UTF32)
-> Offset (Unit UTF32)
-> Either (Error UTF32) (Char, Offset (Unit UTF32))
next
    encodingWrite :: forall (st :: * -> *) err.
(PrimMonad st, Monad st) =>
UTF32
-> Char
-> Builder
     (UArray (Unit UTF32)) (MUArray (Unit UTF32)) (Unit UTF32) st err ()
encodingWrite UTF32
_ = Char -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
Char
-> Builder
     (UArray (Unit UTF32)) (MUArray (Unit UTF32)) (Unit UTF32) st err ()
forall (st :: * -> *) err.
(PrimMonad st, Monad st) =>
Char -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
write

next :: (Offset Word32 -> Word32)
     -> Offset Word32
     -> Either UTF32_Invalid (Char, Offset Word32)
next :: (Offset Word32 -> Word32)
-> Offset Word32 -> Either UTF32_Invalid (Char, Offset Word32)
next Offset Word32 -> Word32
getter Offset Word32
off = (Char, Offset Word32) -> Either UTF32_Invalid (Char, Offset Word32)
forall a b. b -> Either a b
Right (Char
char, Offset Word32
off Offset Word32 -> Offset Word32 -> Offset Word32
forall a. Additive a => a -> a -> a
+ Int -> Offset Word32
forall ty. Int -> Offset ty
Offset Int
1)
  where
    !(W32# Word32#
hh) = Offset Word32 -> Word32
getter Offset Word32
off
    char :: Char
    char :: Char
char = Char# -> Char
C# (Word32# -> Char#
word32ToChar# Word32#
hh)

write :: (PrimMonad st, Monad st)
      => Char
      -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
write :: forall (st :: * -> *) err.
(PrimMonad st, Monad st) =>
Char -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
write Char
c = Word32 -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
forall ty (state :: * -> *) err.
(PrimType ty, PrimMonad state) =>
ty -> Builder (UArray ty) (MUArray ty) ty state err ()
builderAppend Word32
w32
  where
    !(C# Char#
ch) = Char
c
    w32 :: Word32
    w32 :: Word32
w32 = Word32# -> Word32
W32# (Char# -> Word32#
charToWord32# Char#
ch)