Как .NET определяет категорию символов Unicode? - PullRequest
5 голосов
/ 25 февраля 2011

Я искал 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;
}

Примечание: Надеюсь, это не нарушит никакую лицензию.Если так, я удалю код.

Ответы [ 2 ]

2 голосов
/ 25 февраля 2011

Основная информация хранится в charinfo.nlp, который встроен в mscorlib.dll как ресурс и загружается во время выполнения.Специфика этого файла, вероятно, известна только Microsoft, но достаточно сказать, что он, вероятно, является таблицей поиска в некотором роде.в MSDN :

Это перечисление основано на стандарте Unicode, версия 5.0.Для получения дополнительной информации см. Подтемы « Формат файла UCD » и « Общие значения категории » в базе данных символов Unicode.

1 голос
/ 25 февраля 2011

Это похоже на своего рода b-дерево.

Преимущество состоит в том, что все регионы могут указывать на один и тот же блок "символ неизвестен", вместо того, чтобы нуждаться в уникальном элементе в массиве для каждого из них.возможное значение Char.

...