    {-# LANGUAGE DeriveDataTypeable #-}
    {- | This module implements KOI8-R encoding which covers the russian and bulgarian alphabet.
         See <http://en.wikipedia.org/wiki/KOI8-R> for more information.
     -}
    module Data.Encoding.KOI8R
    	(KOI8R(..)) where

    import Control.Throws
    import Data.Array.Unboxed
    import Data.Char (ord,chr)
    import Data.Map hiding (map,(!))
    import Data.Word
    import Prelude hiding (lookup)
    import Data.Typeable

    import Data.Encoding.Base
    import Data.Encoding.ByteSource
    import Data.Encoding.ByteSink
    import Data.Encoding.Exception

    data KOI8R = KOI8R deriving (KOI8R -> KOI8R -> Bool
    (KOI8R -> KOI8R -> Bool) -> (KOI8R -> KOI8R -> Bool) -> Eq KOI8R
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KOI8R -> KOI8R -> Bool
    == :: KOI8R -> KOI8R -> Bool
    $c/= :: KOI8R -> KOI8R -> Bool
    /= :: KOI8R -> KOI8R -> Bool
    Eq,Int -> KOI8R -> ShowS
    [KOI8R] -> ShowS
    KOI8R -> String
    (Int -> KOI8R -> ShowS)
    -> (KOI8R -> String) -> ([KOI8R] -> ShowS) -> Show KOI8R
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KOI8R -> ShowS
    showsPrec :: Int -> KOI8R -> ShowS
    $cshow :: KOI8R -> String
    show :: KOI8R -> String
    $cshowList :: [KOI8R] -> ShowS
    showList :: [KOI8R] -> ShowS
    Show,Typeable)

    koi8rArr :: UArray Word8 Char
    koi8rArr :: UArray Word8 Char
    koi8rArr = (Word8, Word8) -> String -> UArray Word8 Char
    forall (a :: * -> * -> *) e i.
    (IArray a e, Ix i) =>
    (i, i) -> [e] -> a i e
    listArray (Word8
    128,Word8
    255) String
    koi8rList

    koi8rMap :: Map Char Word8
    koi8rMap :: Map Char Word8
    koi8rMap = [(Char, Word8)] -> Map Char Word8
    forall k a. Ord k => [(k, a)] -> Map k a
    fromList (String -> [Word8] -> [(Char, Word8)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip String
    koi8rList [Word8
    128..])

    koi8rList :: [Char]
    koi8rList :: String
    koi8rList =
    	[Char
    '\x2500',Char
    '\x2502',Char
    '\x250c',Char
    '\x2510',Char
    '\x2514',Char
    '\x2518',Char
    '\x251c',Char
    '\x2524'
    	,Char
    '\x252c',Char
    '\x2534',Char
    '\x253c',Char
    '\x2580',Char
    '\x2584',Char
    '\x2588',Char
    '\x258c',Char
    '\x2590'
    	,Char
    '\x2591',Char
    '\x2592',Char
    '\x2593',Char
    '\x2320',Char
    '\x25a0',Char
    '\x2219',Char
    '\x221a',Char
    '\x2248'
    	,Char
    '\x2264',Char
    '\x2265',Char
    '\x00a0',Char
    '\x2321',Char
    '\x00b0',Char
    '\x00b2',Char
    '\x00b7',Char
    '\x00f7'
    	,Char
    '\x2550',Char
    '\x2551',Char
    '\x2552',Char
    '\x0451',Char
    '\x2553',Char
    '\x2554',Char
    '\x2555',Char
    '\x2556'
    	,Char
    '\x2557',Char
    '\x2558',Char
    '\x2559',Char
    '\x255a',Char
    '\x255b',Char
    '\x255c',Char
    '\x255d',Char
    '\x255e'
    	,Char
    '\x255f',Char
    '\x2560',Char
    '\x2561',Char
    '\x0401',Char
    '\x2562',Char
    '\x2563',Char
    '\x2564',Char
    '\x2565'
    	,Char
    '\x2566',Char
    '\x2567',Char
    '\x2568',Char
    '\x2569',Char
    '\x256a',Char
    '\x256b',Char
    '\x256c',Char
    '\x00a9'
    	,Char
    '\x044e',Char
    '\x0430',Char
    '\x0431',Char
    '\x0446',Char
    '\x0434',Char
    '\x0435',Char
    '\x0444',Char
    '\x0433'
    	,Char
    '\x0445',Char
    '\x0438',Char
    '\x0439',Char
    '\x043a',Char
    '\x043b',Char
    '\x043c',Char
    '\x043d',Char
    '\x043e'
    	,Char
    '\x043f',Char
    '\x044f',Char
    '\x0440',Char
    '\x0441',Char
    '\x0442',Char
    '\x0443',Char
    '\x0436',Char
    '\x0432'
    	,Char
    '\x044c',Char
    '\x044b',Char
    '\x0437',Char
    '\x0448',Char
    '\x044d',Char
    '\x0449',Char
    '\x0447',Char
    '\x044a'
    	,Char
    '\x042e',Char
    '\x0410',Char
    '\x0411',Char
    '\x0426',Char
    '\x0414',Char
    '\x0415',Char
    '\x0424',Char
    '\x0413'
    	,Char
    '\x0425',Char
    '\x0418',Char
    '\x0419',Char
    '\x041a',Char
    '\x041b',Char
    '\x041c',Char
    '\x041d',Char
    '\x041e'
    	,Char
    '\x041f',Char
    '\x042f',Char
    '\x0420',Char
    '\x0421',Char
    '\x0422',Char
    '\x0423',Char
    '\x0416',Char
    '\x0412'
    	,Char
    '\x042c',Char
    '\x042b',Char
    '\x0417',Char
    '\x0428',Char
    '\x042d',Char
    '\x0429',Char
    '\x0427',Char
    '\x042a'
    	]

    instance Encoding KOI8R where
        decodeChar :: forall (m :: * -> *). ByteSource m => KOI8R -> m Char
    decodeChar KOI8R
    _ = do
          w <- m Word8
    forall (m :: * -> *). ByteSource m => m Word8
    fetchWord8
          if w < 128
            then return $ chr $ fromIntegral w
            else return $ koi8rArr!w
        encodeChar :: forall (m :: * -> *). ByteSink m => KOI8R -> Char -> m ()
    encodeChar KOI8R
    _ Char
    ch
    	| Char
    ch Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    < Char
    '\128' = Word8 -> m ()
    forall (m :: * -> *). ByteSink m => Word8 -> m ()
    pushWord8 (Word8 -> m ()) -> Word8 -> m ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word8) -> Int -> Word8
    forall a b. (a -> b) -> a -> b
    $ Char -> Int
    ord Char
    ch
    	| Bool
    otherwise   = case Char -> Map Char Word8 -> Maybe Word8
    forall k a. Ord k => k -> Map k a -> Maybe a
    lookup Char
    ch Map Char Word8
    koi8rMap of
    		Just Word8
    w -> Word8 -> m ()
    forall (m :: * -> *). ByteSink m => Word8 -> m ()
    pushWord8 Word8
    w
    		Maybe Word8
    Nothing -> EncodingException -> m ()
    forall a. EncodingException -> m a
    forall e (m :: * -> *) a. Throws e m => e -> m a
    throwException (Char -> EncodingException
    HasNoRepresentation Char
    ch)
        encodeable :: KOI8R -> Char -> Bool
    encodeable KOI8R
    _ Char
    c = Char -> Map Char Word8 -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    member Char
    c Map Char Word8
    koi8rMap