public unsafe static CharacterDecompositionMapping Parse(string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return(default(CharacterDecompositionMapping));
            }

            CompatibilityFormattingTag tag = CompatibilityFormattingTag.Canonical;

            int index;

            if (s[0] == '<')
            {
                if (!EnumHelper <CompatibilityFormattingTag> .TryGetNamedValue(s.Substring(1, (index = s.IndexOf('>')) - 1), out tag))
                {
                    throw new FormatException();
                }
                ++index;
            }
            else
            {
                index = 0;
            }

            var buffer    = stackalloc char[36];           // From the Unicode docs, a decomposition cannot have more than 18 code points.
            int charIndex = 0;

            while (index < s.Length && charIndex < 35)
            {
                char c = s[index];

                if (c == ' ')
                {
                    ++index;
                }
                else
                {
                    int codePoint = HexCodePoint.Parse(s, ref index);

                    if (codePoint < 0x10000)
                    {
                        buffer[charIndex++] = (char)codePoint;
                    }
                    else if (codePoint < 0x10FFFF)
                    {
                        codePoint          -= 0x10000;
                        buffer[charIndex++] = (char)((codePoint >> 10) + 0xD800);
                        buffer[charIndex++] = (char)((codePoint & 0x3FF) + 0xDC00);
                    }
                    else
                    {
                        throw new FormatException("The code point was outside of the allowed range.");
                    }
                }
            }

            return(new CharacterDecompositionMapping(tag, new string(buffer, 0, charIndex)));
        }
        public readonly int[]                      CrossRerefences; // NB: It seems that parsing NamesList is required in order to provide data for this field ?

        internal UnicodeCharacterData
        (
            UnicodeCodePointRange codePointRange,
            string name,
            UnicodeNameAlias[] nameAliases,
            UnicodeCategory category,
            CanonicalCombiningClass canonicalCombiningClass,
            BidirectionalClass bidirectionalClass,
            CompatibilityFormattingTag decompositionType,
            string decompositionMapping,
            UnicodeNumericType numericType,
            UnicodeRationalNumber numericValue,
            bool bidirectionalMirrored,
            string oldName,
            string simpleUpperCaseMapping,
            string simpleLowerCaseMapping,
            string simpleTitleCaseMapping,
            ContributoryProperties contributoryProperties,
            int corePropertiesAndEmojiProperties,
            int[] crossRerefences
        )
        {
            this.CodePointRange                   = codePointRange;
            this.Name                             = name;
            this.NameAliases                      = nameAliases;
            this.Category                         = category;
            this.CanonicalCombiningClass          = canonicalCombiningClass;
            this.BidirectionalClass               = bidirectionalClass;
            this.DecompositionType                = decompositionType;
            this.DecompositionMapping             = decompositionMapping;
            this.NumericType                      = numericType;
            this.numericValue                     = numericValue;
            this.BidirectionalMirrored            = bidirectionalMirrored;
            this.OldName                          = oldName;
            this.SimpleUpperCaseMapping           = simpleUpperCaseMapping;
            this.SimpleLowerCaseMapping           = simpleLowerCaseMapping;
            this.SimpleTitleCaseMapping           = simpleTitleCaseMapping;
            this.ContributoryProperties           = contributoryProperties;
            this.corePropertiesAndEmojiProperties = corePropertiesAndEmojiProperties;
            this.CrossRerefences                  = crossRerefences;
        }
