640ea8847d4ad66448cabbf9959c8b1d4920185a
[ghc-base.git] / GHC / IO / Encoding / Types.hs
1 {-# OPTIONS_GHC -XNoImplicitPrelude -funbox-strict-fields #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  GHC.IO.Encoding.Types
5 -- Copyright   :  (c) The University of Glasgow, 2008-2009
6 -- License     :  see libraries/base/LICENSE
7 -- 
8 -- Maintainer  :  libraries@haskell.org
9 -- Stability   :  internal
10 -- Portability :  non-portable
11 --
12 -- Types for text encoding/decoding
13 --
14 -----------------------------------------------------------------------------
15
16 module GHC.IO.Encoding.Types (
17     BufferCodec(..),
18     TextEncoding(..),
19     TextEncoder, TextDecoder,
20     EncodeBuffer, DecodeBuffer,
21   ) where
22
23 import GHC.Base
24 import GHC.Word
25 import GHC.Show
26 -- import GHC.IO
27 import GHC.IO.Buffer
28
29 -- -----------------------------------------------------------------------------
30 -- Text encoders/decoders
31
32 data BufferCodec from to state = BufferCodec {
33   encode :: Buffer from -> Buffer to -> IO (Buffer from, Buffer to),
34    -- ^ The @encode@ function translates elements of the buffer @from@
35    -- to the buffer @to@.  It should translate as many elements as possible
36    -- given the sizes of the buffers, including translating zero elements
37    -- if there is either not enough room in @to@, or @from@ does not
38    -- contain a complete multibyte sequence.
39    -- 
40    -- @encode@ should raise an exception if, and only if, @from@
41    -- begins with an illegal sequence, or the first element of @from@
42    -- is not representable in the encoding of @to@.  That is, if any
43    -- elements can be successfully translated before an error is
44    -- encountered, then @encode@ should translate as much as it can
45    -- and not throw an exception.  This behaviour is used by the IO
46    -- library in order to report translation errors at the point they
47    -- actually occur, rather than when the buffer is translated.
48    --
49   close  :: IO (),
50    -- ^ Resources associated with the encoding may now be released.
51    -- The @encode@ function may not be called again after calling
52    -- @close@.
53
54   getState :: IO state,
55    -- ^ Return the current state of the codec.
56    --
57    -- Many codecs are not stateful, and in these case the state can be
58    -- represented as '()'.  Other codecs maintain a state.  For
59    -- example, UTF-16 recognises a BOM (byte-order-mark) character at
60    -- the beginning of the input, and remembers thereafter whether to
61    -- use big-endian or little-endian mode.  In this case, the state
62    -- of the codec would include two pieces of information: whether we
63    -- are at the beginning of the stream (the BOM only occurs at the
64    -- beginning), and if not, whether to use the big or little-endian
65    -- encoding.
66
67   setState :: state -> IO()
68    -- restore the state of the codec using the state from a previous
69    -- call to 'getState'.
70  }
71
72 type DecodeBuffer = Buffer Word8 -> Buffer Char
73                   -> IO (Buffer Word8, Buffer Char)
74
75 type EncodeBuffer = Buffer Char -> Buffer Word8
76                   -> IO (Buffer Char, Buffer Word8)
77
78 type TextDecoder state = BufferCodec Word8 CharBufElem state
79 type TextEncoder state = BufferCodec CharBufElem Word8 state
80
81 -- | A 'TextEncoding' is a specification of a conversion scheme
82 -- between sequences of bytes and sequences of Unicode characters.
83 --
84 -- For example, UTF-8 is an encoding of Unicode characters into a sequence
85 -- of bytes.  The 'TextEncoding' for UTF-8 is 'utf8'.
86 data TextEncoding
87   = forall dstate estate . TextEncoding  {
88         textEncodingName :: String,
89                    -- ^ a string that can be passed to 'mkTextEncoding' to
90                    -- create an equivalent 'TextEncoding'.
91         mkTextDecoder :: IO (TextDecoder dstate),
92         mkTextEncoder :: IO (TextEncoder estate)
93   }
94
95 instance Show TextEncoding where
96   -- | Returns the value of 'textEncodingName'
97   show te = textEncodingName te