1mod big5;
16mod ebcdic;
17mod euc;
18mod gb2312;
19mod iso2022jp;
20mod iso8859;
21mod jisx;
22mod koi8r;
23mod ksx;
24mod shift_jis;
25mod ucs4;
26mod us_ascii;
27mod utf16;
28mod utf8;
29
30use std::{
31 borrow::Cow,
32 collections::BTreeMap,
33 sync::{LazyLock, RwLock},
34};
35
36pub use big5::*;
37pub use ebcdic::*;
38pub use euc::*;
39pub use iso2022jp::*;
40pub use iso8859::*;
41pub use koi8r::*;
42pub use shift_jis::*;
43pub use ucs4::*;
44pub use us_ascii::*;
45pub use utf8::*;
46pub use utf16::*;
47
48#[derive(Debug, Clone)]
50pub enum EncodeError {
51 InputIsEmpty,
53 OutputTooShort,
56 Unmappable { read: usize, write: usize, c: char },
62 Other { msg: Cow<'static, str> },
64}
65
66impl std::fmt::Display for EncodeError {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 write!(f, "{self:?}")
69 }
70}
71
72impl std::error::Error for EncodeError {}
73
74pub trait Encoder {
75 fn name(&self) -> &'static str;
76 fn encode(
78 &mut self,
79 src: &str,
80 dst: &mut [u8],
81 finish: bool,
82 ) -> Result<(usize, usize), EncodeError>;
83}
84
85#[derive(Debug, Clone)]
87pub enum DecodeError {
88 InputIsEmpty,
90 OutputTooShort,
93 Malformed {
98 read: usize,
99 write: usize,
100 length: usize,
101 offset: usize,
102 },
103 Other { msg: Cow<'static, str> },
105}
106
107impl std::fmt::Display for DecodeError {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 write!(f, "{self:?}")
110 }
111}
112
113impl std::error::Error for DecodeError {}
114
115pub trait Decoder {
116 fn name(&self) -> &'static str;
117 fn decode(
119 &mut self,
120 src: &[u8],
121 dst: &mut String,
122 finish: bool,
123 ) -> Result<(usize, usize), DecodeError>;
124}
125
126pub const DEFAULT_SUPPORTED_ENCODINGS: &[&str] = {
130 const NAMES: &[&str] = &[
131 BIG5_NAME,
132 EUCJP_NAME,
133 EUCKR_NAME,
134 GB2312_NAME,
135 IBM037,
136 IBM1026,
137 IBM273,
138 IBM274,
139 IBM275,
140 IBM277,
141 IBM278,
142 IBM280,
143 IBM284,
144 IBM285,
145 IBM290,
146 IBM297,
147 IBM420,
148 IBM423,
149 IBM424,
150 IBM437,
151 IBM500,
152 IBM850,
153 IBM851,
154 IBM852,
155 IBM855,
156 IBM857,
157 IBM860,
158 IBM861,
159 IBM862,
160 IBM863,
161 IBM864,
162 IBM865,
163 IBM868,
164 IBM869,
165 IBM870,
166 IBM871,
167 IBM880,
168 IBM891,
169 IBM903,
170 IBM904,
171 IBM905,
172 IBM918,
173 ISO_2022_JP_NAME,
174 ISO_8859_10_NAME,
175 ISO_8859_13_NAME,
176 ISO_8859_14_NAME,
177 ISO_8859_15_NAME,
178 ISO_8859_16_NAME,
179 ISO_8859_1_NAME,
180 ISO_8859_2_NAME,
181 ISO_8859_3_NAME,
182 ISO_8859_4_NAME,
183 ISO_8859_5_NAME,
184 ISO_8859_6_NAME,
185 ISO_8859_7_NAME,
186 ISO_8859_8_NAME,
187 ISO_8859_9_NAME,
188 KOI8R_NAME,
189 SHIFT_JIS_NAME,
190 ISO_8859_11_NAME,
191 US_ASCII_NAME,
192 UTF16_NAME,
193 UTF16BE_NAME,
194 UTF16LE_NAME,
195 UTF32_NAME,
196 UTF32BE_NAME,
197 UTF32LE_NAME,
198 UTF8_NAME,
199 ];
200 let len = NAMES.len();
201 let mut i = 0;
202 while i + 1 < len {
203 let x = NAMES[i].as_bytes();
204 let y = NAMES[i + 1].as_bytes();
205 let mut j = 0;
206 while j < x.len() {
207 assert!(x[j] <= y[j]);
208 if x[j] < y[j] {
209 break;
210 }
211 j += 1;
212 if j == x.len() {
213 break;
214 }
215 assert!(j < y.len());
216 }
217 i += 1;
218 }
219 NAMES
220};
221pub static ENCODING_ALIASES: LazyLock<RwLock<BTreeMap<Cow<'static, str>, &'static str>>> =
223 LazyLock::new(|| {
224 RwLock::new(BTreeMap::from([
226 ("UTF8".into(), UTF8_NAME),
227 ("UTF16".into(), UTF16_NAME),
228 ("UTF16BE".into(), UTF16BE_NAME),
229 ("UTF16LE".into(), UTF16LE_NAME),
230 ("ISO-IR-100".into(), ISO_8859_1_NAME),
231 ("ISO_8859-1".into(), ISO_8859_1_NAME),
232 ("ISO-8859-1".into(), ISO_8859_1_NAME),
233 ("LATIN1".into(), ISO_8859_1_NAME),
234 ("L1".into(), ISO_8859_1_NAME),
235 ("IBM819".into(), ISO_8859_1_NAME),
236 ("CP819".into(), ISO_8859_1_NAME),
237 ("ISOLATIN1".into(), ISO_8859_1_NAME),
238 ("ISO-IR-101".into(), ISO_8859_2_NAME),
239 ("ISO_8859-2".into(), ISO_8859_2_NAME),
240 ("ISO-8859-2".into(), ISO_8859_2_NAME),
241 ("LATIN2".into(), ISO_8859_2_NAME),
242 ("L2".into(), ISO_8859_2_NAME),
243 ("ISOLATIN2".into(), ISO_8859_2_NAME),
244 ("ISO-IR-109".into(), ISO_8859_3_NAME),
245 ("ISO_8859-3".into(), ISO_8859_3_NAME),
246 ("ISO-8859-3".into(), ISO_8859_3_NAME),
247 ("LATIN3".into(), ISO_8859_3_NAME),
248 ("L3".into(), ISO_8859_3_NAME),
249 ("ISOLATIN3".into(), ISO_8859_3_NAME),
250 ("ISO-IR-110".into(), ISO_8859_4_NAME),
251 ("ISO_8859-4".into(), ISO_8859_4_NAME),
252 ("ISO-8859-4".into(), ISO_8859_4_NAME),
253 ("LATIN4".into(), ISO_8859_4_NAME),
254 ("L4".into(), ISO_8859_4_NAME),
255 ("ISOLATIN4".into(), ISO_8859_4_NAME),
256 ("ISO-IR-144".into(), ISO_8859_5_NAME),
257 ("ISO_8859-5".into(), ISO_8859_5_NAME),
258 ("ISO-8859-5".into(), ISO_8859_5_NAME),
259 ("CYRILLIC".into(), ISO_8859_5_NAME),
260 ("ISOLATINCYRILLIC".into(), ISO_8859_5_NAME),
261 ("ISO-IR-127".into(), ISO_8859_6_NAME),
262 ("ISO_8859-6".into(), ISO_8859_6_NAME),
263 ("ISO-8859-6".into(), ISO_8859_6_NAME),
264 ("ECMA-114".into(), ISO_8859_6_NAME),
265 ("ASMO-708".into(), ISO_8859_6_NAME),
266 ("ARABIC".into(), ISO_8859_6_NAME),
267 ("ISOLATINARABIC".into(), ISO_8859_6_NAME),
268 ("ISO-IR-126".into(), ISO_8859_7_NAME),
269 ("ISO_8859-7".into(), ISO_8859_7_NAME),
270 ("ISO-8859-7".into(), ISO_8859_7_NAME),
271 ("ELOT_928".into(), ISO_8859_7_NAME),
272 ("ECMA-118".into(), ISO_8859_7_NAME),
273 ("GREEK".into(), ISO_8859_7_NAME),
274 ("GREEK8".into(), ISO_8859_7_NAME),
275 ("ISOLATINGREEK".into(), ISO_8859_7_NAME),
276 ("ISO-IR-138".into(), ISO_8859_8_NAME),
277 ("ISO_8859-8".into(), ISO_8859_8_NAME),
278 ("ISO-8859-8".into(), ISO_8859_8_NAME),
279 ("HEBREW".into(), ISO_8859_8_NAME),
280 ("ISOLATINHEBREW".into(), ISO_8859_8_NAME),
281 ("ISO-IR-148".into(), ISO_8859_9_NAME),
282 ("ISO_8859-9".into(), ISO_8859_9_NAME),
283 ("ISO-8859-9".into(), ISO_8859_9_NAME),
284 ("LATIN5".into(), ISO_8859_9_NAME),
285 ("L5".into(), ISO_8859_9_NAME),
286 ("ISOLATIN5".into(), ISO_8859_9_NAME),
287 ("ISO-IR-157".into(), ISO_8859_10_NAME),
288 ("L6".into(), ISO_8859_10_NAME),
289 ("ISO_8859-10:1992".into(), ISO_8859_10_NAME),
290 ("ISOLATIN6".into(), ISO_8859_10_NAME),
291 ("LATIN6".into(), ISO_8859_10_NAME),
292 ("TIS620".into(), ISO_8859_11_NAME),
293 ("ISO-8859-11".into(), ISO_8859_11_NAME),
294 ("ISO885913".into(), ISO_8859_13_NAME),
295 ("ISO-IR-199".into(), ISO_8859_14_NAME),
296 ("ISO_8859-14:1998".into(), ISO_8859_14_NAME),
297 ("ISO_8859-14".into(), ISO_8859_14_NAME),
298 ("LATIN8".into(), ISO_8859_14_NAME),
299 ("ISO-CELTIC".into(), ISO_8859_14_NAME),
300 ("L8".into(), ISO_8859_14_NAME),
301 ("ISO885914".into(), ISO_8859_14_NAME),
302 ("ISO_8859-15".into(), ISO_8859_15_NAME),
303 ("LATIN-9".into(), ISO_8859_15_NAME),
304 ("ISO885915".into(), ISO_8859_15_NAME),
305 ("ISO-IR-226".into(), ISO_8859_16_NAME),
306 ("ISO_8859-16:2001".into(), ISO_8859_16_NAME),
307 ("ISO_8859-16".into(), ISO_8859_16_NAME),
308 ("LATIN10".into(), ISO_8859_16_NAME),
309 ("L10".into(), ISO_8859_16_NAME),
310 ("ISO885916".into(), ISO_8859_16_NAME),
311 ("UTF32".into(), UTF32_NAME),
312 ("UTF32BE".into(), UTF32BE_NAME),
313 ("UTF32LE".into(), UTF32LE_NAME),
314 ("MS_KANJI".into(), SHIFT_JIS_NAME),
315 ("SHIFTJIS".into(), SHIFT_JIS_NAME),
316 ("ISO-IR-6".into(), US_ASCII_NAME),
317 ("ANSI_X3.4-1968".into(), US_ASCII_NAME),
318 ("ANSI_X3.4-1986".into(), US_ASCII_NAME),
319 ("ISO_646.IRV:1991".into(), US_ASCII_NAME),
320 ("ISO646-US".into(), US_ASCII_NAME),
321 ("US-ASCII".into(), US_ASCII_NAME),
322 ("US".into(), US_ASCII_NAME),
323 ("IBM367".into(), US_ASCII_NAME),
324 ("CP367".into(), US_ASCII_NAME),
325 ("ASCII".into(), US_ASCII_NAME),
326 ("CP037".into(), IBM037),
327 ("EBCDIC-CP-US".into(), IBM037),
328 ("EBCDIC-CP-CA".into(), IBM037),
329 ("EBCDIC-CP-WT".into(), IBM037),
330 ("EBCDIC-CP-NL".into(), IBM037),
331 ("CP273".into(), IBM273),
332 ("EBCDIC-BE".into(), IBM274),
333 ("CP274".into(), IBM274),
334 ("EBCDIC-BR".into(), IBM275),
335 ("CP275".into(), IBM275),
336 ("EBCDIC-CP-DK".into(), IBM277),
337 ("EBCDIC-CP-NO".into(), IBM277),
338 ("CP278".into(), IBM278),
339 ("EBCDIC-CP-FI".into(), IBM278),
340 ("EBCDIC-CP-SE".into(), IBM278),
341 ("CP280".into(), IBM280),
342 ("EBCDIC-CP-IT".into(), IBM280),
343 ("CP284".into(), IBM284),
344 ("EBCDIC-CP-ES".into(), IBM284),
345 ("CP285".into(), IBM285),
346 ("EBCDIC-CP-GB".into(), IBM285),
347 ("CP290".into(), IBM290),
348 ("EBCDIC-JP-KANA".into(), IBM290),
349 ("CP297".into(), IBM297),
350 ("EBCDIC-CP-FR".into(), IBM297),
351 ("CP420".into(), IBM420),
352 ("EBCDIC-CP-AR1".into(), IBM420),
353 ("CP423".into(), IBM423),
354 ("EBCDIC-CP-GR".into(), IBM423),
355 ("CP424".into(), IBM424),
356 ("EBCDIC-CP-HE".into(), IBM424),
357 ("CP437".into(), IBM437),
358 ("437".into(), IBM437),
359 ("PC8CODEPAGE437".into(), IBM437),
360 ("CP500".into(), IBM500),
361 ("EBCDIC-CP-BE".into(), IBM500),
362 ("EBCDIC-CP-CH".into(), IBM500),
363 ("CP851".into(), IBM851),
364 ("851".into(), IBM851),
365 ("CP852".into(), IBM852),
366 ("852".into(), IBM852),
367 ("PCP852".into(), IBM852),
368 ("CP855".into(), IBM855),
369 ("855".into(), IBM855),
370 ("CP857".into(), IBM857),
371 ("857".into(), IBM857),
372 ("CP860".into(), IBM860),
373 ("860".into(), IBM860),
374 ("CP861".into(), IBM861),
375 ("861".into(), IBM861),
376 ("CP-IS".into(), IBM861),
377 ("CP863".into(), IBM863),
378 ("863".into(), IBM863),
379 ("CP864".into(), IBM864),
380 ("CP865".into(), IBM865),
381 ("865".into(), IBM865),
382 ("CP868".into(), IBM868),
383 ("CP-AR".into(), IBM868),
384 ("CP869".into(), IBM869),
385 ("869".into(), IBM869),
386 ("CP-GR".into(), IBM869),
387 ("CP870".into(), IBM870),
388 ("EBCDIC-CP-ROECE".into(), IBM870),
389 ("EBCDIC-CP-YU".into(), IBM870),
390 ("CP871".into(), IBM871),
391 ("EBCDIC-CP-IS".into(), IBM871),
392 ("CP880".into(), IBM880),
393 ("EBCDIC-CYRILLIC".into(), IBM880),
394 ("CP891".into(), IBM891),
395 ("CP903".into(), IBM903),
396 ("CP904".into(), IBM904),
397 ("904".into(), IBM904),
398 ("IBBM904".into(), IBM904),
401 ("CP905".into(), IBM905),
402 ("EBCDIC-CP-TR".into(), IBM905),
403 ("CP918".into(), IBM918),
404 ("EBCDIC-CP-AR2".into(), IBM918),
405 ("CP1026".into(), IBM1026),
406 ("EUCPKDFMTJAPANESE".into(), EUCJP_NAME),
407 ("EUCKR".into(), EUCKR_NAME),
408 ("ISO2022JP".into(), ISO_2022_JP_NAME),
409 ]))
410 });
411pub fn register_encoding_alias(alias: &'static str, real: &'static str) -> Option<&'static str> {
424 let mut table = ENCODING_ALIASES.write().unwrap();
425 if alias.chars().all(|c| c.is_ascii_uppercase()) {
426 table.insert(alias.into(), real)
427 } else {
428 table.insert(alias.to_ascii_uppercase().into(), real)
429 }
430}
431pub fn unregister_encoding_alias(alias: &'static str) -> Option<&'static str> {
434 ENCODING_ALIASES
435 .write()
436 .unwrap()
437 .remove(alias.to_ascii_uppercase().as_str())
438}
439pub fn resolve_encoding_alias(alias: &str) -> Option<&'static str> {
444 let aliases = ENCODING_ALIASES.read().unwrap();
445 aliases
446 .get(alias)
447 .or_else(|| aliases.get(alias.to_ascii_uppercase().as_str()))
448 .copied()
449}
450
451pub type EncoderFactory = fn() -> Box<dyn Encoder>;
452pub static ENCODER_TABLE: LazyLock<RwLock<BTreeMap<&'static str, EncoderFactory>>> =
453 LazyLock::new(|| {
454 let mut map = BTreeMap::<&'static str, EncoderFactory>::new();
455 map.insert(UTF8_NAME, || Box::new(UTF8Encoder));
456 map.insert(UTF16_NAME, || Box::new(UTF16Encoder::default()));
457 map.insert(UTF16BE_NAME, || Box::new(UTF16BEEncoder));
458 map.insert(UTF16LE_NAME, || Box::new(UTF16LEEncoder));
459 map.insert(ISO_8859_1_NAME, || Box::new(ISO8859_1Encoder));
460 map.insert(ISO_8859_2_NAME, || Box::new(ISO8859_2Encoder));
461 map.insert(ISO_8859_3_NAME, || Box::new(ISO8859_3Encoder));
462 map.insert(ISO_8859_4_NAME, || Box::new(ISO8859_4Encoder));
463 map.insert(ISO_8859_5_NAME, || Box::new(ISO8859_5Encoder));
464 map.insert(ISO_8859_6_NAME, || Box::new(ISO8859_6Encoder));
465 map.insert(ISO_8859_7_NAME, || Box::new(ISO8859_7Encoder));
466 map.insert(ISO_8859_8_NAME, || Box::new(ISO8859_8Encoder));
467 map.insert(ISO_8859_9_NAME, || Box::new(ISO8859_9Encoder));
468 map.insert(ISO_8859_10_NAME, || Box::new(ISO8859_10Encoder));
469 map.insert(ISO_8859_11_NAME, || Box::new(ISO8859_11Encoder));
470 map.insert(ISO_8859_13_NAME, || Box::new(ISO8859_13Encoder));
471 map.insert(ISO_8859_14_NAME, || Box::new(ISO8859_14Encoder));
472 map.insert(ISO_8859_15_NAME, || Box::new(ISO8859_15Encoder));
473 map.insert(ISO_8859_16_NAME, || Box::new(ISO8859_16Encoder));
474 map.insert(UTF32_NAME, || Box::new(UTF32Encoder::default()));
475 map.insert(UTF32BE_NAME, || Box::new(UTF32BEEncoder));
476 map.insert(UTF32LE_NAME, || Box::new(UTF32LEEncoder));
477 map.insert(SHIFT_JIS_NAME, || Box::new(ShiftJISEncoder));
478 map.insert(US_ASCII_NAME, || Box::new(USASCIIEncoder));
479 map.insert(IBM037, || Box::new(IBM037Encoder));
480 map.insert(IBM273, || Box::new(IBM273Encoder));
481 map.insert(IBM274, || Box::new(IBM274Encoder));
482 map.insert(IBM275, || Box::new(IBM275Encoder));
483 map.insert(IBM277, || Box::new(IBM277Encoder));
484 map.insert(IBM278, || Box::new(IBM278Encoder));
485 map.insert(IBM280, || Box::new(IBM280Encoder));
486 map.insert(IBM284, || Box::new(IBM284Encoder));
487 map.insert(IBM285, || Box::new(IBM285Encoder));
488 map.insert(IBM290, || Box::new(IBM290Encoder));
489 map.insert(IBM297, || Box::new(IBM297Encoder));
490 map.insert(IBM420, || Box::new(IBM420Encoder));
491 map.insert(IBM423, || Box::new(IBM423Encoder));
492 map.insert(IBM424, || Box::new(IBM424Encoder));
493 map.insert(IBM437, || Box::new(IBM437Encoder));
494 map.insert(IBM500, || Box::new(IBM500Encoder));
495 map.insert(IBM850, || Box::new(IBM850Encoder));
496 map.insert(IBM851, || Box::new(IBM851Encoder));
497 map.insert(IBM852, || Box::new(IBM852Encoder));
498 map.insert(IBM855, || Box::new(IBM855Encoder));
499 map.insert(IBM857, || Box::new(IBM857Encoder));
500 map.insert(IBM860, || Box::new(IBM860Encoder));
501 map.insert(IBM861, || Box::new(IBM861Encoder));
502 map.insert(IBM862, || Box::new(IBM862Encoder));
503 map.insert(IBM863, || Box::new(IBM863Encoder));
504 map.insert(IBM864, || Box::new(IBM864Encoder));
505 map.insert(IBM865, || Box::new(IBM865Encoder));
506 map.insert(IBM868, || Box::new(IBM868Encoder));
507 map.insert(IBM869, || Box::new(IBM869Encoder));
508 map.insert(IBM870, || Box::new(IBM870Encoder));
509 map.insert(IBM871, || Box::new(IBM871Encoder));
510 map.insert(IBM880, || Box::new(IBM880Encoder));
511 map.insert(IBM891, || Box::new(IBM891Encoder));
512 map.insert(IBM903, || Box::new(IBM903Encoder));
513 map.insert(IBM904, || Box::new(IBM904Encoder));
514 map.insert(IBM905, || Box::new(IBM905Encoder));
515 map.insert(IBM918, || Box::new(IBM918Encoder));
516 map.insert(IBM1026, || Box::new(IBM1026Encoder));
517 map.insert(EUCJP_NAME, eucjp_encoder_factory);
518 map.insert(EUCKR_NAME, euckr_encoder_factory);
519 map.insert(BIG5_NAME, || Box::new(Big5Encoder));
520 map.insert(KOI8R_NAME, || Box::new(KOI8REncoder));
521 map.insert(GB2312_NAME, gb2312_encoder_factory);
522 map.insert(ISO_2022_JP_NAME, || Box::new(ISO2022JPEncoder::default()));
523 RwLock::new(map)
524 });
525pub fn find_encoder(encoding_name: &str) -> Option<Box<dyn Encoder>> {
526 let table = ENCODER_TABLE.read().unwrap();
527 if let Some(factory) = table.get(encoding_name) {
528 return Some(factory());
529 }
530 if let Some(factory) = table.get(encoding_name.to_ascii_uppercase().as_str()) {
531 return Some(factory());
532 }
533
534 let alias = resolve_encoding_alias(encoding_name)?;
535 table.get(alias).map(|f| f())
536}
537pub fn register_encoder(
538 encoding_name: &'static str,
539 factory: EncoderFactory,
540) -> Option<EncoderFactory> {
541 ENCODER_TABLE
542 .write()
543 .unwrap()
544 .insert(encoding_name, factory)
545}
546pub fn unregister_encoder(encoding_name: &str) -> Option<EncoderFactory> {
547 ENCODER_TABLE.write().unwrap().remove(encoding_name)
548}
549
550pub type DecoderFactory = fn() -> Box<dyn Decoder>;
551pub static DECODER_TABLE: LazyLock<RwLock<BTreeMap<&'static str, DecoderFactory>>> =
552 LazyLock::new(|| {
553 let mut map = BTreeMap::<&'static str, DecoderFactory>::new();
554 map.insert(UTF8_NAME, || Box::new(UTF8Decoder));
555 map.insert(UTF16_NAME, || Box::new(UTF16Decoder::default()));
556 map.insert(UTF16BE_NAME, || Box::new(UTF16BEDecoder));
557 map.insert(UTF16LE_NAME, || Box::new(UTF16LEDecoder));
558 map.insert(ISO_8859_1_NAME, || Box::new(ISO8859_1Decoder));
559 map.insert(ISO_8859_2_NAME, || Box::new(ISO8859_2Decoder));
560 map.insert(ISO_8859_3_NAME, || Box::new(ISO8859_3Decoder));
561 map.insert(ISO_8859_4_NAME, || Box::new(ISO8859_4Decoder));
562 map.insert(ISO_8859_5_NAME, || Box::new(ISO8859_5Decoder));
563 map.insert(ISO_8859_6_NAME, || Box::new(ISO8859_6Decoder));
564 map.insert(ISO_8859_7_NAME, || Box::new(ISO8859_7Decoder));
565 map.insert(ISO_8859_8_NAME, || Box::new(ISO8859_8Decoder));
566 map.insert(ISO_8859_9_NAME, || Box::new(ISO8859_9Decoder));
567 map.insert(ISO_8859_10_NAME, || Box::new(ISO8859_10Decoder));
568 map.insert(ISO_8859_11_NAME, || Box::new(ISO8859_11Decoder));
569 map.insert(ISO_8859_13_NAME, || Box::new(ISO8859_13Decoder));
570 map.insert(ISO_8859_14_NAME, || Box::new(ISO8859_14Decoder));
571 map.insert(ISO_8859_15_NAME, || Box::new(ISO8859_15Decoder));
572 map.insert(ISO_8859_16_NAME, || Box::new(ISO8859_16Decoder));
573 map.insert(UTF32_NAME, || Box::new(UTF32Decoder::default()));
574 map.insert(UTF32BE_NAME, || Box::new(UTF32BEDecoder));
575 map.insert(UTF32LE_NAME, || Box::new(UTF32LEDecoder));
576 map.insert(SHIFT_JIS_NAME, || Box::new(ShiftJISDecoder));
577 map.insert(US_ASCII_NAME, || Box::new(USASCIIDecoder));
578 map.insert(IBM037, || Box::new(IBM037Decoder));
579 map.insert(IBM273, || Box::new(IBM273Decoder));
580 map.insert(IBM274, || Box::new(IBM274Decoder));
581 map.insert(IBM275, || Box::new(IBM275Decoder));
582 map.insert(IBM277, || Box::new(IBM277Decoder));
583 map.insert(IBM278, || Box::new(IBM278Decoder));
584 map.insert(IBM280, || Box::new(IBM280Decoder));
585 map.insert(IBM284, || Box::new(IBM284Decoder));
586 map.insert(IBM285, || Box::new(IBM285Decoder));
587 map.insert(IBM290, || Box::new(IBM290Decoder));
588 map.insert(IBM297, || Box::new(IBM297Decoder));
589 map.insert(IBM420, || Box::new(IBM420Decoder));
590 map.insert(IBM423, || Box::new(IBM423Decoder));
591 map.insert(IBM424, || Box::new(IBM424Decoder));
592 map.insert(IBM437, || Box::new(IBM437Decoder));
593 map.insert(IBM500, || Box::new(IBM500Decoder));
594 map.insert(IBM850, || Box::new(IBM850Decoder));
595 map.insert(IBM851, || Box::new(IBM851Decoder));
596 map.insert(IBM852, || Box::new(IBM852Decoder));
597 map.insert(IBM855, || Box::new(IBM855Decoder));
598 map.insert(IBM857, || Box::new(IBM857Decoder));
599 map.insert(IBM860, || Box::new(IBM860Decoder));
600 map.insert(IBM861, || Box::new(IBM861Decoder));
601 map.insert(IBM862, || Box::new(IBM862Decoder));
602 map.insert(IBM863, || Box::new(IBM863Decoder));
603 map.insert(IBM864, || Box::new(IBM864Decoder));
604 map.insert(IBM865, || Box::new(IBM865Decoder));
605 map.insert(IBM868, || Box::new(IBM868Decoder));
606 map.insert(IBM869, || Box::new(IBM869Decoder));
607 map.insert(IBM870, || Box::new(IBM870Decoder));
608 map.insert(IBM871, || Box::new(IBM871Decoder));
609 map.insert(IBM880, || Box::new(IBM880Decoder));
610 map.insert(IBM891, || Box::new(IBM891Decoder));
611 map.insert(IBM903, || Box::new(IBM903Decoder));
612 map.insert(IBM904, || Box::new(IBM904Decoder));
613 map.insert(IBM905, || Box::new(IBM905Decoder));
614 map.insert(IBM918, || Box::new(IBM918Decoder));
615 map.insert(IBM1026, || Box::new(IBM1026Decoder));
616 map.insert(EUCJP_NAME, eucjp_decoder_factory);
617 map.insert(EUCKR_NAME, euckr_decoder_factory);
618 map.insert(BIG5_NAME, || Box::new(Big5Decoder));
619 map.insert(KOI8R_NAME, || Box::new(KOI8RDecoder));
620 map.insert(GB2312_NAME, gb2312_decoder_factory);
621 map.insert(ISO_2022_JP_NAME, || Box::new(ISO2022JPDecoder::default()));
622 RwLock::new(map)
623 });
624pub fn find_decoder(encoding_name: &str) -> Option<Box<dyn Decoder>> {
625 let table = DECODER_TABLE.read().unwrap();
626 if let Some(factory) = table.get(encoding_name) {
627 return Some(factory());
628 }
629 if let Some(factory) = table.get(encoding_name.to_ascii_uppercase().as_str()) {
630 return Some(factory());
631 }
632
633 let alias = resolve_encoding_alias(encoding_name)?;
634 table.get(alias).map(|f| f())
635}
636pub fn register_decoder(
637 encoding_name: &'static str,
638 factory: DecoderFactory,
639) -> Option<DecoderFactory> {
640 DECODER_TABLE
641 .write()
642 .unwrap()
643 .insert(encoding_name, factory)
644}
645pub fn unregister_decoder(encoding_name: &str) -> Option<DecoderFactory> {
646 DECODER_TABLE.write().unwrap().remove(encoding_name)
647}
648
649#[cfg(test)]
650mod tests {
651 use super::*;
652
653 #[test]
654 fn find_encoder_tests() {
655 for &name in DEFAULT_SUPPORTED_ENCODINGS {
656 let encoder = find_encoder(name).unwrap();
657 assert_eq!(name, encoder.name());
658 }
659 }
660
661 #[test]
662 fn find_decoder_tests() {
663 for &name in DEFAULT_SUPPORTED_ENCODINGS {
664 let decoder = find_decoder(name).unwrap();
665 assert_eq!(name, decoder.name());
666 }
667 }
668}