module GHC.IO.Encoding.Latin1 (
latin1,
latin1_checked,
latin1_decode,
latin1_encode,
latin1_checked_encode,
) where
import GHC.Base
import GHC.Real
import GHC.Num
import GHC.IO.Exception
import GHC.IO.Buffer
import GHC.IO.Encoding.Types
import Data.Maybe
latin1 :: TextEncoding
latin1 = TextEncoding { mkTextDecoder = latin1_DF,
mkTextEncoder = latin1_EF }
latin1_DF :: IO (TextDecoder ())
latin1_DF =
return (BufferCodec {
encode = latin1_decode,
close = return (),
getState = return (),
setState = const $ return ()
})
latin1_EF :: IO (TextEncoder ())
latin1_EF =
return (BufferCodec {
encode = latin1_encode,
close = return (),
getState = return (),
setState = const $ return ()
})
latin1_checked :: TextEncoding
latin1_checked = TextEncoding { mkTextDecoder = latin1_DF,
mkTextEncoder = latin1_checked_EF }
latin1_checked_EF :: IO (TextEncoder ())
latin1_checked_EF =
return (BufferCodec {
encode = latin1_checked_encode,
close = return (),
getState = return (),
setState = const $ return ()
})
latin1_decode :: DecodeBuffer
latin1_decode
input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }
output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }
= let
loop !ir !ow
| ow >= os || ir >= iw = done ir ow
| otherwise = do
c0 <- readWord8Buf iraw ir
ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0))
loop (ir+1) ow'
done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 }
else input{ bufL=ir },
output{ bufR=ow })
in
loop ir0 ow0
latin1_encode :: EncodeBuffer
latin1_encode
input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }
output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }
= let
done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 }
else input{ bufL=ir },
output{ bufR=ow })
loop !ir !ow
| ow >= os || ir >= iw = done ir ow
| otherwise = do
(c,ir') <- readCharBuf iraw ir
writeWord8Buf oraw ow (fromIntegral (ord c))
loop ir' (ow+1)
in
loop ir0 ow0
latin1_checked_encode :: EncodeBuffer
latin1_checked_encode
input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }
output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }
= let
done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 }
else input{ bufL=ir },
output{ bufR=ow })
loop !ir !ow
| ow >= os || ir >= iw = done ir ow
| otherwise = do
(c,ir') <- readCharBuf iraw ir
if ord c > 0xff then invalid else do
writeWord8Buf oraw ow (fromIntegral (ord c))
loop ir' (ow+1)
where
invalid = if ir > ir0 then done ir ow else ioe_encodingError
in
loop ir0 ow0
ioe_encodingError :: IO a
ioe_encodingError = ioException
(IOError Nothing InvalidArgument "latin1_checked_encode"
"character is out of range for this encoding" Nothing Nothing)