Я искал mscorelib.dll с помощью .NET Reflector и наткнулся на класс Char.Мне всегда было интересно, как делаются такие методы, как Char.isLetter.Я ожидал огромный список тестов, но, купив немного копать, я нашел действительно короткий код, который определяет категорию Unicode.Тем не менее, в этом коде используются какие-то таблицы и немного вуду со сдвигом битов.Может кто-нибудь объяснить мне, как это делается, или указать мне на некоторые ресурсы?
РЕДАКТИРОВАТЬ: Вот код.Он находится в System.Globalization.CharUnicodeInfo.
internal static unsafe byte InternalGetCategoryValue(int ch, int offset)
{
ushort num = s_pCategoryLevel1Index[ch >> 8];
num = s_pCategoryLevel1Index[num + ((ch >> 4) & 15)];
byte* numPtr = (byte*) (s_pCategoryLevel1Index + num);
byte num2 = numPtr[ch & 15];
return s_pCategoriesValue[(num2 * 2) + offset];
}
s_pCategoryLevel1Index
- это short*
, а s_pCategoryValues
- это byte*
Оба созданы в статическом конструкторе CharUnicodeInfo:
static unsafe CharUnicodeInfo()
{
s_pDataTable = GlobalizationAssembly.GetGlobalizationResourceBytePtr(typeof(CharUnicodeInfo).Assembly, "charinfo.nlp");
UnicodeDataHeader* headerPtr = (UnicodeDataHeader*) s_pDataTable;
s_pCategoryLevel1Index = (ushort*) (s_pDataTable + headerPtr->OffsetToCategoriesIndex);
s_pCategoriesValue = s_pDataTable + ((byte*) headerPtr->OffsetToCategoriesValue);
s_pNumericLevel1Index = (ushort*) (s_pDataTable + headerPtr->OffsetToNumbericIndex);
s_pNumericValues = s_pDataTable + ((byte*) headerPtr->OffsetToNumbericValue);
s_pDigitValues = (DigitValues*) (s_pDataTable + headerPtr->OffsetToDigitValue);
nativeInitTable(s_pDataTable);
}
Вот UnicodeDataHeader.
internal struct UnicodeDataHeader
{
// Fields
[FieldOffset(40)]
internal uint OffsetToCategoriesIndex;
[FieldOffset(0x2c)]
internal uint OffsetToCategoriesValue;
[FieldOffset(0x34)]
internal uint OffsetToDigitValue;
[FieldOffset(0x30)]
internal uint OffsetToNumbericIndex;
[FieldOffset(0x38)]
internal uint OffsetToNumbericValue;
[FieldOffset(0)]
internal char TableName;
[FieldOffset(0x20)]
internal ushort version;
}
Примечание: Надеюсь, это не нарушит никакую лицензию.Если так, я удалю код.