module Codec.Phaser.UTF16 (
  utf16_char,
  utf16_word16_stream,
  utf16_stream_useBOM,
  utf16_stream_le,
  utf16_stream_be,
  utf16_stream_unknown,
  utf16_encode_stream_be_nobom,
  utf16_encode_stream_le_nobom,
  utf16_encode_stream_be,
  utf16_encode_stream_le,
  utf16_encode_char
 ) where

import Data.Bits
import Data.Word

import Control.Applicative
import Control.Monad

import Codec.Phaser.Core
import Codec.Phaser.Common

unit_be :: Phase p Word8 o Word16
unit_be :: forall p o. Phase p Word8 o Word16
unit_be = (\Word16
a Word16
b -> Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftL Word16
a Int
8 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16
b) (Word16 -> Word16 -> Word16)
-> Phase p Word8 o Word16 -> Phase p Word8 o (Word16 -> Word16)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Phase p Word8 o Word16
forall p o. Phase p Word8 o Word16
byte Phase p Word8 o (Word16 -> Word16)
-> Phase p Word8 o Word16 -> Phase p Word8 o Word16
forall a b.
Phase p Word8 o (a -> b) -> Phase p Word8 o a -> Phase p Word8 o b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Phase p Word8 o Word16
forall p o. Phase p Word8 o Word16
byte where
  byte :: Phase p Word8 o Word16
byte = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word16)
-> Phase p Word8 o Word8 -> Phase p Word8 o Word16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Phase p Word8 o Word8
forall p i o. Phase p i o i
get

unit_le :: Phase p Word8 o Word16
unit_le :: forall p o. Phase p Word8 o Word16
unit_le = (\Word16
a Word16
b -> Word16
a Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftL Word16
b Int
8) (Word16 -> Word16 -> Word16)
-> Phase p Word8 o Word16 -> Phase p Word8 o (Word16 -> Word16)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Phase p Word8 o Word16
forall p o. Phase p Word8 o Word16
byte Phase p Word8 o (Word16 -> Word16)
-> Phase p Word8 o Word16 -> Phase p Word8 o Word16
forall a b.
Phase p Word8 o (a -> b) -> Phase p Word8 o a -> Phase p Word8 o b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Phase p Word8 o Word16
forall p o. Phase p Word8 o Word16
byte where
  byte :: Phase p Word8 o Word16
byte = Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word16)
-> Phase p Word8 o Word8 -> Phase p Word8 o Word16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Phase p Word8 o Word8
forall p i o. Phase p i o i
get

encode_unit_be :: Word16 -> Phase p i Word8 ()
encode_unit_be :: forall p i. Word16 -> Phase p i Word8 ()
encode_unit_be Word16
c = do
  Word8 -> Phase p i Word8 ()
forall o p i. o -> Phase p i o ()
yield (Word8 -> Phase p i Word8 ()) -> Word8 -> Phase p i Word8 ()
forall a b. (a -> b) -> a -> b
$ Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word8) -> Word16 -> Word8
forall a b. (a -> b) -> a -> b
$ Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftR Word16
c Int
8
  Word8 -> Phase p i Word8 ()
forall o p i. o -> Phase p i o ()
yield (Word8 -> Phase p i Word8 ()) -> Word8 -> Phase p i Word8 ()
forall a b. (a -> b) -> a -> b
$ Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word8) -> Word16 -> Word8
forall a b. (a -> b) -> a -> b
$ Word16
c Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0xFF

encode_unit_le :: Word16 -> Phase p i Word8 ()
encode_unit_le :: forall p i. Word16 -> Phase p i Word8 ()
encode_unit_le Word16
c = do
  Word8 -> Phase p i Word8 ()
forall o p i. o -> Phase p i o ()
yield (Word8 -> Phase p i Word8 ()) -> Word8 -> Phase p i Word8 ()
forall a b. (a -> b) -> a -> b
$ Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word8) -> Word16 -> Word8
forall a b. (a -> b) -> a -> b
$ Word16
c Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
0xFF
  Word8 -> Phase p i Word8 ()
forall o p i. o -> Phase p i o ()
yield (Word8 -> Phase p i Word8 ()) -> Word8 -> Phase p i Word8 ()
forall a b. (a -> b) -> a -> b
$ Word16 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Word8) -> Word16 -> Word8
forall a b. (a -> b) -> a -> b
$ Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
shiftR Word16
c Int
8

