System.Text.DBCSCodePageEncoding.LoadManagedCodePage C# (CSharp) Method

LoadManagedCodePage() private method

private LoadManagedCodePage ( ) : void
return void
        protected unsafe override void LoadManagedCodePage()
        {
            fixed (byte* pBytes = m_codePageHeader)
            {
                CodePageHeader* pCodePage = (CodePageHeader*)pBytes;

                // Should be loading OUR code page
                Debug.Assert(pCodePage->CodePage == dataTableCodePage,
                    "[DBCSCodePageEncoding.LoadManagedCodePage]Expected to load data table code page");

                // Make sure we're really a 1-byte code page
                if (pCodePage->ByteCount != 2)
                    throw new NotSupportedException(SR.Format(SR.NotSupported_NoCodepageData, CodePage));
                // Remember our unknown bytes & chars
                _bytesUnknown = pCodePage->ByteReplace;
                charUnknown = pCodePage->UnicodeReplace;

                // Need to make sure the fallback buffer's fallback char is correct
                if (DecoderFallback is InternalDecoderBestFitFallback)
                {
                    ((InternalDecoderBestFitFallback)(DecoderFallback)).cReplacement = charUnknown;
                }

                // Is our replacement bytesUnknown a single or double byte character?
                _byteCountUnknown = 1;
                if (_bytesUnknown > 0xff)
                    _byteCountUnknown++;

                // We use fallback encoder, which uses ?, which so far all of our tables do as well
                Debug.Assert(_bytesUnknown == 0x3f,
                    "[DBCSCodePageEncoding.LoadManagedCodePage]Expected 0x3f (?) as unknown byte character");

                // Get our mapped section (bytes to allocate = 2 bytes per 65536 Unicode chars + 2 bytes per 65536 DBCS chars)
                // Plus 4 byte to remember CP # when done loading it. (Don't want to get IA64 or anything out of alignment)
                byte* pNativeMemory = GetNativeMemory(65536 * 2 * 2 + 4 + iExtraBytes);

                mapBytesToUnicode = (char*)pNativeMemory;
                mapUnicodeToBytes = (ushort*)(pNativeMemory + 65536 * 2);

                // Need to read our data file and fill in our section.
                // WARNING: Multiple code pieces could do this at once (so we don't have to lock machine-wide)
                //          so be careful here.  Only stick legal values in here, don't stick temporary values.

                // Move to the beginning of the data section

                byte[] buffer = new byte[m_dataSize];
                lock (s_streamLock)
                {
                    s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset, SeekOrigin.Begin);
                    s_codePagesEncodingDataStream.Read(buffer, 0, m_dataSize);
                }

                fixed (byte* pBuffer = buffer)
                {
                    char* pData = (char*)pBuffer;

                    // We start at bytes position 0
                    int bytePosition = 0;
                    int useBytes = 0;

                    while (bytePosition < 0x10000)
                    {
                        // Get the next byte
                        char input = *pData;
                        pData++;

                        // build our table:
                        if (input == 1)
                        {
                            // Use next data as our byte position
                            bytePosition = (int)(*pData);
                            pData++;
                            continue;
                        }
                        else if (input < 0x20 && input > 0)
                        {
                            // Advance input characters
                            bytePosition += input;
                            continue;
                        }
                        else if (input == 0xFFFF)
                        {
                            // Same as our bytePosition
                            useBytes = bytePosition;
                            input = unchecked((char)bytePosition);
                        }
                        else if (input == LEAD_BYTE_CHAR) // 0xfffe
                        {
                            // Lead byte mark
                            Debug.Assert(bytePosition < 0x100, "[DBCSCodePageEncoding.LoadManagedCodePage]expected lead byte to be < 0x100");
                            useBytes = bytePosition;
                            // input stays 0xFFFE
                        }
                        else if (input == UNICODE_REPLACEMENT_CHAR)
                        {
                            // Replacement char is already done
                            bytePosition++;
                            continue;
                        }
                        else
                        {
                            // Use this character
                            useBytes = bytePosition;
                            // input == input;
                        }

                        // We may need to clean up the selected character & position
                        if (CleanUpBytes(ref useBytes))
                        {
                            // Use this selected character at the selected position, don't do this if not supposed to.
                            if (input != LEAD_BYTE_CHAR)
                            {
                                // Don't do this for lead byte marks.
                                mapUnicodeToBytes[input] = unchecked((ushort)useBytes);
                            }
                            mapBytesToUnicode[useBytes] = input;
                        }
                        bytePosition++;
                    }
                }

                // See if we have any clean up to do
                CleanUpEndBytes(mapBytesToUnicode);
            }
        }