System.Text.SBCSCodePageEncoding.ReadBestFitTable C# (CSharp) Метод

ReadBestFitTable() приватный Метод

private ReadBestFitTable ( ) : void
Результат void
        protected unsafe override void ReadBestFitTable()
        {
            // Lock so we don't confuse ourselves.
            lock (InternalSyncObject)
            {
                // If we got a best fit array already, then don't do this
                if (arrayUnicodeBestFit == null)
                {
                    //
                    // Read in Best Fit table.
                    //

                    // First check the SBCS->Unicode best fit table, which starts right after the
                    // 256 word data table.  This table looks like word, word where 1st word is byte and 2nd
                    // word is replacement for that word.  It ends when byte == 0.
                    byte[] buffer = new byte[m_dataSize - 512];
                    lock (s_streamLock)
                    {
                        s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset + 512, SeekOrigin.Begin);
                        s_codePagesEncodingDataStream.Read(buffer, 0, buffer.Length);
                    }

                    fixed (byte* pBuffer = buffer)
                    {
                        byte* pData = pBuffer;
                        // Need new best fit array
                        char[] arrayTemp = new char[256];
                        for (int i = 0; i < 256; i++)
                            arrayTemp[i] = _mapBytesToUnicode[i];

                        // See if our words are zero
                        ushort byteTemp;
                        while ((byteTemp = *((ushort*)pData)) != 0)
                        {
                            Debug.Assert(arrayTemp[byteTemp] == UNKNOWN_CHAR, String.Format(CultureInfo.InvariantCulture,
                                "[SBCSCodePageEncoding::ReadBestFitTable] Expected unallocated byte (not 0x{2:X2}) for best fit byte at 0x{0:X2} for code page {1}",
                                byteTemp, CodePage, (int)arrayTemp[byteTemp]));
                            pData += 2;

                            arrayTemp[byteTemp] = *((char*)pData);
                            pData += 2;
                        }

                        // Remember our new array
                        arrayBytesBestFit = arrayTemp;

                        // It was on 0, it needs to be on next byte
                        pData += 2;
                        byte* pUnicodeToSBCS = pData;

                        // Now count our characters from our Unicode->SBCS best fit table,
                        // which is right after our 256 byte data table
                        int iBestFitCount = 0;

                        // Now do the UnicodeToBytes Best Fit mapping (this is the one we normally think of when we say "best fit")
                        // pData should be pointing at the first data point for Bytes->Unicode table
                        int unicodePosition = *((ushort*)pData);
                        pData += 2;

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

                            // build our table:
                            if (input == 1)
                            {
                                // Use next 2 bytes as our byte position
                                unicodePosition = *((ushort*)pData);
                                pData += 2;
                            }
                            else if (input < 0x20 && input > 0 && input != 0x1e)
                            {
                                // Advance input characters
                                unicodePosition += input;
                            }
                            else
                            {
                                // Use this character if it isn't zero
                                if (input > 0)
                                    iBestFitCount++;

                                // skip this unicode position in any case
                                unicodePosition++;
                            }
                        }

                        // Make an array for our best fit data
                        arrayTemp = new char[iBestFitCount * 2];

                        // Now actually read in the data
                        // reset pData should be pointing at the first data point for Bytes->Unicode table
                        pData = pUnicodeToSBCS;
                        unicodePosition = *((ushort*)pData);
                        pData += 2;
                        iBestFitCount = 0;

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

                            // build our table:
                            if (input == 1)
                            {
                                // Use next 2 bytes as our byte position
                                unicodePosition = *((ushort*)pData);
                                pData += 2;
                            }
                            else if (input < 0x20 && input > 0 && input != 0x1e)
                            {
                                // Advance input characters
                                unicodePosition += input;
                            }
                            else
                            {
                                // Check for escape for glyph range
                                if (input == 0x1e)
                                {
                                    // Its an escape, so just read next byte directly
                                    input = *pData;
                                    pData++;
                                }

                                // 0 means just skip me
                                if (input > 0)
                                {
                                    // Use this character
                                    arrayTemp[iBestFitCount++] = (char)unicodePosition;
                                    // Have to map it to Unicode because best fit will need unicode value of best fit char.
                                    arrayTemp[iBestFitCount++] = _mapBytesToUnicode[input];

                                    // This won't work if it won't round trip.
                                    Debug.Assert(arrayTemp[iBestFitCount - 1] != (char)0,
                                        String.Format(CultureInfo.InvariantCulture,
                                        "[SBCSCodePageEncoding.ReadBestFitTable] No valid Unicode value {0:X4} for round trip bytes {1:X4}, encoding {2}",
                                        (int)_mapBytesToUnicode[input], (int)input, CodePage));
                                }
                                unicodePosition++;
                            }
                        }

                        // Remember it
                        arrayUnicodeBestFit = arrayTemp;
                    } // Fixed()
                }
            }
        }