1use crate::{DecodeError, Decoder, EncodeError, Encoder, jisx, ksx};
2
3pub struct EUCDecoder {
4 g1: &'static [&'static [char]],
9 g2: &'static [&'static [char]],
11 g3: &'static [&'static [char]],
13}
14
15impl EUCDecoder {
16 fn decode(
18 &mut self,
19 src: &[u8],
20 dst: &mut String,
21 finish: bool,
22 ) -> Result<(usize, usize), DecodeError> {
23 if src.is_empty() {
24 return if finish {
25 Ok((0, 0))
26 } else {
27 Err(DecodeError::InputIsEmpty)
28 };
29 }
30 let len = dst.capacity() - dst.len();
31 if len < 4 {
32 return Err(DecodeError::OutputTooShort);
33 }
34
35 let (mut read, mut write) = (0, 0);
36 macro_rules! malformed {
37 ( $length:expr ) => {
38 Err(DecodeError::Malformed {
39 read,
40 write,
41 length: $length,
42 offset: 0,
43 })
44 };
45 }
46
47 while read < src.len() {
48 match src[read..] {
49 [0x8E, ..] | [0x8F, ..] => {
50 let g = if src[read] == 0x8E {
52 &self.g2
53 } else {
54 &self.g3
55 };
56
57 read += 1;
58 if read >= src.len() {
59 if finish {
60 return malformed!(1);
61 }
62 break;
63 }
64
65 if src[read] < 0xA0 {
66 read += 1;
67 return malformed!(1);
68 }
69 let s = src[read] as usize - 0xA0;
70 read += 1;
71 if g.len() == 1 {
72 let c = g[0][s];
73 if g[0].len() <= s || g[0][s] == char::REPLACEMENT_CHARACTER {
74 return malformed!(2);
75 }
76 dst.push(c);
77 write += c.len_utf8();
78 } else {
79 if read >= src.len() {
80 if finish {
81 return malformed!(2);
82 }
83 break;
84 }
85 if src[read] < 0xA0 {
86 read += 1;
87 return malformed!(3);
88 }
89 let t = src[read] as usize - 0xA0;
90 read += 1;
91 if g.len() <= s || g[s].len() <= t || g[s][t] == char::REPLACEMENT_CHARACTER
92 {
93 return malformed!(3);
94 }
95 let c = g[s][t];
96 dst.push(c);
97 write += c.len_utf8();
98 }
99 }
100 _ => {
101 if src[read] < 0xA0 {
102 let c = src[read] as char;
108 dst.push(c);
109 read += 1;
110 write += c.len_utf8();
111 } else {
112 if self.g1.len() > 1 {
114 if read + 1 == src.len() {
116 if finish {
118 read += 1;
119 return malformed!(1);
120 }
121 break;
122 }
123 let s = src[read] as usize - 0xA0;
124 if src[read + 1] < 0xA0 {
125 read += 2;
126 return malformed!(2);
127 }
128 let t = src[read + 1] as usize - 0xA0;
129 read += 2;
130 if self.g1.len() <= s
131 || self.g1[s].len() <= t
132 || self.g1[s][t] == char::REPLACEMENT_CHARACTER
133 {
134 return malformed!(2);
135 }
136 let c = self.g1[s][t];
137 dst.push(c);
138 write += c.len_utf8();
139 } else {
140 let c = self.g1[0][src[read] as usize - 0xA0];
142 read += 1;
143 if c == char::REPLACEMENT_CHARACTER {
144 return malformed!(1);
145 } else {
146 dst.push(c);
147 write += c.len_utf8();
148 }
149 }
150 }
151 }
152 }
153
154 if dst.capacity() - dst.len() < 4 {
155 break;
156 }
157 }
158
159 Ok((read, write))
160 }
161}
162
163pub struct EUCEncoder<
164 G1From,
165 G1To,
166 G2From,
167 G2To,
168 G3From,
169 G3To,
170 const G1DIM: u8,
171 const G2DIM: u8,
172 const G3DIM: u8,
173> where
174 G1From: Into<u32> + 'static,
175 G1To: Into<u32> + 'static,
176 G2From: Into<u32> + 'static,
177 G2To: Into<u32> + 'static,
178 G3From: Into<u32> + 'static,
179 G3To: Into<u32> + 'static,
180{
181 g1: &'static [(G1From, G1To)],
185 g2: &'static [(G2From, G2To)],
187 g3: &'static [(G3From, G3To)],
189}
190
191impl<G1From, G1To, G2From, G2To, G3From, G3To, const G1DIM: u8, const G2DIM: u8, const G3DIM: u8>
192 EUCEncoder<G1From, G1To, G2From, G2To, G3From, G3To, G1DIM, G2DIM, G3DIM>
193where
194 G1From: Into<u32> + Copy,
195 G1To: Into<u32> + Copy,
196 G2From: Into<u32> + Copy,
197 G2To: Into<u32> + Copy,
198 G3From: Into<u32> + Copy,
199 G3To: Into<u32> + Copy,
200{
201 fn encode(
203 &mut self,
204 src: &str,
205 dst: &mut [u8],
206 finish: bool,
207 ) -> Result<(usize, usize), EncodeError> {
208 assert!(0 < G1DIM && G1DIM <= 2 && 0 < G2DIM && G2DIM <= 2 && 0 < G3DIM && G3DIM <= 2);
209 if src.is_empty() {
210 return if finish {
211 Ok((0, 0))
212 } else {
213 Err(EncodeError::InputIsEmpty)
214 };
215 }
216
217 if dst.len() < 3 {
218 return Err(EncodeError::OutputTooShort);
219 }
220
221 let (mut read, mut write) = (0, 0);
222 macro_rules! write_buffer {
223 ( $dim:expr, $to:expr ) => {
224 if $dim == 1 {
225 assert!($to < u8::MAX as u32);
226 dst[write] = $to as u8 + 0xA0;
227 write += 1;
228 } else if $dim == 2 {
229 let to = $to + 0x8080;
230 dst[write] = (to >> 8) as u8;
231 dst[write + 1] = (to & 0xFF) as u8;
232 write += 2;
233 } else {
234 unreachable!();
235 }
236 };
237 }
238 for c in src.chars() {
239 read += c.len_utf8();
240 if c.is_ascii() || ((..'\u{A0}').contains(&c) && c != '\u{8E}' && c != '\u{8F}') {
241 dst[read] = c as u8;
242 write += 1;
243 } else if let Ok(pos) = self.g1.binary_search_by_key(&(c as u32), |e| e.0.into()) {
244 let to = self.g1[pos].1.into();
245 write_buffer!(G1DIM, to);
246 } else if let Ok(pos) = self.g2.binary_search_by_key(&(c as u32), |e| e.0.into()) {
247 dst[write] = 0x8E;
248 write += 1;
249 let to = self.g2[pos].1.into();
250 write_buffer!(G2DIM, to);
251 } else if let Ok(pos) = self.g3.binary_search_by_key(&(c as u32), |e| e.0.into()) {
252 dst[write] = 0x8F;
253 write += 1;
254 let to = self.g3[pos].1.into();
255 write_buffer!(G3DIM, to);
256 } else {
257 return Err(EncodeError::Unmappable { read, write, c });
258 }
259
260 if dst[write..].len() < 3 {
261 break;
262 }
263 }
264
265 Ok((read, write))
266 }
267}
268
269pub const EUCJP_NAME: &str = "EUC-JP";
271pub struct EUCJPDecoder {
273 decoder: EUCDecoder,
274}
275
276pub(crate) fn eucjp_decoder_factory() -> Box<dyn Decoder> {
277 static G2: &[&[char]] = &[jisx::JIS_X_0201_KATAKANA_DECODE_TABLE];
278 Box::new(EUCJPDecoder {
279 decoder: EUCDecoder {
280 g1: &jisx::JIS_X_0208_DECODE_TABLE,
281 g2: G2,
282 g3: &jisx::JIS_X_0212_DECODE_TABLE,
283 },
284 })
285}
286
287impl Decoder for EUCJPDecoder {
288 fn name(&self) -> &'static str {
289 EUCJP_NAME
290 }
291
292 fn decode(
293 &mut self,
294 src: &[u8],
295 dst: &mut String,
296 finish: bool,
297 ) -> Result<(usize, usize), DecodeError> {
298 self.decoder.decode(src, dst, finish)
299 }
300}
301
302pub struct EUCJPEncoder {
304 encoder: EUCEncoder<u16, u16, u16, u8, u16, u16, 2, 1, 2>,
305}
306
307pub(crate) fn eucjp_encoder_factory() -> Box<dyn Encoder> {
308 Box::new(EUCJPEncoder {
309 encoder: EUCEncoder {
310 g1: jisx::JIS_X_0208_ENCODE_TABLE,
311 g2: jisx::JIS_X_0201_KATAKANA_ENCODE_TABLE,
312 g3: jisx::JIS_X_0212_ENCODE_TABLE,
313 },
314 })
315}
316
317impl Encoder for EUCJPEncoder {
318 fn name(&self) -> &'static str {
319 EUCJP_NAME
320 }
321
322 fn encode(
323 &mut self,
324 src: &str,
325 dst: &mut [u8],
326 finish: bool,
327 ) -> Result<(usize, usize), EncodeError> {
328 self.encoder.encode(src, dst, finish)
329 }
330}
331
332pub const EUCKR_NAME: &str = "EUC-KR";
334pub struct EUCKRDecoder {
336 decoder: EUCDecoder,
337}
338
339pub(crate) fn euckr_decoder_factory() -> Box<dyn Decoder> {
340 Box::new(EUCKRDecoder {
341 decoder: EUCDecoder {
342 g1: &ksx::KS_X_1001_DECODE_TABLE,
343 g2: &[&[]],
344 g3: &[&[]],
345 },
346 })
347}
348
349impl Decoder for EUCKRDecoder {
350 fn name(&self) -> &'static str {
351 EUCKR_NAME
352 }
353
354 fn decode(
355 &mut self,
356 src: &[u8],
357 dst: &mut String,
358 finish: bool,
359 ) -> Result<(usize, usize), DecodeError> {
360 self.decoder.decode(src, dst, finish)
361 }
362}
363
364pub struct EUCKREncoder {
366 encoder: EUCEncoder<u16, u16, u8, u8, u8, u8, 2, 1, 1>,
367}
368
369pub(crate) fn euckr_encoder_factory() -> Box<dyn Encoder> {
370 Box::new(EUCKREncoder {
371 encoder: EUCEncoder {
372 g1: ksx::KS_X_1001_ENCODE_TABLE,
373 g2: &[],
374 g3: &[],
375 },
376 })
377}
378
379impl Encoder for EUCKREncoder {
380 fn name(&self) -> &'static str {
381 EUCKR_NAME
382 }
383
384 fn encode(
385 &mut self,
386 src: &str,
387 dst: &mut [u8],
388 finish: bool,
389 ) -> Result<(usize, usize), EncodeError> {
390 self.encoder.encode(src, dst, finish)
391 }
392}
393
394#[cfg(test)]
395mod tests {
396 use super::*;
397
398 #[test]
399 fn eucjp_katakana_tests() {
400 let bytes = &[
401 0x8e, 0xb1, 0x8e, 0xb2, 0x8e, 0xb3, 0x8e, 0xb4, 0x8e, 0xb5, 0x8e, 0xb6, 0x8e, 0xb7,
402 0x8e, 0xb8, 0x8e, 0xb9, 0x8e, 0xba, 0x8e, 0xbb, 0x8e, 0xbc, 0x8e, 0xbd, 0x8e, 0xbe,
403 0x8e, 0xbf, 0x8e, 0xc0, 0x8e, 0xc1, 0x8e, 0xc2, 0x8e, 0xc3, 0x8e, 0xc4, 0x8e, 0xc5,
404 0x8e, 0xc6, 0x8e, 0xc7, 0x8e, 0xc8, 0x8e, 0xc9, 0x8e, 0xca, 0x8e, 0xcb, 0x8e, 0xcc,
405 0x8e, 0xcd, 0x8e, 0xce, 0x8e, 0xcf, 0x8e, 0xd0, 0x8e, 0xd1, 0x8e, 0xd2, 0x8e, 0xd3,
406 0x8e, 0xd4, 0x8e, 0xd5, 0x8e, 0xd6, 0x8e, 0xd7, 0x8e, 0xd8, 0x8e, 0xd9, 0x8e, 0xda,
407 0x8e, 0xdb, 0x8e, 0xdc, 0x8e, 0xa6, 0x8e, 0xdd,
408 ];
409 let mut buf = String::with_capacity(512);
410 eucjp_decoder_factory()
411 .decode(bytes, &mut buf, true)
412 .unwrap();
413 assert_eq!(buf, "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン");
414 }
415
416 #[test]
417 fn eucjp_kanji_tests() {
418 let bytes = &[
419 0xc4, 0xbf, 0xb9, 0xf1, 0xb2, 0xc8, 0xa5, 0xce, 0xce, 0xb4, 0xbe, 0xbb, 0xa5, 0xc8,
420 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xce, 0xb7, 0xc4, 0xca, 0xa1, 0xa5, 0xc8, 0xa5, 0xf2,
421 0xb0, 0xca, 0xa5, 0xc6, 0xc3, 0xe6, 0xbf, 0xb4, 0xa5, 0xce, 0xb6, 0xd5, 0xb1, 0xc9,
422 0xa5, 0xc8, 0xa5, 0xb7, 0xc4, 0xbf, 0xa5, 0xab, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xcb,
423 0xbe, 0xb5, 0xa5, 0xaf, 0xa5, 0xeb, 0xa5, 0xce, 0xc2, 0xe7, 0xb8, 0xa2, 0xa5, 0xcb,
424 0xb0, 0xcd, 0xa5, 0xea, 0xb8, 0xbd, 0xba, 0xdf, 0xb5, 0xda, 0xbe, 0xad, 0xcd, 0xe8,
425 0xa5, 0xce, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xcb, 0xc2, 0xd0, 0xa5, 0xb7, 0xba, 0xa1,
426 0xa5, 0xce, 0xc9, 0xd4, 0xcb, 0xe1, 0xa5, 0xce, 0xc2, 0xe7, 0xc5, 0xb5, 0xa5, 0xf2,
427 0xc0, 0xeb, 0xc9, 0xdb, 0xa5, 0xb9, 0x0a, 0xb0, 0xd4, 0xa5, 0xd5, 0xa5, 0xcb, 0xb2,
428 0xe6, 0xa5, 0xab, 0xc1, 0xc4, 0xb2, 0xe6, 0xa5, 0xab, 0xbd, 0xa1, 0xa5, 0xcf, 0xb2,
429 0xe6, 0xa5, 0xab, 0xbf, 0xc3, 0xcc, 0xb1, 0xc1, 0xc4, 0xc0, 0xe8, 0xa5, 0xce, 0xb6,
430 0xa8, 0xce, 0xcf, 0xca, 0xe5, 0xcd, 0xe3, 0xa5, 0xcb, 0xd0, 0xe1, 0xa5, 0xea, 0xb2,
431 0xe6, 0xa5, 0xab, 0xc4, 0xeb, 0xb9, 0xf1, 0xa5, 0xf2, 0xc8, 0xa5, 0xc2, 0xa4, 0xa5,
432 0xb7, 0xb0, 0xca, 0xa5, 0xc6, 0xcc, 0xb5, 0xb5, 0xe7, 0xa5, 0xcb, 0xbf, 0xe2, 0xa5,
433 0xec, 0xa5, 0xbf, 0xa5, 0xea, 0xba, 0xa1, 0xa5, 0xec, 0xb2, 0xe6, 0xa5, 0xab, 0xbf,
434 0xc0, 0xc0, 0xbb, 0xa5, 0xca, 0xa5, 0xeb, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xce, 0xb0,
435 0xd2, 0xc6, 0xc1, 0xa5, 0xc8, 0xca, 0xc2, 0xa5, 0xcb, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5,
436 0xce, 0xc3, 0xe9, 0xbc, 0xc2, 0xcd, 0xa6, 0xc9, 0xf0, 0xa5, 0xcb, 0xa5, 0xb7, 0xa5,
437 0xc6, 0xb9, 0xf1, 0xa5, 0xf2, 0xb0, 0xa6, 0xa5, 0xb7, 0xb8, 0xf8, 0xa5, 0xcb, 0xbd,
438 0xde, 0xa5, 0xd2, 0xb0, 0xca, 0xa5, 0xc6, 0xba, 0xa1, 0xa5, 0xce, 0xb8, 0xf7, 0xb5,
439 0xb1, 0xa5, 0xa2, 0xa5, 0xeb, 0xb9, 0xf1, 0xbb, 0xcb, 0xa5, 0xce, 0xc0, 0xae, 0xc0,
440 0xd7, 0xa5, 0xf2, 0xec, 0xc6, 0xa5, 0xb7, 0xa5, 0xbf, 0xa5, 0xeb, 0xa5, 0xca, 0xa5,
441 0xea, 0xc4, 0xbf, 0xb2, 0xe6, 0xa5, 0xab, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xcf, 0xc2,
442 0xa8, 0xa5, 0xc1, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xce, 0xc3, 0xe9, 0xce, 0xc9, 0xa5,
443 0xca, 0xa5, 0xeb, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xce, 0xbb, 0xd2, 0xc2, 0xb9, 0xa5,
444 0xca, 0xa5, 0xeb, 0xa5, 0xf2, 0xb2, 0xf3, 0xc1, 0xdb, 0xa5, 0xb7, 0xc2, 0xb6, 0xa5,
445 0xce, 0xc4, 0xbf, 0xa5, 0xab, 0xb0, 0xd5, 0xa5, 0xf2, 0xca, 0xf4, 0xc2, 0xce, 0xa5,
446 0xb7, 0xc4, 0xbf, 0xa5, 0xab, 0xbb, 0xf6, 0xa5, 0xf2, 0xbe, 0xa9, 0xbd, 0xe7, 0xa5,
447 0xb7, 0xc1, 0xea, 0xcd, 0xbf, 0xa5, 0xcb, 0xcf, 0xc2, 0xc3, 0xef, 0xb6, 0xa8, 0xc6,
448 0xb1, 0xa5, 0xb7, 0xb1, 0xd7, 0xa1, 0xb9, 0xb2, 0xe6, 0xa5, 0xab, 0xc4, 0xeb, 0xb9,
449 0xf1, 0xa5, 0xce, 0xb8, 0xf7, 0xb1, 0xc9, 0xa5, 0xf2, 0xc3, 0xe6, 0xb3, 0xb0, 0xa5,
450 0xcb, 0xc0, 0xeb, 0xcd, 0xc8, 0xa5, 0xb7, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xce, 0xb0,
451 0xe4, 0xb6, 0xc8, 0xa5, 0xf2, 0xb1, 0xca, 0xb5, 0xd7, 0xa5, 0xcb, 0xf0, 0xdf, 0xb8,
452 0xc7, 0xa5, 0xca, 0xa5, 0xe9, 0xa5, 0xb7, 0xa5, 0xe0, 0xa5, 0xeb, 0xa5, 0xce, 0xb4,
453 0xf5, 0xcb, 0xbe, 0xa5, 0xf2, 0xc6, 0xb1, 0xa5, 0xaf, 0xa5, 0xb7, 0xba, 0xa1, 0xa5,
454 0xce, 0xc9, 0xe9, 0xc3, 0xb4, 0xa5, 0xf2, 0xca, 0xac, 0xa5, 0xc4, 0xa5, 0xcb, 0xb4,
455 0xae, 0xa5, 0xd5, 0xa5, 0xeb, 0xa5, 0xb3, 0xa5, 0xc8, 0xa5, 0xf2, 0xb5, 0xbf, 0xa5,
456 0xcf, 0xa5, 0xb5, 0xa5, 0xeb, 0xa5, 0xca, 0xa5, 0xea,
457 ];
458
459 let mut buf = String::with_capacity(1024);
460 let (read, _) = eucjp_decoder_factory()
461 .decode(bytes, &mut buf, true)
462 .unwrap();
463 assert_eq!(read, bytes.len());
464 assert_eq!(
465 buf,
466 "朕国家ノ隆昌ト臣民ノ慶福トヲ以テ中心ノ欣栄トシ朕カ祖宗ニ承クルノ大権ニ依リ現在及将来ノ臣民ニ対シ此ノ不磨ノ大典ヲ宣布ス\n惟フニ我カ祖我カ宗ハ我カ臣民祖先ノ協力輔翼ニ倚リ我カ帝国ヲ肇造シ以テ無窮ニ垂レタリ此レ我カ神聖ナル祖宗ノ威徳ト並ニ臣民ノ忠実勇武ニシテ国ヲ愛シ公ニ殉ヒ以テ此ノ光輝アル国史ノ成跡ヲ貽シタルナリ朕我カ臣民ハ即チ祖宗ノ忠良ナル臣民ノ子孫ナルヲ回想シ其ノ朕カ意ヲ奉体シ朕カ事ヲ奨順シ相与ニ和衷協同シ益々我カ帝国ノ光栄ヲ中外ニ宣揚シ祖宗ノ遺業ヲ永久ニ鞏固ナラシムルノ希望ヲ同クシ此ノ負担ヲ分ツニ堪フルコトヲ疑ハサルナリ"
467 );
468 }
469
470 #[test]
471 fn euckr_kanji_hangul_tests() {
472 let bytes = &[
473 0xea, 0xed, 0xce, 0xf9, 0xc7, 0xd1, 0x20, 0xd5, 0xf6, 0xde, 0xc8, 0xbf, 0xcd, 0x20,
474 0xee, 0xee, 0xf7, 0xd6, 0xbf, 0xa1, 0x20, 0xba, 0xfb, 0xb3, 0xaa, 0xb4, 0xc2, 0x20,
475 0xbf, 0xec, 0xb8, 0xae, 0x20, 0xd3, 0xde, 0xf9, 0xdb, 0xcf, 0xd0, 0xda, 0xc5, 0xc0,
476 0xba, 0x20, 0x33, 0xa1, 0xa4, 0x31, 0x20, 0xea, 0xa1, 0xd4, 0xd1, 0xc0, 0xb8, 0xb7,
477 0xce, 0x20, 0xcb, 0xef, 0xd8, 0xa1, 0xb5, 0xc8, 0x20, 0xd3, 0xde, 0xf9, 0xdb, 0xda,
478 0xc5, 0xcf, 0xd0, 0xd7, 0xfc, 0xe3, 0xc1, 0xef, 0xd9, 0xdd, 0xa4, 0xc0, 0xc7, 0x20,
479 0xdb, 0xf6, 0xf7, 0xd6, 0xb0, 0xfa, 0x20, 0xdc, 0xf4, 0xeb, 0xf9, 0xbf, 0xa1, 0x20,
480 0xf9, 0xf7, 0xcb, 0xde, 0xc7, 0xd1, 0x20, 0x34, 0xa1, 0xa4, 0x31, 0x39, 0x20, 0xda,
481 0xc5, 0xf1, 0xab, 0xd7, 0xe2, 0xd2, 0xb7, 0xc0, 0xbb, 0x20, 0xcd, 0xa9, 0xe3, 0xaf,
482 0xc7, 0xcf, 0xb0, 0xed, 0x2c, 0x20, 0xf0, 0xd3, 0xcf, 0xd0, 0xc0, 0xc7, 0x20, 0xda,
483 0xc5, 0xf1, 0xab, 0xcb, 0xc7, 0xfa, 0xd4, 0xb0, 0xfa, 0x20, 0xf8, 0xc1, 0xfb, 0xfa,
484 0xee, 0xdc, 0xf7, 0xd6, 0xec, 0xe9, 0xc0, 0xc7, 0x20, 0xde, 0xc5, 0xd9, 0xa4, 0xbf,
485 0xa1, 0x20, 0xd8, 0xa1, 0xca, 0xc5, 0xc7, 0xcf, 0xbf, 0xa9, 0x20, 0xef, 0xe1, 0xeb,
486 0xf9, 0xa1, 0xa4, 0xec, 0xd1, 0xd4, 0xb3, 0xbf, 0xcd, 0x20, 0xd4, 0xd2, 0xf8, 0xe0,
487 0xe4, 0xf1, 0xb7, 0xce, 0xbd, 0xe1, 0x20, 0xda, 0xc5, 0xf0, 0xe9, 0xc0, 0xc7, 0x20,
488 0xd3, 0xa5, 0xcc, 0xbf, 0xc0, 0xbb, 0x20, 0xcd, 0xf9, 0xcd, 0xb3, 0xc8, 0xf7, 0x20,
489 0xc7, 0xcf, 0xb0, 0xed, 0x2c, 0x20, 0xb8, 0xf0, 0xb5, 0xe7, 0x20, 0xde, 0xe4, 0xfc,
490 0xe5, 0xee, 0xdc, 0xf8, 0xc9, 0xe3, 0xa7, 0xb0, 0xfa, 0x20, 0xdc, 0xf4, 0xeb, 0xf9,
491 0xb8, 0xa6, 0x20, 0xf6, 0xe8, 0xf7, 0xf2, 0xc7, 0xcf, 0xb8, 0xe7, 0x2c, 0x20, 0xed,
492 0xbb, 0xd7, 0xc8, 0xb0, 0xfa, 0x20, 0xf0, 0xe0, 0xfb, 0xfa, 0xb8, 0xa6, 0x20, 0xb9,
493 0xd9, 0xc5, 0xc1, 0xc0, 0xb8, 0xb7, 0xce, 0x20, 0xed, 0xbb, 0xeb, 0xa6, 0xda, 0xc5,
494 0xf1, 0xab, 0xee, 0xdc, 0xd0, 0xf1, 0xdc, 0xe2, 0xf2, 0xf1, 0xdf, 0xed, 0xb8, 0xa6,
495 0x20, 0xb4, 0xf5, 0xbf, 0xed, 0x20, 0xfc, 0xac, 0xcd, 0xb3, 0xc8, 0xf7, 0x20, 0xc7,
496 0xcf, 0xbf, 0xa9, 0x20, 0xef, 0xd9, 0xf6, 0xbd, 0xa1, 0xa4, 0xcc, 0xe8, 0xf0, 0xad,
497 0xa1, 0xa4, 0xde, 0xe4, 0xfc, 0xe5, 0xa1, 0xa4, 0xd9, 0xfe, 0xfb, 0xf9, 0xc0, 0xc7,
498 0x20, 0xb8, 0xf0, 0xb5, 0xe7, 0x20, 0xd6, 0xc5, 0xe6, 0xb4, 0xbf, 0xa1, 0x20, 0xc0,
499 0xd6, 0xbe, 0xee, 0xbc, 0xad, 0x20, 0xca, 0xc0, 0xec, 0xd1, 0xc0, 0xc7, 0x20, 0xd1,
500 0xa6, 0xfc, 0xe5, 0xb8, 0xa6, 0x20, 0xd0, 0xb3, 0xd4, 0xf5, 0xc8, 0xf7, 0x20, 0xc7,
501 0xcf, 0xb0, 0xed, 0x2c, 0x20, 0xd2, 0xf6, 0xd5, 0xf4, 0xc0, 0xbb, 0x20, 0xf5, 0xcc,
502 0xcd, 0xd4, 0xd3, 0xf8, 0xb7, 0xce, 0x20, 0xdb, 0xa1, 0xfd, 0xc6, 0xc7, 0xcf, 0xb0,
503 0xd4, 0x20, 0xc7, 0xcf, 0xb8, 0xe7, 0x2c, 0x20, 0xed, 0xbb, 0xeb, 0xa6, 0xbf, 0xcd,
504 0x20, 0xcf, 0xed, 0xd7, 0xd7, 0xbf, 0xa1, 0x20, 0xb5, 0xfb, 0xb8, 0xa3, 0xb4, 0xc2,
505 0x20, 0xf4, 0xa1, 0xec, 0xf2, 0xb0, 0xfa, 0x20, 0xeb, 0xf9, 0xd9, 0xe2, 0xb8, 0xa6,
506 0x20, 0xe8, 0xc7, 0xe2, 0xc4, 0xc7, 0xcf, 0xb0, 0xd4, 0x20, 0xc7, 0xcf, 0xbf, 0xa9,
507 0x2c, 0x20, 0xbe, 0xc8, 0xc0, 0xb8, 0xb7, 0xce, 0xb4, 0xc2, 0x20, 0xcf, 0xd0, 0xda,
508 0xc5, 0xdf, 0xe6, 0xfc, 0xc0, 0xc0, 0xc7, 0x20, 0xd0, 0xb3, 0xd4, 0xf5, 0xc7, 0xd1,
509 0x20, 0xfa, 0xbe, 0xdf, 0xbe, 0xc0, 0xbb, 0x20, 0xd1, 0xa2, 0xc7, 0xcf, 0xb0, 0xed,
510 0x20, 0xb9, 0xdb, 0xc0, 0xb8, 0xb7, 0xce, 0xb4, 0xc2, 0x20, 0xf9, 0xf6, 0xce, 0xf9,
511 0xee, 0xdc, 0xc0, 0xce, 0x20, 0xe1, 0xa6, 0xcd, 0xa3, 0xf8, 0xc1, 0xfb, 0xfa, 0xbf,
512 0xcd, 0x20, 0xec, 0xd1, 0xd7, 0xbe, 0xcd, 0xec, 0xe7, 0xb4, 0xbf, 0xa1, 0x20, 0xc0,
513 0xcc, 0xb9, 0xd9, 0xc1, 0xf6, 0xc7, 0xd4, 0xc0, 0xb8, 0xb7, 0xce, 0xbd, 0xe1, 0x20,
514 0xbf, 0xec, 0xb8, 0xae, 0xb5, 0xe9, 0xb0, 0xfa, 0x20, 0xbf, 0xec, 0xb8, 0xae, 0xb5,
515 0xe9, 0xc0, 0xc7, 0x20, 0xed, 0xad, 0xe1, 0xdd, 0xc0, 0xc7, 0x20, 0xe4, 0xcc, 0xee,
516 0xef, 0xb0, 0xfa, 0x20, 0xed, 0xbb, 0xeb, 0xa6, 0xbf, 0xcd, 0x20, 0xfa, 0xb9, 0xdc,
517 0xd8, 0xc0, 0xbb, 0x20, 0xe7, 0xb5, 0xea, 0xc0, 0xc8, 0xf7, 0x20, 0xfc, 0xac, 0xdc,
518 0xc1, 0xc7, 0xd2, 0x20, 0xb0, 0xcd, 0xc0, 0xbb, 0x20, 0xb4, 0xd9, 0xc1, 0xfc, 0xc7,
519 0xcf, 0xb8, 0xe9, 0xbc, 0xad, 0x20, 0x31, 0x39, 0x34, 0x38, 0xd2, 0xb4, 0x20, 0x37,
520 0xea, 0xc5, 0x20, 0x31, 0x32, 0xec, 0xed, 0xbf, 0xa1, 0x20, 0xf0, 0xa4, 0xef, 0xd2,
521 0xb5, 0xc7, 0xb0, 0xed, 0x20, 0x38, 0xf3, 0xad, 0xbf, 0xa1, 0x20, 0xb0, 0xc9, 0xc3,
522 0xc4, 0x20, 0xcb, 0xc7, 0xef, 0xe1, 0xb5, 0xc8, 0x20, 0xfa, 0xca, 0xdb, 0xf6, 0xc0,
523 0xbb, 0x20, 0xc0, 0xcc, 0xc1, 0xa6, 0x20, 0xcf, 0xd0, 0xfc, 0xe5, 0xc0, 0xc7, 0x20,
524 0xec, 0xa1, 0xcc, 0xbd, 0xc0, 0xbb, 0x20, 0xb0, 0xc5, 0xc3, 0xc4, 0x20, 0xcf, 0xd0,
525 0xda, 0xc5, 0xf7, 0xe1, 0xf8, 0xf9, 0xbf, 0xa1, 0x20, 0xeb, 0xee, 0xc7, 0xcf, 0xbf,
526 0xa9, 0x20, 0xcb, 0xc7, 0xef, 0xe1, 0xc7, 0xd1, 0xb4, 0xd9, 0x2e,
527 ];
528
529 let mut buf = String::with_capacity(2048);
530 let (read, _) = euckr_decoder_factory()
531 .decode(bytes, &mut buf, true)
532 .unwrap();
533 assert_eq!(read, bytes.len());
534 assert_eq!(
535 buf,
536 "悠久한 歷史와 傳統에 빛나는 우리 大韓國民은 3·1 運動으로 建立된 大韓民國臨時政府의 法統과 不義에 抗拒한 4·19 民主理念을 繼承하고, 祖國의 民主改革과 平和的統一의 使命에 立脚하여 正義·人道와 同胞愛로써 民族의 團結을 鞏固히 하고, 모든 社會的弊習과 不義를 打破하며, 自律과 調和를 바탕으로 自由民主的基本秩序를 더욱 確固히 하여 政治·經濟·社會·文化의 모든 領域에 있어서 各人의 機會를 均等히 하고, 能力을 最高度로 發揮하게 하며, 自由와 權利에 따르는 責任과 義務를 完遂하게 하여, 안으로는 國民生活의 均等한 向上을 期하고 밖으로는 恒久的인 世界平和와 人類共榮에 이바지함으로써 우리들과 우리들의 子孫의 安全과 自由와 幸福을 永遠히 確保할 것을 다짐하면서 1948年 7月 12日에 制定되고 8次에 걸쳐 改正된 憲法을 이제 國會의 議決을 거쳐 國民投票에 依하여 改正한다."
537 );
538 }
539}