useBOM_unit :: Monoid p => Phase p Word8 o1 (Phase p Word8 o2 Word16)
useBOM_unit :: forall p o1 o2.
Monoid p =>
Phase p Word8 o1 (Phase p Word8 o2 Word16)
useBOM_unit = String
"UTF-16: No byte order mark" String
-> Phase p Word8 o1 (Phase p Word8 o2 Word16)
-> Phase p Word8 o1 (Phase p Word8 o2 Word16)
forall {p} {i} {o} {a}. String -> Phase p i o a -> Phase p i o a
<?> (Phase p Word8 Void Word16
-> Phase p Word8 o1 (Phase p Word8 o2 Word16)
forall {s :: * -> * -> * -> * -> *} {p} {i} {o} {a} {o}.
(Monad (s p i o), PhaserType s, Eq a, Num a,
 Alternative (s p i o)) =>
s p i Void a -> s p i o (s p i o a)
go Phase p Word8 Void Word16
forall p o. Phase p Word8 o Word16
unit_be Phase p Word8 o1 (Phase p Word8 o2 Word16)
-> Phase p Word8 o1 (Phase p Word8 o2 Word16)
-> Phase p Word8 o1 (Phase p Word8 o2 Word16)
forall a.
Phase p Word8 o1 a -> Phase p Word8 o1 a -> Phase p Word8 o1 a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Phase p Word8 Void Word16
-> Phase p Word8 o1 (Phase p Word8 o2 Word16)
forall {s :: * -> * -> * -> * -> *} {p} {i} {o} {a} {o}.
(Monad (s p i o), PhaserType s, Eq a, Num a,
 Alternative (s p i o)) =>
s p i Void a -> s p i o (s p i o a)
go Phase p Word8 Void Word16
forall p o. Phase p Word8 o Word16
unit_le) where
  go :: s p i Void a -> s p i o (s p i o a)
go s p i Void a
u = do
    a
bom <- s p i Void a -> s p i o a
forall (s :: * -> * -> * -> * -> *) p i a o.
PhaserType s =>
s p i Void a -> s p i o a
fitYield s p i Void a
u
    if a
bom a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0xFEFF
      then s p i o a -> s p i o (s p i o a)
forall a. a -> s p i o a
forall (m :: * -> *) a. Monad m => a -> m a
return (s p i o a -> s p i o (s p i o a))
-> s p i o a -> s p i o (s p i o a)
forall a b. (a -> b) -> a -> b
$ s p i Void a -> s p i o a
forall (s :: * -> * -> * -> * -> *) p i a o.
PhaserType s =>
s p i Void a -> s p i o a
fitYield s p i Void a
u
      else s p i o (s p i o a)
forall a. s p i o a
forall (f :: * -> *) a. Alternative f => f a
empty

-- | Consume one or two 16 bit words and decode to a 'Char' using UTF-16
utf16_char :: Monoid p => Phase p Word16 o Char
utf16_char :: forall p o. Monoid p => Phase p Word16 o Char
utf16_char = do
  Int
hs <- Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> Phase p Word16 o Word16 -> Phase p Word16 o Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Phase p Word16 o Word16
forall p i o. Phase p i o i
get :: Phase p Word16 o Int
  case () of
   ()
_ | Int
hs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xD7FF Bool -> Bool -> Bool
|| Int
hs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0xE000 -> Char -> Phase p Word16 o Char
forall a. a -> Phase p Word16 o a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> Phase p Word16 o Char) -> Char -> Phase p Word16 o Char
forall a b. (a -> b) -> a -> b
$ Int -> Char
forall a. Enum a => Int -> a
toEnum Int
hs
     | Int
hs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0xD800 Bool -> Bool -> Bool
&& Int
hs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xDBFF -> do
       Int
ls <- Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int) -> Phase p Word16 o Word16 -> Phase p Word16 o Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Phase p Word16 o Word16
forall p i o. Phase p i o i
get :: Phase p Word16 o Int
       String
