2006-06-27 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / I18N / Common / ByteEncoding.cs
1 /*
2  * ByteEncoding.cs - Implementation of the "I18N.Common.ByteEncoding" class.
3  *
4  * Copyright (c) 2002  Southern Storm Software, Pty Ltd
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 namespace I18N.Common
26 {
27
28 using System;
29 using System.Text;
30
31 // This class provides an abstract base for encodings that use a single
32 // byte per character.  The bulk of the work is done in this class, with
33 // subclasses providing implementations of the "ToBytes" methods to perform
34 // the char->byte conversion.
35
36 public abstract class ByteEncoding : Encoding
37 {
38         // Internal state.
39         protected char[] toChars;
40         protected String encodingName;
41         protected String bodyName;
42         protected String headerName;
43         protected String webName;
44         protected bool isBrowserDisplay;
45         protected bool isBrowserSave;
46         protected bool isMailNewsDisplay;
47         protected bool isMailNewsSave;
48         protected int windowsCodePage;
49
50         // Constructor.
51         protected ByteEncoding(int codePage, char[] toChars,
52                                                    String encodingName, String bodyName,
53                                                    String headerName, String webName,
54                                                    bool isBrowserDisplay, bool isBrowserSave,
55                                                    bool isMailNewsDisplay, bool isMailNewsSave,
56                                                    int windowsCodePage)
57                         : base(codePage)
58                         {
59                                 this.toChars = toChars;
60                                 this.encodingName = encodingName;
61                                 this.bodyName = bodyName;
62                                 this.headerName = headerName;
63                                 this.webName = webName;
64                                 this.isBrowserDisplay = isBrowserDisplay;
65                                 this.isBrowserSave = isBrowserSave;
66                                 this.isMailNewsDisplay = isMailNewsDisplay;
67                                 this.isMailNewsSave = isMailNewsSave;
68                                 this.windowsCodePage = windowsCodePage;
69                         }
70
71         // Get the number of bytes needed to encode a character buffer.
72         public override int GetByteCount(char[] chars, int index, int count)
73                         {
74                                 if(chars == null)
75                                 {
76                                         throw new ArgumentNullException("chars");
77                                 }
78                                 if(index < 0 || index > chars.Length)
79                                 {
80                                         throw new ArgumentOutOfRangeException
81                                                 ("index", Strings.GetString("ArgRange_Array"));
82                                 }
83                                 if(count < 0 || count > (chars.Length - index))
84                                 {
85                                         throw new ArgumentOutOfRangeException
86                                                 ("count", Strings.GetString("ArgRange_Array"));
87                                 }
88                                 return count;
89                         }
90
91         // Convenience wrappers for "GetByteCount".
92         public override int GetByteCount(String s)
93                         {
94                                 if(s == null)
95                                 {
96                                         throw new ArgumentNullException("s");
97                                 }
98                                 return s.Length;
99                         }
100
101         // Convert an array of characters into a byte buffer,
102         // once the parameters have been validated.
103         protected abstract void ToBytes(char[] chars, int charIndex, int charCount,
104                                                                         byte[] bytes, int byteIndex);
105
106         // Convert a string into a byte buffer, once the parameters
107         // have been validated.
108         protected abstract void ToBytes(String s, int charIndex, int charCount,
109                                                                         byte[] bytes, int byteIndex);
110
111         // Get the bytes that result from encoding a character buffer.
112         public override int GetBytes(char[] chars, int charIndex, int charCount,
113                                                                  byte[] bytes, int byteIndex)
114                         {
115                                 if(chars == null)
116                                 {
117                                         throw new ArgumentNullException("chars");
118                                 }
119                                 if(bytes == null)
120                                 {
121                                         throw new ArgumentNullException("bytes");
122                                 }
123                                 if(charIndex < 0 || charIndex > chars.Length)
124                                 {
125                                         throw new ArgumentOutOfRangeException
126                                                 ("charIndex", Strings.GetString("ArgRange_Array"));
127                                 }
128                                 if(charCount < 0 || charCount > (chars.Length - charIndex))
129                                 {
130                                         throw new ArgumentOutOfRangeException
131                                                 ("charCount", Strings.GetString("ArgRange_Array"));
132                                 }
133                                 if(byteIndex < 0 || byteIndex > bytes.Length)
134                                 {
135                                         throw new ArgumentOutOfRangeException
136                                                 ("byteIndex", Strings.GetString("ArgRange_Array"));
137                                 }
138                                 if((bytes.Length - byteIndex) < charCount)
139                                 {
140                                         throw new ArgumentException
141                                                 (Strings.GetString("Arg_InsufficientSpace"));
142                                 }
143                                 ToBytes(chars, charIndex, charCount, bytes, byteIndex);
144                                 return charCount;
145                         }
146
147         // Convenience wrappers for "GetBytes".
148         public override int GetBytes(String s, int charIndex, int charCount,
149                                                                  byte[] bytes, int byteIndex)
150                         {
151                                 if(s == null)
152                                 {
153                                         throw new ArgumentNullException("s");
154                                 }
155                                 if(bytes == null)
156                                 {
157                                         throw new ArgumentNullException("bytes");
158                                 }
159                                 if(charIndex < 0 || charIndex > s.Length)
160                                 {
161                                         throw new ArgumentOutOfRangeException
162                                                 ("charIndex",
163                                                  Strings.GetString("ArgRange_StringIndex"));
164                                 }
165                                 if(charCount < 0 || charCount > (s.Length - charIndex))
166                                 {
167                                         throw new ArgumentOutOfRangeException
168                                                 ("charCount",
169                                                  Strings.GetString("ArgRange_StringRange"));
170                                 }
171                                 if(byteIndex < 0 || byteIndex > bytes.Length)
172                                 {
173                                         throw new ArgumentOutOfRangeException
174                                                 ("byteIndex", Strings.GetString("ArgRange_Array"));
175                                 }
176                                 if((bytes.Length - byteIndex) < charCount)
177                                 {
178                                         throw new ArgumentException
179                                                 (Strings.GetString("Arg_InsufficientSpace"));
180                                 }
181                                 ToBytes(s, charIndex, charCount, bytes, byteIndex);
182                                 return charCount;
183                         }
184
185         // Get the number of characters needed to decode a byte buffer.
186         public override int GetCharCount(byte[] bytes, int index, int count)
187                         {
188                                 if(bytes == null)
189                                 {
190                                         throw new ArgumentNullException("bytes");
191                                 }
192                                 if(index < 0 || index > bytes.Length)
193                                 {
194                                         throw new ArgumentOutOfRangeException
195                                                 ("index", Strings.GetString("ArgRange_Array"));
196                                 }
197                                 if(count < 0 || count > (bytes.Length - index))
198                                 {
199                                         throw new ArgumentOutOfRangeException
200                                                 ("count", Strings.GetString("ArgRange_Array"));
201                                 }
202                                 return count;
203                         }
204
205         // Get the characters that result from decoding a byte buffer.
206         public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
207                                                                  char[] chars, int charIndex)
208                         {
209                                 if(bytes == null)
210                                 {
211                                         throw new ArgumentNullException("bytes");
212                                 }
213                                 if(chars == null)
214                                 {
215                                         throw new ArgumentNullException("chars");
216                                 }
217                                 if(byteIndex < 0 || byteIndex > bytes.Length)
218                                 {
219                                         throw new ArgumentOutOfRangeException
220                                                 ("byteIndex", Strings.GetString("ArgRange_Array"));
221                                 }
222                                 if(byteCount < 0 || byteCount > (bytes.Length - byteIndex))
223                                 {
224                                         throw new ArgumentOutOfRangeException
225                                                 ("byteCount", Strings.GetString("ArgRange_Array"));
226                                 }
227                                 if(charIndex < 0 || charIndex > chars.Length)
228                                 {
229                                         throw new ArgumentOutOfRangeException
230                                                 ("charIndex", Strings.GetString("ArgRange_Array"));
231                                 }
232                                 if((chars.Length - charIndex) < byteCount)
233                                 {
234                                         throw new ArgumentException
235                                                 (Strings.GetString("Arg_InsufficientSpace"));
236                                 }
237                                 int count = byteCount;
238                                 char[] cvt = toChars;
239                                 while(count-- > 0)
240                                 {
241                                         chars[charIndex++] = cvt[(int)(bytes[byteIndex++])];
242                                 }
243                                 return byteCount;
244                         }
245
246         // Get the maximum number of bytes needed to encode a
247         // specified number of characters.
248         public override int GetMaxByteCount(int charCount)
249                         {
250                                 if(charCount < 0)
251                                 {
252                                         throw new ArgumentOutOfRangeException
253                                                 ("charCount",
254                                                  Strings.GetString("ArgRange_NonNegative"));
255                                 }
256                                 return charCount;
257                         }
258
259         // Get the maximum number of characters needed to decode a
260         // specified number of bytes.
261         public override int GetMaxCharCount(int byteCount)
262                         {
263                                 if(byteCount < 0)
264                                 {
265                                         throw new ArgumentOutOfRangeException
266                                                 ("byteCount",
267                                                  Strings.GetString("ArgRange_NonNegative"));
268                                 }
269                                 return byteCount;
270                         }
271
272         // Decode a buffer of bytes into a string.
273         public override String GetString(byte[] bytes, int index, int count)
274                         {
275                                 if(bytes == null)
276                                 {
277                                         throw new ArgumentNullException("bytes");
278                                 }
279                                 if(index < 0 || index > bytes.Length)
280                                 {
281                                         throw new ArgumentOutOfRangeException
282                                                 ("index", Strings.GetString("ArgRange_Array"));
283                                 }
284                                 if(count < 0 || count > (bytes.Length - index))
285                                 {
286                                         throw new ArgumentOutOfRangeException
287                                                 ("count", Strings.GetString("ArgRange_Array"));
288                                 }
289                                 StringBuilder s = new StringBuilder();
290                                 char[] cvt = toChars;
291                                 while(count-- > 0)
292                                 {
293                                         s.Append(cvt[(int)(bytes[index++])]);
294                                 }
295                                 return s.ToString();
296                         }
297         public override String GetString(byte[] bytes)
298                         {
299                                 if(bytes == null)
300                                 {
301                                         throw new ArgumentNullException("bytes");
302                                 }
303                                 int count = bytes.Length;
304                                 int posn = 0;
305                                 StringBuilder s = new StringBuilder();
306                                 char[] cvt = toChars;
307                                 while(count-- > 0)
308                                 {
309                                         s.Append(cvt[(int)(bytes[posn++])]);
310                                 }
311                                 return s.ToString();
312                         }
313
314 #if !ECMA_COMPAT
315
316         // Get the mail body name for this encoding.
317         public override String BodyName
318                         {
319                                 get
320                                 {
321                                         return bodyName;
322                                 }
323                         }
324
325         // Get the human-readable name for this encoding.
326         public override String EncodingName
327                         {
328                                 get
329                                 {
330                                         return encodingName;
331                                 }
332                         }
333
334         // Get the mail agent header name for this encoding.
335         public override String HeaderName
336                         {
337                                 get
338                                 {
339                                         return headerName;
340                                 }
341                         }
342
343         // Determine if this encoding can be displayed in a Web browser.
344         public override bool IsBrowserDisplay
345                         {
346                                 get
347                                 {
348                                         return isBrowserDisplay;
349                                 }
350                         }
351
352         // Determine if this encoding can be saved from a Web browser.
353         public override bool IsBrowserSave
354                         {
355                                 get
356                                 {
357                                         return isBrowserSave;
358                                 }
359                         }
360
361         // Determine if this encoding can be displayed in a mail/news agent.
362         public override bool IsMailNewsDisplay
363                         {
364                                 get
365                                 {
366                                         return isMailNewsDisplay;
367                                 }
368                         }
369
370         // Determine if this encoding can be saved from a mail/news agent.
371         public override bool IsMailNewsSave
372                         {
373                                 get
374                                 {
375                                         return isMailNewsSave;
376                                 }
377                         }
378
379         // Get the IANA-preferred Web name for this encoding.
380         public override String WebName
381                         {
382                                 get
383                                 {
384                                         return webName;
385                                 }
386                         }
387
388         // Get the Windows code page represented by this object.
389         public override int WindowsCodePage
390                         {
391                                 get
392                                 {
393                                         return windowsCodePage;
394                                 }
395                         }
396
397 #endif // !ECMA_COMPAT
398
399 }; // class ByteEncoding
400
401 }; // namespace I18N.Encoding