Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
DecoderDBCS.cs
Go to the documentation of this file.
2
3namespace System.Text;
4
5internal sealed class DecoderDBCS : Decoder
6{
7 private readonly Encoding _encoding;
8
9 private readonly byte[] _leadByteRanges = new byte[10];
10
11 private readonly int _rangesCount;
12
13 private byte _leftOverLeadByte;
14
15 internal DecoderDBCS(Encoding encoding)
16 {
17 _encoding = encoding;
18 _rangesCount = global::Interop.Kernel32.GetLeadByteRanges(_encoding.CodePage, _leadByteRanges);
19 Reset();
20 }
21
22 private bool IsLeadByte(byte b)
23 {
24 if (b < _leadByteRanges[0])
25 {
26 return false;
27 }
28 for (int i = 0; i < _rangesCount; i += 2)
29 {
30 if (b >= _leadByteRanges[i] && b <= _leadByteRanges[i + 1])
31 {
32 return true;
33 }
34 }
35 return false;
36 }
37
38 public override void Reset()
39 {
41 }
42
43 public override int GetCharCount(byte[] bytes, int index, int count)
44 {
45 return GetCharCount(bytes, index, count, flush: false);
46 }
47
48 public unsafe override int GetCharCount(byte[] bytes, int index, int count, bool flush)
49 {
50 if (bytes == null)
51 {
53 }
54 if (index < 0 || count < 0)
55 {
57 }
58 if (bytes.Length - index < count)
59 {
61 }
62 if (count == 0 && (_leftOverLeadByte == 0 || !flush))
63 {
64 return 0;
65 }
66 fixed (byte* ptr = bytes)
67 {
68 Unsafe.SkipInit(out byte b);
69 byte* bytes2 = ((ptr == null) ? (&b) : (ptr + index));
70 return GetCharCount(bytes2, count, flush);
71 }
72 }
73
74 private unsafe int ConvertWithLeftOverByte(byte* bytes, int count, char* chars, int charCount)
75 {
76 byte* ptr = stackalloc byte[2];
77 *ptr = _leftOverLeadByte;
78 int num = 0;
79 if (count > 0)
80 {
81 ptr[1] = *bytes;
82 num++;
83 }
85 if (count - num > 0)
86 {
87 num2 += OSEncoding.MultiByteToWideChar(_encoding.CodePage, bytes + num, count - num, (chars == null) ? null : (chars + num2), (chars != null) ? (charCount - num2) : 0);
88 }
89 return num2;
90 }
91
92 public unsafe override int GetCharCount(byte* bytes, int count, bool flush)
93 {
94 if (bytes == null)
95 {
97 }
98 if (count < 0)
99 {
101 }
102 bool flag = count > 0 && !flush && IsLastByteALeadByte(bytes, count);
103 if (flag)
104 {
105 count--;
106 }
107 if (_leftOverLeadByte == 0)
108 {
109 if (count <= 0)
110 {
111 return 0;
112 }
114 }
115 if (count == 0 && !flag && !flush)
116 {
117 return 0;
118 }
119 return ConvertWithLeftOverByte(bytes, count, null, 0);
120 }
121
122 public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
123 {
124 return GetChars(bytes, byteIndex, byteCount, chars, charIndex, flush: false);
125 }
126
127 public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, bool flush)
128 {
129 if (bytes == null || chars == null)
130 {
131 throw new ArgumentNullException((bytes == null) ? "bytes" : "chars", System.SR.ArgumentNull_Array);
132 }
133 if (byteIndex < 0 || byteCount < 0)
134 {
135 throw new ArgumentOutOfRangeException((byteIndex < 0) ? "byteIndex" : "byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
136 }
137 if (bytes.Length - byteIndex < byteCount)
138 {
140 }
141 if (charIndex < 0 || charIndex > chars.Length)
142 {
144 }
145 if (chars.Length == 0)
146 {
147 return 0;
148 }
149 if (byteCount == 0 && (_leftOverLeadByte == 0 || !flush))
150 {
151 return 0;
152 }
153 fixed (char* ptr2 = &chars[0])
154 {
155 fixed (byte* ptr = bytes)
156 {
157 Unsafe.SkipInit(out byte b);
158 byte* bytes2 = ((ptr == null) ? (&b) : (ptr + byteIndex));
159 return GetChars(bytes2, byteCount, ptr2 + charIndex, chars.Length - charIndex, flush);
160 }
161 }
162 }
163
164 public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, bool flush)
165 {
166 if (chars == null || bytes == null)
167 {
168 throw new ArgumentNullException((chars == null) ? "chars" : "bytes", System.SR.ArgumentNull_Array);
169 }
170 if (byteCount < 0 || charCount < 0)
171 {
172 throw new ArgumentOutOfRangeException((byteCount < 0) ? "byteCount" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
173 }
174 if (charCount == 0)
175 {
176 return 0;
177 }
178 byte b = (byte)((byteCount > 0 && !flush && IsLastByteALeadByte(bytes, byteCount)) ? bytes[byteCount - 1] : 0);
179 if (b != 0)
180 {
181 byteCount--;
182 }
183 if (_leftOverLeadByte == 0)
184 {
185 if (byteCount <= 0)
186 {
188 return 0;
189 }
192 return result;
193 }
194 if (byteCount == 0 && b == 0 && !flush)
195 {
196 return 0;
197 }
200 return result2;
201 }
202
203 public unsafe override void Convert(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
204 {
205 if (bytes == null || chars == null)
206 {
207 throw new ArgumentNullException((bytes == null) ? "bytes" : "chars", System.SR.ArgumentNull_Array);
208 }
209 if (byteIndex < 0 || byteCount < 0)
210 {
211 throw new ArgumentOutOfRangeException((byteIndex < 0) ? "byteIndex" : "byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
212 }
213 if (charIndex < 0 || charCount < 0)
214 {
215 throw new ArgumentOutOfRangeException((charIndex < 0) ? "charIndex" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
216 }
217 if (bytes.Length - byteIndex < byteCount)
218 {
220 }
221 if (chars.Length - charIndex < charCount)
222 {
224 }
225 if (charCount == 0 || (bytes.Length == 0 && (_leftOverLeadByte == 0 || !flush)))
226 {
227 bytesUsed = 0;
228 charsUsed = 0;
229 completed = false;
230 return;
231 }
232 fixed (char* ptr2 = &chars[0])
233 {
234 fixed (byte* ptr = bytes)
235 {
236 Unsafe.SkipInit(out byte b);
237 byte* bytes2 = ((ptr == null) ? (&b) : (ptr + byteIndex));
238 Convert(bytes2, byteCount, ptr2 + charIndex, charCount, flush, out bytesUsed, out charsUsed, out completed);
239 }
240 }
241 }
242
243 public unsafe override void Convert(byte* bytes, int byteCount, char* chars, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
244 {
245 if (chars == null || bytes == null)
246 {
247 throw new ArgumentNullException((chars == null) ? "chars" : "bytes", System.SR.ArgumentNull_Array);
248 }
249 if (byteCount < 0 || charCount < 0)
250 {
251 throw new ArgumentOutOfRangeException((byteCount < 0) ? "byteCount" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
252 }
253 int num;
254 for (num = byteCount; num > 0; num /= 2)
255 {
256 int charCount2 = GetCharCount(bytes, num, flush);
257 if (charCount2 <= charCount)
258 {
259 break;
260 }
261 }
262 if (num > 0)
263 {
264 charsUsed = GetChars(bytes, num, chars, charCount, flush);
265 bytesUsed = num;
266 completed = _leftOverLeadByte == 0 && byteCount == num;
267 }
268 else
269 {
270 bytesUsed = 0;
271 charsUsed = 0;
272 completed = false;
273 }
274 }
275
276 private unsafe bool IsLastByteALeadByte(byte* bytes, int count)
277 {
278 if (!IsLeadByte(bytes[count - 1]))
279 {
280 return false;
281 }
282 int i = 0;
283 if (_leftOverLeadByte != 0)
284 {
285 i++;
286 }
287 for (; i < count; i++)
288 {
289 if (IsLeadByte(bytes[i]))
290 {
291 i++;
292 if (i >= count)
293 {
294 return true;
295 }
296 }
297 }
298 return false;
299 }
300}
static string ArgumentOutOfRange_Index
Definition SR.cs:30
static string ArgumentOutOfRange_IndexCountBuffer
Definition SR.cs:78
static string ArgumentNull_Array
Definition SR.cs:24
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
Definition SR.cs:7
bool IsLeadByte(byte b)
unsafe bool IsLastByteALeadByte(byte *bytes, int count)
unsafe override int GetCharCount(byte *bytes, int count, bool flush)
readonly byte[] _leadByteRanges
Definition DecoderDBCS.cs:9
readonly Encoding _encoding
Definition DecoderDBCS.cs:7
unsafe override void Convert(byte *bytes, int byteCount, char *chars, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
unsafe override int GetChars(byte *bytes, int byteCount, char *chars, int charCount, bool flush)
DecoderDBCS(Encoding encoding)
override void Reset()
unsafe int ConvertWithLeftOverByte(byte *bytes, int count, char *chars, int charCount)
unsafe override int GetCharCount(byte[] bytes, int index, int count, bool flush)
override int GetCharCount(byte[] bytes, int index, int count)
unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, bool flush)
override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
readonly int _rangesCount
unsafe override void Convert(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
virtual int CodePage
Definition Encoding.cs:515
static unsafe int MultiByteToWideChar(int codePage, byte *pBytes, int byteCount, char *pChars, int count)