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";
270pub struct EUCJPDecoder {
271 decoder: EUCDecoder,
272}
273
274pub(crate) fn eucjp_decoder_factory() -> Box<dyn Decoder> {
275 static G2: &[&[char]] = &[jisx::JIS_X_0201_KATAKANA_DECODE_TABLE];
276 Box::new(EUCJPDecoder {
277 decoder: EUCDecoder {
278 g1: &jisx::JIS_X_0208_DECODE_TABLE,
279 g2: G2,
280 g3: &jisx::JIS_X_0212_DECODE_TABLE,
281 },
282 })
283}
284
285impl Decoder for EUCJPDecoder {
286 fn name(&self) -> &'static str {
287 EUCJP_NAME
288 }
289
290 fn decode(
291 &mut self,
292 src: &[u8],
293 dst: &mut String,
294 finish: bool,
295 ) -> Result<(usize, usize), DecodeError> {
296 self.decoder.decode(src, dst, finish)
297 }
298}
299
300pub struct EUCJPEncoder {
301 encoder: EUCEncoder<u16, u16, u16, u8, u16, u16, 2, 1, 2>,
302}
303
304pub(crate) fn eucjp_encoder_factory() -> Box<dyn Encoder> {
305 Box::new(EUCJPEncoder {
306 encoder: EUCEncoder {
307 g1: jisx::JIS_X_0208_ENCODE_TABLE,
308 g2: jisx::JIS_X_0201_KATAKANA_ENCODE_TABLE,
309 g3: jisx::JIS_X_0212_ENCODE_TABLE,
310 },
311 })
312}
313
314impl Encoder for EUCJPEncoder {
315 fn name(&self) -> &'static str {
316 EUCJP_NAME
317 }
318
319 fn encode(
320 &mut self,
321 src: &str,
322 dst: &mut [u8],
323 finish: bool,
324 ) -> Result<(usize, usize), EncodeError> {
325 self.encoder.encode(src, dst, finish)
326 }
327}
328
329pub const EUCKR_NAME: &str = "EUC-KR";
330pub struct EUCKRDecoder {
331 decoder: EUCDecoder,
332}
333
334pub(crate) fn euckr_decoder_factory() -> Box<dyn Decoder> {
335 Box::new(EUCKRDecoder {
336 decoder: EUCDecoder {
337 g1: &ksx::KS_X_1001_DECODE_TABLE,
338 g2: &[&[]],
339 g3: &[&[]],
340 },
341 })
342}
343
344impl Decoder for EUCKRDecoder {
345 fn name(&self) -> &'static str {
346 EUCKR_NAME
347 }
348
349 fn decode(
350 &mut self,
351 src: &[u8],
352 dst: &mut String,
353 finish: bool,
354 ) -> Result<(usize, usize), DecodeError> {
355 self.decoder.decode(src, dst, finish)
356 }
357}
358
359pub struct EUCKREncoder {
360 encoder: EUCEncoder<u16, u16, u8, u8, u8, u8, 2, 1, 1>,
361}
362
363pub(crate) fn euckr_encoder_factory() -> Box<dyn Encoder> {
364 Box::new(EUCKREncoder {
365 encoder: EUCEncoder {
366 g1: ksx::KS_X_1001_ENCODE_TABLE,
367 g2: &[],
368 g3: &[],
369 },
370 })
371}
372
373impl Encoder for EUCKREncoder {
374 fn name(&self) -> &'static str {
375 EUCKR_NAME
376 }
377
378 fn encode(
379 &mut self,
380 src: &str,
381 dst: &mut [u8],
382 finish: bool,
383 ) -> Result<(usize, usize), EncodeError> {
384 self.encoder.encode(src, dst, finish)
385 }
386}
387
388#[cfg(test)]
389mod tests {
390 use super::*;
391
392 #[test]
393 fn eucjp_katakana_tests() {
394 let bytes = &[
395 0x8e, 0xb1, 0x8e, 0xb2, 0x8e, 0xb3, 0x8e, 0xb4, 0x8e, 0xb5, 0x8e, 0xb6, 0x8e, 0xb7,
396 0x8e, 0xb8, 0x8e, 0xb9, 0x8e, 0xba, 0x8e, 0xbb, 0x8e, 0xbc, 0x8e, 0xbd, 0x8e, 0xbe,
397 0x8e, 0xbf, 0x8e, 0xc0, 0x8e, 0xc1, 0x8e, 0xc2, 0x8e, 0xc3, 0x8e, 0xc4, 0x8e, 0xc5,
398 0x8e, 0xc6, 0x8e, 0xc7, 0x8e, 0xc8, 0x8e, 0xc9, 0x8e, 0xca, 0x8e, 0xcb, 0x8e, 0xcc,
399 0x8e, 0xcd, 0x8e, 0xce, 0x8e, 0xcf, 0x8e, 0xd0, 0x8e, 0xd1, 0x8e, 0xd2, 0x8e, 0xd3,
400 0x8e, 0xd4, 0x8e, 0xd5, 0x8e, 0xd6, 0x8e, 0xd7, 0x8e, 0xd8, 0x8e, 0xd9, 0x8e, 0xda,
401 0x8e, 0xdb, 0x8e, 0xdc, 0x8e, 0xa6, 0x8e, 0xdd,
402 ];
403 let mut buf = String::with_capacity(512);
404 eucjp_decoder_factory()
405 .decode(bytes, &mut buf, true)
406 .unwrap();
407 assert_eq!(buf, "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン");
408 }
409
410 #[test]
411 fn eucjp_kanji_tests() {
412 let bytes = &[
413 0xc4, 0xbf, 0xb9, 0xf1, 0xb2, 0xc8, 0xa5, 0xce, 0xce, 0xb4, 0xbe, 0xbb, 0xa5, 0xc8,
414 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xce, 0xb7, 0xc4, 0xca, 0xa1, 0xa5, 0xc8, 0xa5, 0xf2,
415 0xb0, 0xca, 0xa5, 0xc6, 0xc3, 0xe6, 0xbf, 0xb4, 0xa5, 0xce, 0xb6, 0xd5, 0xb1, 0xc9,
416 0xa5, 0xc8, 0xa5, 0xb7, 0xc4, 0xbf, 0xa5, 0xab, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xcb,
417 0xbe, 0xb5, 0xa5, 0xaf, 0xa5, 0xeb, 0xa5, 0xce, 0xc2, 0xe7, 0xb8, 0xa2, 0xa5, 0xcb,
418 0xb0, 0xcd, 0xa5, 0xea, 0xb8, 0xbd, 0xba, 0xdf, 0xb5, 0xda, 0xbe, 0xad, 0xcd, 0xe8,
419 0xa5, 0xce, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xcb, 0xc2, 0xd0, 0xa5, 0xb7, 0xba, 0xa1,
420 0xa5, 0xce, 0xc9, 0xd4, 0xcb, 0xe1, 0xa5, 0xce, 0xc2, 0xe7, 0xc5, 0xb5, 0xa5, 0xf2,
421 0xc0, 0xeb, 0xc9, 0xdb, 0xa5, 0xb9, 0x0a, 0xb0, 0xd4, 0xa5, 0xd5, 0xa5, 0xcb, 0xb2,
422 0xe6, 0xa5, 0xab, 0xc1, 0xc4, 0xb2, 0xe6, 0xa5, 0xab, 0xbd, 0xa1, 0xa5, 0xcf, 0xb2,
423 0xe6, 0xa5, 0xab, 0xbf, 0xc3, 0xcc, 0xb1, 0xc1, 0xc4, 0xc0, 0xe8, 0xa5, 0xce, 0xb6,
424 0xa8, 0xce, 0xcf, 0xca, 0xe5, 0xcd, 0xe3, 0xa5, 0xcb, 0xd0, 0xe1, 0xa5, 0xea, 0xb2,
425 0xe6, 0xa5, 0xab, 0xc4, 0xeb, 0xb9, 0xf1, 0xa5, 0xf2, 0xc8, 0xa5, 0xc2, 0xa4, 0xa5,
426 0xb7, 0xb0, 0xca, 0xa5, 0xc6, 0xcc, 0xb5, 0xb5, 0xe7, 0xa5, 0xcb, 0xbf, 0xe2, 0xa5,
427 0xec, 0xa5, 0xbf, 0xa5, 0xea, 0xba, 0xa1, 0xa5, 0xec, 0xb2, 0xe6, 0xa5, 0xab, 0xbf,
428 0xc0, 0xc0, 0xbb, 0xa5, 0xca, 0xa5, 0xeb, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xce, 0xb0,
429 0xd2, 0xc6, 0xc1, 0xa5, 0xc8, 0xca, 0xc2, 0xa5, 0xcb, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5,
430 0xce, 0xc3, 0xe9, 0xbc, 0xc2, 0xcd, 0xa6, 0xc9, 0xf0, 0xa5, 0xcb, 0xa5, 0xb7, 0xa5,
431 0xc6, 0xb9, 0xf1, 0xa5, 0xf2, 0xb0, 0xa6, 0xa5, 0xb7, 0xb8, 0xf8, 0xa5, 0xcb, 0xbd,
432 0xde, 0xa5, 0xd2, 0xb0, 0xca, 0xa5, 0xc6, 0xba, 0xa1, 0xa5, 0xce, 0xb8, 0xf7, 0xb5,
433 0xb1, 0xa5, 0xa2, 0xa5, 0xeb, 0xb9, 0xf1, 0xbb, 0xcb, 0xa5, 0xce, 0xc0, 0xae, 0xc0,
434 0xd7, 0xa5, 0xf2, 0xec, 0xc6, 0xa5, 0xb7, 0xa5, 0xbf, 0xa5, 0xeb, 0xa5, 0xca, 0xa5,
435 0xea, 0xc4, 0xbf, 0xb2, 0xe6, 0xa5, 0xab, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xcf, 0xc2,
436 0xa8, 0xa5, 0xc1, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xce, 0xc3, 0xe9, 0xce, 0xc9, 0xa5,
437 0xca, 0xa5, 0xeb, 0xbf, 0xc3, 0xcc, 0xb1, 0xa5, 0xce, 0xbb, 0xd2, 0xc2, 0xb9, 0xa5,
438 0xca, 0xa5, 0xeb, 0xa5, 0xf2, 0xb2, 0xf3, 0xc1, 0xdb, 0xa5, 0xb7, 0xc2, 0xb6, 0xa5,
439 0xce, 0xc4, 0xbf, 0xa5, 0xab, 0xb0, 0xd5, 0xa5, 0xf2, 0xca, 0xf4, 0xc2, 0xce, 0xa5,
440 0xb7, 0xc4, 0xbf, 0xa5, 0xab, 0xbb, 0xf6, 0xa5, 0xf2, 0xbe, 0xa9, 0xbd, 0xe7, 0xa5,
441 0xb7, 0xc1, 0xea, 0xcd, 0xbf, 0xa5, 0xcb, 0xcf, 0xc2, 0xc3, 0xef, 0xb6, 0xa8, 0xc6,
442 0xb1, 0xa5, 0xb7, 0xb1, 0xd7, 0xa1, 0xb9, 0xb2, 0xe6, 0xa5, 0xab, 0xc4, 0xeb, 0xb9,
443 0xf1, 0xa5, 0xce, 0xb8, 0xf7, 0xb1, 0xc9, 0xa5, 0xf2, 0xc3, 0xe6, 0xb3, 0xb0, 0xa5,
444 0xcb, 0xc0, 0xeb, 0xcd, 0xc8, 0xa5, 0xb7, 0xc1, 0xc4, 0xbd, 0xa1, 0xa5, 0xce, 0xb0,
445 0xe4, 0xb6, 0xc8, 0xa5, 0xf2, 0xb1, 0xca, 0xb5, 0xd7, 0xa5, 0xcb, 0xf0, 0xdf, 0xb8,
446 0xc7, 0xa5, 0xca, 0xa5, 0xe9, 0xa5, 0xb7, 0xa5, 0xe0, 0xa5, 0xeb, 0xa5, 0xce, 0xb4,
447 0xf5, 0xcb, 0xbe, 0xa5, 0xf2, 0xc6, 0xb1, 0xa5, 0xaf, 0xa5, 0xb7, 0xba, 0xa1, 0xa5,
448 0xce, 0xc9, 0xe9, 0xc3, 0xb4, 0xa5, 0xf2, 0xca, 0xac, 0xa5, 0xc4, 0xa5, 0xcb, 0xb4,
449 0xae, 0xa5, 0xd5, 0xa5, 0xeb, 0xa5, 0xb3, 0xa5, 0xc8, 0xa5, 0xf2, 0xb5, 0xbf, 0xa5,
450 0xcf, 0xa5, 0xb5, 0xa5, 0xeb, 0xa5, 0xca, 0xa5, 0xea,
451 ];
452
453 let mut buf = String::with_capacity(1024);
454 let (read, _) = eucjp_decoder_factory()
455 .decode(bytes, &mut buf, true)
456 .unwrap();
457 assert_eq!(read, bytes.len());
458 assert_eq!(
459 buf,
460 "朕国家ノ隆昌ト臣民ノ慶福トヲ以テ中心ノ欣栄トシ朕カ祖宗ニ承クルノ大権ニ依リ現在及将来ノ臣民ニ対シ此ノ不磨ノ大典ヲ宣布ス\n惟フニ我カ祖我カ宗ハ我カ臣民祖先ノ協力輔翼ニ倚リ我カ帝国ヲ肇造シ以テ無窮ニ垂レタリ此レ我カ神聖ナル祖宗ノ威徳ト並ニ臣民ノ忠実勇武ニシテ国ヲ愛シ公ニ殉ヒ以テ此ノ光輝アル国史ノ成跡ヲ貽シタルナリ朕我カ臣民ハ即チ祖宗ノ忠良ナル臣民ノ子孫ナルヲ回想シ其ノ朕カ意ヲ奉体シ朕カ事ヲ奨順シ相与ニ和衷協同シ益々我カ帝国ノ光栄ヲ中外ニ宣揚シ祖宗ノ遺業ヲ永久ニ鞏固ナラシムルノ希望ヲ同クシ此ノ負担ヲ分ツニ堪フルコトヲ疑ハサルナリ"
461 );
462 }
463
464 #[test]
465 fn euckr_kanji_hangul_tests() {
466 let bytes = &[
467 0xea, 0xed, 0xce, 0xf9, 0xc7, 0xd1, 0x20, 0xd5, 0xf6, 0xde, 0xc8, 0xbf, 0xcd, 0x20,
468 0xee, 0xee, 0xf7, 0xd6, 0xbf, 0xa1, 0x20, 0xba, 0xfb, 0xb3, 0xaa, 0xb4, 0xc2, 0x20,
469 0xbf, 0xec, 0xb8, 0xae, 0x20, 0xd3, 0xde, 0xf9, 0xdb, 0xcf, 0xd0, 0xda, 0xc5, 0xc0,
470 0xba, 0x20, 0x33, 0xa1, 0xa4, 0x31, 0x20, 0xea, 0xa1, 0xd4, 0xd1, 0xc0, 0xb8, 0xb7,
471 0xce, 0x20, 0xcb, 0xef, 0xd8, 0xa1, 0xb5, 0xc8, 0x20, 0xd3, 0xde, 0xf9, 0xdb, 0xda,
472 0xc5, 0xcf, 0xd0, 0xd7, 0xfc, 0xe3, 0xc1, 0xef, 0xd9, 0xdd, 0xa4, 0xc0, 0xc7, 0x20,
473 0xdb, 0xf6, 0xf7, 0xd6, 0xb0, 0xfa, 0x20, 0xdc, 0xf4, 0xeb, 0xf9, 0xbf, 0xa1, 0x20,
474 0xf9, 0xf7, 0xcb, 0xde, 0xc7, 0xd1, 0x20, 0x34, 0xa1, 0xa4, 0x31, 0x39, 0x20, 0xda,
475 0xc5, 0xf1, 0xab, 0xd7, 0xe2, 0xd2, 0xb7, 0xc0, 0xbb, 0x20, 0xcd, 0xa9, 0xe3, 0xaf,
476 0xc7, 0xcf, 0xb0, 0xed, 0x2c, 0x20, 0xf0, 0xd3, 0xcf, 0xd0, 0xc0, 0xc7, 0x20, 0xda,
477 0xc5, 0xf1, 0xab, 0xcb, 0xc7, 0xfa, 0xd4, 0xb0, 0xfa, 0x20, 0xf8, 0xc1, 0xfb, 0xfa,
478 0xee, 0xdc, 0xf7, 0xd6, 0xec, 0xe9, 0xc0, 0xc7, 0x20, 0xde, 0xc5, 0xd9, 0xa4, 0xbf,
479 0xa1, 0x20, 0xd8, 0xa1, 0xca, 0xc5, 0xc7, 0xcf, 0xbf, 0xa9, 0x20, 0xef, 0xe1, 0xeb,
480 0xf9, 0xa1, 0xa4, 0xec, 0xd1, 0xd4, 0xb3, 0xbf, 0xcd, 0x20, 0xd4, 0xd2, 0xf8, 0xe0,
481 0xe4, 0xf1, 0xb7, 0xce, 0xbd, 0xe1, 0x20, 0xda, 0xc5, 0xf0, 0xe9, 0xc0, 0xc7, 0x20,
482 0xd3, 0xa5, 0xcc, 0xbf, 0xc0, 0xbb, 0x20, 0xcd, 0xf9, 0xcd, 0xb3, 0xc8, 0xf7, 0x20,
483 0xc7, 0xcf, 0xb0, 0xed, 0x2c, 0x20, 0xb8, 0xf0, 0xb5, 0xe7, 0x20, 0xde, 0xe4, 0xfc,
484 0xe5, 0xee, 0xdc, 0xf8, 0xc9, 0xe3, 0xa7, 0xb0, 0xfa, 0x20, 0xdc, 0xf4, 0xeb, 0xf9,
485 0xb8, 0xa6, 0x20, 0xf6, 0xe8, 0xf7, 0xf2, 0xc7, 0xcf, 0xb8, 0xe7, 0x2c, 0x20, 0xed,
486 0xbb, 0xd7, 0xc8, 0xb0, 0xfa, 0x20, 0xf0, 0xe0, 0xfb, 0xfa, 0xb8, 0xa6, 0x20, 0xb9,
487 0xd9, 0xc5, 0xc1, 0xc0, 0xb8, 0xb7, 0xce, 0x20, 0xed, 0xbb, 0xeb, 0xa6, 0xda, 0xc5,
488 0xf1, 0xab, 0xee, 0xdc, 0xd0, 0xf1, 0xdc, 0xe2, 0xf2, 0xf1, 0xdf, 0xed, 0xb8, 0xa6,
489 0x20, 0xb4, 0xf5, 0xbf, 0xed, 0x20, 0xfc, 0xac, 0xcd, 0xb3, 0xc8, 0xf7, 0x20, 0xc7,
490 0xcf, 0xbf, 0xa9, 0x20, 0xef, 0xd9, 0xf6, 0xbd, 0xa1, 0xa4, 0xcc, 0xe8, 0xf0, 0xad,
491 0xa1, 0xa4, 0xde, 0xe4, 0xfc, 0xe5, 0xa1, 0xa4, 0xd9, 0xfe, 0xfb, 0xf9, 0xc0, 0xc7,
492 0x20, 0xb8, 0xf0, 0xb5, 0xe7, 0x20, 0xd6, 0xc5, 0xe6, 0xb4, 0xbf, 0xa1, 0x20, 0xc0,
493 0xd6, 0xbe, 0xee, 0xbc, 0xad, 0x20, 0xca, 0xc0, 0xec, 0xd1, 0xc0, 0xc7, 0x20, 0xd1,
494 0xa6, 0xfc, 0xe5, 0xb8, 0xa6, 0x20, 0xd0, 0xb3, 0xd4, 0xf5, 0xc8, 0xf7, 0x20, 0xc7,
495 0xcf, 0xb0, 0xed, 0x2c, 0x20, 0xd2, 0xf6, 0xd5, 0xf4, 0xc0, 0xbb, 0x20, 0xf5, 0xcc,
496 0xcd, 0xd4, 0xd3, 0xf8, 0xb7, 0xce, 0x20, 0xdb, 0xa1, 0xfd, 0xc6, 0xc7, 0xcf, 0xb0,
497 0xd4, 0x20, 0xc7, 0xcf, 0xb8, 0xe7, 0x2c, 0x20, 0xed, 0xbb, 0xeb, 0xa6, 0xbf, 0xcd,
498 0x20, 0xcf, 0xed, 0xd7, 0xd7, 0xbf, 0xa1, 0x20, 0xb5, 0xfb, 0xb8, 0xa3, 0xb4, 0xc2,
499 0x20, 0xf4, 0xa1, 0xec, 0xf2, 0xb0, 0xfa, 0x20, 0xeb, 0xf9, 0xd9, 0xe2, 0xb8, 0xa6,
500 0x20, 0xe8, 0xc7, 0xe2, 0xc4, 0xc7, 0xcf, 0xb0, 0xd4, 0x20, 0xc7, 0xcf, 0xbf, 0xa9,
501 0x2c, 0x20, 0xbe, 0xc8, 0xc0, 0xb8, 0xb7, 0xce, 0xb4, 0xc2, 0x20, 0xcf, 0xd0, 0xda,
502 0xc5, 0xdf, 0xe6, 0xfc, 0xc0, 0xc0, 0xc7, 0x20, 0xd0, 0xb3, 0xd4, 0xf5, 0xc7, 0xd1,
503 0x20, 0xfa, 0xbe, 0xdf, 0xbe, 0xc0, 0xbb, 0x20, 0xd1, 0xa2, 0xc7, 0xcf, 0xb0, 0xed,
504 0x20, 0xb9, 0xdb, 0xc0, 0xb8, 0xb7, 0xce, 0xb4, 0xc2, 0x20, 0xf9, 0xf6, 0xce, 0xf9,
505 0xee, 0xdc, 0xc0, 0xce, 0x20, 0xe1, 0xa6, 0xcd, 0xa3, 0xf8, 0xc1, 0xfb, 0xfa, 0xbf,
506 0xcd, 0x20, 0xec, 0xd1, 0xd7, 0xbe, 0xcd, 0xec, 0xe7, 0xb4, 0xbf, 0xa1, 0x20, 0xc0,
507 0xcc, 0xb9, 0xd9, 0xc1, 0xf6, 0xc7, 0xd4, 0xc0, 0xb8, 0xb7, 0xce, 0xbd, 0xe1, 0x20,
508 0xbf, 0xec, 0xb8, 0xae, 0xb5, 0xe9, 0xb0, 0xfa, 0x20, 0xbf, 0xec, 0xb8, 0xae, 0xb5,
509 0xe9, 0xc0, 0xc7, 0x20, 0xed, 0xad, 0xe1, 0xdd, 0xc0, 0xc7, 0x20, 0xe4, 0xcc, 0xee,
510 0xef, 0xb0, 0xfa, 0x20, 0xed, 0xbb, 0xeb, 0xa6, 0xbf, 0xcd, 0x20, 0xfa, 0xb9, 0xdc,
511 0xd8, 0xc0, 0xbb, 0x20, 0xe7, 0xb5, 0xea, 0xc0, 0xc8, 0xf7, 0x20, 0xfc, 0xac, 0xdc,
512 0xc1, 0xc7, 0xd2, 0x20, 0xb0, 0xcd, 0xc0, 0xbb, 0x20, 0xb4, 0xd9, 0xc1, 0xfc, 0xc7,
513 0xcf, 0xb8, 0xe9, 0xbc, 0xad, 0x20, 0x31, 0x39, 0x34, 0x38, 0xd2, 0xb4, 0x20, 0x37,
514 0xea, 0xc5, 0x20, 0x31, 0x32, 0xec, 0xed, 0xbf, 0xa1, 0x20, 0xf0, 0xa4, 0xef, 0xd2,
515 0xb5, 0xc7, 0xb0, 0xed, 0x20, 0x38, 0xf3, 0xad, 0xbf, 0xa1, 0x20, 0xb0, 0xc9, 0xc3,
516 0xc4, 0x20, 0xcb, 0xc7, 0xef, 0xe1, 0xb5, 0xc8, 0x20, 0xfa, 0xca, 0xdb, 0xf6, 0xc0,
517 0xbb, 0x20, 0xc0, 0xcc, 0xc1, 0xa6, 0x20, 0xcf, 0xd0, 0xfc, 0xe5, 0xc0, 0xc7, 0x20,
518 0xec, 0xa1, 0xcc, 0xbd, 0xc0, 0xbb, 0x20, 0xb0, 0xc5, 0xc3, 0xc4, 0x20, 0xcf, 0xd0,
519 0xda, 0xc5, 0xf7, 0xe1, 0xf8, 0xf9, 0xbf, 0xa1, 0x20, 0xeb, 0xee, 0xc7, 0xcf, 0xbf,
520 0xa9, 0x20, 0xcb, 0xc7, 0xef, 0xe1, 0xc7, 0xd1, 0xb4, 0xd9, 0x2e,
521 ];
522
523 let mut buf = String::with_capacity(2048);
524 let (read, _) = euckr_decoder_factory()
525 .decode(bytes, &mut buf, true)
526 .unwrap();
527 assert_eq!(read, bytes.len());
528 assert_eq!(
529 buf,
530 "悠久한 歷史와 傳統에 빛나는 우리 大韓國民은 3·1 運動으로 建立된 大韓民國臨時政府의 法統과 不義에 抗拒한 4·19 民主理念을 繼承하고, 祖國의 民主改革과 平和的統一의 使命에 立脚하여 正義·人道와 同胞愛로써 民族의 團結을 鞏固히 하고, 모든 社會的弊習과 不義를 打破하며, 自律과 調和를 바탕으로 自由民主的基本秩序를 더욱 確固히 하여 政治·經濟·社會·文化의 모든 領域에 있어서 各人의 機會를 均等히 하고, 能力을 最高度로 發揮하게 하며, 自由와 權利에 따르는 責任과 義務를 完遂하게 하여, 안으로는 國民生活의 均等한 向上을 期하고 밖으로는 恒久的인 世界平和와 人類共榮에 이바지함으로써 우리들과 우리들의 子孫의 安全과 自由와 幸福을 永遠히 確保할 것을 다짐하면서 1948年 7月 12日에 制定되고 8次에 걸쳐 改正된 憲法을 이제 國會의 議決을 거쳐 國民投票에 依하여 改正한다."
531 );
532 }
533}