New test.
[mono.git] / mcs / class / I18N / Common / MonoEncoding.cs
1 //
2 // MonoEncoding.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
8 //
9 using System;
10 using System.Runtime.InteropServices;
11 using System.Text;
12
13 namespace I18N.Common
14 {
15         [Serializable]
16         public abstract class MonoEncoding : Encoding
17         {
18                 readonly int win_code_page;
19
20                 public MonoEncoding (int codePage)
21                         : this (codePage, 0)
22                 {
23                 }
24
25                 public MonoEncoding (int codePage, int windowsCodePage)
26                         : base (codePage)
27                 {
28                         win_code_page = windowsCodePage;
29                 }
30
31                 public override int WindowsCodePage {
32                         get { return win_code_page != 0 ? win_code_page : base.WindowsCodePage; }
33                 }
34
35 #if NET_2_0
36                 [CLSCompliant (false)]
37                 public unsafe void HandleFallback (ref EncoderFallbackBuffer buffer,
38                         char* chars, ref int charIndex, ref int charCount,
39                         byte* bytes, ref int byteIndex, ref int byteCount)
40                 {
41                         if (buffer == null)
42                                 buffer = EncoderFallback.CreateFallbackBuffer ();
43                         if (Char.IsSurrogate (chars [charIndex]) && charCount > 0 &&
44                                 Char.IsSurrogate (chars [charIndex + 1])) {
45                                 buffer.Fallback (chars [charIndex], chars [charIndex + 1], charIndex);
46                                 charIndex++;
47                                 charCount--;
48                         }
49                         else
50                                 buffer.Fallback (chars [charIndex], charIndex);
51                         char [] tmp = new char [buffer.Remaining];
52                         int idx = 0;
53                         while (buffer.Remaining > 0)
54                                 tmp [idx++] = buffer.GetNextChar ();
55                         fixed (char* tmparr = tmp) {
56                                 byteIndex += GetBytes (tmparr, tmp.Length, bytes + byteIndex, byteCount);
57                         }
58                 }
59 #endif
60
61                 // Get the bytes that result from encoding a character buffer.
62                 public override int GetByteCount (
63                         char [] chars, int index, int count)
64                 {
65                         if (chars == null)
66                                 throw new ArgumentNullException ("chars");
67                         if (index < 0 || index > chars.Length)
68                                 throw new ArgumentOutOfRangeException
69                                         ("index", Strings.GetString ("ArgRange_Array"));
70                         if (count < 0 || count > (chars.Length - index))
71                                 throw new ArgumentOutOfRangeException
72                                         ("count", Strings.GetString ("ArgRange_Array"));
73
74                         if (count == 0)
75                                 return 0;
76
77                         unsafe {
78                                 fixed (char* cptr = chars) {
79                                         return GetByteCountImpl (
80                                                 cptr + index, count);
81                                 }
82                         }
83                 }
84
85                 // Get the bytes that result from encoding a character buffer.
86                 public override int GetBytes (
87                         char [] chars, int charIndex, int charCount,
88                         byte [] bytes, int byteIndex)
89                 {
90                         if (chars == null)
91                                 throw new ArgumentNullException ("chars");
92                         if (bytes == null)
93                                 throw new ArgumentNullException ("bytes");
94                         if (charIndex < 0 || charIndex > chars.Length)
95                                 throw new ArgumentOutOfRangeException
96                                         ("charIndex", Strings.GetString ("ArgRange_Array"));
97                         if (charCount < 0 || charCount > (chars.Length - charIndex))
98                                 throw new ArgumentOutOfRangeException
99                                         ("charCount", Strings.GetString ("ArgRange_Array"));
100                         if (byteIndex < 0 || byteIndex > bytes.Length)
101                                 throw new ArgumentOutOfRangeException
102                                         ("byteIndex", Strings.GetString ("ArgRange_Array"));
103                         if (bytes.Length - byteIndex < charCount)
104                                 throw new ArgumentException (Strings.GetString ("Arg_InsufficientSpace"), "bytes");
105
106                         if (charCount == 0)
107                                 return 0;
108
109                         unsafe {
110                                 fixed (char* cptr = chars) {
111                                         fixed (byte* bptr = bytes) {
112                                                 return GetBytesImpl (
113                                                         cptr + charIndex,
114                                                         charCount,
115                                                         bptr + byteIndex,
116                                                         bytes.Length - byteIndex);
117                                         }
118                                 }
119                         }
120                 }
121
122                 // Convenience wrappers for "GetBytes".
123                 public override int GetBytes (string s, int charIndex, int charCount,
124                         byte [] bytes, int byteIndex)
125                 {
126                         // Validate the parameters.
127                         if(s == null)
128                                 throw new ArgumentNullException("s");
129                         if(bytes == null)
130                                 throw new ArgumentNullException("bytes");
131                         if(charIndex < 0 || charIndex > s.Length)
132                                 throw new ArgumentOutOfRangeException
133                                         ("charIndex",
134                                          Strings.GetString("ArgRange_StringIndex"));
135                         if(charCount < 0 || charCount > (s.Length - charIndex))
136                                 throw new ArgumentOutOfRangeException
137                                         ("charCount",
138                                          Strings.GetString("ArgRange_StringRange"));
139                         if(byteIndex < 0 || byteIndex > bytes.Length)
140                                 throw new ArgumentOutOfRangeException
141                                         ("byteIndex",
142                                          Strings.GetString("ArgRange_Array"));
143                         if((bytes.Length - byteIndex) < charCount)
144                                 throw new ArgumentException
145                                         (Strings.GetString("Arg_InsufficientSpace"), "bytes");
146
147                         if (charCount == 0 || bytes.Length == byteIndex)
148                                 return 0;
149                         unsafe {
150                                 fixed (char* cptr = s) {
151                                         fixed (byte* bptr = bytes) {
152                                                 return GetBytesImpl (
153                                                         cptr + charIndex,
154                                                         charCount,
155                                                         bptr + byteIndex,
156                                                         bytes.Length - byteIndex);
157                                         }
158                                 }
159                         }
160                 }
161
162 #if NET_2_0
163                 public unsafe override int GetByteCount (char* chars, int count)
164
165                 {
166                         return GetByteCountImpl (chars, count);
167                 }
168
169                 public unsafe override int GetBytes (char* chars, int charCount,
170                         byte* bytes, int byteCount)
171
172                 {
173                         return GetBytesImpl (chars, charCount, bytes, byteCount);
174                 }
175 #endif
176
177                 //[CLSCompliant (false)]
178                 public unsafe abstract int GetByteCountImpl (char* chars, int charCount);
179
180                 //[CLSCompliant (false)]
181                 public unsafe abstract int GetBytesImpl (char* chars, int charCount,
182                         byte* bytes, int byteCount);
183         }
184
185                 public abstract class MonoEncoder : Encoder
186                 {
187                         MonoEncoding encoding;
188
189                         public MonoEncoder (MonoEncoding encoding)
190                         {
191                                 this.encoding = encoding;
192                         }
193
194                         public override int GetByteCount (
195                                 char [] chars, int index, int count, bool refresh)
196                         {
197                                 if (chars == null)
198                                         throw new ArgumentNullException ("chars");
199                                 if (index < 0 || index > chars.Length)
200                                         throw new ArgumentOutOfRangeException
201                                                 ("index", Strings.GetString ("ArgRange_Array"));
202                                 if (count < 0 || count > (chars.Length - index))
203                                         throw new ArgumentOutOfRangeException
204                                                 ("count", Strings.GetString ("ArgRange_Array"));
205
206                                 if (count == 0)
207                                         return 0;
208
209                                 unsafe {
210                                         fixed (char* cptr = chars) {
211                                                 return GetByteCountImpl (
212                                                         cptr + index, count, refresh);
213                                         }
214                                 }
215                         }
216
217                         public override int GetBytes (char [] chars, int charIndex, int charCount, byte [] bytes, int byteIndex, bool flush)
218                         {
219                                 if (chars == null)
220                                         throw new ArgumentNullException ("chars");
221                                 if (bytes == null)
222                                         throw new ArgumentNullException ("bytes");
223                                 if (charIndex < 0 || charIndex > chars.Length)
224                                         throw new ArgumentOutOfRangeException
225                                                 ("charIndex", Strings.GetString ("ArgRange_Array"));
226                                 if (charCount < 0 || charCount > (chars.Length - charIndex))
227                                         throw new ArgumentOutOfRangeException
228                                                 ("charCount", Strings.GetString ("ArgRange_Array"));
229                                 if (byteIndex < 0 || byteIndex > bytes.Length)
230                                         throw new ArgumentOutOfRangeException
231                                                 ("byteIndex", Strings.GetString ("ArgRange_Array"));
232                                 if (bytes.Length - byteIndex < charCount)
233                                         throw new ArgumentException (Strings.GetString ("Arg_InsufficientSpace"), "bytes");
234
235                                 if (charCount == 0)
236                                         return 0;
237                                 unsafe {
238                                         fixed (char* cptr = chars) {
239                                                 fixed (byte* bptr = bytes) {
240                                                         return GetBytesImpl (cptr + charIndex, 
241                                                                 charCount,
242                                                                 bptr + byteIndex,
243                                                                 bytes.Length - byteIndex,
244                                                                 flush);
245                                                 }
246                                         }
247                                 }
248                         }
249
250                         public unsafe abstract int GetByteCountImpl (char* chars, int charCount, bool refresh);
251
252                         public unsafe abstract int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount, bool refresh);
253
254                 #if NET_2_0
255                         public unsafe override int GetBytes (char* chars, int charCount, byte* bytes, int byteCount, bool flush)
256                         {
257                                 return GetBytesImpl (chars, charCount, bytes, byteCount, flush);
258                         }
259
260                         //[CLSCompliant (false)]
261                         public unsafe void HandleFallback (
262                                 char* chars, ref int charIndex, ref int charCount,
263                                 byte* bytes, ref int byteIndex, ref int byteCount)
264                         {
265                                 EncoderFallbackBuffer buffer = FallbackBuffer;
266                                 encoding.HandleFallback (ref buffer,
267                                         chars, ref charIndex, ref charCount,
268                                         bytes, ref byteIndex, ref byteCount);
269                         }
270                 #endif
271                 }
272 }