"UTF-16: Invalid low surrogate" String -> Phase p Word16 o () -> Phase p Word16 o ()
forall {p} {i} {o} {a}. String -> Phase p i o a -> Phase p i o a
<?> Bool -> Phase p Word16 o ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Int
ls Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0xDC00 Bool -> Bool -> Bool
&& Int
ls Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xDFFF)
       Char -> Phase p Word16 o Char
forall a. a -> Phase p Word16 o a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> Phase p Word16 o Char) -> Char -> Phase p Word16 o Char
forall a b. (a -> b) -> a -> b
$ Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> Int -> Char
forall a b. (a -> b) -> a -> b
$ Int
0x010000 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x0400 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (Int
hs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0xD800) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
ls Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0xDC00)
     | Bool
otherwise -> String -> Phase p Word16 o Char
forall a. String -> Phase p Word16 o a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"UTF-16: Invalid high surrogate"

utf16_encode_char :: Char -> Phase p i Word16 ()
utf16_encode_char :: forall p i. Char -> Phase p i Word16 ()
utf16_encode_char Char
c = let
  cc :: Int
cc = Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
c
  in case () of
   ()
_ | Int
cc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xD7FF Bool -> Bool -> Bool
|| (Int
cc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0xE000 Bool -> Bool -> Bool
&& Int
cc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xFFFF) ->
         Word16 -> Phase p i Word16 ()
forall o p i. o -> Phase p i o ()
yield (Word16 -> Phase p i Word16 ()) -> Word16 -> Phase p i Word16 ()
forall a b. (a -> b) -> a -> b
$ Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
cc
     | Int
cc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0x10000 Bool -> Bool -> Bool
&& Int
cc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x10FFFF -> do
         let s :: Int
s = Int
cc Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int -> Int
forall a. Bits a => a -> a
complement Int
0x010000
         Word16 -> Phase p i Word16 ()
forall o p i. o -> Phase p i o ()
yield (Word16 -> Phase p i Word16 ()) -> Word16 -> Phase p i Word16 ()
forall a b. (a -> b) -> a -> b
$ Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word16) -> Int -> Word16
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftR Int
s Int
10 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
0xD800
         Word16 -> Phase p i Word16 ()
forall o p i. o -> Phase p i o ()
yield (Word16 -> Phase p i Word16 ()) -> Word16 -> Phase p i Word16 ()
forall a b. (a -> b) -> a -> b
$ Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word16) -> Int -> Word16
forall a b. (a -> b) -> a -> b
$ (Int
s Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x03FF) Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
0xDC00
     | Bool
otherwise -> String -> Phase p i Word16 ()
forall a. String -> Phase p i Word16 a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Character not representable in UTF-16"

mkStream :: Monoid p => Phase p i a a -> Phase p i a ()
mkStream :: forall p i a. Monoid p => Phase p i a a -> Phase p i a ()
mkStream Phase p i a a
u = Phase p i a ()
go where
  go :: Phase p i a ()
go = ((Phase p i a a
u Phase p i a a -> (a -> Phase p i a ()) -> Phase p i a ()
forall a b. Phase p i a a -> (a -> Phase p i a b) -> Phase p i a b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> Phase p i a ()
forall o p i. o -> Phase p i o ()
yield) Phase p i a () -> Phase p i a () -> Phase p i a ()
forall a b. Phase p i a a -> Phase p i a b -> Phase p i a b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Phase p i a ()
go) Phase p i a () -> Phase p i a () -> Phase p i a ()
forall a. Phase p i a a -> Phase p i a a -> Phase p i a a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> () -> Phase p i a ()
forall a. a -> Phase p i a a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

mkEncodeStream :: Monoid p => (c -> Phase p c o a) -> Phase p c o ()
mkEncodeStream :: forall p c o a. Monoid p => (c -> Phase p c o a) -> Phase p c o ()
mkEncodeStream c -> Phase p c o a
f = Phase p c o ()
go where
  go :: Phase p c o ()
go = (Phase p c o c
forall p i o. Phase p i o i
get Phase p c o c -> (c -> Phase p c o a) -> Phase p c o a
forall a b. Phase p c o a -> (a -> Phase p c o b) -> Phase p c o b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= c -> Phase p c o a
f Phase p c o a -> Phase p c o () -> Phase p c o ()
forall a b. Phase p c o a -> Phase p c o b -> Phase p c o b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Phase p c o ()
go) Phase p c o () -> Phase p c o () -> Phase p c o ()
forall a. Phase p c o a -> Phase p c o a -> Phase p c o a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> () -> Phase p c o ()
forall a. a -> Phase p c o a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

