{-# LANGUAGE Trustworthy #-}{-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation , MagicHash #-}{-# OPTIONS_GHC -funbox-strict-fields #-}------------------------------------------------------------------------------- |-- Module : GHC.IO.Encoding.UTF16-- Copyright : (c) The University of Glasgow, 2009-- License : see libraries/base/LICENSE---- Maintainer : libraries@haskell.org-- Stability : internal-- Portability : non-portable---- UTF-16 Codecs for the IO library---- Portions Copyright : (c) Tom Harper 2008-2009,-- (c) Bryan O'Sullivan 2009,-- (c) Duncan Coutts 2009-------------------------------------------------------------------------------moduleGHC.IO.Encoding.UTF16(utf16 ,mkUTF16 ,utf16_decode ,utf16_encode ,utf16be ,mkUTF16be ,utf16be_decode ,utf16be_encode ,utf16le ,mkUTF16le ,utf16le_decode ,utf16le_encode ,)whereimportGHC.Base importGHC.Real importGHC.Num -- import GHC.IOimportGHC.IO.Buffer importGHC.IO.Encoding.Failure importGHC.IO.Encoding.Types importGHC.Word importData.Bits importGHC.IORef -- ------------------------------------------------------------------------------- The UTF-16 codec: either UTF16BE or UTF16LE with a BOMutf16 ::TextEncoding utf16 :: TextEncoding utf16 =CodingFailureMode -> TextEncoding mkUTF16 CodingFailureMode ErrorOnCodingFailure -- | @since 4.4.0.0mkUTF16 ::CodingFailureMode ->TextEncoding mkUTF16 :: CodingFailureMode -> TextEncoding mkUTF16 CodingFailureMode cfm =TextEncoding :: forall dstate estate. String -> IO (TextDecoder dstate) -> IO (TextEncoder estate) -> TextEncoding TextEncoding {textEncodingName :: String textEncodingName =String "UTF-16",mkTextDecoder :: IO (TextDecoder (Maybe DecodeBuffer)) mkTextDecoder =CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) utf16_DF CodingFailureMode cfm ,mkTextEncoder :: IO (TextEncoder Bool) mkTextEncoder =CodingFailureMode -> IO (TextEncoder Bool) utf16_EF CodingFailureMode cfm }utf16_DF ::CodingFailureMode ->IO(TextDecoder (Maybe DecodeBuffer ))utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) utf16_DF CodingFailureMode cfm =doIORef (Maybe DecodeBuffer) seen_bom <-Maybe DecodeBuffer -> IO (IORef (Maybe DecodeBuffer)) forall a. a -> IO (IORef a) newIORef Maybe DecodeBuffer forall a. Maybe a Nothing TextDecoder (Maybe DecodeBuffer) -> IO (TextDecoder (Maybe DecodeBuffer)) forall (m :: * -> *) a. Monad m => a -> m a return (BufferCodec :: forall from to state. CodeBuffer from to -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) -> IO () -> IO state -> (state -> IO ()) -> BufferCodec from to state BufferCodec {encode :: DecodeBuffer encode =IORef (Maybe DecodeBuffer) -> DecodeBuffer utf16_decode IORef (Maybe DecodeBuffer) seen_bom ,recover :: Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recover =CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode CodingFailureMode cfm ,close :: IO () close =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),getState :: IO (Maybe DecodeBuffer) getState =IORef (Maybe DecodeBuffer) -> IO (Maybe DecodeBuffer) forall a. IORef a -> IO a readIORef IORef (Maybe DecodeBuffer) seen_bom ,setState :: Maybe DecodeBuffer -> IO () setState =IORef (Maybe DecodeBuffer) -> Maybe DecodeBuffer -> IO () forall a. IORef a -> a -> IO () writeIORef IORef (Maybe DecodeBuffer) seen_bom })utf16_EF ::CodingFailureMode ->IO(TextEncoder Bool)utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF CodingFailureMode cfm =doIORef Bool done_bom <-Bool -> IO (IORef Bool) forall a. a -> IO (IORef a) newIORef Bool FalseTextEncoder Bool -> IO (TextEncoder Bool) forall (m :: * -> *) a. Monad m => a -> m a return (BufferCodec :: forall from to state. CodeBuffer from to -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) -> IO () -> IO state -> (state -> IO ()) -> BufferCodec from to state BufferCodec {encode :: CodeBuffer Char Word8 encode =IORef Bool -> CodeBuffer Char Word8 utf16_encode IORef Bool done_bom ,recover :: Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recover =CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode CodingFailureMode cfm ,close :: IO () close =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),getState :: IO Bool getState =IORef Bool -> IO Bool forall a. IORef a -> IO a readIORef IORef Bool done_bom ,setState :: Bool -> IO () setState =IORef Bool -> Bool -> IO () forall a. IORef a -> a -> IO () writeIORef IORef Bool done_bom })utf16_encode ::IORef Bool->EncodeBuffer utf16_encode :: IORef Bool -> CodeBuffer Char Word8 utf16_encode IORef Bool done_bom Buffer Char input output :: Buffer Word8 output @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Word8 oraw ,bufL :: forall e. Buffer e -> Int bufL =Int _,bufR :: forall e. Buffer e -> Int bufR =Int ow ,bufSize :: forall e. Buffer e -> Int bufSize =Int os }=doBool b <-IORef Bool -> IO Bool forall a. IORef a -> IO a readIORef IORef Bool done_bom ifBool b thenCodeBuffer Char Word8 utf16_native_encode Buffer Char input Buffer Word8 output elseifInt os Int -> Int -> Int forall a. Num a => a -> a -> a - Int ow Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 2then(CodingProgress, Buffer Char, Buffer Word8) -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> m a return (CodingProgress OutputUnderflow ,Buffer Char input ,Buffer Word8 output )elsedoIORef Bool -> Bool -> IO () forall a. IORef a -> a -> IO () writeIORef IORef Bool done_bom Bool TrueRawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw Int ow Word8 bom1 RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)Word8 bom2 CodeBuffer Char Word8 utf16_native_encode Buffer Char input Buffer Word8 output {bufR :: Int bufR =Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2}utf16_decode ::IORef (Maybe DecodeBuffer )->DecodeBuffer utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer utf16_decode IORef (Maybe DecodeBuffer) seen_bom input :: Buffer Word8 input @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Word8 iraw ,bufL :: forall e. Buffer e -> Int bufL =Int ir ,bufR :: forall e. Buffer e -> Int bufR =Int iw ,bufSize :: forall e. Buffer e -> Int bufSize =Int _}Buffer Char output =doMaybe DecodeBuffer mb <-IORef (Maybe DecodeBuffer) -> IO (Maybe DecodeBuffer) forall a. IORef a -> IO a readIORef IORef (Maybe DecodeBuffer) seen_bom caseMaybe DecodeBuffer mb ofJust DecodeBuffer decode ->DecodeBuffer decode Buffer Word8 input Buffer Char output Maybe DecodeBuffer Nothing ->ifInt iw Int -> Int -> Int forall a. Num a => a -> a -> a - Int ir Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 2then(CodingProgress, Buffer Word8, Buffer Char) -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> m a return (CodingProgress InputUnderflow ,Buffer Word8 input ,Buffer Char output )elsedoWord8 c0 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw Int ir Word8 c1 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)case()of() _|Word8 c0 Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool ==Word8 bomB Bool -> Bool -> Bool &&Word8 c1 Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool ==Word8 bomL ->doIORef (Maybe DecodeBuffer) -> Maybe DecodeBuffer -> IO () forall a. IORef a -> a -> IO () writeIORef IORef (Maybe DecodeBuffer) seen_bom (DecodeBuffer -> Maybe DecodeBuffer forall a. a -> Maybe a Just DecodeBuffer utf16be_decode )DecodeBuffer utf16be_decode Buffer Word8 input {bufL :: Int bufL =Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2}Buffer Char output |Word8 c0 Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool ==Word8 bomL Bool -> Bool -> Bool &&Word8 c1 Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool ==Word8 bomB ->doIORef (Maybe DecodeBuffer) -> Maybe DecodeBuffer -> IO () forall a. IORef a -> a -> IO () writeIORef IORef (Maybe DecodeBuffer) seen_bom (DecodeBuffer -> Maybe DecodeBuffer forall a. a -> Maybe a Just DecodeBuffer utf16le_decode )DecodeBuffer utf16le_decode Buffer Word8 input {bufL :: Int bufL =Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2}Buffer Char output |Bool otherwise ->doIORef (Maybe DecodeBuffer) -> Maybe DecodeBuffer -> IO () forall a. IORef a -> a -> IO () writeIORef IORef (Maybe DecodeBuffer) seen_bom (DecodeBuffer -> Maybe DecodeBuffer forall a. a -> Maybe a Just DecodeBuffer utf16_native_decode )DecodeBuffer utf16_native_decode Buffer Word8 input Buffer Char output bomB ,bomL ,bom1 ,bom2 ::Word8 bomB :: Word8 bomB =Word8 0xfebomL :: Word8 bomL =Word8 0xff-- choose UTF-16BE by default for UTF-16 outpututf16_native_decode ::DecodeBuffer utf16_native_decode :: DecodeBuffer utf16_native_decode =DecodeBuffer utf16be_decode utf16_native_encode ::EncodeBuffer utf16_native_encode :: CodeBuffer Char Word8 utf16_native_encode =CodeBuffer Char Word8 utf16be_encode bom1 :: Word8 bom1 =Word8 bomB bom2 :: Word8 bom2 =Word8 bomL -- ------------------------------------------------------------------------------- UTF16LE and UTF16BEutf16be ::TextEncoding utf16be :: TextEncoding utf16be =CodingFailureMode -> TextEncoding mkUTF16be CodingFailureMode ErrorOnCodingFailure -- | @since 4.4.0.0mkUTF16be ::CodingFailureMode ->TextEncoding mkUTF16be :: CodingFailureMode -> TextEncoding mkUTF16be CodingFailureMode cfm =TextEncoding :: forall dstate estate. String -> IO (TextDecoder dstate) -> IO (TextEncoder estate) -> TextEncoding TextEncoding {textEncodingName :: String textEncodingName =String "UTF-16BE",mkTextDecoder :: IO (TextDecoder ()) mkTextDecoder =CodingFailureMode -> IO (TextDecoder ()) utf16be_DF CodingFailureMode cfm ,mkTextEncoder :: IO (TextEncoder ()) mkTextEncoder =CodingFailureMode -> IO (TextEncoder ()) utf16be_EF CodingFailureMode cfm }utf16be_DF ::CodingFailureMode ->IO(TextDecoder ())utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF CodingFailureMode cfm =TextDecoder () -> IO (TextDecoder ()) forall (m :: * -> *) a. Monad m => a -> m a return (BufferCodec :: forall from to state. CodeBuffer from to -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) -> IO () -> IO state -> (state -> IO ()) -> BufferCodec from to state BufferCodec {encode :: DecodeBuffer encode =DecodeBuffer utf16be_decode ,recover :: Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recover =CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode CodingFailureMode cfm ,close :: IO () close =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),getState :: IO () getState =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),setState :: () -> IO () setState =IO () -> () -> IO () forall a b. a -> b -> a const (IO () -> () -> IO ()) -> IO () -> () -> IO () forall a b. (a -> b) -> a -> b $ () -> IO () forall (m :: * -> *) a. Monad m => a -> m a return ()})utf16be_EF ::CodingFailureMode ->IO(TextEncoder ())utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF CodingFailureMode cfm =TextEncoder () -> IO (TextEncoder ()) forall (m :: * -> *) a. Monad m => a -> m a return (BufferCodec :: forall from to state. CodeBuffer from to -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) -> IO () -> IO state -> (state -> IO ()) -> BufferCodec from to state BufferCodec {encode :: CodeBuffer Char Word8 encode =CodeBuffer Char Word8 utf16be_encode ,recover :: Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recover =CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode CodingFailureMode cfm ,close :: IO () close =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),getState :: IO () getState =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),setState :: () -> IO () setState =IO () -> () -> IO () forall a b. a -> b -> a const (IO () -> () -> IO ()) -> IO () -> () -> IO () forall a b. (a -> b) -> a -> b $ () -> IO () forall (m :: * -> *) a. Monad m => a -> m a return ()})utf16le ::TextEncoding utf16le :: TextEncoding utf16le =CodingFailureMode -> TextEncoding mkUTF16le CodingFailureMode ErrorOnCodingFailure -- | @since 4.4.0.0mkUTF16le ::CodingFailureMode ->TextEncoding mkUTF16le :: CodingFailureMode -> TextEncoding mkUTF16le CodingFailureMode cfm =TextEncoding :: forall dstate estate. String -> IO (TextDecoder dstate) -> IO (TextEncoder estate) -> TextEncoding TextEncoding {textEncodingName :: String textEncodingName =String "UTF16-LE",mkTextDecoder :: IO (TextDecoder ()) mkTextDecoder =CodingFailureMode -> IO (TextDecoder ()) utf16le_DF CodingFailureMode cfm ,mkTextEncoder :: IO (TextEncoder ()) mkTextEncoder =CodingFailureMode -> IO (TextEncoder ()) utf16le_EF CodingFailureMode cfm }utf16le_DF ::CodingFailureMode ->IO(TextDecoder ())utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF CodingFailureMode cfm =TextDecoder () -> IO (TextDecoder ()) forall (m :: * -> *) a. Monad m => a -> m a return (BufferCodec :: forall from to state. CodeBuffer from to -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) -> IO () -> IO state -> (state -> IO ()) -> BufferCodec from to state BufferCodec {encode :: DecodeBuffer encode =DecodeBuffer utf16le_decode ,recover :: Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recover =CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode CodingFailureMode cfm ,close :: IO () close =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),getState :: IO () getState =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),setState :: () -> IO () setState =IO () -> () -> IO () forall a b. a -> b -> a const (IO () -> () -> IO ()) -> IO () -> () -> IO () forall a b. (a -> b) -> a -> b $ () -> IO () forall (m :: * -> *) a. Monad m => a -> m a return ()})utf16le_EF ::CodingFailureMode ->IO(TextEncoder ())utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF CodingFailureMode cfm =TextEncoder () -> IO (TextEncoder ()) forall (m :: * -> *) a. Monad m => a -> m a return (BufferCodec :: forall from to state. CodeBuffer from to -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) -> IO () -> IO state -> (state -> IO ()) -> BufferCodec from to state BufferCodec {encode :: CodeBuffer Char Word8 encode =CodeBuffer Char Word8 utf16le_encode ,recover :: Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recover =CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode CodingFailureMode cfm ,close :: IO () close =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),getState :: IO () getState =() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return (),setState :: () -> IO () setState =IO () -> () -> IO () forall a b. a -> b -> a const (IO () -> () -> IO ()) -> IO () -> () -> IO () forall a b. (a -> b) -> a -> b $ () -> IO () forall (m :: * -> *) a. Monad m => a -> m a return ()})utf16be_decode ::DecodeBuffer utf16be_decode :: DecodeBuffer utf16be_decode input :: Buffer Word8 input @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Word8 iraw ,bufL :: forall e. Buffer e -> Int bufL =Int ir0 ,bufR :: forall e. Buffer e -> Int bufR =Int iw ,bufSize :: forall e. Buffer e -> Int bufSize =Int _}output :: Buffer Char output @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Char oraw ,bufL :: forall e. Buffer e -> Int bufL =Int _,bufR :: forall e. Buffer e -> Int bufR =Int ow0 ,bufSize :: forall e. Buffer e -> Int bufSize =Int os }=letloop :: Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop !Int ir !Int ow |Int ow Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >=Int os =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress OutputUnderflow Int ir Int ow |Int ir Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >=Int iw =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InputUnderflow Int ir Int ow |Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1Int -> Int -> Bool forall a. Eq a => a -> a -> Bool ==Int iw =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InputUnderflow Int ir Int ow |Bool otherwise =doWord8 c0 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw Int ir Word8 c1 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)letx1 :: Word16 x1 =Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c0 Word16 -> Int -> Word16 forall a. Bits a => a -> Int -> a `shiftL` Int 8Word16 -> Word16 -> Word16 forall a. Num a => a -> a -> a + Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c1 ifWord16 -> Bool validate1 Word16 x1 thendoInt ow' <-RawBuffer Char -> Int -> Char -> IO Int writeCharBuf RawBuffer Char oraw Int ow (Int -> Char unsafeChr (Word16 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Word16 x1 ))Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)Int ow' elseifInt iw Int -> Int -> Int forall a. Num a => a -> a -> a - Int ir Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 4thenCodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InputUnderflow Int ir Int ow elsedoWord8 c2 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)Word8 c3 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 3)letx2 :: Word16 x2 =Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c2 Word16 -> Int -> Word16 forall a. Bits a => a -> Int -> a `shiftL` Int 8Word16 -> Word16 -> Word16 forall a. Num a => a -> a -> a + Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c3 ifBool -> Bool not(Word16 -> Word16 -> Bool validate2 Word16 x1 Word16 x2 )thenIO (CodingProgress, Buffer Word8, Buffer Char) invalid elsedoInt ow' <-RawBuffer Char -> Int -> Char -> IO Int writeCharBuf RawBuffer Char oraw Int ow (Word16 -> Word16 -> Char chr2 Word16 x1 Word16 x2 )Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 4)Int ow' whereinvalid :: IO (CodingProgress, Buffer Word8, Buffer Char) invalid =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InvalidSequence Int ir Int ow -- lambda-lifted, to avoid thunks being built in the inner-loop:done :: a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done a why !Int ir !Int ow =(a, Buffer Word8, Buffer Char) -> m (a, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> m a return (a why ,ifInt ir Int -> Int -> Bool forall a. Eq a => a -> a -> Bool ==Int iw thenBuffer Word8 input {bufL :: Int bufL =Int 0,bufR :: Int bufR =Int 0}elseBuffer Word8 input {bufL :: Int bufL =Int ir },Buffer Char output {bufR :: Int bufR =Int ow })inInt -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop Int ir0 Int ow0 utf16le_decode ::DecodeBuffer utf16le_decode :: DecodeBuffer utf16le_decode input :: Buffer Word8 input @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Word8 iraw ,bufL :: forall e. Buffer e -> Int bufL =Int ir0 ,bufR :: forall e. Buffer e -> Int bufR =Int iw ,bufSize :: forall e. Buffer e -> Int bufSize =Int _}output :: Buffer Char output @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Char oraw ,bufL :: forall e. Buffer e -> Int bufL =Int _,bufR :: forall e. Buffer e -> Int bufR =Int ow0 ,bufSize :: forall e. Buffer e -> Int bufSize =Int os }=letloop :: Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop !Int ir !Int ow |Int ow Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >=Int os =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress OutputUnderflow Int ir Int ow |Int ir Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >=Int iw =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InputUnderflow Int ir Int ow |Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1Int -> Int -> Bool forall a. Eq a => a -> a -> Bool ==Int iw =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InputUnderflow Int ir Int ow |Bool otherwise =doWord8 c0 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw Int ir Word8 c1 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)letx1 :: Word16 x1 =Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c1 Word16 -> Int -> Word16 forall a. Bits a => a -> Int -> a `shiftL` Int 8Word16 -> Word16 -> Word16 forall a. Num a => a -> a -> a + Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c0 ifWord16 -> Bool validate1 Word16 x1 thendoInt ow' <-RawBuffer Char -> Int -> Char -> IO Int writeCharBuf RawBuffer Char oraw Int ow (Int -> Char unsafeChr (Word16 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Word16 x1 ))Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)Int ow' elseifInt iw Int -> Int -> Int forall a. Num a => a -> a -> a - Int ir Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 4thenCodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InputUnderflow Int ir Int ow elsedoWord8 c2 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)Word8 c3 <-RawBuffer Word8 -> Int -> IO Word8 readWord8Buf RawBuffer Word8 iraw (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 3)letx2 :: Word16 x2 =Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c3 Word16 -> Int -> Word16 forall a. Bits a => a -> Int -> a `shiftL` Int 8Word16 -> Word16 -> Word16 forall a. Num a => a -> a -> a + Word8 -> Word16 forall a b. (Integral a, Num b) => a -> b fromIntegral Word8 c2 ifBool -> Bool not(Word16 -> Word16 -> Bool validate2 Word16 x1 Word16 x2 )thenIO (CodingProgress, Buffer Word8, Buffer Char) invalid elsedoInt ow' <-RawBuffer Char -> Int -> Char -> IO Int writeCharBuf RawBuffer Char oraw Int ow (Word16 -> Word16 -> Char chr2 Word16 x1 Word16 x2 )Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop (Int ir Int -> Int -> Int forall a. Num a => a -> a -> a + Int 4)Int ow' whereinvalid :: IO (CodingProgress, Buffer Word8, Buffer Char) invalid =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done CodingProgress InvalidSequence Int ir Int ow -- lambda-lifted, to avoid thunks being built in the inner-loop:done :: a -> Int -> Int -> m (a, Buffer Word8, Buffer Char) done a why !Int ir !Int ow =(a, Buffer Word8, Buffer Char) -> m (a, Buffer Word8, Buffer Char) forall (m :: * -> *) a. Monad m => a -> m a return (a why ,ifInt ir Int -> Int -> Bool forall a. Eq a => a -> a -> Bool ==Int iw thenBuffer Word8 input {bufL :: Int bufL =Int 0,bufR :: Int bufR =Int 0}elseBuffer Word8 input {bufL :: Int bufL =Int ir },Buffer Char output {bufR :: Int bufR =Int ow })inInt -> Int -> IO (CodingProgress, Buffer Word8, Buffer Char) loop Int ir0 Int ow0 utf16be_encode ::EncodeBuffer utf16be_encode :: CodeBuffer Char Word8 utf16be_encode input :: Buffer Char input @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Char iraw ,bufL :: forall e. Buffer e -> Int bufL =Int ir0 ,bufR :: forall e. Buffer e -> Int bufR =Int iw ,bufSize :: forall e. Buffer e -> Int bufSize =Int _}output :: Buffer Word8 output @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Word8 oraw ,bufL :: forall e. Buffer e -> Int bufL =Int _,bufR :: forall e. Buffer e -> Int bufR =Int ow0 ,bufSize :: forall e. Buffer e -> Int bufSize =Int os }=letdone :: a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done a why !Int ir !Int ow =(a, Buffer Char, Buffer Word8) -> m (a, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> m a return (a why ,ifInt ir Int -> Int -> Bool forall a. Eq a => a -> a -> Bool ==Int iw thenBuffer Char input {bufL :: Int bufL =Int 0,bufR :: Int bufR =Int 0}elseBuffer Char input {bufL :: Int bufL =Int ir },Buffer Word8 output {bufR :: Int bufR =Int ow })loop :: Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop !Int ir !Int ow |Int ir Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >=Int iw =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress InputUnderflow Int ir Int ow |Int os Int -> Int -> Int forall a. Num a => a -> a -> a - Int ow Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 2=CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress OutputUnderflow Int ir Int ow |Bool otherwise =do(Char c ,Int ir' )<-RawBuffer Char -> Int -> IO (Char, Int) readCharBuf RawBuffer Char iraw Int ir caseChar -> Int ord Char c ofInt x |Int x Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 0x10000->ifChar -> Bool isSurrogate Char c thenCodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress InvalidSequence Int ir Int ow elsedoRawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw Int ow (Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int x Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 8))RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)(Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral Int x )Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop Int ir' (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)|Bool otherwise ->doifInt os Int -> Int -> Int forall a. Num a => a -> a -> a - Int ow Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 4thenCodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress OutputUnderflow Int ir Int ow elsedoletn1 :: Int n1 =Int x Int -> Int -> Int forall a. Num a => a -> a -> a - Int 0x10000c1 :: Word8 c1 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int n1 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 18Int -> Int -> Int forall a. Num a => a -> a -> a + Int 0xD8)c2 :: Word8 c2 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int n1 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 10)n2 :: Int n2 =Int n1 Int -> Int -> Int forall a. Bits a => a -> a -> a .&. Int 0x3FFc3 :: Word8 c3 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int n2 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 8Int -> Int -> Int forall a. Num a => a -> a -> a + Int 0xDC)c4 :: Word8 c4 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral Int n2 --RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw Int ow Word8 c1 RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)Word8 c2 RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)Word8 c3 RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 3)Word8 c4 Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop Int ir' (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 4)inInt -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop Int ir0 Int ow0 utf16le_encode ::EncodeBuffer utf16le_encode :: CodeBuffer Char Word8 utf16le_encode input :: Buffer Char input @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Char iraw ,bufL :: forall e. Buffer e -> Int bufL =Int ir0 ,bufR :: forall e. Buffer e -> Int bufR =Int iw ,bufSize :: forall e. Buffer e -> Int bufSize =Int _}output :: Buffer Word8 output @Buffer {bufRaw :: forall e. Buffer e -> RawBuffer e bufRaw =RawBuffer Word8 oraw ,bufL :: forall e. Buffer e -> Int bufL =Int _,bufR :: forall e. Buffer e -> Int bufR =Int ow0 ,bufSize :: forall e. Buffer e -> Int bufSize =Int os }=letdone :: a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done a why !Int ir !Int ow =(a, Buffer Char, Buffer Word8) -> m (a, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> m a return (a why ,ifInt ir Int -> Int -> Bool forall a. Eq a => a -> a -> Bool ==Int iw thenBuffer Char input {bufL :: Int bufL =Int 0,bufR :: Int bufR =Int 0}elseBuffer Char input {bufL :: Int bufL =Int ir },Buffer Word8 output {bufR :: Int bufR =Int ow })loop :: Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop !Int ir !Int ow |Int ir Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >=Int iw =CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress InputUnderflow Int ir Int ow |Int os Int -> Int -> Int forall a. Num a => a -> a -> a - Int ow Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 2=CodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress OutputUnderflow Int ir Int ow |Bool otherwise =do(Char c ,Int ir' )<-RawBuffer Char -> Int -> IO (Char, Int) readCharBuf RawBuffer Char iraw Int ir caseChar -> Int ord Char c ofInt x |Int x Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 0x10000->ifChar -> Bool isSurrogate Char c thenCodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress InvalidSequence Int ir Int ow elsedoRawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw Int ow (Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral Int x )RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)(Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int x Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 8))Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop Int ir' (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)|Bool otherwise ->ifInt os Int -> Int -> Int forall a. Num a => a -> a -> a - Int ow Int -> Int -> Bool forall a. Ord a => a -> a -> Bool <Int 4thenCodingProgress -> Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) forall (m :: * -> *) a. Monad m => a -> Int -> Int -> m (a, Buffer Char, Buffer Word8) done CodingProgress OutputUnderflow Int ir Int ow elsedoletn1 :: Int n1 =Int x Int -> Int -> Int forall a. Num a => a -> a -> a - Int 0x10000c1 :: Word8 c1 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int n1 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 18Int -> Int -> Int forall a. Num a => a -> a -> a + Int 0xD8)c2 :: Word8 c2 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int n1 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 10)n2 :: Int n2 =Int n1 Int -> Int -> Int forall a. Bits a => a -> a -> a .&. Int 0x3FFc3 :: Word8 c3 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int n2 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 8Int -> Int -> Int forall a. Num a => a -> a -> a + Int 0xDC)c4 :: Word8 c4 =Int -> Word8 forall a b. (Integral a, Num b) => a -> b fromIntegral Int n2 --RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw Int ow Word8 c2 RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1)Word8 c1 RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 2)Word8 c4 RawBuffer Word8 -> Int -> Word8 -> IO () writeWord8Buf RawBuffer Word8 oraw (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 3)Word8 c3 Int -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop Int ir' (Int ow Int -> Int -> Int forall a. Num a => a -> a -> a + Int 4)inInt -> Int -> IO (CodingProgress, Buffer Char, Buffer Word8) loop Int ir0 Int ow0 chr2 ::Word16 ->Word16 ->Charchr2 :: Word16 -> Word16 -> Char chr2 (W16# Word# a# )(W16# Word# b# )=Char# -> Char C#(Int# -> Char# chr#(Int# upper# Int# -> Int# -> Int# +#Int# lower# Int# -> Int# -> Int# +#Int# 0x10000#))where!x# :: Int# x# =Word# -> Int# word2Int#Word# a# !y# :: Int# y# =Word# -> Int# word2Int#Word# b# !upper# :: Int# upper# =Int# -> Int# -> Int# uncheckedIShiftL#(Int# x# Int# -> Int# -> Int# -#Int# 0xD800#)Int# 10#!lower# :: Int# lower# =Int# y# Int# -> Int# -> Int# -#Int# 0xDC00#{-# INLINEchr2 #-}validate1 ::Word16 ->Boolvalidate1 :: Word16 -> Bool validate1 Word16 x1 =(Word16 x1 Word16 -> Word16 -> Bool forall a. Ord a => a -> a -> Bool >=Word16 0Bool -> Bool -> Bool &&Word16 x1 Word16 -> Word16 -> Bool forall a. Ord a => a -> a -> Bool <Word16 0xD800)Bool -> Bool -> Bool ||Word16 x1 Word16 -> Word16 -> Bool forall a. Ord a => a -> a -> Bool >Word16 0xDFFF{-# INLINEvalidate1 #-}validate2 ::Word16 ->Word16 ->Boolvalidate2 :: Word16 -> Word16 -> Bool validate2 Word16 x1 Word16 x2 =Word16 x1 Word16 -> Word16 -> Bool forall a. Ord a => a -> a -> Bool >=Word16 0xD800Bool -> Bool -> Bool &&Word16 x1 Word16 -> Word16 -> Bool forall a. Ord a => a -> a -> Bool <=Word16 0xDBFFBool -> Bool -> Bool &&Word16 x2 Word16 -> Word16 -> Bool forall a. Ord a => a -> a -> Bool >=Word16 0xDC00Bool -> Bool -> Bool &&Word16 x2 Word16 -> Word16 -> Bool forall a. Ord a => a -> a -> Bool <=Word16 0xDFFF{-# INLINEvalidate2 #-}