<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0-preview.1.23110.8" />

SBCSCodePageEncoding

using System.Buffers.Binary; using System.IO; using System.Runtime.CompilerServices; using System.Threading; namespace System.Text { internal sealed class SBCSCodePageEncoding : BaseCodePageEncoding { private unsafe char* _mapBytesToUnicode = null; private unsafe byte* _mapUnicodeToBytes = null; private const char UNKNOWN_CHAR = '�'; private byte _byteUnknown; private 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; } } public override bool IsSingleByte => true; public SBCSCodePageEncoding(int codePage) : this(codePage, codePage) { } public unsafe SBCSCodePageEncoding(int codePage, int dataCodePage) : base(codePage, dataCodePage) { } internal unsafe static ushort ReadUInt16(byte* pByte) { if (BitConverter.IsLittleEndian) return *(ushort*)pByte; return BinaryPrimitives.ReverseEndianness(*(ushort*)pByte); } protected unsafe override void LoadManagedCodePage() { fixed (byte* ptr = &m_codePageHeader[0]) { CodePageHeader* ptr2 = (CodePageHeader*)ptr; if (ptr2->ByteCount != 1) throw new NotSupportedException(System.SR.Format(System.SR.NotSupported_NoCodepageData, CodePage)); _byteUnknown = (byte)ptr2->ByteReplace; _charUnknown = ptr2->UnicodeReplace; int num = 66052 + iExtraBytes; byte* nativeMemory = GetNativeMemory(num); Unsafe.InitBlockUnaligned(nativeMemory, 0, (uint)num); char* ptr3 = (char*)nativeMemory; byte* ptr4 = nativeMemory + 512; byte[] array = new byte[512]; lock (BaseCodePageEncoding.s_streamLock) { BaseCodePageEncoding.s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset, SeekOrigin.Begin); int num2 = BaseCodePageEncoding.s_codePagesEncodingDataStream.Read(array, 0, array.Length); } fixed (byte* ptr5 = &array[0]) { for (int i = 0; i < 256; i++) { char c = (char)ReadUInt16(ptr5 + 2 * i); if (c != 0 || i == 0) { ptr3[i] = c; if (c != '�') ptr4[(int)c] = (byte)i; } else ptr3[i] = '�'; } } _mapBytesToUnicode = ptr3; _mapUnicodeToBytes = ptr4; } } protected unsafe override void ReadBestFitTable() { lock (InternalSyncObject) { if (arrayUnicodeBestFit == null) { byte[] array = new byte[m_dataSize - 512]; lock (BaseCodePageEncoding.s_streamLock) { BaseCodePageEncoding.s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset + 512, SeekOrigin.Begin); int num = BaseCodePageEncoding.s_codePagesEncodingDataStream.Read(array, 0, array.Length); } fixed (byte* ptr = array) { byte* ptr2 = ptr; char[] array2 = new char[256]; for (int i = 0; i < 256; i++) { array2[i] = _mapBytesToUnicode[i]; } ushort num2; while ((num2 = ReadUInt16(ptr2)) != 0) { ptr2 += 2; array2[num2] = (char)ReadUInt16(ptr2); ptr2 += 2; } arrayBytesBestFit = array2; ptr2 += 2; byte* ptr3 = ptr2; int num3 = 0; int num4 = ReadUInt16(ptr2); ptr2 += 2; while (num4 < 65536) { byte b = *ptr2; ptr2++; if (b == 1) { num4 = ReadUInt16(ptr2); ptr2 += 2; } else if (b < 32 && b > 0 && b != 30) { num4 += b; } else { if (b > 0) num3++; num4++; } } array2 = new char[num3 * 2]; ptr2 = ptr3; num4 = ReadUInt16(ptr2); ptr2 += 2; num3 = 0; while (num4 < 65536) { byte b2 = *ptr2; ptr2++; if (b2 == 1) { num4 = ReadUInt16(ptr2); ptr2 += 2; } else if (b2 < 32 && b2 > 0 && b2 != 30) { num4 += b2; } else { if (b2 == 30) { b2 = *ptr2; ptr2++; } if (b2 > 0) { array2[num3++] = (char)num4; array2[num3++] = _mapBytesToUnicode[(int)b2]; } num4++; } } arrayUnicodeBestFit = array2; } } } } public unsafe override int GetByteCount(char* chars, int count, System.Text.EncoderNLS encoder) { CheckMemorySection(); EncoderReplacementFallback encoderReplacementFallback = null; char c = ''; if (encoder != null) { c = encoder.charLeftOver; encoderReplacementFallback = (encoder.Fallback as EncoderReplacementFallback); } else encoderReplacementFallback = (base.EncoderFallback as EncoderReplacementFallback); if (encoderReplacementFallback != null && encoderReplacementFallback.MaxCharCount == 1) { if (c > '') count++; return count; } EncoderFallbackBuffer encoderFallbackBuffer = null; int num = 0; char* ptr = chars + count; 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++; } if (_mapUnicodeToBytes[(int)c2] == 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++; } return num; } public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, System.Text.EncoderNLS encoder) { CheckMemorySection(); EncoderReplacementFallback encoderReplacementFallback = null; char c = ''; if (encoder != null) { c = encoder.charLeftOver; encoderReplacementFallback = (encoder.Fallback as EncoderReplacementFallback); } else encoderReplacementFallback = (base.EncoderFallback as EncoderReplacementFallback); char* ptr = chars + charCount; byte* ptr2 = bytes; char* ptr3 = chars; if (encoderReplacementFallback != null && encoderReplacementFallback.MaxCharCount == 1) { byte b = _mapUnicodeToBytes[(int)encoderReplacementFallback.DefaultString[0]]; if (b != 0) { if (c > '') { if (byteCount == 0) ThrowBytesOverflow(encoder, true); byte* intPtr = bytes; bytes = intPtr + 1; *intPtr = b; byteCount--; } if (byteCount < charCount) { ThrowBytesOverflow(encoder, byteCount < 1); ptr = chars + byteCount; } while (chars < ptr) { char c2 = *chars; chars++; byte b2 = _mapUnicodeToBytes[(int)c2]; if (b2 == 0 && c2 != 0) *bytes = b; else *bytes = b2; bytes++; } if (encoder != null) { encoder.charLeftOver = ''; encoder.m_charsUsed = (int)(chars - ptr3); } return (int)(bytes - ptr2); } } EncoderFallbackBuffer encoderFallbackBuffer = null; byte* ptr4 = bytes + byteCount; EncoderFallbackBufferHelper encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); if (c > '') { encoderFallbackBuffer = encoder.FallbackBuffer; encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); encoderFallbackBufferHelper.InternalInitialize(chars, ptr, encoder, true); encoderFallbackBufferHelper.InternalFallback(c, ref chars); if (encoderFallbackBuffer.Remaining > ptr4 - bytes) ThrowBytesOverflow(encoder, true); } char c3; while ((c3 = ((encoderFallbackBuffer != null) ? encoderFallbackBufferHelper.InternalGetNextChar() : '')) != 0 || chars < ptr) { if (c3 == '') { c3 = *chars; chars++; } byte b3 = _mapUnicodeToBytes[(int)c3]; if (b3 == 0 && c3 != 0) { if (encoderFallbackBuffer == null) { encoderFallbackBuffer = ((encoder != null) ? encoder.FallbackBuffer : base.EncoderFallback.CreateFallbackBuffer()); encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer); encoderFallbackBufferHelper.InternalInitialize(ptr - charCount, ptr, encoder, true); } encoderFallbackBufferHelper.InternalFallback(c3, ref chars); if (encoderFallbackBuffer.Remaining > ptr4 - bytes) { chars--; encoderFallbackBufferHelper.InternalReset(); ThrowBytesOverflow(encoder, chars == ptr3); break; } } else { if (bytes >= ptr4) { if (encoderFallbackBuffer == null || !encoderFallbackBufferHelper.bFallingBack) chars--; ThrowBytesOverflow(encoder, chars == ptr3); break; } *bytes = b3; bytes++; } } if (encoder != null) { if (encoderFallbackBuffer != null && !encoderFallbackBufferHelper.bUsedEncoder) encoder.charLeftOver = ''; encoder.m_charsUsed = (int)(chars - ptr3); } return (int)(bytes - ptr2); } public unsafe override int GetCharCount(byte* bytes, int count, System.Text.DecoderNLS decoder) { CheckMemorySection(); bool flag = false; DecoderReplacementFallback decoderReplacementFallback = null; if (decoder == null) { decoderReplacementFallback = (base.DecoderFallback as DecoderReplacementFallback); flag = (base.DecoderFallback is InternalDecoderBestFitFallback); } else { decoderReplacementFallback = (decoder.Fallback as DecoderReplacementFallback); flag = (decoder.Fallback is InternalDecoderBestFitFallback); } if (flag || (decoderReplacementFallback != null && decoderReplacementFallback.MaxCharCount == 1)) return count; DecoderFallbackBuffer decoderFallbackBuffer = null; DecoderFallbackBufferHelper decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); int num = count; byte[] array = new byte[1]; byte* ptr = bytes + count; while (bytes < ptr) { char c = _mapBytesToUnicode[(int)(*bytes)]; bytes++; if (c == '�') { if (decoderFallbackBuffer == null) { decoderFallbackBuffer = ((decoder != null) ? decoder.FallbackBuffer : base.DecoderFallback.CreateFallbackBuffer()); decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(ptr - count, null); } array[0] = *(bytes - 1); num--; num += decoderFallbackBufferHelper.InternalFallback(array, bytes); } } return num; } public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, System.Text.DecoderNLS decoder) { CheckMemorySection(); bool flag = false; byte* ptr = bytes + byteCount; byte* ptr2 = bytes; char* ptr3 = chars; DecoderReplacementFallback decoderReplacementFallback = null; if (decoder == null) { decoderReplacementFallback = (base.DecoderFallback as DecoderReplacementFallback); flag = (base.DecoderFallback is InternalDecoderBestFitFallback); } else { decoderReplacementFallback = (decoder.Fallback as DecoderReplacementFallback); flag = (decoder.Fallback is InternalDecoderBestFitFallback); } if (flag || (decoderReplacementFallback != null && decoderReplacementFallback.MaxCharCount == 1)) { char c = decoderReplacementFallback?.DefaultString[0] ?? '?'; if (charCount < byteCount) { ThrowCharsOverflow(decoder, charCount < 1); ptr = bytes + charCount; } while (bytes < ptr) { char c2; if (flag) { if (arrayBytesBestFit == null) ReadBestFitTable(); c2 = arrayBytesBestFit[*bytes]; } else c2 = _mapBytesToUnicode[(int)(*bytes)]; bytes++; if (c2 == '�') *chars = c; else *chars = c2; chars++; } if (decoder != null) decoder.m_bytesUsed = (int)(bytes - ptr2); return (int)(chars - ptr3); } DecoderFallbackBuffer decoderFallbackBuffer = null; byte[] array = new byte[1]; char* ptr4 = chars + charCount; DecoderFallbackBufferHelper decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(null); while (bytes < ptr) { char c3 = _mapBytesToUnicode[(int)(*bytes)]; bytes++; if (c3 == '�') { if (decoderFallbackBuffer == null) { decoderFallbackBuffer = ((decoder != null) ? decoder.FallbackBuffer : base.DecoderFallback.CreateFallbackBuffer()); decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer); decoderFallbackBufferHelper.InternalInitialize(ptr - byteCount, ptr4); } array[0] = *(bytes - 1); if (!decoderFallbackBufferHelper.InternalFallback(array, bytes, ref chars)) { bytes--; decoderFallbackBufferHelper.InternalReset(); ThrowCharsOverflow(decoder, bytes == ptr2); break; } } else { if (chars >= ptr4) { bytes--; ThrowCharsOverflow(decoder, bytes == ptr2); break; } *chars = c3; chars++; } } if (decoder != null) decoder.m_bytesUsed = (int)(bytes - ptr2); 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; 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 = byteCount; if (base.DecoderFallback.MaxCharCount > 1) num *= base.DecoderFallback.MaxCharCount; if (num > 2147483647) throw new ArgumentOutOfRangeException("byteCount", System.SR.ArgumentOutOfRange_GetCharCountOverflow); return (int)num; } } }