utf16_word16_stream :: Monoid p => Phase p Word16 Char ()
utf16_word16_stream :: forall p. Monoid p => Phase p Word16 Char ()
utf16_word16_stream = Phase p Word16 Char Char -> Phase p Word16 Char ()
forall p i a. Monoid p => Phase p i a a -> Phase p i a ()
mkStream Phase p Word16 Char Char
forall p o. Monoid p => Phase p Word16 o Char
utf16_char

-- | Decode bytes to characters using UTF-16, using the byte order mark to
-- detect endianness.
utf16_stream_useBOM :: Monoid p => Phase p Word8 Char ()
utf16_stream_useBOM :: forall p. Monoid p => Phase p Word8 Char ()
utf16_stream_useBOM = do
  Phase p Word8 Word16 Word16
unit <- Phase p Word8 Char (Phase p Word8 Word16 Word16)
forall {p}.
Monoid p =>
Phase p Word8 Char (Phase p Word8 Word16 Word16)
forall p o1 o2.
Monoid p =>
Phase p Word8 o1 (Phase p Word8 o2 Word16)
useBOM_unit :: Monoid p =>
    Phase p Word8 Char (Phase p Word8 Word16 Word16)
  Automaton p Word8 Char () -> Phase p Word8 Char ()
forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Phase p i o a
toPhase (Automaton p Word8 Char () -> Phase p Word8 Char ())
-> Automaton p Word8 Char () -> Phase p Word8 Char ()
forall a b. (a -> b) -> a -> b
$ Phase p Word8 Word16 Word16 -> Phase p Word8 Word16 ()
forall p i a. Monoid p => Phase p i a a -> Phase p i a ()
mkStream Phase p Word8 Word16 Word16
unit Phase p Word8 Word16 ()
-> Phase p Word16 Char () -> Automaton p Word8 Char ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># Phase p Word16 Char ()
forall p. Monoid p => Phase p Word16 Char ()
utf16_word16_stream

-- | Decode bytes to characters using UTF-16, little endian mode
utf16_stream_le :: Monoid p => Automaton p Word8 Char ()
utf16_stream_le :: forall p. Monoid p => Automaton p Word8 Char ()
utf16_stream_le = Phase p Word8 Word16 Word16 -> Phase p Word8 Word16 ()
forall p i a. Monoid p => Phase p i a a -> Phase p i a ()
mkStream Phase p Word8 Word16 Word16
forall p o. Phase p Word8 o Word16
unit_le Phase p Word8 Word16 ()
-> Phase p Word16 Char () -> Automaton p Word8 Char ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># Phase p Word16 Char ()
forall p. Monoid p => Phase p Word16 Char ()
utf16_word16_stream

-- | Decode bytes to characters using UTF-16, big endian mode
utf16_stream_be :: Monoid p => Automaton p Word8 Char ()
utf16_stream_be :: forall p. Monoid p => Automaton p Word8 Char ()
utf16_stream_be = Phase p Word8 Word16 Word16 -> Phase p Word8 Word16 ()
forall p i a. Monoid p => Phase p i a a -> Phase p i a ()
mkStream Phase p Word8 Word16 Word16
forall p o. Phase p Word8 o Word16
unit_be Phase p Word8 Word16 ()
-> Phase p Word16 Char () -> Automaton p Word8 Char ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># Phase p Word16 Char ()
forall p. Monoid p => Phase p Word16 Char ()
utf16_word16_stream

-- | Decode bytes to characters using UTF-16, using byte order mark if
-- available, otherwise trying both byte orders. Downstream parser may be used
-- to disambiguate.
utf16_stream_unknown :: Monoid p => Phase p Word8 Char ()
utf16_stream_unknown :: forall p. Monoid p => Phase p Word8 Char ()
utf16_stream_unknown = (Phase p Word8 Char ()
 -> Phase p Word8 Char () -> Phase p Word8 Char ())
