2 * ASCIIEncoding.cs - Implementation of the "System.Text.ASCIIEncoding" class.
4 * Copyright (c) 2001 Southern Storm Software, Pty Ltd
5 * Copyright (C) 2003 Novell, Inc.
6 * Copyright (C) 2004 Novell, Inc (http://www.novell.com)
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
31 using System.Runtime.InteropServices;
37 [MonoTODO ("Serialization format not compatible with .NET")]
38 public class ASCIIEncoding : Encoding
40 // Magic number used by Windows for "ASCII".
41 internal const int ASCII_CODE_PAGE = 20127;
44 public ASCIIEncoding () : base(ASCII_CODE_PAGE) {
45 body_name = header_name = web_name= "us-ascii";
46 encoding_name = "US-ASCII";
47 is_mail_news_display = true;
48 is_mail_news_save = true;
53 public override bool IsSingleByte {
58 // Get the number of bytes needed to encode a character buffer.
59 public override int GetByteCount (char[] chars, int index, int count)
62 throw new ArgumentNullException ("chars");
64 if (index < 0 || index > chars.Length) {
65 throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
67 if (count < 0 || count > (chars.Length - index)) {
68 throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
73 // Convenience wrappers for "GetByteCount".
74 public override int GetByteCount (String s)
77 throw new ArgumentNullException ("s");
82 // Get the bytes that result from encoding a character buffer.
83 public override int GetBytes (char[] chars, int charIndex, int charCount,
84 byte[] bytes, int byteIndex)
87 // well, yes, I know this #if is ugly, but I think it is the simplest switch.
88 EncoderFallbackBuffer buffer = null;
89 char [] fallback_chars = null;
90 return GetBytes (chars, charIndex, charCount, bytes,
91 byteIndex, ref buffer, ref fallback_chars);
94 int GetBytes (char[] chars, int charIndex, int charCount,
95 byte[] bytes, int byteIndex,
96 ref EncoderFallbackBuffer buffer,
97 ref char [] fallback_chars)
101 throw new ArgumentNullException ("chars");
104 throw new ArgumentNullException ("bytes");
106 if (charIndex < 0 || charIndex > chars.Length) {
107 throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
109 if (charCount < 0 || charCount > (chars.Length - charIndex)) {
110 throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
112 if (byteIndex < 0 || byteIndex > bytes.Length) {
113 throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
115 if ((bytes.Length - byteIndex) < charCount) {
116 throw new ArgumentException (_("Arg_InsufficientSpace"));
118 int count = charCount;
120 while (count-- > 0) {
121 ch = chars [charIndex++];
122 if (ch < (char)0x80) {
123 bytes [byteIndex++] = (byte)ch;
127 buffer = EncoderFallback.CreateFallbackBuffer ();
128 if (Char.IsSurrogate (ch) && count > 1 &&
129 Char.IsSurrogate (chars [charIndex]))
130 buffer.Fallback (ch, chars [charIndex], charIndex++ - 1);
132 buffer.Fallback (ch, charIndex - 1);
133 if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
134 fallback_chars = new char [buffer.Remaining];
135 for (int i = 0; i < fallback_chars.Length; i++)
136 fallback_chars [i] = buffer.GetNextChar ();
137 byteIndex += GetBytes (fallback_chars, 0,
138 fallback_chars.Length, bytes, byteIndex,
139 ref buffer, ref fallback_chars);
141 bytes [byteIndex++] = (byte)'?';
148 // Convenience wrappers for "GetBytes".
149 public override int GetBytes (String s, int charIndex, int charCount, byte[] bytes, int byteIndex)
152 // I know this #if is ugly, but I think it is the simplest switch.
153 EncoderFallbackBuffer buffer = null;
154 char [] fallback_chars = null;
155 return GetBytes (s, charIndex, charCount, bytes, byteIndex,
156 ref buffer, ref fallback_chars);
159 int GetBytes (String s, int charIndex, int charCount,
160 byte[] bytes, int byteIndex,
161 ref EncoderFallbackBuffer buffer,
162 ref char [] fallback_chars)
166 throw new ArgumentNullException ("s");
169 throw new ArgumentNullException ("bytes");
171 if (charIndex < 0 || charIndex > s.Length) {
172 throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_StringIndex"));
174 if (charCount < 0 || charCount > (s.Length - charIndex)) {
175 throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_StringRange"));
177 if (byteIndex < 0 || byteIndex > bytes.Length) {
178 throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
180 if ((bytes.Length - byteIndex) < charCount) {
181 throw new ArgumentException (_("Arg_InsufficientSpace"));
183 int count = charCount;
185 while (count-- > 0) {
186 ch = s [charIndex++];
187 if (ch < (char)0x80) {
188 bytes [byteIndex++] = (byte)ch;
192 buffer = EncoderFallback.CreateFallbackBuffer ();
193 if (Char.IsSurrogate (ch) && count > 1 &&
194 Char.IsSurrogate (s [charIndex]))
195 buffer.Fallback (ch, s [charIndex], charIndex++ - 1);
197 buffer.Fallback (ch, charIndex - 1);
198 if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
199 fallback_chars = new char [buffer.Remaining];
200 for (int i = 0; i < fallback_chars.Length; i++)
201 fallback_chars [i] = buffer.GetNextChar ();
202 byteIndex += GetBytes (fallback_chars, 0,
203 fallback_chars.Length, bytes, byteIndex,
204 ref buffer, ref fallback_chars);
206 bytes [byteIndex++] = (byte)'?';
213 // Get the number of characters needed to decode a byte buffer.
214 public override int GetCharCount (byte[] bytes, int index, int count)
217 throw new ArgumentNullException ("bytes");
219 if (index < 0 || index > bytes.Length) {
220 throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
222 if (count < 0 || count > (bytes.Length - index)) {
223 throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
228 // Get the characters that result from decoding a byte buffer.
229 public override int GetChars (byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
232 // well, yes, I know this #if is ugly, but I think it is the simplest switch.
233 DecoderFallbackBuffer buffer = null;
234 return GetChars (bytes, byteIndex, byteCount, chars,
235 charIndex, ref buffer);
238 int GetChars (byte[] bytes, int byteIndex, int byteCount,
239 char[] chars, int charIndex,
240 ref DecoderFallbackBuffer buffer)
244 throw new ArgumentNullException ("bytes");
246 throw new ArgumentNullException ("chars");
247 if (byteIndex < 0 || byteIndex > bytes.Length)
248 throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
249 if (byteCount < 0 || byteCount > (bytes.Length - byteIndex))
250 throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array"));
251 if (charIndex < 0 || charIndex > chars.Length)
252 throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
254 if ((chars.Length - charIndex) < byteCount)
255 throw new ArgumentException (_("Arg_InsufficientSpace"));
257 int count = byteCount;
258 while (count-- > 0) {
259 char c = (char) bytes [byteIndex++];
261 chars [charIndex++] = c;
265 buffer = DecoderFallback.CreateFallbackBuffer ();
266 buffer.Fallback (bytes, byteIndex);
267 while (buffer.Remaining > 0)
268 chars [charIndex++] = buffer.GetNextChar ();
270 chars [charIndex++] = '?';
277 // Get the maximum number of bytes needed to encode a
278 // specified number of characters.
279 public override int GetMaxByteCount (int charCount)
282 throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_NonNegative"));
287 // Get the maximum number of characters needed to decode a
288 // specified number of bytes.
289 public override int GetMaxCharCount (int byteCount)
292 throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_NonNegative"));
297 // Decode a buffer of bytes into a string.
298 public override String GetString (byte[] bytes, int index, int count)
301 throw new ArgumentNullException ("bytes");
303 if (index < 0 || index > bytes.Length) {
304 throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
306 if (count < 0 || count > (bytes.Length - index)) {
307 throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
313 fixed (byte* bytePtr = bytes) {
314 string s = string.InternalAllocateStr (count);
316 fixed (char* charPtr = s) {
317 byte* currByte = bytePtr + index;
318 byte* lastByte = currByte + count;
319 char* currChar = charPtr;
321 while (currByte < lastByte) {
323 byte b = currByte++ [0];
324 currChar++ [0] = b <= 0x7F ? (char) b : (char) '?';
326 // GetString is incompatible with GetChars
327 currChar++ [0] = (char) (currByte++ [0] & 0x7F);
338 [CLSCompliantAttribute (false)]
340 public unsafe override int GetBytes (char *chars, int charCount, byte *bytes, int byteCount)
343 throw new ArgumentNullException ("chars");
345 throw new ArgumentNullException ("bytes");
347 throw new ArgumentOutOfRangeException ("charCount");
349 throw new ArgumentOutOfRangeException ("byteCount");
351 if (byteCount < charCount)
352 throw new ArgumentException ("bytecount is less than the number of bytes required", "byteCount");
354 for (int i = 0; i < charCount; i++){
356 bytes [i] = (byte) ((c < (char) 0x80) ? c : '?');
361 [CLSCompliantAttribute(false)]
363 public unsafe override int GetChars (byte *bytes, int byteCount, char *chars, int charCount)
366 throw new ArgumentNullException ("bytes");
368 throw new ArgumentNullException ("chars");
370 throw new ArgumentOutOfRangeException ("charCount");
372 throw new ArgumentOutOfRangeException ("byteCount");
373 if (charCount < byteCount)
374 throw new ArgumentException ("charcount is less than the number of bytes required", "charCount");
376 for (int i = 0; i < byteCount; i++){
378 chars [i] = b > 127 ? '?' : (char) b;
384 [CLSCompliantAttribute(false)]
386 public unsafe override int GetCharCount (byte *bytes, int count)
391 [CLSCompliantAttribute(false)]
393 public unsafe override int GetByteCount (char *chars, int count)
398 // This routine is gone in 2.x
399 public override String GetString (byte[] bytes)
402 throw new ArgumentNullException ("bytes");
405 return GetString (bytes, 0, bytes.Length);
410 [MonoTODO ("we have simple override to match method signature.")]
412 public override Decoder GetDecoder ()
414 return base.GetDecoder ();
417 [MonoTODO ("we have simple override to match method signature.")]
419 public override Encoder GetEncoder ()
421 return base.GetEncoder ();
424 }; // class ASCIIEncoding
426 }; // namespace System.Text