    -- |
    -- Module      :  Codec.Archive.Zip.CP437
    -- Copyright   :  © 2016–present Mark Karpov
    -- License     :  BSD 3 clause
    --
    -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Support for decoding of CP 437 text.
    module Codec.Archive.Zip.CP437
      ( decodeCP437,
      )
    where

    import Control.Arrow (first)
    import Data.ByteString (ByteString)
    import Data.ByteString qualified as B
    import Data.Char
    import Data.Text (Text)
    import Data.Text qualified as T
    import Data.Word (Word8)

    -- | Decode a 'ByteString' containing CP 437 encoded text.
    decodeCP437 :: ByteString -> Text
    decodeCP437 :: ByteString -> Text
    decodeCP437 ByteString
    bs =
      Int
    -> (ByteString -> Maybe (Char, ByteString)) -> ByteString -> Text
    forall a. Int -> (a -> Maybe (Char, a)) -> a -> Text
    T.unfoldrN
        (ByteString -> Int
    B.length ByteString
    bs)
        (((Word8, ByteString) -> (Char, ByteString))
    -> Maybe (Word8, ByteString) -> Maybe (Char, ByteString)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((Word8 -> Char) -> (Word8, ByteString) -> (Char, ByteString)
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first Word8 -> Char
    decodeByteCP437) (Maybe (Word8, ByteString) -> Maybe (Char, ByteString))
    -> (ByteString -> Maybe (Word8, ByteString))
    -> ByteString
    -> Maybe (Char, ByteString)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Maybe (Word8, ByteString)
    B.uncons)
        ByteString
    bs

    -- | Decode a single byte of CP437 encoded text.
    decodeByteCP437 :: Word8 -> Char
    decodeByteCP437 :: Word8 -> Char
    decodeByteCP437 Word8
    byte = Int -> Char
    chr (Int -> Char) -> Int -> Char
    forall a b. (a -> b) -> a -> b
    $ case Word8
    byte of
      Word8
    128 -> Int
    199
      Word8
    129 -> Int
    252
      Word8
    130 -> Int
    233
      Word8
    131 -> Int
    226
      Word8
    132 -> Int
    228
      Word8
    133 -> Int
    224
      Word8
    134 -> Int
    229
      Word8
    135 -> Int
    231
      Word8
    136 -> Int
    234
      Word8
    137 -> Int
    235
      Word8
    138 -> Int
    232
      Word8
    139 -> Int
    239
      Word8
    140 -> Int
    238
      Word8
    141 -> Int
    236
      Word8
    142 -> Int
    196
      Word8
    143 -> Int
    197
      Word8
    144 -> Int
    201
      Word8
    145 -> Int
    230
      Word8
    146 -> Int
    198
      Word8
    147 -> Int
    244
      Word8
    148 -> Int
    246
      Word8
    149 -> Int
    242
      Word8
    150 -> Int
    251
      Word8
    151 -> Int
    249
      Word8
    152 -> Int
    255
      Word8
    153 -> Int
    214
      Word8
    154 -> Int
    220
      Word8
    155 -> Int
    162
      Word8
    156 -> Int
    163
      Word8
    157 -> Int
    165
      Word8
    158 -> Int
    8359
      Word8
    159 -> Int
    402
      Word8
    160 -> Int
    225
      Word8
    161 -> Int
    237
      Word8
    162 -> Int
    243
      Word8
    163 -> Int
    250
      Word8
    164 -> Int
    241
      Word8
    165 -> Int
    209
      Word8
    166 -> Int
    170
      Word8
    167 -> Int
    186
      Word8
    168 -> Int
    191
      Word8
    169 -> Int
    8976
      Word8
    170 -> Int
    172
      Word8
    171 -> Int
    189
      Word8
    172 -> Int
    188
      Word8
    173 -> Int
    161
      Word8
    174 -> Int
    171
      Word8
    175 -> Int
    187
      Word8
    176 -> Int
    9617
      Word8
    177 -> Int
    9618
      Word8
    178 -> Int
    9619
      Word8
    179 -> Int
    9474
      Word8
    180 -> Int
    9508
      Word8
    181 -> Int
    9569
      Word8
    182 -> Int
    9570
      Word8
    183 -> Int
    9558
      Word8
    184 -> Int
    9557
      Word8
    185 -> Int
    9571
      Word8
    186 -> Int
    9553
      Word8
    187 -> Int
    9559
      Word8
    188 -> Int
    9565
      Word8
    189 -> Int
    9564
      Word8
    190 -> Int
    9563
      Word8
    191 -> Int
    9488
      Word8
    192 -> Int
    9492
      Word8
    193 -> Int
    9524
      Word8
    194 -> Int
    9516
      Word8
    195 -> Int
    9500
      Word8
    196 -> Int
    9472
      Word8
    197 -> Int
    9532
      Word8
    198 -> Int
    9566
      Word8
    199 -> Int
    9567
      Word8
    200 -> Int
    9562
      Word8
    201 -> Int
    9556
      Word8
    202 -> Int
    9577
      Word8
    203 -> Int
    9574
      Word8
    204 -> Int
    9568
      Word8
    205 -> Int
    9552
      Word8
    206 -> Int
    9580
      Word8
    207 -> Int
    9575
      Word8
    208 -> Int
    9576
      Word8
    209 -> Int
    9572
      Word8
    210 -> Int
    9573
      Word8
    211 -> Int
    9561
      Word8
    212 -> Int
    9560
      Word8
    213 -> Int
    9554
      Word8
    214 -> Int
    9555
      Word8
    215 -> Int
    9579
      Word8
    216 -> Int
    9578
      Word8
    217 -> Int
    9496
      Word8
    218 -> Int
    9484
      Word8
    219 -> Int
    9608
      Word8
    220 -> Int
    9604
      Word8
    221 -> Int
    9612
      Word8
    222 -> Int
    9616
      Word8
    223 -> Int
    9600
      Word8
    224 -> Int
    945
      Word8
    225 -> Int
    223
      Word8
    226 -> Int
    915
      Word8
    227 -> Int
    960
      Word8
    228 -> Int
    931
      Word8
    229 -> Int
    963
      Word8
    230 -> Int
    181
      Word8
    231 -> Int
    964
      Word8
    232 -> Int
    934
      Word8
    233 -> Int
    920
      Word8
    234 -> Int
    937
      Word8
    235 -> Int
    948
      Word8
    236 -> Int
    8734
      Word8
    237 -> Int
    966
      Word8
    238 -> Int
    949
      Word8
    239 -> Int
    8745
      Word8
    240 -> Int
    8801
      Word8
    241 -> Int
    177
      Word8
    242 -> Int
    8805
      Word8
    243 -> Int
    8804
      Word8
    244 -> Int
    8992
      Word8
    245 -> Int
    8993
      Word8
    246 -> Int
    247
      Word8
    247 -> Int
    8776
      Word8
    248 -> Int
    176
      Word8
    249 -> Int
    8729
      Word8
    250 -> Int
    183
      Word8
    251 -> Int
    8730
      Word8
    252 -> Int
    8319
      Word8
    253 -> Int
    178
      Word8
    254 -> Int
    9632
      Word8
    255 -> Int
    160
      Word8
    x -> Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word8
    x -- the rest of characters translate directly