Added tests for Task.WhenAll w/ empty list
[mono.git] / mcs / class / corlib / System.Text / Decoder.cs
1 /*
2  * Decoder.cs - Implementation of the "System.Text.Decoder" class.
3  *
4  * Copyright (c) 2001  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 System.Text
26 {
27
28 using System;
29 using System.Runtime.InteropServices;
30
31 [Serializable]
32 [ComVisible (true)]
33 public abstract class Decoder
34 {
35
36         // Constructor.
37         protected Decoder () {}
38
39         DecoderFallback fallback = new DecoderReplacementFallback ();
40         DecoderFallbackBuffer fallback_buffer;
41
42         [ComVisible (false)]
43         public DecoderFallback Fallback {
44                 get { return fallback; }
45                 set {
46                         if (value == null)
47                                 throw new ArgumentNullException ();
48                         fallback = value;
49                         fallback_buffer = null;
50                 }
51         }
52
53         [ComVisible (false)]
54         public DecoderFallbackBuffer FallbackBuffer {
55                 get {
56                         if (fallback_buffer == null)
57                                 fallback_buffer = fallback.CreateFallbackBuffer ();
58                         return fallback_buffer;
59                 }
60         }
61
62         // Get the number of characters needed to decode a buffer.
63         public abstract int GetCharCount (byte[] bytes, int index, int count);
64
65         // Get the characters that result from decoding a buffer.
66         public abstract int GetChars (byte[] bytes, int byteIndex, int byteCount,
67                                                                  char[] chars, int charIndex);
68
69         [ComVisible (false)]
70         public virtual int GetCharCount (byte [] bytes, int index, int count, bool flush)
71         {
72                 if (flush)
73                         Reset ();
74                 return GetCharCount (bytes, index, count);
75         }
76
77         [CLSCompliant (false)]
78         [ComVisible (false)]
79         public unsafe virtual int GetCharCount (byte* bytes, int count, bool flush)
80         {
81                 if (bytes == null)
82                         throw new ArgumentNullException ("bytes");
83                 if (count < 0)
84                         throw new ArgumentOutOfRangeException ("count");
85
86                 byte [] barr = new byte [count];
87                 Marshal.Copy ((IntPtr) bytes, barr, 0, count);
88                 return GetCharCount (barr, 0, count, flush);
89         }
90
91         public virtual int GetChars (
92                 byte[] bytes, int byteIndex, int byteCount,
93                 char[] chars, int charIndex, bool flush)
94         {
95                 CheckArguments (bytes, byteIndex, byteCount);
96                 CheckArguments (chars, charIndex);
97
98                 if (flush)
99                         Reset ();
100                 return GetChars (bytes, byteIndex, byteCount, chars, charIndex);
101         }
102
103         [CLSCompliant (false)]
104         [ComVisible (false)]
105         public unsafe virtual int GetChars (byte* bytes, int byteCount,
106                 char* chars, int charCount, bool flush)
107         {
108                 CheckArguments (chars, charCount, bytes, byteCount);
109
110                 char [] carr = new char [charCount];
111                 Marshal.Copy ((IntPtr) chars, carr, 0, charCount);
112                 byte [] barr = new byte [byteCount];
113                 Marshal.Copy ((IntPtr) bytes, barr, 0, byteCount);
114                 return GetChars (barr, 0, byteCount, carr, 0, flush);
115         }
116
117         [ComVisible (false)]
118         public virtual void Reset ()
119         {
120                 if (fallback_buffer != null)
121                         fallback_buffer.Reset ();
122         }
123
124         [CLSCompliant (false)]
125         [ComVisible (false)]
126         public unsafe virtual void Convert (
127                 byte* bytes, int byteCount,
128                 char* chars, int charCount, bool flush,
129                 out int bytesUsed, out int charsUsed, out bool completed)
130         {
131                 CheckArguments (chars, charCount, bytes, byteCount);
132
133                 bytesUsed = byteCount;
134                 while (true) {
135                         charsUsed = GetCharCount (bytes, bytesUsed, flush);
136                         if (charsUsed <= charCount)
137                                 break;
138                         flush = false;
139                         bytesUsed >>= 1;
140                 }
141                 completed = bytesUsed == byteCount;
142                 charsUsed = GetChars (bytes, bytesUsed, chars, charCount, flush);
143         }
144
145         [ComVisible (false)]
146         public virtual void Convert (
147                 byte [] bytes, int byteIndex, int byteCount,
148                 char [] chars, int charIndex, int charCount, bool flush,
149                 out int bytesUsed, out int charsUsed, out bool completed)
150         {
151                 CheckArguments (bytes, byteIndex, byteCount);
152                 if (chars == null)
153                         throw new ArgumentNullException ("chars");
154                 if (charIndex < 0)
155                         throw new ArgumentOutOfRangeException ("charIndex");
156                 if (charCount < 0 || chars.Length < charIndex + charCount)
157                         throw new ArgumentOutOfRangeException ("charCount");
158
159                 bytesUsed = byteCount;
160                 while (true) {
161                         charsUsed = GetCharCount (bytes, byteIndex, bytesUsed, flush);
162                         if (charsUsed <= charCount)
163                                 break;
164                         flush = false;
165                         bytesUsed >>= 1;
166                 }
167                 completed = bytesUsed == byteCount;
168                 charsUsed = GetChars (bytes, byteIndex, bytesUsed, chars, charIndex, flush);
169         }
170
171         void CheckArguments (char [] chars, int charIndex)
172         {
173                 if (chars == null)
174                         throw new ArgumentNullException ("chars");
175                 if (charIndex < 0 || chars.Length < charIndex)
176                         throw new ArgumentOutOfRangeException ("charIndex");
177         }
178
179         void CheckArguments (byte [] bytes, int byteIndex, int byteCount)
180         {
181                 if (bytes == null)
182                         throw new ArgumentNullException ("bytes");
183                 if (byteIndex < 0)
184                         throw new ArgumentOutOfRangeException ("byteIndex");
185                 if (byteCount < 0 || bytes.Length < byteIndex + byteCount)
186                         throw new ArgumentOutOfRangeException ("byteCount");
187         }
188
189         unsafe void CheckArguments (char* chars, int charCount, byte* bytes, int byteCount)
190         {
191                 if (chars == null)
192                         throw new ArgumentNullException ("chars");
193                 if (bytes == null)
194                         throw new ArgumentNullException ("bytes");
195                 if (charCount < 0)
196                         throw new ArgumentOutOfRangeException ("charCount");
197                 if (byteCount < 0)
198                         throw new ArgumentOutOfRangeException ("byteCount");
199         }
200 }; // class Decoder
201
202 }; // namespace System.Text