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