[msvc] Update csproj files (#4846)
[mono.git] / mcs / class / I18N / CJK / CP950.cs
1 //
2 // I18N.CJK.CP950
3 //
4 // Author:
5 //   Alan Tam Siu Lung (Tam@SiuLung.com)
6 //   Atsushi Enomoto  <atsushi@ximian.com>
7 //
8
9 using System;
10 using System.Text;
11 using I18N.Common;
12
13 namespace I18N.CJK
14 {
15         [Serializable]
16         internal class CP950 : DbcsEncoding
17         {
18                 // Magic number used by Windows for the Big5 code page.
19                 private const int BIG5_CODE_PAGE = 950;
20                 
21                 // Constructor.
22                 public CP950() : base(BIG5_CODE_PAGE) {
23                 }
24
25                 internal override DbcsConvert GetConvert ()
26                 {
27                         return DbcsConvert.Big5;
28                 }
29
30 #if !DISABLE_UNSAFE
31                 // Get the bytes that result from encoding a character buffer.
32                 public unsafe override int GetByteCountImpl (char* chars, int count)
33                 {
34                         DbcsConvert convert = GetConvert ();
35                         int index = 0;
36                         int length = 0;
37
38                         while (count-- > 0) {
39                                 char c = chars[index++];
40                                 if (c <= 0x80 || c == 0xFF) { // ASCII
41                                         length++;
42                                         continue;
43                                 }
44                                 byte b1 = convert.u2n[((int)c) * 2 + 1];
45                                 byte b2 = convert.u2n[((int)c) * 2];
46                                 if (b1 == 0 && b2 == 0) {
47                                         // FIXME: handle fallback for GetByteCountImpl().
48                                         length++;
49                                 }
50                                 else
51                                         length += 2;
52                         }
53                         return length;
54                 }
55
56                 // Get the bytes that result from encoding a character buffer.
57                 public unsafe override int GetBytesImpl (char* chars, int charCount,
58                                              byte* bytes, int byteCount)
59                 {
60                         DbcsConvert convert = GetConvert ();
61                         int charIndex = 0;
62                         int byteIndex = 0;
63                         int end = charCount;
64                         EncoderFallbackBuffer buffer = null;
65
66                         int origIndex = byteIndex;
67                         for (int i = charIndex; i < end; i++, charCount--) 
68                         {
69                                 char c = chars[i];
70                                 if (c <= 0x80 || c == 0xFF) { // ASCII
71                                         bytes[byteIndex++] = (byte)c;
72                                         continue;
73                                 }
74                                 byte b1 = convert.u2n[((int)c) * 2 + 1];
75                                 byte b2 = convert.u2n[((int)c) * 2];
76                                 if (b1 == 0 && b2 == 0) {
77                                         HandleFallback (ref buffer, chars,
78                                                 ref i, ref charCount,
79                                                 bytes, ref byteIndex, ref byteCount, null);
80                                 } else {
81                                         bytes[byteIndex++] = b1;
82                                         bytes[byteIndex++] = b2;
83                                 }
84                         }
85                         return byteIndex - origIndex;
86                 }
87 #else
88                 // Get the bytes that result from encoding a character buffer.
89                 public override int GetByteCount(char[] chars, int index, int count)
90                 {
91                         DbcsConvert convert = GetConvert();
92                         int length = 0;
93
94                         while (count-- > 0)
95                         {
96                                 char c = chars[index++];
97                                 if (c <= 0x80 || c == 0xFF)
98                                 { // ASCII
99                                         length++;
100                                         continue;
101                                 }
102                                 byte b1 = convert.u2n[((int)c) * 2 + 1];
103                                 byte b2 = convert.u2n[((int)c) * 2];
104                                 if (b1 == 0 && b2 == 0)
105                                 {
106                                         // FIXME: handle fallback for GetByteCountImpl().
107                                         length++;
108                                 }
109                                 else
110                                         length += 2;
111                         }
112                         return length;
113                 }
114
115                 // Get the bytes that result from encoding a character buffer.
116                 public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
117                 {
118                         int byteCount = bytes.Length;
119                         int end = charIndex + charCount;
120
121                         DbcsConvert convert = GetConvert();
122                         EncoderFallbackBuffer buffer = null;
123
124                         int origIndex = byteIndex;
125                         for (int i = charIndex; i < end; i++, charCount--)
126                         {
127                                 char c = chars[i];
128                                 if (c <= 0x80 || c == 0xFF)
129                                 { // ASCII
130                                         bytes[byteIndex++] = (byte)c;
131                                         continue;
132                                 }
133                                 byte b1 = convert.u2n[((int)c) * 2 + 1];
134                                 byte b2 = convert.u2n[((int)c) * 2];
135                                 if (b1 == 0 && b2 == 0)
136                                 {
137                                         HandleFallback (ref buffer, chars, ref i, ref charCount,
138                                                 bytes, ref byteIndex, ref byteCount, null);
139                                 }
140                                 else
141                                 {
142                                         bytes[byteIndex++] = b1;
143                                         bytes[byteIndex++] = b2;
144                                 }
145                         }
146                         return byteIndex - origIndex;
147                 }
148 #endif
149                 // Get the characters that result from decoding a byte buffer.
150                 public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
151                                              char[] chars, int charIndex)
152                 {
153                         /*
154                         DbcsConvert convert = GetConvert ();
155                         // A1 40 - FA FF
156                         base.GetChars(bytes, byteIndex, byteCount, chars, charIndex);
157                         int origIndex = charIndex;
158                         int lastByte = 0;
159                         while (byteCount-- > 0) {
160                                 int b = bytes[byteIndex++];
161                                 if (lastByte == 0) {
162                                         if (b <= 0x80 || b == 0xFF) { // ASCII
163                                                 chars[charIndex++] = (char)b;
164                                         } else if (b < 0xA1 || b >= 0xFA) {
165                                                 // incorrect first byte.
166                                                 chars[charIndex++] = '?';
167                                                 byteCount--; // cut one more byte.
168                                         } else {
169                                                 lastByte = b;
170                                         }
171                                         continue;
172                                 }
173                                 int ord = ((lastByte - 0xA1) * 191 + b - 0x40) * 2;
174                                 char c1 = ord < 0 || ord > convert.n2u.Length ?
175                                         '\0' :
176                                         (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256);
177                                 if (c1 == 0)
178                                         chars[charIndex++] = '?';
179                                 else
180                                         chars[charIndex++] = c1;
181                                 lastByte = 0;
182                         }
183                         if (lastByte != 0)
184                                 chars[charIndex++] = '?';
185
186                         return charIndex - origIndex;
187                         */
188
189                         return GetDecoder ().GetChars (bytes, byteIndex, byteCount, chars, charIndex);
190                 }
191                 
192                 // Get a decoder that handles a rolling Big5 state.
193                 public override Decoder GetDecoder()
194                 {
195                         return new CP950Decoder(GetConvert ());
196                 }
197                 
198                 // Get the mail body name for this encoding.
199                 public override String BodyName
200                 {
201                         get { return "big5"; }
202                 }
203                 
204                 // Get the human-readable name for this encoding.
205                 public override String EncodingName
206                 {
207                         get { return "Chinese Traditional (Big5)"; }
208                 }
209                 
210                 // Get the mail agent header name for this encoding.
211                 public override String HeaderName
212                 {
213                         get { return "big5"; }
214                 }
215                 
216                 // Get the IANA-preferred Web name for this encoding.
217                 public override String WebName
218                 {
219                         get { return "big5"; }
220                 }
221                 
222                 /*
223                 // Get the Windows code page represented by this object.
224                 public override int WindowsCodePage
225                 {
226                         get { return BIG5_PAGE; }
227                 }
228                 */
229                 
230                 // Decoder that handles a rolling Big5 state.
231                 private sealed class CP950Decoder : DbcsDecoder
232                 {
233                         // Constructor.
234                         public CP950Decoder(DbcsConvert convert) : base(convert) {}
235                         int last_byte_count, last_byte_conv;
236
237                         public override int GetCharCount (byte[] bytes, int index, int count)
238                         {
239                                 return GetCharCount (bytes, index, count, false);
240                         }
241
242                         public override
243                         int GetCharCount (byte[] bytes, int index, int count, bool refresh)
244                         {
245                                 CheckRange (bytes, index, count);
246
247                                 int lastByte = last_byte_count;
248                                 last_byte_count = 0;
249                                 int length = 0;
250                                 while (count-- > 0) {
251                                         int b = bytes[index++];
252                                         if (lastByte == 0) {
253                                                 if (b <= 0x80 || b == 0xFF) { // ASCII
254                                                         length++;
255                                                 } else if (b < 0xA1 || b >= 0xFA) {
256                                                         // incorrect first byte.
257                                                         length++;
258                                                         count--; // cut one more byte.
259                                                 } else {
260                                                         lastByte = b;
261                                                 }
262                                                 continue;
263                                         }
264                                         int ord = ((lastByte - 0xA1) * 191 + b - 0x40) * 2;
265                                         char c1 = ord < 0 || ord > convert.n2u.Length ?
266                                                 '\0' :
267                                                 (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256);
268                                         if (c1 == 0)
269                                                 // FIXME: fallback
270                                                 length++;
271                                         else
272                                                 length++;
273                                         lastByte = 0;
274                                 }
275
276                                 if (lastByte != 0) {
277                                         if (refresh)
278                                                 // FIXME: fallback
279                                                 length++;
280                                         else
281                                                 last_byte_count = lastByte;
282                                 }
283                                 return length;
284                         }
285
286                         public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
287                                                      char[] chars, int charIndex)
288                         {
289                                 return GetChars (bytes, byteIndex, byteCount, chars, charIndex, false);
290                         }
291
292                         public override
293                         int GetChars(byte[] bytes, int byteIndex, int byteCount,
294                                                      char[] chars, int charIndex, bool refresh)
295                         {
296                                 CheckRange (bytes, byteIndex, byteCount, chars, charIndex);
297
298                                 int origIndex = charIndex;
299                                 int lastByte = last_byte_conv;
300                                 last_byte_conv = 0;
301                                 while (byteCount-- > 0) {
302                                         int b = bytes[byteIndex++];
303                                         if (lastByte == 0) {
304                                                 if (b <= 0x80 || b == 0xFF) { // ASCII
305                                                         chars[charIndex++] = (char)b;
306                                                 } else if (b < 0xA1 || b >= 0xFA) {
307                                                         // incorrect first byte.
308                                                         chars[charIndex++] = '?';
309                                                         byteCount--; // cut one more byte.
310                                                 } else {
311                                                         lastByte = b;
312                                                 }
313                                                 continue;
314                                         }
315                                         int ord = ((lastByte - 0xA1) * 191 + b - 0x40) * 2;
316                                         char c1 = ord < 0 || ord > convert.n2u.Length ?
317                                                 '\0' :
318                                                 (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256);
319                                         if (c1 == 0)
320                                                 chars[charIndex++] = '?';
321                                         else
322                                                 chars[charIndex++] = c1;
323                                         lastByte = 0;
324                                 }
325
326                                 if (lastByte != 0) {
327                                         if (refresh)
328                                                 chars [charIndex++] = '?';
329                                         else
330                                                 last_byte_conv = lastByte;
331                                 }
332                                 return charIndex - origIndex;
333                         }
334                 }
335         }
336         
337         [Serializable]
338         internal class ENCbig5 : CP950
339         {
340                 public ENCbig5() {}
341         }
342 }