-> Phase p Word8 Char ()
-> Phase p Word8 Char ()
-> Phase p Word8 Char ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Phase p Word8 Char ()
-> Phase p Word8 Char () -> Phase p Word8 Char ()
forall a.
Phase p Word8 Char a
-> Phase p Word8 Char a -> Phase p Word8 Char a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) (() -> Phase p Word8 Char ()
forall a. a -> Phase p Word8 Char a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (Phase p Word8 Char () -> Phase p Word8 Char ())
-> Phase p Word8 Char () -> Phase p Word8 Char ()
forall a b. (a -> b) -> a -> b
$ do
  Phase p Word8 Void Word16
unit <- Phase p Word8 Void Word16
-> Phase p Word8 Char (Phase p Word8 Void Word16)
forall a. a -> Phase p Word8 Char a
forall (m :: * -> *) a. Monad m => a -> m a
return Phase p Word8 Void Word16
forall p o. Phase p Word8 o Word16
unit_le Phase p Word8 Char (Phase p Word8 Void Word16)
-> Phase p Word8 Char (Phase p Word8 Void Word16)
-> Phase p Word8 Char (Phase p Word8 Void Word16)
forall a.
Phase p Word8 Char a
-> Phase p Word8 Char a -> Phase p Word8 Char a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Phase p Word8 Void Word16
-> Phase p Word8 Char (Phase p Word8 Void Word16)
forall a. a -> Phase p Word8 Char a
forall (m :: * -> *) a. Monad m => a -> m a
return Phase p Word8 Void Word16
forall p o. Phase p Word8 o Word16
unit_be
  Word16
h <- Phase p Word8 Void Word16 -> Phase p Word8 Char Word16
forall (s :: * -> * -> * -> * -> *) p i a o.
PhaserType s =>
s p i Void a -> s p i o a
fitYield Phase p Word8 Void Word16
unit
  case Word16
h of
    Word16
0xFEFF -> Automaton p Word8 Char () -> Phase p Word8 Char ()
forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Phase p i o a
toPhase (Automaton p Word8 Char () -> Phase p Word8 Char ())
-> Automaton p Word8 Char () -> Phase p Word8 Char ()
forall a b. (a -> b) -> a -> b
$ Phase p Word8 Word16 Word16 -> Phase p Word8 Word16 ()
forall p i a. Monoid p => Phase p i a a -> Phase p i a ()
mkStream (Phase p Word8 Void Word16 -> Phase p Word8 Word16 Word16
forall (s :: * -> * -> * -> * -> *) p i a o.
PhaserType s =>
s p i Void a -> s p i o a
fitYield Phase p Word8 Void Word16
unit) Phase p Word8 Word16 ()
-> Phase p Word16 Char () -> Automaton p Word8 Char ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># Phase p Word16 Char ()
forall p. Monoid p => Phase p Word16 Char ()
utf16_word16_stream
    Word16
0xFFFE -> String -> Phase p Word8 Char ()
forall a. String -> Phase p Word8 Char a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Reversed byte order mark"
    Word16
_ -> Automaton p Word8 Char () -> Phase p Word8 Char ()
forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Phase p i o a
toPhase (Automaton p Word8 Char () -> Phase p Word8 Char ())
-> Automaton p Word8 Char () -> Phase p Word8 Char ()
forall a b. (a -> b) -> a -> b
$ Phase p Word8 Word16 Word16 -> Phase p Word8 Word16 ()
forall p i a. Monoid p => Phase p i a a -> Phase p i a ()
mkStream (Phase p Word8 Void Word16 -> Phase p Word8 Word16 Word16
forall (s :: * -> * -> * -> * -> *) p i a o.
PhaserType s =>
s p i Void a -> s p i o a
fitYield Phase p Word8 Void Word16
unit) Phase p Word8 Word16 ()
-> Phase p Word16 Char () -> Automaton p Word8 Char ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># (Word16 -> Phase p Word16 Char ()
forall p i o. Monoid p => i -> Phase p i o ()
put1 Word16
h Phase p Word16 Char ()
-> Phase p Word16 Char () -> Phase p Word16 Char ()
forall a b.
Phase p Word16 Char a
-> Phase p Word16 Char b -> Phase p Word16 Char b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Phase p Word16 Char ()
forall p. Monoid p => Phase p Word16 Char ()
utf16_word16_stream)

