-- |
-- 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 qualified Data.ByteString as B
import Data.Char
import Data.Text (Text)
import qualified Data.Text 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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word8 -> Char) -> (Word8, ByteString) -> (Char, ByteString)
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