[msvc] Update csproj files (#4846)
[mono.git] / mcs / class / I18N / CJK / CP51932.cs
1 /*
2  * CP51932.cs - Japanese EUC-JP code page.
3  *
4  * It is based on CP932.cs from Portable.NET
5  *
6  * Author:
7  *      Atsushi Enomoto <atsushi@ximian.com>
8  *
9  * Below are original (CP932.cs) copyright lines
10  *
11  * (C)2004 Novell Inc.
12  *
13  * Copyright (c) 2002  Southern Storm Software, Pty Ltd
14  *
15  * Permission is hereby granted, free of charge, to any person obtaining
16  * a copy of this software and associated documentation files (the "Software"),
17  * to deal in the Software without restriction, including without limitation
18  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19  * and/or sell copies of the Software, and to permit persons to whom the
20  * Software is furnished to do so, subject to the following conditions:
21  *
22  * The above copyright notice and this permission notice shall be included
23  * in all copies or substantial portions of the Software.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31  * OTHER DEALINGS IN THE SOFTWARE.
32  */
33
34 /*
35
36         Well, there looks no jis.table source. Thus, it seems like it is 
37         generated from text files from Unicode Home Page such like
38         ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0208.TXT
39         However, it is non-normative and in Japan it is contains many problem.
40
41         FIXME:  Some characters such as 0xFF0B (wide "plus") are missing in
42                 that table.
43 */
44
45 /*
46         0x00-0x1F, 0x7F   : control characters
47         0x20-0x7E         : ASCII
48         0xA1A1-0xFEFE     : Kanji (precisely, both bytes contain only A1-FE)
49         0x8EA1-0x8EDF     : half-width Katakana
50         0x8FA1A1-0x8FFEFE : Complemental Kanji
51
52 */
53
54 namespace I18N.CJK
55 {
56
57 using System;
58 using System.Text;
59 using I18N.Common;
60
61 #if DISABLE_UNSAFE
62 using MonoEncoder = I18N.Common.MonoSafeEncoder;
63 using MonoEncoding = I18N.Common.MonoSafeEncoding;
64 #endif
65
66 [Serializable]
67 public class CP51932 : MonoEncoding
68 {
69         // Magic number used by Windows for the EUC-JP code page.
70         private const int EUC_JP_CODE_PAGE = 51932;
71
72         // Constructor.
73         public CP51932 () : base (EUC_JP_CODE_PAGE, 932)
74         {
75         }
76
77 #if !DISABLE_UNSAFE
78         public unsafe override int GetByteCountImpl (char* chars, int count)
79         {
80                 return new CP51932Encoder (this).GetByteCountImpl (chars, count, true);
81         }
82
83         public unsafe override int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount)
84         {
85                 return new CP51932Encoder (this).GetBytesImpl (chars, charCount, bytes, byteCount, true);
86         }
87 #else
88         public override int GetByteCount (char [] chars, int index, int length)
89         {
90                 return new CP51932Encoder (this).GetByteCount (chars, index, length, true);
91         }
92
93         public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
94         {
95                 return new CP51932Encoder (this).GetBytes (chars, charIndex, charCount, bytes, byteIndex, true);
96         }
97 #endif
98
99         public override int GetCharCount (byte [] bytes, int index, int count)
100         {
101                 return new CP51932Decoder ().GetCharCount (
102                         bytes, index, count, true);
103         }
104
105         public override int GetChars (
106                 byte [] bytes, int byteIndex, int byteCount,
107                 char [] chars, int charIndex)
108         {
109                 return new CP51932Decoder ().GetChars (bytes,
110                         byteIndex, byteCount, chars, charIndex, true);
111         }
112
113         // Get the maximum number of bytes needed to encode a
114         // specified number of characters.
115         public override int GetMaxByteCount(int charCount)
116         {
117                 if(charCount < 0)
118                 {
119                         throw new ArgumentOutOfRangeException
120                                 ("charCount",
121                                  Strings.GetString("ArgRange_NonNegative"));
122                 }
123                 return charCount * 3;
124         }
125
126         // Get the maximum number of characters needed to decode a
127         // specified number of bytes.
128         public override int GetMaxCharCount(int byteCount)
129         {
130                 if(byteCount < 0)
131                 {
132                         throw new ArgumentOutOfRangeException
133                                 ("byteCount",
134                                  Strings.GetString ("ArgRange_NonNegative"));
135                 }
136                 return byteCount;
137         }
138
139         public override Encoder GetEncoder ()
140         {
141                 return new CP51932Encoder (this);
142         }
143
144         public override Decoder GetDecoder ()
145         {
146                 return new CP51932Decoder ();
147         }
148
149 #if !ECMA_COMPAT
150
151         // Get the mail body name for this encoding.
152         public override String BodyName {
153                 get { return "euc-jp"; }
154         }
155
156         // Get the human-readable name for this encoding.
157         public override String EncodingName {
158                 get { return "Japanese (EUC)"; }
159         }
160
161         // Get the mail agent header name for this encoding.
162         public override String HeaderName {
163                 get { return "euc-jp"; }
164         }
165
166         // Determine if this encoding can be displayed in a Web browser.
167         public override bool IsBrowserDisplay {
168                 get { return true; }
169         }
170
171         // Determine if this encoding can be saved from a Web browser.
172         public override bool IsBrowserSave {
173                 get { return true; }
174         }
175
176         // Determine if this encoding can be displayed in a mail/news agent.
177         public override bool IsMailNewsDisplay {
178                 get { return true; }
179         }
180
181         // Determine if this encoding can be saved from a mail/news agent.
182         public override bool IsMailNewsSave {
183                 get { return true; }
184         }
185
186         // Get the IANA-preferred Web name for this encoding.
187         public override String WebName {
188                 get { return "euc-jp"; }
189         }
190 } // CP51932
191 #endif // !ECMA_COMPAT
192
193 public class CP51932Encoder : MonoEncoder
194 {
195         public CP51932Encoder (MonoEncoding encoding)
196                 : base (encoding)
197         {
198         }
199
200 #if !DISABLE_UNSAFE
201         // Get the number of bytes needed to encode a character buffer.
202         public unsafe override int GetByteCountImpl (
203                 char* chars, int count, bool refresh)
204         {
205                 // Determine the length of the final output.
206                 int index = 0;
207                 int length = 0;
208                 int ch, value;
209                 byte [] cjkToJis = JISConvert.Convert.cjkToJis;
210                 byte [] extraToJis = JISConvert.Convert.extraToJis;
211
212                 while (count > 0) {
213                         ch = chars [index++];
214                         --count;
215                         ++length;
216                         if (ch < 0x0080) {
217                                 // Character maps to itself.
218                                 continue;
219                         } else if (ch < 0x0100) {
220                                 // Check for special Latin 1 characters that
221                                 // can be mapped to double-byte code points.
222                                 if(ch == 0x00A2 || ch == 0x00A3 || ch == 0x00A7 ||
223                                    ch == 0x00A8 || ch == 0x00AC || ch == 0x00B0 ||
224                                    ch == 0x00B1 || ch == 0x00B4 || ch == 0x00B6 ||
225                                    ch == 0x00D7 || ch == 0x00F7)
226                                 {
227                                         ++length;
228                                 }
229                         } else if (ch >= 0x0391 && ch <= 0x0451) {
230                                 // Greek subset characters.
231                                 ++length;
232                         } else if (ch >= 0x2010 && ch <= 0x9FA5) {
233                                 // This range contains the bulk of the CJK set.
234                                 value = (ch - 0x2010) * 2;
235                                 value = ((int) (cjkToJis[value])) | (((int)(cjkToJis[value + 1])) << 8);
236                                 if(value >= 0x0100)
237                                         ++length;
238                         } else if(ch >= 0xFF01 && ch < 0xFF60) {
239                                 // This range contains extra characters.
240                                 value = (ch - 0xFF01) * 2;
241                                 value = ((int)(extraToJis[value])) |
242                                                 (((int)(extraToJis[value + 1])) << 8);
243                                 if(value >= 0x0100)
244                                         ++length;
245                         } else if(ch >= 0xFF60 && ch <= 0xFFA0) {
246                                 ++length; // half-width kana
247                         }
248                 }
249
250                 // Return the length to the caller.
251                 return length;
252         }
253
254         // Get the bytes that result from encoding a character buffer.
255         public unsafe override int GetBytesImpl (
256                 char* chars, int charCount, byte* bytes, int byteCount, bool refresh)
257         {
258                 int charIndex = 0;
259                 int byteIndex = 0;
260                 int end = charCount;
261
262                 // Convert the characters into their byte form.
263                 int posn = byteIndex;
264                 int byteLength = byteCount;
265                 int ch, value;
266
267                 byte[] cjkToJis = JISConvert.Convert.cjkToJis;
268                 byte[] greekToJis = JISConvert.Convert.greekToJis;
269                 byte[] extraToJis = JISConvert.Convert.extraToJis;
270
271                 for (int i = charIndex; i < end; i++, charCount--) {
272                         ch = chars [i];
273                         if (posn >= byteLength) {
274                                 throw new ArgumentException (Strings.GetString ("Arg_InsufficientSpace"), "bytes");
275                         }
276
277                         if (ch < 0x0080) {
278                                 // Character maps to itself.
279                                 bytes[posn++] = (byte)ch;
280                                 continue;
281                         } else if (ch >= 0x0391 && ch <= 0x0451) {
282                                 // Greek subset characters.
283                                 value = (ch - 0x0391) * 2;
284                                 value = ((int)(greekToJis[value])) |
285                                                 (((int)(greekToJis[value + 1])) << 8);
286                         } else if (ch >= 0x2010 && ch <= 0x9FA5) {
287                                 // This range contains the bulk of the CJK set.
288                                 value = (ch - 0x2010) * 2;
289                                 value = ((int) (cjkToJis[value])) |
290                                                 (((int)(cjkToJis[value + 1])) << 8);
291                         } else if (ch >= 0xFF01 && ch <= 0xFF60) {
292                                 // This range contains extra characters,
293                                 // including half-width katakana.
294                                 value = (ch - 0xFF01) * 2;
295                                 value = ((int) (extraToJis [value])) |
296                                                 (((int) (extraToJis [value + 1])) << 8);
297                         } else if (ch >= 0xFF60 && ch <= 0xFFA0) {
298                                 value = ch - 0xFF60 + 0x8EA0;
299                         } else {
300                                 // Invalid character.
301                                 value = 0;
302                         }
303
304                         if (value == 0) {
305                                 HandleFallback (
306                                         chars, ref i, ref charCount,
307                                         bytes, ref posn, ref byteCount, null);
308                         } else if (value < 0x0100) {
309                                 bytes [posn++] = (byte) value;
310                         } else if ((posn + 1) >= byteLength) {
311                                 throw new ArgumentException (Strings.GetString ("Arg_InsufficientSpace"), "bytes");
312                         } else if (value < 0x8000) {
313                                 // general 2byte glyph/kanji
314                                 value -= 0x0100;
315                                 bytes [posn++] = (byte) (value / 0x5E + 0xA1);
316                                 bytes [posn++] = (byte) (value % 0x5E + 0xA1);
317 //Console.WriteLine ("{0:X04}", ch);
318                                 continue;
319                         }
320                         else
321                         {
322                                 // half-width kana
323                                 bytes [posn++] = 0x8E;
324                                 bytes [posn++] = (byte) (value - 0x8E00);
325                         }
326                 }
327
328                 // Return the final length to the caller.
329                 return posn - byteIndex;
330         }
331 #else
332         // Get the number of bytes needed to encode a character buffer.
333         public override int GetByteCount(char[] chars, int index, int count, bool flush)
334         {
335                 // Determine the length of the final output.
336                 int length = 0;
337                 int ch, value;
338                 byte[] cjkToJis = JISConvert.Convert.cjkToJis;
339                 byte[] extraToJis = JISConvert.Convert.extraToJis;
340
341                 while (count > 0)
342                 {
343                         ch = chars[index++];
344                         --count;
345                         ++length;
346                         if (ch < 0x0080)
347                         {
348                                 // Character maps to itself.
349                                 continue;
350                         }
351                         else if (ch < 0x0100)
352                         {
353                                 // Check for special Latin 1 characters that
354                                 // can be mapped to double-byte code points.
355                                 if (ch == 0x00A2 || ch == 0x00A3 || ch == 0x00A7 ||
356                                    ch == 0x00A8 || ch == 0x00AC || ch == 0x00B0 ||
357                                    ch == 0x00B1 || ch == 0x00B4 || ch == 0x00B6 ||
358                                    ch == 0x00D7 || ch == 0x00F7)
359                                 {
360                                         ++length;
361                                 }
362                         }
363                         else if (ch >= 0x0391 && ch <= 0x0451)
364                         {
365                                 // Greek subset characters.
366                                 ++length;
367                         }
368                         else if (ch >= 0x2010 && ch <= 0x9FA5)
369                         {
370                                 // This range contains the bulk of the CJK set.
371                                 value = (ch - 0x2010) * 2;
372                                 value = ((int)(cjkToJis[value])) | (((int)(cjkToJis[value + 1])) << 8);
373                                 if (value >= 0x0100)
374                                         ++length;
375                         }
376                         else if (ch >= 0xFF01 && ch < 0xFF60)
377                         {
378                                 // This range contains extra characters.
379                                 value = (ch - 0xFF01) * 2;
380                                 value = ((int)(extraToJis[value])) |
381                                                 (((int)(extraToJis[value + 1])) << 8);
382                                 if (value >= 0x0100)
383                                         ++length;
384                         }
385                         else if (ch >= 0xFF60 && ch <= 0xFFA0)
386                         {
387                                 ++length; // half-width kana
388                         }
389                 }
390
391                 // Return the length to the caller.
392                 return length;
393         }
394
395         // Get the bytes that result from encoding a character buffer.
396         public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex, bool flush)
397         {
398                 // Convert the characters into their byte form.
399                 int posn = byteIndex;
400                 int byteLength = bytes.Length;
401                 int byteCount = bytes.Length;
402                 int end = charIndex + charCount;
403                 int ch, value;
404
405                 byte[] cjkToJis = JISConvert.Convert.cjkToJis;
406                 byte[] greekToJis = JISConvert.Convert.greekToJis;
407                 byte[] extraToJis = JISConvert.Convert.extraToJis;
408
409                 for (int i = charIndex; i < end; i++, charCount--)
410                 {
411                         ch = chars[i];
412                         if (posn >= byteLength)
413                         {
414                                 throw new ArgumentException(Strings.GetString("Arg_InsufficientSpace"), "bytes");
415                         }
416
417                         if (ch < 0x0080)
418                         {
419                                 // Character maps to itself.
420                                 bytes[posn++] = (byte)ch;
421                                 continue;
422                         }
423                         else if (ch >= 0x0391 && ch <= 0x0451)
424                         {
425                                 // Greek subset characters.
426                                 value = (ch - 0x0391) * 2;
427                                 value = ((int)(greekToJis[value])) |
428                                                 (((int)(greekToJis[value + 1])) << 8);
429                         }
430                         else if (ch >= 0x2010 && ch <= 0x9FA5)
431                         {
432                                 // This range contains the bulk of the CJK set.
433                                 value = (ch - 0x2010) * 2;
434                                 value = ((int)(cjkToJis[value])) |
435                                                 (((int)(cjkToJis[value + 1])) << 8);
436                         }
437                         else if (ch >= 0xFF01 && ch <= 0xFF60)
438                         {
439                                 // This range contains extra characters,
440                                 // including half-width katakana.
441                                 value = (ch - 0xFF01) * 2;
442                                 value = ((int)(extraToJis[value])) |
443                                                 (((int)(extraToJis[value + 1])) << 8);
444                         }
445                         else if (ch >= 0xFF60 && ch <= 0xFFA0)
446                         {
447                                 value = ch - 0xFF60 + 0x8EA0;
448                         }
449                         else
450                         {
451                                 // Invalid character.
452                                 value = 0;
453                         }
454
455                         if (value == 0)
456                         {
457                                 HandleFallback (chars, ref i, ref charCount,
458                                         bytes, ref posn, ref byteCount, null);
459                         }
460                         else if (value < 0x0100)
461                         {
462                                 bytes[posn++] = (byte)value;
463                         }
464                         else if ((posn + 1) >= byteLength)
465                         {
466                                 throw new ArgumentException(Strings.GetString("Arg_InsufficientSpace"), "bytes");
467                         }
468                         else if (value < 0x8000)
469                         {
470                                 // general 2byte glyph/kanji
471                                 value -= 0x0100;
472                                 bytes[posn++] = (byte)(value / 0x5E + 0xA1);
473                                 bytes[posn++] = (byte)(value % 0x5E + 0xA1);
474                                 //Console.WriteLine ("{0:X04}", ch);
475                                 continue;
476                         }
477                         else
478                         {
479                                 // half-width kana
480                                 bytes[posn++] = 0x8E;
481                                 bytes[posn++] = (byte)(value - 0x8E00);
482                         }
483                 }
484
485                 // Return the final length to the caller.
486                 return posn - byteIndex;
487         }
488 #endif
489 } // CP51932Encoder
490
491 internal class CP51932Decoder : DbcsEncoding.DbcsDecoder
492 {
493         public CP51932Decoder ()
494                 : base (null)
495         {
496         }
497
498         int last_count, last_bytes;
499
500         // Get the number of characters needed to decode a byte buffer.
501         public override int GetCharCount (byte [] bytes, int index, int count)
502         {
503                 return GetCharCount (bytes, index, count, false);
504         }
505
506         public override
507         int GetCharCount (byte [] bytes, int index, int count, bool refresh)
508         {
509                 CheckRange (bytes, index, count);
510
511                 // Determine the total length of the converted string.
512                 int value = 0;
513                 byte[] table0208 = JISConvert.Convert.jisx0208ToUnicode;
514                 byte[] table0212 = JISConvert.Convert.jisx0212ToUnicode;
515                 int length = 0;
516                 int byteval = 0;
517                 int last = last_count;
518
519                 while (count > 0) {
520                         byteval = bytes [index++];
521                         --count;
522                         if (last == 0) {
523                                 if (byteval == 0x8F) {
524                                         // SS3: One-time triple-byte sequence should follow.
525                                         last = byteval;
526                                 } else if (byteval <= 0x7F) {
527                                         // Ordinary ASCII/Latin1/Control character.
528                                         length++;
529                                 } else if (byteval == 0x8E) {
530                                         // SS2: One-time double-byte sequence should follow.
531                                         last = byteval;
532                                 } else if (byteval >= 0xA1 && byteval <= 0xFE) {
533                                         // First byte in a double-byte sequence.
534                                         last = byteval;
535                                 } else {
536                                         // Invalid first byte.
537                                         length++;
538                                 }
539                         }
540                         else if (last == 0x8E) {
541                                 // SS2 (One-time double-byte sequence)
542                                 if (byteval >= 0xA1 && byteval <= 0xDF) {
543                                         length++;
544                                 } else {
545                                         // Invalid second byte.
546                                         length++;
547                                 }
548                                 last =0;
549                         }
550                         else if (last == 0x8F) {
551                                 // SS3: 3-byte character
552                                 // FIXME: not supported (I don't think iso-2022-jp has)
553                                 last = byteval;
554                         }
555                         else
556                         {
557                                 // Second byte in a double-byte sequence.
558                                 value = (last - 0xA1) * 0x5E;
559                                 last = 0;
560                                 if (byteval >= 0xA1 && byteval <= 0xFE)
561                                 {
562                                         value += (byteval - 0xA1);
563                                 }
564                                 else
565                                 {
566                                         // Invalid second byte.
567                                         last = 0;
568                                         length++;
569                                         continue;
570                                 }
571
572                                 value *= 2;
573                                 value = ((int) (table0208 [value]))
574                                         | (((int) (table0208 [value + 1])) << 8);
575                                 if (value == 0)
576                                         value = ((int) (table0212 [value]))
577                                                 | (((int) (table0212 [value + 1])) << 8);
578                                 if (value != 0)
579                                         length++;
580                                 else
581                                         length++;
582                         }
583                 }
584
585                 // seems like .NET 2.0 adds \u30FB for insufficient
586                 // byte seuqence (for Japanese \u30FB makes sense).
587                 if (refresh && last != 0)
588                         length++;
589                 else
590                         last_count = last;
591
592                 // Return the final length to the caller.
593                 return length;
594         }
595
596         public override int GetChars (byte[] bytes, int byteIndex,
597                                                  int byteCount, char[] chars,
598                                                  int charIndex)
599         {
600                 return GetChars (bytes, byteIndex, byteCount, chars, charIndex, false);
601         }
602
603         public override
604         int GetChars (byte[] bytes, int byteIndex,
605                                                  int byteCount, char[] chars,
606                                                  int charIndex, bool refresh)
607         {
608                 CheckRange (bytes, byteIndex, byteCount, chars, charIndex);
609
610                 // Decode the bytes in the buffer.
611                 int posn = charIndex;
612                 int charLength = chars.Length;
613                 int byteval, value;
614                 int last = last_bytes;
615                 byte[] table0208 = JISConvert.Convert.jisx0208ToUnicode;
616                 byte[] table0212 = JISConvert.Convert.jisx0212ToUnicode;
617
618                 while (byteCount > 0) {
619                         byteval = bytes [byteIndex++];
620                         --byteCount;
621                         if (last == 0) {
622                                 if (byteval == 0x8F) {
623                                         // SS3 (One-time triple-byte sequence) should follow.
624                                         last = byteval;
625                                 } else if (byteval <= 0x7F) {
626                                         // Ordinary ASCII/Latin1/Control character.
627                                         if (posn >= charLength)
628                                                 throw Insufficient ();
629                                         chars [posn++] = (char) byteval;
630                                 } else if (byteval == 0x8E) {
631                                         // SS2 (One-time double-byte sequence) should follow.
632                                         last = byteval;
633                                 } else if (byteval >= 0xA1 && byteval <= 0xFE) {
634                                         // First byte in a double-byte sequence.
635                                         last = byteval;
636                                 } else {
637                                         // Invalid first byte.
638                                         if (posn >= charLength)
639                                                 throw Insufficient ();
640                                         chars [posn++] = '\u30FB';
641                                 }
642                         }
643                         else if (last == 0x8E) {
644                                 // SS2 (One-time double-byte sequence)
645                                 if (byteval >= 0xA1 && byteval <= 0xDF) {
646                                         value = ((byteval - 0x40) |
647                                                 (last + 0x71) << 8);
648                                         if (posn >= charLength)
649                                                 throw Insufficient ();
650                                         chars [posn++] = (char) value;
651                                 } else {
652                                         // Invalid second byte.
653                                         if (posn >= charLength)
654                                                 throw Insufficient ();
655                                         chars [posn++] = '\u30FB';
656                                 }
657                                 last =0;
658                         }
659                         else if (last == 0x8F) {
660                                 // SS3: 3-byte character
661                                 // FIXME: not supported (I don't think iso-2022-jp has)
662                                 last = byteval;
663                         }
664                         else
665                         {
666                                 // Second byte in a double-byte sequence.
667                                 value = (last - 0xA1) * 0x5E;
668                                 last = 0;
669                                 if (byteval >= 0xA1 && byteval <= 0xFE)
670                                 {
671                                         value += (byteval - 0xA1);
672                                 }
673                                 else
674                                 {
675                                         // Invalid second byte.
676                                         last = 0;
677                                         if (posn >= charLength)
678                                                 throw Insufficient ();
679                                         chars [posn++] = '\u30FB';
680                                         continue;
681                                 }
682
683                                 value *= 2;
684                                 value = ((int) (table0208 [value]))
685                                         | (((int) (table0208 [value + 1])) << 8);
686                                 if (value == 0)
687                                         value = ((int) (table0212 [value]))
688                                                 | (((int) (table0212 [value + 1])) << 8);
689                                 if (posn >= charLength)
690                                         throw Insufficient ();
691                                 if (value != 0)
692                                         chars [posn++] = (char)value;
693                                 else
694                                         chars [posn++] = '\u30FB';
695                         }
696                 }
697
698                 if (refresh && last != 0) {
699                         // seems like .NET 2.0 adds \u30FB for insufficient
700                         // byte seuqence (for Japanese \u30FB makes sense).
701                         if (posn >= charLength)
702                                 throw Insufficient ();
703                         chars [posn++] = '\u30FB';
704                 }
705                 else
706                         last_bytes = last;
707
708                 // Return the final length to the caller.
709                 return posn - charIndex;
710         }
711
712         Exception Insufficient ()
713         {
714                 throw new ArgumentException
715                         (Strings.GetString
716                                 ("Arg_InsufficientSpace"), "chars");
717         }
718 }; // class CP51932Decoder
719
720 [Serializable]
721 public class ENCeuc_jp : CP51932
722 {
723         public ENCeuc_jp () : base() {}
724
725 }; // class ENCeucjp
726
727 }; // namespace I18N.CJK