-- | Encode a stream of characters to 16 bit units
utf16_encode_stream_word16 :: Monoid p => Phase p Char Word16 ()
utf16_encode_stream_word16 :: forall p. Monoid p => Phase p Char Word16 ()
utf16_encode_stream_word16 = (Char -> Phase p Char Word16 ()) -> Phase p Char Word16 ()
forall p c o a. Monoid p => (c -> Phase p c o a) -> Phase p c o ()
mkEncodeStream Char -> Phase p Char Word16 ()
forall p i. Char -> Phase p i Word16 ()
utf16_encode_char

-- | Encode a stream of characters to bytes using UTF-16, big endian without
-- the byte order mark.
utf16_encode_stream_be_nobom :: Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_be_nobom :: forall p. Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_be_nobom =
  Phase p Char Word16 ()
forall p. Monoid p => Phase p Char Word16 ()
utf16_encode_stream_word16 Phase p Char Word16 ()
-> Phase p Word16 Word8 () -> Automaton p Char Word8 ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># (Word16 -> Phase p Word16 Word8 ()) -> Phase p Word16 Word8 ()
forall p c o a. Monoid p => (c -> Phase p c o a) -> Phase p c o ()
mkEncodeStream Word16 -> Phase p Word16 Word8 ()
forall p i. Word16 -> Phase p i Word8 ()
encode_unit_be

-- | Encode a stream of characters to bytes using UTF-16, little endian without
-- the byte order mark.
utf16_encode_stream_le_nobom :: Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_le_nobom :: forall p. Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_le_nobom =
  Phase p Char Word16 ()
forall p. Monoid p => Phase p Char Word16 ()
utf16_encode_stream_word16 Phase p Char Word16 ()
-> Phase p Word16 Word8 () -> Automaton p Char Word8 ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># (Word16 -> Phase p Word16 Word8 ()) -> Phase p Word16 Word8 ()
forall p c o a. Monoid p => (c -> Phase p c o a) -> Phase p c o ()
mkEncodeStream Word16 -> Phase p Word16 Word8 ()
forall p i. Word16 -> Phase p i Word8 ()
encode_unit_le

-- | Encode a stream of characters to bytes using UTF-16, little endian
-- including the byte order mark.
utf16_encode_stream_be :: Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_be :: forall p. Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_be =
  (Word16 -> Phase p Char Word16 ()
forall o p i. o -> Phase p i o ()
yield Word16
0xFEFF Phase p Char Word16 ()
-> Phase p Char Word16 () -> Phase p Char Word16 ()
forall a b.
Phase p Char Word16 a
-> Phase p Char Word16 b -> Phase p Char Word16 b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Phase p Char Word16 ()
forall p. Monoid p => Phase p Char Word16 ()
utf16_encode_stream_word16) Phase p Char Word16 ()
-> Phase p Word16 Word8 () -> Automaton p Char Word8 ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># (Word16 -> Phase p Word16 Word8 ()) -> Phase p Word16 Word8 ()
forall p c o a. Monoid p => (c -> Phase p c o a) -> Phase p c o ()
mkEncodeStream Word16 -> Phase p Word16 Word8 ()
forall p i. Word16 -> Phase p i Word8 ()
encode_unit_be

-- | Encode a stream of characters to bytes using UTF-16, big endian
-- including the byte order mark.
utf16_encode_stream_le :: Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_le :: forall p. Monoid p => Automaton p Char Word8 ()
utf16_encode_stream_le =
  (Word16 -> Phase p Char Word16 ()
forall o p i. o -> Phase p i o ()
yield Word16
0xFEFF Phase p Char Word16 ()
-> Phase p Char Word16 () -> Phase p Char Word16 ()
forall a b.
Phase p Char Word16 a
-> Phase p Char Word16 b -> Phase p Char Word16 b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Phase p Char Word16 ()
forall p. Monoid p => Phase p Char Word16 ()
utf16_encode_stream_word16) Phase p Char Word16 ()
-> Phase p Word16 Word8 () -> Automaton p Char Word8 ()
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
>># (Word16 -> Phase p Word16 Word8 ()) -> Phase p Word16 Word8 ()
forall p c o a. Monoid p => (c -> Phase p c o a) -> Phase p c o ()
mkEncodeStream Word16 -> Phase p Word16 Word8 ()
forall p i. Word16 -> Phase p i Word8 ()
encode_unit_le