Use GetByteCount instead of GetMaxByteCount (which doesn't seem to be implemented...
[mono.git] / mcs / class / corlib / System.Text / Encoding.cs
1 // -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2 //
3 // System.Text.Encoding.cs
4 //
5 // Author:
6 //   Sean MacIsaac (macisaac@ximian.com)
7 //   Dietmar Maurer (dietmar@ximian.com)
8 //
9 // (C) Ximian, Inc.  http://www.ximian.com
10 //
11
12 using System.Runtime.CompilerServices;
13
14 namespace System.Text {
15
16         [Serializable]
17         public abstract class Encoding {
18                 private static ASCIIEncoding ascii_encoding;
19                 private static UnicodeEncoding big_endian_unicode;
20                 private static UnicodeEncoding unicode_encoding;
21                 private static UTF7Encoding utf7_encoding;
22                 private static UTF8Encoding utf8_encoding;
23
24                 private int codepage;
25    
26                 protected string body_name;
27                 protected string encoding_name;
28                 protected string header_name;
29                 protected string web_name;
30
31                 protected bool is_browser_display = false;
32                 protected bool is_browser_save = false;
33                 protected bool is_mail_news_display = false;
34                 protected bool is_mail_news_save = false;
35                 
36                 private Encoder default_encoder = null;
37                 private Decoder default_decoder = null;
38                 
39                 // used for iconv 
40                 private string  iconv_name;
41                 private bool    big_endian;
42                 private Encoder iconv_encoder = null;
43                 private Decoder iconv_decoder = null;
44
45                 protected Encoding()
46                 {
47                 }
48
49                 protected Encoding (int codepage)
50                 {
51                         this.codepage = codepage;
52                 }
53
54                 internal protected Encoding (string name, bool big_endian)
55                 {
56                         this.iconv_name = name;
57                         this.big_endian = big_endian;
58                         
59                         iconv_decoder = new IConvDecoder (iconv_name, big_endian);
60                         iconv_encoder = new IConvEncoder (iconv_name, big_endian);
61                 }
62
63                 public static Encoding Unicode {
64                         get {
65                                 if (unicode_encoding == null) {
66                                         unicode_encoding = new UnicodeEncoding();
67                                 }
68                                 return unicode_encoding;
69                         }
70                 }
71
72                 public static Encoding UTF7 {
73                         get {
74                                 if (utf7_encoding == null) {
75                                         utf7_encoding = new UTF7Encoding();
76                                 }
77                                 return utf7_encoding;
78                         }
79                 }
80
81                 public static Encoding UTF8 {
82                         get {
83                                 if (utf8_encoding == null) {
84                                         utf8_encoding = new UTF8Encoding();
85                                 }
86                                 return utf8_encoding;
87                         }
88                 }
89
90                 public static Encoding ASCII {
91                         get {
92                                 if (ascii_encoding == null)
93                                         ascii_encoding = new ASCIIEncoding ();
94                                 return ascii_encoding;
95                         }
96                 }
97
98                 public static Encoding BigEndianUnicode {
99                         get {
100                                 if (big_endian_unicode == null)
101                                         big_endian_unicode = new UnicodeEncoding (true, true);
102                                 return big_endian_unicode;
103                         }
104                 }
105
106                 public virtual string BodyName {
107                         get {
108                                 return body_name;
109                         }
110                 }
111
112                 public virtual int CodePage {
113                         get {
114                                 return codepage;
115                         }
116                 }
117
118                 public static Encoding Default {
119                         get {
120                                 return ASCII;
121                         }
122                 }
123
124                 public virtual string EncodingName {
125                         get {
126                                 return encoding_name;
127                         }
128                 }
129
130                 public virtual string HeaderName {
131                         get {
132                                 return header_name;
133                         }
134                 }
135
136                 public virtual bool IsBrowserDisplay {
137                         get {
138                                 return is_browser_display;
139                         }
140                 }
141
142                 public virtual bool IsBrowserSave {
143                         get {
144                                 return is_browser_save;
145                         }
146                 }
147
148                 public virtual bool IsMailNewsDisplay {
149                         get {
150                                 return is_mail_news_display;
151                         }
152                 }
153
154                 public virtual bool IsMailNewsSave {
155                         get {
156                                 return is_mail_news_save;
157                         }
158                 }
159
160                 public virtual string WebName {
161                         get {
162                                 return web_name;
163                         }
164                 }
165
166                 [MonoTODO]
167                 public virtual int WindowsCodePage {
168                         get {
169                                 // FIXME
170                                 return 0;
171                         }
172                 }
173
174                 public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding, byte[] bytes)
175                 {
176                         return dstEncoding.GetBytes (srcEncoding.GetChars (bytes));
177                 }
178
179                 public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
180                                              byte[] bytes, int index, int count)
181                 {
182                         return dstEncoding.GetBytes (srcEncoding.GetChars (bytes, index, count));
183                 }
184
185                 public override bool Equals (object value)
186                 {
187                         if (!(value is Encoding))
188                                 return false;
189
190                         Encoding e = (Encoding) value;
191
192                         if (e.codepage != codepage)
193                                 return false;
194
195                         if (e.body_name != body_name)
196                                 return false;
197
198                         if (e.encoding_name != encoding_name)
199                                 return false;
200
201                         if (e.header_name != header_name)
202                                 return false;
203                         
204                         return true;
205                 }
206
207                 public virtual int GetByteCount (char[] chars)
208                 {
209                         return GetByteCount (chars, 0, chars.Length);
210                 }
211
212                 public virtual int GetByteCount (string s)
213                 {
214                         char [] chars = s.ToCharArray ();
215                         
216                         return GetByteCount (chars, 0, chars.Length);
217                 }
218
219                 public virtual int GetByteCount (char[] chars, int index, int count)
220                 {
221                         return iconv_encoder.GetByteCount (chars, index, count, false);
222                 }
223
224                 public virtual byte[] GetBytes(char[] chars)
225                 {
226                         return GetBytes (chars, 0, chars.Length);
227                 }
228
229                 public virtual byte[] GetBytes(string s)
230                 {
231                         char [] chars = s.ToCharArray (); 
232                         return GetBytes (chars, 0, chars.Length);
233                 }
234
235                 public virtual byte[] GetBytes(char[] chars, int index, int count)
236                 {
237                         int bc = GetByteCount (chars, index, count);
238                         byte [] bytes = new byte [bc];
239                         
240                         int len = GetBytes (chars, index, count, bytes, 0);
241                         byte [] res = new byte [len];
242
243                         Array.Copy (bytes, res, len);
244                         
245                         return res;
246                 }
247
248                 public virtual int GetBytes (char[] chars, int charIndex, int charCount,
249                                              byte[] bytes, int byteIndex)
250                 {
251                         return iconv_encoder.GetBytes (chars, charIndex, charCount, bytes, byteIndex, true);
252                 }
253
254                 public virtual int GetBytes(string s, int charIndex, int charCount,
255                                             byte[] bytes, int byteIndex)
256                 {
257                         return GetBytes (s.ToCharArray (), charIndex, charCount, bytes, byteIndex);
258                 }
259
260                 public virtual int GetCharCount (byte[] bytes)
261                 {
262                         return GetCharCount (bytes, 0, bytes.Length);
263                 }
264
265                 public virtual int GetCharCount (byte[] bytes, int index, int count)
266                 {
267                         return iconv_decoder.GetCharCount (bytes, index, count);
268                 }
269
270                 public virtual char[] GetChars (byte[] bytes)
271                 {
272                         return GetChars (bytes, 0, bytes.Length);
273                 }
274
275                 public virtual char[] GetChars (byte[] bytes, int index, int count)
276                 {
277                         int cc = GetMaxCharCount (count);
278                         char [] chars = new char [cc];
279
280                         int len = GetChars (bytes, index, count, chars, 0);
281                         char [] res = new char [len];
282                         
283                         Array.Copy (chars, res, len);
284
285                         return res;
286                 }
287
288                 public virtual int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
289                 {
290                         return iconv_decoder.GetChars (bytes, byteIndex, byteCount, chars, charIndex);
291                 }
292
293                 public virtual Decoder GetDecoder()
294                 {
295                         if (iconv_name != null)
296                                 return new IConvDecoder (iconv_name, big_endian);
297                         
298                         if (default_decoder == null)
299                                 default_decoder = new DefaultDecoder (this);
300                         
301                         return default_decoder;
302                 }
303
304                 public virtual Encoder GetEncoder() 
305                 {
306                         if (iconv_name != null)
307                                 return new IConvEncoder (iconv_name, big_endian);
308
309                         if (default_encoder == null)
310                                 default_encoder = new DefaultEncoder (this);
311                         
312                         return default_encoder;
313                 }
314
315                 [MonoTODO]
316                 public static Encoding GetEncoding (int codepage)
317                 {
318                         // FIXME
319                         return null;
320                 }
321                 
322                 [MonoTODO]
323                 public static Encoding GetEncoding (string name)
324                 {
325                         // FIXME
326                         return null;
327                 }
328
329                 [MonoTODO]
330                 public override int GetHashCode()
331                 {
332                         // FIXME
333                         return 0;
334                 }
335
336                 public abstract int GetMaxByteCount (int charCount);
337
338                 public abstract int GetMaxCharCount (int byteCount);
339
340                 [MonoTODO]
341                 public virtual byte[] GetPreamble()
342                 {
343                         // FIXME
344                         return null;
345                 }
346
347                 public virtual string GetString(byte[] bytes)
348                 {
349                         return GetString (bytes, 0, bytes.Length);
350                 }
351
352                 public virtual string GetString(byte[] bytes, int index, int count)
353                 {
354                         char [] chars = GetChars (bytes, index, count);
355
356                         return chars.ToString ();
357                 }
358
359                 [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
360                 internal extern static IntPtr IConvNewEncoder (string name, bool big_endian);
361
362                 [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
363                 internal extern static IntPtr IConvNewDecoder (string name, bool big_endian);
364
365                 [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
366                 internal extern static void IConvReset (IntPtr converter);
367
368                 [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
369                 internal extern static int IConvGetByteCount (IntPtr converter, char[] chars,
370                                                               int index, int count);
371
372                 [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
373                 internal extern static int IConvGetBytes (IntPtr converter, char[] chars, int charIndex,
374                                                           int charCount, byte[] bytes, int byteIndex);
375                 
376                 [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
377                 internal extern static int IConvGetCharCount (IntPtr converter, byte[] bytes,
378                                                               int index, int count);
379
380                 [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
381                 internal extern static int IConvGetChars (IntPtr converter, byte[] bytes, int byteIndex,
382                                                           int byteCount, char[] chars, int charIndex);
383         }
384 }