base-4.12.0.0: GHC/IO/Encoding/Types.hs
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude, ExistentialQuantification #-}
{-# OPTIONS_GHC -funbox-strict-fields #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.IO.Encoding.Types
-- Copyright : (c) The University of Glasgow, 2008-2009
-- License : see libraries/base/LICENSE
--
-- Maintainer : libraries@haskell.org
-- Stability : internal
-- Portability : non-portable
--
-- Types for text encoding/decoding
--
-----------------------------------------------------------------------------
module GHC.IO.Encoding.Types (
BufferCodec(..),
TextEncoding(..),
TextEncoder, TextDecoder,
CodeBuffer, EncodeBuffer, DecodeBuffer,
CodingProgress(..)
) where
import GHC.Base
import GHC.Word
import GHC.Show
-- import GHC.IO
import GHC.IO.Buffer
-- -----------------------------------------------------------------------------
-- Text encoders/decoders
data BufferCodec from to state = BufferCodec {
encode :: CodeBuffer from to,
-- ^ The @encode@ function translates elements of the buffer @from@
-- to the buffer @to@. It should translate as many elements as possible
-- given the sizes of the buffers, including translating zero elements
-- if there is either not enough room in @to@, or @from@ does not
-- contain a complete multibyte sequence.
--
-- If multiple CodingProgress returns are possible, OutputUnderflow must be
-- preferred to InvalidSequence. This allows GHC's IO library to assume that
-- if we observe InvalidSequence there is at least a single element available
-- in the output buffer.
--
-- The fact that as many elements as possible are translated is used by the IO
-- library in order to report translation errors at the point they
-- actually occur, rather than when the buffer is translated.
recover :: Buffer from -> Buffer to -> IO (Buffer from, Buffer to),
-- ^ The @recover@ function is used to continue decoding
-- in the presence of invalid or unrepresentable sequences. This includes
-- both those detected by @encode@ returning @InvalidSequence@ and those
-- that occur because the input byte sequence appears to be truncated.
--
-- Progress will usually be made by skipping the first element of the @from@
-- buffer. This function should only be called if you are certain that you
-- wish to do this skipping and if the @to@ buffer has at least one element
-- of free space. Because this function deals with decoding failure, it assumes
-- that the from buffer has at least one element.
--
-- @recover@ may raise an exception rather than skipping anything.
--
-- Currently, some implementations of @recover@ may mutate the input buffer.
-- In particular, this feature is used to implement transliteration.
--
-- @since 4.4.0.0
close :: IO (),
-- ^ Resources associated with the encoding may now be released.
-- The @encode@ function may not be called again after calling
-- @close@.
getState :: IO state,
-- ^ Return the current state of the codec.
--
-- Many codecs are not stateful, and in these case the state can be
-- represented as '()'. Other codecs maintain a state. For
-- example, UTF-16 recognises a BOM (byte-order-mark) character at
-- the beginning of the input, and remembers thereafter whether to
-- use big-endian or little-endian mode. In this case, the state
-- of the codec would include two pieces of information: whether we
-- are at the beginning of the stream (the BOM only occurs at the
-- beginning), and if not, whether to use the big or little-endian
-- encoding.
setState :: state -> IO ()
-- restore the state of the codec using the state from a previous
-- call to 'getState'.
}
type CodeBuffer from to = Buffer from -> Buffer to -> IO (CodingProgress, Buffer from, Buffer to)
type DecodeBuffer = CodeBuffer Word8 Char
type EncodeBuffer = CodeBuffer Char Word8
type TextDecoder state = BufferCodec Word8 CharBufElem state
type TextEncoder state = BufferCodec CharBufElem Word8 state
-- | A 'TextEncoding' is a specification of a conversion scheme
-- between sequences of bytes and sequences of Unicode characters.
--
-- For example, UTF-8 is an encoding of Unicode characters into a sequence
-- of bytes. The 'TextEncoding' for UTF-8 is 'utf8'.
data TextEncoding
= forall dstate estate . TextEncoding {
textEncodingName :: String,
-- ^ a string that can be passed to 'mkTextEncoding' to
-- create an equivalent 'TextEncoding'.
mkTextDecoder :: IO (TextDecoder dstate),
-- ^ Creates a means of decoding bytes into characters: the result must not
-- be shared between several byte sequences or simultaneously across threads
mkTextEncoder :: IO (TextEncoder estate)
-- ^ Creates a means of encode characters into bytes: the result must not
-- be shared between several character sequences or simultaneously across threads
}
-- | @since 4.3.0.0
instance Show TextEncoding where
-- | Returns the value of 'textEncodingName'
show te = textEncodingName te
-- | @since 4.4.0.0
data CodingProgress = InputUnderflow -- ^ Stopped because the input contains insufficient available elements,
-- or all of the input sequence has been successfully translated.
| OutputUnderflow -- ^ Stopped because the output contains insufficient free elements
| InvalidSequence -- ^ Stopped because there are sufficient free elements in the output
-- to output at least one encoded ASCII character, but the input contains
-- an invalid or unrepresentable sequence
deriving ( Eq -- ^ @since 4.4.0.0
, Show -- ^ @since 4.4.0.0
)