Skip to main content

anyxml_encoding/
koi8r.rs

1use crate::{DecodeError, Decoder, EncodeError, Encoder};
2
3/// Encoding name for KOI8-R.
4pub const KOI8R_NAME: &str = "KOI8-R";
5
6/// Encoder for KOI8-R.
7pub 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
54/// Decoder for KOI8-R.
55pub 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                // ASCII compatible
85                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                    // # Safety
93                    // No input other than the embedded UCS code is ever accepted,
94                    // so as long as the embedded UCS code is correct, it is always safe.
95                    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];