2010-06-07 Jonathan Chambers <joncham@gmail.com>
[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                 CheckArguments (chars, charIndex);
153                 if (charCount < 0 || chars.Length < charIndex + charCount)
154                         throw new ArgumentOutOfRangeException ("charCount");
155
156                 bytesUsed = byteCount;
157                 while (true) {
158                         charsUsed = GetCharCount (bytes, byteIndex, bytesUsed, flush);
159                         if (charsUsed <= charCount)
160                                 break;
161                         flush = false;
162                         bytesUsed >>= 1;
163                 }
164                 completed = bytesUsed == byteCount;
165                 charsUsed = GetChars (bytes, byteIndex, bytesUsed, chars, charIndex, flush);
166         }
167
168         void CheckArguments (char [] chars, int charIndex)
169         {
170                 if (chars == null)
171                         throw new ArgumentNullException ("chars");
172                 if (charIndex < 0 || chars.Length <= charIndex)
173                         throw new ArgumentOutOfRangeException ("charIndex");
174         }
175
176         void CheckArguments (byte [] bytes, int byteIndex, int byteCount)
177         {
178                 if (bytes == null)
179                         throw new ArgumentNullException ("bytes");
180                 if (byteIndex < 0 || bytes.Length <= byteIndex)
181                         throw new ArgumentOutOfRangeException ("byteIndex");
182                 if (byteCount < 0 || bytes.Length < byteIndex + byteCount)
183                         throw new ArgumentOutOfRangeException ("byteCount");
184         }
185
186         unsafe void CheckArguments (char* chars, int charCount, byte* bytes, int byteCount)
187         {
188                 if (chars == null)
189                         throw new ArgumentNullException ("chars");
190                 if (bytes == null)
191                         throw new ArgumentNullException ("bytes");
192                 if (charCount < 0)
193                         throw new ArgumentOutOfRangeException ("charCount");
194                 if (byteCount < 0)
195                         throw new ArgumentOutOfRangeException ("byteCount");
196         }
197 }; // class Decoder
198
199 }; // namespace System.Text