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);
}
}
}