<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0-preview2.19523.17" />

DBCSCodePageEncoding

using System.IO; using System.Security; using System.Threading; namespace System.Text { internal class DBCSCodePageEncoding : BaseCodePageEncoding { internal class DBCSDecoder : System.Text.DecoderNLS { internal byte bLeftOver; internal override bool HasState => bLeftOver != 0; public DBCSDecoder(DBCSCodePageEncoding encoding) : base(encoding) { } public override void Reset() { bLeftOver = 0; if (m_fallbackBuffer != null) m_fallbackBuffer.Reset(); } } [SecurityCritical] protected unsafe char* mapBytesToUnicode = null; [SecurityCritical] protected unsafe ushort* mapUnicodeToBytes = null; protected const char UNKNOWN_CHAR_FLAG = ''; protected const char UNICODE_REPLACEMENT_CHAR = '�'; protected const char LEAD_BYTE_CHAR = '￾'; private ushort _bytesUnknown; private int _byteCountUnknown; protected char charUnknown; private static object s_InternalSyncObject; private static object InternalSyncObject { get { if (s_InternalSyncObject == null) { object value = new object(); Interlocked.CompareExchange<object>(ref s_InternalSyncObject, value, (object)null); } return s_InternalSyncObject; } } [SecurityCritical] public DBCSCodePageEncoding(int codePage) : this(codePage, codePage) { } [SecurityCritical] internal unsafe DBCSCodePageEncoding(int codePage, int dataCodePage) : base(codePage, dataCodePage) { } [SecurityCritical] internal unsafe DBCSCodePageEncoding(int codePage, int dataCodePage, EncoderFallback enc, DecoderFallback dec) : base(codePage, dataCodePage, enc, dec) { } [SecurityCritical] protected unsafe override void LoadManagedCodePage() { byte[] codePageHeader = m_codePageHeader; fixed (byte* ptr = codePageHeader) { CodePageHeader* ptr2 = (CodePageHeader*)ptr; if (ptr2->ByteCount != 2) throw new NotSupportedException(System.SR.Format(System.SR.NotSupported_NoCodepageData, CodePage)); _bytesUnknown = ptr2->ByteReplace; charUnknown = ptr2->UnicodeReplace; if (base.DecoderFallback is InternalDecoderBestFitFallback) ((InternalDecoderBestFitFallback)base.DecoderFallback).cReplacement = charUnknown; _byteCountUnknown = 1; if (_bytesUnknown > 255) _byteCountUnknown++; mapUnicodeToBytes = (ushort*)((mapBytesToUnicode = (char*)GetNativeMemory(262148 + iExtraBytes)) + 65536); byte[] array = new byte[m_dataSize]; lock (BaseCodePageEncoding.s_streamLock) { BaseCodePageEncoding.s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset, SeekOrigin.Begin); BaseCodePageEncoding.s_codePagesEncodingDataStream.Read(array, 0, m_dataSize); } byte[] array2 = array; fixed (byte* ptr3 = array2) { char* ptr4 = (char*)ptr3; int num = 0; int bytes = 0; while (num < 65536) { char c = *ptr4; ptr4++; if (c == '') { num = *ptr4; ptr4++; } else if (c >= ' ' || c <= '') { switch (c) { case '￿': bytes = num; c = (char)num; goto IL_01b5; case '￾': bytes = num; goto IL_01b5; case '�': num++; break; default: { bytes = num; goto IL_01b5; } IL_01b5: if (CleanUpBytes(ref bytes)) { if (c != '￾') mapUnicodeToBytes[(int)c] = (ushort)bytes; mapBytesToUnicode[bytes] = c; } num++; break; } } else { num += c; } } } CleanUpEndBytes(mapBytesToUnicode); } } protected virtual bool CleanUpBytes(ref int bytes) { return true; } [SecurityCritical] protected unsafe virtual void CleanUpEndBytes(char* chars) { } [SecurityCritical] protected unsafe override void ReadBestFitTable() { lock (InternalSyncObject) { if (arrayUnicodeBestFit == null) { byte[] array = new byte[m_dataSize]; lock (BaseCodePageEncoding.s_streamLock) { BaseCodePageEncoding.s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset, SeekOrigin.Begin); BaseCodePageEncoding.s_codePagesEncodingDataStream.Read(array, 0, m_dataSize); } byte[] array2 = array; fixed (byte* ptr = array2) { char* ptr2 = (char*)ptr; int num = 0; while (num < 65536) { char c = *ptr2; ptr2++; if (c == '') { num = *ptr2; ptr2++; } else num = ((c >= ' ' || c <= '') ? (num + 1) : (num + c)); } char* ptr3 = ptr2; int num2 = 0; num = *ptr2; ptr2++; while (num < 65536) { char c2 = *ptr2; ptr2++; if (c2 == '') { num = *ptr2; ptr2++; } else if (c2 < ' ' && c2 > '') { num += c2; } else { if (c2 != '�') { int bytes = num; if (CleanUpBytes(ref bytes) && mapBytesToUnicode[bytes] != c2) num2++; } num++; } } char[] array3 = new char[num2 * 2]; num2 = 0; ptr2 = ptr3; num = *ptr2; ptr2++; bool flag = false; while (num < 65536) { char c3 = *ptr2; ptr2++; if (c3 == '') { num = *ptr2; ptr2++; } else if (c3 < ' ' && c3 > '') { num += c3; } else { if (c3 != '�') { int bytes2 = num; if (CleanUpBytes(ref bytes2) && mapBytesToUnicode[bytes2] != c3) { if (bytes2 != num) flag = true; array3[num2++] = (char)bytes2; array3[num2++] = c3; } } num++; } } if (flag) { for (int i = 0; i < array3.Length - 2; i += 2) { int num5 = i; char c4 = array3[i]; for (int j = i + 2; j < array3.Length; j += 2) { if (c4 > array3[j]) { c4 = array3[j]; num5 = j; } } if (num5 != i) { char c5 = array3[num5]; array3[num5] = array3[i]; array3[i] = c5; c5 = array3[num5 + 1]; array3[num5 + 1] = array3[i + 1]; array3[i + 1] = c5; } } } arrayBytesBestFit = array3; char* ptr4 = ptr2; char* intPtr = ptr2; ptr2 = intPtr + 1; int num6 = *intPtr; num2 = 0; while (num6 < 65536) { char c6 = *ptr2; ptr2++; if (c6 == '') { num6 = *ptr2; ptr2++; } else if (c6 < ' ' && c6 > '') { num6 += c6; } else { if (c6 > '') num2++; num6++; } } array3 = new char[num2 * 2]; ptr2 = ptr4; char* intPtr2 = ptr2; ptr2 = intPtr2 + 1; num6 = *intPtr2; num2 = 0; while (num6 < 65536) { char c7 = *ptr2; ptr2++; if (c7 == '') { num6 = *ptr2; ptr2++; } else if (c7 < ' ' && c7 > '') { num6 += c7; } else { if (c7 > '') { int bytes3 = c7; if (CleanUpBytes(ref bytes3)) { array3[num2++] = (char)num6; array3[num2++] = mapBytesToUnicode[bytes3]; } } num6++; } } arrayUnicodeBestFit = array3; } } } } [SecurityCritical] public unsafe override int GetByteCount(char* chars, int count, System.Text.EncoderNLS encoder) { CheckMemorySection(); char c = ''; if (encoder != null) { c = encoder.charLeftOver; if (encoder.InternalHasFallbackBuffer && encoder.FallbackBuffer.Remaining > 0) throw new ArgumentException(System.SR.Format(System.SR.Argument_EncoderFallbackNotEmpty, EncodingName, encoder.Fallback.GetType())); } int num = 0; char* ptr = chars + count; EncoderFallbackBuffer encoderFallbackBuffer = null; EncoderFallbackBufferHelper encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); if (c > '') { encoderFallbackBuffer = encoder.FallbackBuffer; encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); encoderFallbackBufferHelper.InternalInitialize(chars, ptr, encoder, false); encoderFallbackBufferHelper.InternalFallback(c, ref chars); } char c2; while ((c2 = ((encoderFallbackBuffer != null) ? encoderFallbackBufferHelper.InternalGetNextChar() : '')) != 0 || chars < ptr) { if (c2 == '') { c2 = *chars; chars++; } ushort num2 = mapUnicodeToBytes[(int)c2]; if (num2 == 0 && c2 != 0) { if (encoderFallbackBuffer == null) { encoderFallbackBuffer = ((encoder != null) ? encoder.FallbackBuffer : base.EncoderFallback.CreateFallbackBuffer()); encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); encoderFallbackBufferHelper.InternalInitialize(ptr - count, ptr, encoder, false); } encoderFallbackBufferHelper.InternalFallback(c2, ref chars); } else { num++; if (num2 >= 256) num++; } } return num; } [SecurityCritical] public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, System.Text.EncoderNLS encoder) { CheckMemorySection(); EncoderFallbackBuffer encoderFallbackBuffer = null; char* ptr = chars + charCount; char* ptr2 = chars; byte* ptr3 = bytes; byte* ptr4 = bytes + byteCount; EncoderFallbackBufferHelper encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); char c = ''; if (encoder != null) { c = encoder.charLeftOver; encoderFallbackBuffer = encoder.FallbackBuffer; encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); encoderFallbackBufferHelper.InternalInitialize(chars, ptr, encoder, true); if (encoder.m_throwOnOverflow && encoderFallbackBuffer.Remaining > 0) throw new ArgumentException(System.SR.Format(System.SR.Argument_EncoderFallbackNotEmpty, EncodingName, encoder.Fallback.GetType())); if (c > '') encoderFallbackBufferHelper.InternalFallback(c, ref chars); } char c2; while ((c2 = ((encoderFallbackBuffer != null) ? encoderFallbackBufferHelper.InternalGetNextChar() : '')) != 0 || chars < ptr) { if (c2 == '') { c2 = *chars; chars++; } ushort num = mapUnicodeToBytes[(int)c2]; if (num == 0 && c2 != 0) { if (encoderFallbackBuffer == null) { encoderFallbackBuffer = base.EncoderFallback.CreateFallbackBuffer(); encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); encoderFallbackBufferHelper.InternalInitialize(ptr - charCount, ptr, encoder, true); } encoderFallbackBufferHelper.InternalFallback(c2, ref chars); } else { if (num >= 256) { if (bytes + 1 >= ptr4) { if (encoderFallbackBuffer == null || !encoderFallbackBufferHelper.bFallingBack) chars--; else encoderFallbackBuffer.MovePrevious(); ThrowBytesOverflow(encoder, chars == ptr2); break; } *bytes = (byte)(num >> 8); bytes++; } else if (bytes >= ptr4) { if (encoderFallbackBuffer == null || !encoderFallbackBufferHelper.bFallingBack) chars--; else encoderFallbackBuffer.MovePrevious(); ThrowBytesOverflow(encoder, chars == ptr2); break; } *bytes = (byte)(num & 255); bytes++; } } if (encoder != null) { if (encoderFallbackBuffer != null && !encoderFallbackBufferHelper.bUsedEncoder) encoder.charLeftOver = ''; encoder.m_charsUsed = (int)(chars - ptr2); } return (int)(bytes - ptr3); } [SecurityCritical] public unsafe override int GetCharCount(byte* bytes, int count, System.Text.DecoderNLS baseDecoder) { CheckMemorySection(); DBCSDecoder dBCSDecoder = (DBCSDecoder)baseDecoder; DecoderFallbackBuffer decoderFallbackBuffer = null; byte* ptr = bytes + count; int num = count; DecoderFallbackBufferHelper decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); if (dBCSDecoder != null && dBCSDecoder.bLeftOver > 0) { if (count == 0) { if (!dBCSDecoder.MustFlush) return 0; decoderFallbackBuffer = dBCSDecoder.FallbackBuffer; decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(bytes, null); byte[] bytes2 = new byte[1] { dBCSDecoder.bLeftOver }; return decoderFallbackBufferHelper.InternalFallback(bytes2, bytes); } int num2 = dBCSDecoder.bLeftOver << 8; num2 |= *bytes; bytes++; if (mapBytesToUnicode[num2] == '' && num2 != 0) { num--; decoderFallbackBuffer = dBCSDecoder.FallbackBuffer; decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(ptr - count, null); byte[] bytes3 = new byte[2] { (byte)(num2 >> 8), (byte)num2 }; num += decoderFallbackBufferHelper.InternalFallback(bytes3, bytes); } } while (bytes < ptr) { int num3 = *bytes; bytes++; char c = mapBytesToUnicode[num3]; if (c == '￾') { num--; if (bytes < ptr) { num3 <<= 8; num3 |= *bytes; bytes++; c = mapBytesToUnicode[num3]; } else { if (dBCSDecoder != null && !dBCSDecoder.MustFlush) break; num++; c = ''; } } if (c == '' && num3 != 0) { if (decoderFallbackBuffer == null) { decoderFallbackBuffer = ((dBCSDecoder != null) ? dBCSDecoder.FallbackBuffer : base.DecoderFallback.CreateFallbackBuffer()); decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(ptr - count, null); } num--; byte[] array = null; array = ((num3 >= 256) ? new byte[2] { (byte)(num3 >> 8), (byte)num3 } : new byte[1] { (byte)num3 }); num += decoderFallbackBufferHelper.InternalFallback(array, bytes); } } return num; } [SecurityCritical] public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, System.Text.DecoderNLS baseDecoder) { CheckMemorySection(); DBCSDecoder dBCSDecoder = (DBCSDecoder)baseDecoder; byte* ptr = bytes; byte* ptr2 = bytes + byteCount; char* ptr3 = chars; char* ptr4 = chars + charCount; bool flag = false; DecoderFallbackBuffer decoderFallbackBuffer = null; DecoderFallbackBufferHelper decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); if (dBCSDecoder != null && dBCSDecoder.bLeftOver > 0) { if (byteCount == 0) { if (!dBCSDecoder.MustFlush) return 0; decoderFallbackBuffer = dBCSDecoder.FallbackBuffer; decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(bytes, ptr4); byte[] bytes2 = new byte[1] { dBCSDecoder.bLeftOver }; if (!decoderFallbackBufferHelper.InternalFallback(bytes2, bytes, ref chars)) ThrowCharsOverflow(dBCSDecoder, true); dBCSDecoder.bLeftOver = 0; return (int)(chars - ptr3); } int num = dBCSDecoder.bLeftOver << 8; num |= *bytes; bytes++; char c = mapBytesToUnicode[num]; if (c == '' && num != 0) { decoderFallbackBuffer = dBCSDecoder.FallbackBuffer; decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(ptr2 - byteCount, ptr4); byte[] bytes3 = new byte[2] { (byte)(num >> 8), (byte)num }; if (!decoderFallbackBufferHelper.InternalFallback(bytes3, bytes, ref chars)) ThrowCharsOverflow(dBCSDecoder, true); } else { if (chars >= ptr4) ThrowCharsOverflow(dBCSDecoder, true); char* intPtr = chars; chars = intPtr + 1; *intPtr = c; } } while (bytes < ptr2) { int num2 = *bytes; bytes++; char c2 = mapBytesToUnicode[num2]; if (c2 == '￾') { if (bytes < ptr2) { num2 <<= 8; num2 |= *bytes; bytes++; c2 = mapBytesToUnicode[num2]; } else { if (dBCSDecoder != null && !dBCSDecoder.MustFlush) { flag = true; dBCSDecoder.bLeftOver = (byte)num2; break; } c2 = ''; } } if (c2 == '' && num2 != 0) { if (decoderFallbackBuffer == null) { decoderFallbackBuffer = ((dBCSDecoder != null) ? dBCSDecoder.FallbackBuffer : base.DecoderFallback.CreateFallbackBuffer()); decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(ptr2 - byteCount, ptr4); } byte[] array = null; array = ((num2 >= 256) ? new byte[2] { (byte)(num2 >> 8), (byte)num2 } : new byte[1] { (byte)num2 }); if (!decoderFallbackBufferHelper.InternalFallback(array, bytes, ref chars)) { bytes -= array.Length; decoderFallbackBufferHelper.InternalReset(); ThrowCharsOverflow(dBCSDecoder, bytes == ptr); break; } } else { if (chars >= ptr4) { bytes--; if (num2 >= 256) bytes--; ThrowCharsOverflow(dBCSDecoder, bytes == ptr); break; } char* intPtr2 = chars; chars = intPtr2 + 1; *intPtr2 = c2; } } if (dBCSDecoder != null) { if (!flag) dBCSDecoder.bLeftOver = 0; dBCSDecoder.m_bytesUsed = (int)(bytes - ptr); } return (int)(chars - ptr3); } public override int GetMaxByteCount(int charCount) { if (charCount < 0) throw new ArgumentOutOfRangeException("charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum); long num = (long)charCount + 1; if (base.EncoderFallback.MaxCharCount > 1) num *= base.EncoderFallback.MaxCharCount; num *= 2; if (num > 2147483647) throw new ArgumentOutOfRangeException("charCount", System.SR.ArgumentOutOfRange_GetByteCountOverflow); return (int)num; } public override int GetMaxCharCount(int byteCount) { if (byteCount < 0) throw new ArgumentOutOfRangeException("byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum); long num = (long)byteCount + 1; if (base.DecoderFallback.MaxCharCount > 1) num *= base.DecoderFallback.MaxCharCount; if (num > 2147483647) throw new ArgumentOutOfRangeException("byteCount", System.SR.ArgumentOutOfRange_GetCharCountOverflow); return (int)num; } public override Decoder GetDecoder() { return new DBCSDecoder(this); } } }