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