Пример #3
0
        private static void ReadUnicodeCharacterDataEntry(BinaryReader reader, byte[] nameBuffer, out UnicodeCharacterData value)
        {
            var fields = (UcdFields)reader.ReadUInt16();

            var codePointRange = (fields & UcdFields.CodePointRange) != 0 ? new UnicodeCodePointRange(ReadCodePoint(reader), ReadCodePoint(reader)) : new UnicodeCodePointRange(ReadCodePoint(reader));

            string name = null;

            UnicodeNameAlias[] nameAliases = UnicodeNameAlias.EmptyArray;

            // Read all the official names of the character.
            if ((fields & UcdFields.Name) != 0)
            {
                int  length = reader.ReadByte();
                byte @case  = (byte)(length & 0xC0);

                if (@case < 0x80)                   // Handles the case where only the name is present.
                {
                    length = (length & 0x7F) + 1;
                    if (reader.Read(nameBuffer, 0, length) != length)
                    {
                        throw new EndOfStreamException();
                    }

                    name = Encoding.UTF8.GetString(nameBuffer, 0, length);
                }
                else
                {
                    nameAliases = new UnicodeNameAlias[(length & 0x3F) + 1];

                    if ((@case & 0x40) != 0)
                    {
                        length = reader.ReadByte() + 1;
                        if (length > 128)
                        {
                            throw new InvalidDataException("Did not expect names longer than 128 bytes.");
                        }
                        if (reader.Read(nameBuffer, 0, length) != length)
                        {
                            throw new EndOfStreamException();
                        }
                        name = Encoding.UTF8.GetString(nameBuffer, 0, length);
                    }

                    for (int i = 0; i < nameAliases.Length; ++i)
                    {
                        nameAliases[i] = new UnicodeNameAlias(reader.ReadString(), (UnicodeNameAliasKind)(reader.ReadByte()));
                    }
                }
            }

            var category = (fields & UcdFields.Category) != 0 ? (UnicodeCategory)reader.ReadByte() : UnicodeCategory.OtherNotAssigned;
            var canonicalCombiningClass = (fields & UcdFields.CanonicalCombiningClass) != 0 ? (CanonicalCombiningClass)reader.ReadByte() : CanonicalCombiningClass.NotReordered;
            var bidirectionalClass      = (fields & UcdFields.BidirectionalClass) != 0 ? (BidirectionalClass)reader.ReadByte() : 0;
            CompatibilityFormattingTag decompositionType = (fields & UcdFields.DecompositionMapping) != 0 ? (CompatibilityFormattingTag)reader.ReadByte() : CompatibilityFormattingTag.Canonical;
            string decompositionMapping        = (fields & UcdFields.DecompositionMapping) != 0 ? reader.ReadString() : null;
            var    numericType                 = (UnicodeNumericType)((int)(fields & UcdFields.NumericNumeric) >> 6);
            UnicodeRationalNumber numericValue = numericType != UnicodeNumericType.None ?
                                                 new UnicodeRationalNumber(reader.ReadInt64(), reader.ReadByte()) :
                                                 default(UnicodeRationalNumber);
            string oldName = (fields & UcdFields.OldName) != 0 ? reader.ReadString() : null;
            string simpleUpperCaseMapping = (fields & UcdFields.SimpleUpperCaseMapping) != 0 ? reader.ReadString() : null;
            string simpleLowerCaseMapping = (fields & UcdFields.SimpleLowerCaseMapping) != 0 ? reader.ReadString() : null;
            string simpleTitleCaseMapping = (fields & UcdFields.SimpleTitleCaseMapping) != 0 ? reader.ReadString() : null;
            ContributoryProperties contributoryProperties = (fields & UcdFields.ContributoryProperties) != 0 ? (ContributoryProperties)reader.ReadInt32() : 0;
            int corePropertiesAndEmojiProperties          = (fields & UcdFields.CorePropertiesAndEmojiProperties) != 0 ? ReadInt24(reader) : 0;

            int[] crossReferences = (fields & UcdFields.CrossRerefences) != 0 ? new int[reader.ReadByte() + 1] : null;

            if (crossReferences != null)
            {
                for (int i = 0; i < crossReferences.Length; ++i)
                {
                    crossReferences[i] = ReadCodePoint(reader);
                }
            }

            value = new UnicodeCharacterData
                    (
                codePointRange,
                name,
                nameAliases,
                category,
                canonicalCombiningClass,
                bidirectionalClass,
                decompositionType,
                decompositionMapping,
                numericType,
                numericValue,
                (fields & UcdFields.BidirectionalMirrored) != 0,
                oldName,
                simpleUpperCaseMapping,
                simpleLowerCaseMapping,
                simpleTitleCaseMapping,
                contributoryProperties,
                corePropertiesAndEmojiProperties,
                crossReferences
                    );
        }
Пример #4
0
 public CharacterDecompositionMapping(CompatibilityFormattingTag decompositionType, string decompositionMapping)
 {
     DecompositionType    = decompositionType;
     DecompositionMapping = decompositionMapping;
 }