{-# LANGUAGE DeriveDataTypeable #-} {- | This module implements KOI8-R encoding which covers the russian and bulgarian alphabet. See 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 (Eq,Show,Typeable) koi8rArr :: UArray Word8 Char koi8rArr = listArray (128,255) koi8rList koi8rMap :: Map Char Word8 koi8rMap = fromList (zip koi8rList [128..]) koi8rList :: [Char] koi8rList = ['\x2500','\x2502','\x250c','\x2510','\x2514','\x2518','\x251c','\x2524' ,'\x252c','\x2534','\x253c','\x2580','\x2584','\x2588','\x258c','\x2590' ,'\x2591','\x2592','\x2593','\x2320','\x25a0','\x2219','\x221a','\x2248' ,'\x2264','\x2265','\x00a0','\x2321','\x00b0','\x00b2','\x00b7','\x00f7' ,'\x2550','\x2551','\x2552','\x0451','\x2553','\x2554','\x2555','\x2556' ,'\x2557','\x2558','\x2559','\x255a','\x255b','\x255c','\x255d','\x255e' ,'\x255f','\x2560','\x2561','\x0401','\x2562','\x2563','\x2564','\x2565' ,'\x2566','\x2567','\x2568','\x2569','\x256a','\x256b','\x256c','\x00a9' ,'\x044e','\x0430','\x0431','\x0446','\x0434','\x0435','\x0444','\x0433' ,'\x0445','\x0438','\x0439','\x043a','\x043b','\x043c','\x043d','\x043e' ,'\x043f','\x044f','\x0440','\x0441','\x0442','\x0443','\x0436','\x0432' ,'\x044c','\x044b','\x0437','\x0448','\x044d','\x0449','\x0447','\x044a' ,'\x042e','\x0410','\x0411','\x0426','\x0414','\x0415','\x0424','\x0413' ,'\x0425','\x0418','\x0419','\x041a','\x041b','\x041c','\x041d','\x041e' ,'\x041f','\x042f','\x0420','\x0421','\x0422','\x0423','\x0416','\x0412' ,'\x042c','\x042b','\x0417','\x0428','\x042d','\x0429','\x0427','\x042a' ] instance Encoding KOI8R where decodeChar _ = do w <- fetchWord8 if w < 128 then return $ chr $ fromIntegral w else return $ koi8rArr!w encodeChar _ ch | ch < '\128' = pushWord8 $ fromIntegral $ ord ch | otherwise = case lookup ch koi8rMap of Just w -> pushWord8 w Nothing -> throwException (HasNoRepresentation ch) encodeable _ c = member c koi8rMap