1use crate::{DecodeError, Decoder, EncodeError, Encoder};
2
3pub const KOI8R_NAME: &str = "KOI8-R";
5
6pub struct KOI8REncoder;
8impl Encoder for KOI8REncoder {
9 fn name(&self) -> &'static str {
10 KOI8R_NAME
11 }
12
13 fn encode(
14 &mut self,
15 src: &str,
16 dst: &mut [u8],
17 finish: bool,
18 ) -> Result<(usize, usize), EncodeError> {
19 if src.is_empty() {
20 return if finish {
21 Ok((0, 0))
22 } else {
23 Err(EncodeError::InputIsEmpty)
24 };
25 }
26
27 if dst.len() < 2 {
28 return Err(EncodeError::OutputTooShort);
29 }
30
31 let (mut read, mut write) = (0, 0);
32 for c in src.chars() {
33 if c.is_ascii() {
34 read += 1;
35 dst[write] = c as u8;
36 write += 1;
37 } else {
38 read += c.len_utf8();
39 if let Ok(pos) = UCS_TO_KOI8R.binary_search_by_key(&(c as u32), |v| v.0 as u32) {
40 dst[write] = UCS_TO_KOI8R[pos].1;
41 write += 1;
42 } else {
43 return Err(EncodeError::Unmappable { read, write, c });
44 }
45 }
46 if dst.len() == write {
47 break;
48 }
49 }
50 Ok((read, write))
51 }
52}
53
54pub struct KOI8RDecoder;
56impl Decoder for KOI8RDecoder {
57 fn name(&self) -> &'static str {
58 KOI8R_NAME
59 }
60
61 fn decode(
62 &mut self,
63 src: &[u8],
64 dst: &mut String,
65 finish: bool,
66 ) -> Result<(usize, usize), DecodeError> {
67 if src.is_empty() {
68 return if finish {
69 Ok((0, 0))
70 } else {
71 Err(DecodeError::InputIsEmpty)
72 };
73 }
74 let mut len = dst.capacity() - dst.len();
75 if len < 4 {
76 return Err(DecodeError::OutputTooShort);
77 }
78
79 let (mut read, mut write) = (0, 0);
80 while read < src.len() && len > 0 {
81 read += 1;
82 let b = src[read];
83 if b < 0x80 {
84 dst.push(b as char);
86 write += 1;
87 len -= 1;
88 } else {
89 let b = b - 0x80;
90 let ucs_code = KOI8R_TO_UCS[b as usize];
91 let ucs = unsafe {
92 char::from_u32_unchecked(ucs_code as u32)
96 };
97 if len < ucs.len_utf8() {
98 read -= 1;
99 break;
100 }
101 len -= ucs.len_utf8();
102 write += ucs.len_utf8();
103 dst.push(ucs);
104 }
105 }
106 Ok((read, write))
107 }
108}
109
110const KOI8R_TO_UCS: [u16; 128] = [
111 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 0x252C, 0x2534, 0x253C, 0x2580,
112 0x2584, 0x2588, 0x258C, 0x2590, 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
113 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, 0x2550, 0x2551, 0x2552, 0x0451,
114 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
115 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569,
116 0x256A, 0x256B, 0x256C, 0x00A9, 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
117 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x044F, 0x0440, 0x0441,
118 0x0442, 0x0443, 0x0436, 0x0432, 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
119 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041A,
120 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
121 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A,
122];
123const UCS_TO_KOI8R: [(u16, u8); 128] = [
124 (0x00A0, 0x9A),
125 (0x00A9, 0xBF),
126 (0x00B0, 0x9C),
127 (0x00B2, 0x9D),
128 (0x00B7, 0x9E),
129 (0x00F7, 0x9F),
130 (0x0401, 0xB3),
131 (0x0410, 0xE1),
132 (0x0411, 0xE2),
133 (0x0412, 0xF7),
134 (0x0413, 0xE7),
135 (0x0414, 0xE4),
136 (0x0415, 0xE5),
137 (0x0416, 0xF6),
138 (0x0417, 0xFA),
139 (0x0418, 0xE9),
140 (0x0419, 0xEA),
141 (0x041A, 0xEB),
142 (0x041B, 0xEC),
143 (0x041C, 0xED),
144 (0x041D, 0xEE),
145 (0x041E, 0xEF),
146 (0x041F, 0xF0),
147 (0x0420, 0xF2),
148 (0x0421, 0xF3),
149 (0x0422, 0xF4),
150 (0x0423, 0xF5),
151 (0x0424, 0xE6),
152 (0x0425, 0xE8),
153 (0x0426, 0xE3),
154 (0x0427, 0xFE),
155 (0x0428, 0xFB),
156 (0x0429, 0xFD),
157 (0x042A, 0xFF),
158 (0x042B, 0xF9),
159 (0x042C, 0xF8),
160 (0x042D, 0xFC),
161 (0x042E, 0xE0),
162 (0x042F, 0xF1),
163 (0x0430, 0xC1),
164 (0x0431, 0xC2),
165 (0x0432, 0xD7),
166 (0x0433, 0xC7),
167 (0x0434, 0xC4),
168 (0x0435, 0xC5),
169 (0x0436, 0xD6),
170 (0x0437, 0xDA),
171 (0x0438, 0xC9),
172 (0x0439, 0xCA),
173 (0x043A, 0xCB),
174 (0x043B, 0xCC),
175 (0x043C, 0xCD),
176 (0x043D, 0xCE),
177 (0x043E, 0xCF),
178 (0x043F, 0xD0),
179 (0x0440, 0xD2),
180 (0x0441, 0xD3),
181 (0x0442, 0xD4),
182 (0x0443, 0xD5),
183 (0x0444, 0xC6),
184 (0x0445, 0xC8),
185 (0x0446, 0xC3),
186 (0x0447, 0xDE),
187 (0x0448, 0xDB),
188 (0x0449, 0xDD),
189 (0x044A, 0xDF),
190 (0x044B, 0xD9),
191 (0x044C, 0xD8),
192 (0x044D, 0xDC),
193 (0x044E, 0xC0),
194 (0x044F, 0xD1),
195 (0x0451, 0xA3),
196 (0x2219, 0x95),
197 (0x221A, 0x96),
198 (0x2248, 0x97),
199 (0x2264, 0x98),
200 (0x2265, 0x99),
201 (0x2320, 0x93),
202 (0x2321, 0x9B),
203 (0x2500, 0x80),
204 (0x2502, 0x81),
205 (0x250C, 0x82),
206 (0x2510, 0x83),
207 (0x2514, 0x84),
208 (0x2518, 0x85),
209 (0x251C, 0x86),
210 (0x2524, 0x87),
211 (0x252C, 0x88),
212 (0x2534, 0x89),
213 (0x253C, 0x8A),
214 (0x2550, 0xA0),
215 (0x2551, 0xA1),
216 (0x2552, 0xA2),
217 (0x2553, 0xA4),
218 (0x2554, 0xA5),
219 (0x2555, 0xA6),
220 (0x2556, 0xA7),
221 (0x2557, 0xA8),
222 (0x2558, 0xA9),
223 (0x2559, 0xAA),
224 (0x255A, 0xAB),
225 (0x255B, 0xAC),
226 (0x255C, 0xAD),
227 (0x255D, 0xAE),
228 (0x255E, 0xAF),
229 (0x255F, 0xB0),
230 (0x2560, 0xB1),
231 (0x2561, 0xB2),
232 (0x2562, 0xB4),
233 (0x2563, 0xB5),
234 (0x2564, 0xB6),
235 (0x2565, 0xB7),
236 (0x2566, 0xB8),
237 (0x2567, 0xB9),
238 (0x2568, 0xBA),
239 (0x2569, 0xBB),
240 (0x256A, 0xBC),
241 (0x256B, 0xBD),
242 (0x256C, 0xBE),
243 (0x2580, 0x8B),
244 (0x2584, 0x8C),
245 (0x2588, 0x8D),
246 (0x258C, 0x8E),
247 (0x2590, 0x8F),
248 (0x2591, 0x90),
249 (0x2592, 0x91),
250 (0x2593, 0x92),
251 (0x25A0, 0x94),
252];