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

BaseCodePageEncoding

using Microsoft.Win32.SafeHandles; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Security; namespace System.Text { internal abstract class BaseCodePageEncoding : EncodingNLS { [StructLayout(LayoutKind.Explicit)] internal struct CodePageDataFileHeader { [FieldOffset(0)] internal char TableName; [FieldOffset(32)] internal ushort Version; [FieldOffset(40)] internal short CodePageCount; [FieldOffset(42)] internal short unused1; } [StructLayout(LayoutKind.Explicit, Pack = 2)] internal struct CodePageIndex { [FieldOffset(0)] internal char CodePageName; [FieldOffset(32)] internal short CodePage; [FieldOffset(34)] internal short ByteCount; [FieldOffset(36)] internal int Offset; } [StructLayout(LayoutKind.Explicit)] internal struct CodePageHeader { [FieldOffset(0)] internal char CodePageName; [FieldOffset(32)] internal ushort VersionMajor; [FieldOffset(34)] internal ushort VersionMinor; [FieldOffset(36)] internal ushort VersionRevision; [FieldOffset(38)] internal ushort VersionBuild; [FieldOffset(40)] internal short CodePage; [FieldOffset(42)] internal short ByteCount; [FieldOffset(44)] internal char UnicodeReplace; [FieldOffset(46)] internal ushort ByteReplace; } internal const string CODE_PAGE_DATA_FILE_NAME = "codepages.nlp"; protected int dataTableCodePage; protected int iExtraBytes; protected char[] arrayUnicodeBestFit; protected char[] arrayBytesBestFit; private const int CODEPAGE_DATA_FILE_HEADER_SIZE = 44; private const int CODEPAGE_HEADER_SIZE = 48; private static byte[] s_codePagesDataHeader = new byte[44]; protected static Stream s_codePagesEncodingDataStream = GetEncodingDataStream("codepages.nlp"); protected static readonly object s_streamLock = new object(); protected byte[] m_codePageHeader = new byte[48]; protected int m_firstDataWordOffset; protected int m_dataSize; [SecurityCritical] protected SafeAllocHHandle safeNativeMemoryHandle; [SecurityCritical] internal BaseCodePageEncoding(int codepage) : this(codepage, codepage) { } [SecurityCritical] internal BaseCodePageEncoding(int codepage, int dataCodePage) : base(codepage, new InternalEncoderBestFitFallback(null), new InternalDecoderBestFitFallback(null)) { SetFallbackEncoding(); dataTableCodePage = dataCodePage; LoadCodePageTables(); } internal BaseCodePageEncoding(int codepage, int dataCodePage, EncoderFallback enc, DecoderFallback dec) : base(codepage, enc, dec) { dataTableCodePage = dataCodePage; LoadCodePageTables(); } private void SetFallbackEncoding() { (base.EncoderFallback as InternalEncoderBestFitFallback).encoding = this; (base.DecoderFallback as InternalDecoderBestFitFallback).encoding = this; } internal static Stream GetEncodingDataStream(string tableName) { Stream manifestResourceStream = typeof(CodePagesEncodingProvider).GetTypeInfo().get_Assembly().GetManifestResourceStream(tableName); if (manifestResourceStream == null) throw new InvalidOperationException(); manifestResourceStream.Read(s_codePagesDataHeader, 0, s_codePagesDataHeader.Length); return manifestResourceStream; } [SecurityCritical] private void LoadCodePageTables() { if (!FindCodePage(dataTableCodePage)) throw new NotSupportedException(System.SR.Format(System.SR.NotSupported_NoCodepageData, CodePage)); LoadManagedCodePage(); } [SecurityCritical] private unsafe bool FindCodePage(int codePage) { byte[] array = new byte[sizeof(CodePageIndex)]; lock (s_streamLock) { s_codePagesEncodingDataStream.Seek(44, SeekOrigin.Begin); byte[] array2 = s_codePagesDataHeader; int codePageCount; fixed (byte* ptr = array2) { CodePageDataFileHeader* ptr2 = (CodePageDataFileHeader*)ptr; codePageCount = ptr2->CodePageCount; } array2 = array; fixed (byte* ptr3 = array2) { CodePageIndex* ptr4 = (CodePageIndex*)ptr3; for (int i = 0; i < codePageCount; i++) { s_codePagesEncodingDataStream.Read(array, 0, array.Length); if (ptr4->CodePage == codePage) { long position = s_codePagesEncodingDataStream.Position; s_codePagesEncodingDataStream.Seek(ptr4->Offset, SeekOrigin.Begin); s_codePagesEncodingDataStream.Read(m_codePageHeader, 0, m_codePageHeader.Length); m_firstDataWordOffset = (int)s_codePagesEncodingDataStream.Position; if (i == codePageCount - 1) m_dataSize = (int)(s_codePagesEncodingDataStream.Length - ptr4->Offset - m_codePageHeader.Length); else { s_codePagesEncodingDataStream.Seek(position, SeekOrigin.Begin); int offset = ptr4->Offset; s_codePagesEncodingDataStream.Read(array, 0, array.Length); m_dataSize = ptr4->Offset - offset - m_codePageHeader.Length; } return true; } } ptr3 = null; } } return false; } [SecurityCritical] internal unsafe static int GetCodePageByteSize(int codePage) { byte[] array = new byte[sizeof(CodePageIndex)]; lock (s_streamLock) { s_codePagesEncodingDataStream.Seek(44, SeekOrigin.Begin); byte[] array2 = s_codePagesDataHeader; int codePageCount; fixed (byte* ptr = array2) { CodePageDataFileHeader* ptr2 = (CodePageDataFileHeader*)ptr; codePageCount = ptr2->CodePageCount; } array2 = array; fixed (byte* ptr3 = array2) { CodePageIndex* ptr4 = (CodePageIndex*)ptr3; for (int i = 0; i < codePageCount; i++) { s_codePagesEncodingDataStream.Read(array, 0, array.Length); if (ptr4->CodePage == codePage) return ptr4->ByteCount; } ptr3 = null; } } return 0; } [SecurityCritical] protected abstract void LoadManagedCodePage(); [SecurityCritical] protected unsafe byte* GetNativeMemory(int iSize) { if (safeNativeMemoryHandle == null) { byte* value = (byte*)(void*)Marshal.AllocHGlobal(iSize); safeNativeMemoryHandle = new SafeAllocHHandle((IntPtr)(void*)value); } return (byte*)(void*)safeNativeMemoryHandle.DangerousGetHandle(); } [SecurityCritical] protected abstract void ReadBestFitTable(); [SecuritySafeCritical] internal char[] GetBestFitUnicodeToBytesData() { if (arrayUnicodeBestFit == null) ReadBestFitTable(); return arrayUnicodeBestFit; } [SecuritySafeCritical] internal char[] GetBestFitBytesToUnicodeData() { if (arrayBytesBestFit == null) ReadBestFitTable(); return arrayBytesBestFit; } [SecurityCritical] internal void CheckMemorySection() { if (safeNativeMemoryHandle != null && safeNativeMemoryHandle.DangerousGetHandle() == IntPtr.Zero) LoadManagedCodePage(); } } }