5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
10 using System.Runtime.InteropServices;
16 public abstract class MonoEncoding : Encoding
18 readonly int win_code_page;
20 public MonoEncoding (int codePage)
25 public MonoEncoding (int codePage, int windowsCodePage)
28 win_code_page = windowsCodePage;
31 public override int WindowsCodePage {
32 get { return win_code_page != 0 ? win_code_page : base.WindowsCodePage; }
36 /// GetBytes method used internally by state-full encoders/encodings.
38 /// <param name="chars">The chars.</param>
39 /// <param name="charIndex">Index of the char.</param>
40 /// <param name="charCount">The char count.</param>
41 /// <param name="bytes">The bytes.</param>
42 /// <param name="byteIndex">Index of the byte.</param>
43 /// <param name="flush">if set to <c>true</c> [flush].</param>
44 /// <param name="encoding">The encoding class to use (or null if state-less).</param>
45 /// <returns></returns>
47 /// Only state-full encoders need to implement this method (ie. ISO-2022-JP)
49 protected unsafe virtual int GetBytesInternal(char *chars, int charCount,
50 byte *bytes, int byteCount, bool flush, object state)
52 throw new NotImplementedException("Statefull encoding is not implemented (yet?) by this encoding class.");
55 public unsafe void HandleFallback (ref EncoderFallbackBuffer buffer,
56 char* chars, ref int charIndex, ref int charCount,
57 byte* bytes, ref int byteIndex, ref int byteCount, object state)
60 buffer = EncoderFallback.CreateFallbackBuffer ();
62 if (charCount > 1 && (Char.IsSurrogate (chars [charIndex]) && Char.IsSurrogate (chars [charIndex + 1]))) {
63 buffer.Fallback (chars [charIndex], chars [charIndex + 1], charIndex);
68 buffer.Fallback (chars [charIndex], charIndex);
69 char [] tmp = new char [buffer.Remaining];
71 while (buffer.Remaining > 0)
72 tmp [idx++] = buffer.GetNextChar ();
74 fixed (char* tmparr = tmp) {
75 var outbytes = bytes == null ? null : bytes + byteIndex;
76 var len = state == null ?
77 GetBytes(tmparr, tmp.Length, outbytes, byteCount)
78 : GetBytesInternal(tmparr, tmp.Length, outbytes, byteCount, true, state);
85 public unsafe void HandleFallback (ref EncoderFallbackBuffer buffer,
86 char* chars, ref int charIndex, ref int charCount,
87 byte* bytes, ref int byteIndex, ref int byteCount)
89 HandleFallback(ref buffer, chars, ref charIndex, ref charCount,
90 bytes, ref byteIndex, ref byteCount, null);
93 // Get the bytes that result from encoding a character buffer.
94 public override int GetByteCount (
95 char [] chars, int index, int count)
98 throw new ArgumentNullException ("chars");
99 if (index < 0 || index > chars.Length)
100 throw new ArgumentOutOfRangeException
101 ("index", Strings.GetString ("ArgRange_Array"));
102 if (count < 0 || count > (chars.Length - index))
103 throw new ArgumentOutOfRangeException
104 ("count", Strings.GetString ("ArgRange_Array"));
110 fixed (char* cptr = chars) {
111 return GetByteCountImpl (
112 cptr + index, count);
117 // Get the bytes that result from encoding a character buffer.
118 public override int GetBytes (
119 char [] chars, int charIndex, int charCount,
120 byte [] bytes, int byteIndex)
123 throw new ArgumentNullException ("chars");
125 throw new ArgumentNullException ("bytes");
126 if (charIndex < 0 || charIndex > chars.Length)
127 throw new ArgumentOutOfRangeException
128 ("charIndex", Strings.GetString ("ArgRange_Array"));
129 if (charCount < 0 || charCount > (chars.Length - charIndex))
130 throw new ArgumentOutOfRangeException
131 ("charCount", Strings.GetString ("ArgRange_Array"));
132 if (byteIndex < 0 || byteIndex > bytes.Length)
133 throw new ArgumentOutOfRangeException
134 ("byteIndex", Strings.GetString ("ArgRange_Array"));
135 if (bytes.Length - byteIndex < charCount)
136 throw new ArgumentException (Strings.GetString ("Arg_InsufficientSpace"), "bytes");
142 fixed (char* cptr = chars) {
143 fixed (byte* bptr = bytes) {
144 return GetBytesImpl (
148 bytes.Length - byteIndex);
154 // Convenience wrappers for "GetBytes".
155 public override int GetBytes (string s, int charIndex, int charCount,
156 byte [] bytes, int byteIndex)
158 // Validate the parameters.
160 throw new ArgumentNullException("s");
162 throw new ArgumentNullException("bytes");
163 if(charIndex < 0 || charIndex > s.Length)
164 throw new ArgumentOutOfRangeException
166 Strings.GetString("ArgRange_StringIndex"));
167 if(charCount < 0 || charCount > (s.Length - charIndex))
168 throw new ArgumentOutOfRangeException
170 Strings.GetString("ArgRange_StringRange"));
171 if(byteIndex < 0 || byteIndex > bytes.Length)
172 throw new ArgumentOutOfRangeException
174 Strings.GetString("ArgRange_Array"));
175 if((bytes.Length - byteIndex) < charCount)
176 throw new ArgumentException
177 (Strings.GetString("Arg_InsufficientSpace"), "bytes");
179 if (charCount == 0 || bytes.Length == byteIndex)
182 fixed (char* cptr = s) {
183 fixed (byte* bptr = bytes) {
184 return GetBytesImpl (
188 bytes.Length - byteIndex);
194 public unsafe override int GetByteCount (char* chars, int count)
197 return GetByteCountImpl (chars, count);
200 public unsafe override int GetBytes (char* chars, int charCount,
201 byte* bytes, int byteCount)
204 return GetBytesImpl (chars, charCount, bytes, byteCount);
207 //[CLSCompliant (false)]
208 public unsafe abstract int GetByteCountImpl (char* chars, int charCount);
210 //[CLSCompliant (false)]
211 public unsafe abstract int GetBytesImpl (char* chars, int charCount,
212 byte* bytes, int byteCount);
215 public abstract class MonoEncoder : Encoder
217 MonoEncoding encoding;
219 public MonoEncoder (MonoEncoding encoding)
221 this.encoding = encoding;
224 public override int GetByteCount (
225 char [] chars, int index, int count, bool refresh)
228 throw new ArgumentNullException ("chars");
229 if (index < 0 || index > chars.Length)
230 throw new ArgumentOutOfRangeException
231 ("index", Strings.GetString ("ArgRange_Array"));
232 if (count < 0 || count > (chars.Length - index))
233 throw new ArgumentOutOfRangeException
234 ("count", Strings.GetString ("ArgRange_Array"));
240 fixed (char* cptr = chars) {
241 return GetByteCountImpl (
242 cptr + index, count, refresh);
247 public override int GetBytes (char [] chars, int charIndex, int charCount, byte [] bytes, int byteIndex, bool flush)
250 throw new ArgumentNullException ("chars");
252 throw new ArgumentNullException ("bytes");
253 if (charIndex < 0 || charIndex > chars.Length)
254 throw new ArgumentOutOfRangeException
255 ("charIndex", Strings.GetString ("ArgRange_Array"));
256 if (charCount < 0 || charCount > (chars.Length - charIndex))
257 throw new ArgumentOutOfRangeException
258 ("charCount", Strings.GetString ("ArgRange_Array"));
259 if (byteIndex < 0 || byteIndex > bytes.Length)
260 throw new ArgumentOutOfRangeException
261 ("byteIndex", Strings.GetString ("ArgRange_Array"));
262 if (bytes.Length - byteIndex < charCount)
263 throw new ArgumentException (Strings.GetString ("Arg_InsufficientSpace"), "bytes");
268 fixed (char* cptr = chars) {
269 fixed (byte* bptr = bytes) {
270 return GetBytesImpl (cptr + charIndex,
273 bytes.Length - byteIndex,
280 public unsafe abstract int GetByteCountImpl (char* chars, int charCount, bool refresh);
282 public unsafe abstract int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount, bool refresh);
284 public unsafe override int GetBytes (char* chars, int charCount, byte* bytes, int byteCount, bool flush)
286 return GetBytesImpl (chars, charCount, bytes, byteCount, flush);
289 public unsafe void HandleFallback (
290 char* chars, ref int charIndex, ref int charCount,
291 byte* bytes, ref int byteIndex, ref int byteCount, object state)
293 EncoderFallbackBuffer buffer = FallbackBuffer;
294 encoding.HandleFallback (ref buffer,
295 chars, ref charIndex, ref charCount,
296 bytes, ref byteIndex, ref byteCount, state);
299 /* public unsafe void HandleFallback(
300 char* chars, ref int charIndex, ref int charCount,
301 byte* bytes, ref int byteIndex, ref int byteCount)
303 HandleFallback(chars, ref charIndex, ref charCount,
304 bytes, ref byteIndex, ref byteCount, null);