コード例 #1
0
        internal static bool CompareCurrentDecodedString(CharacterStream stream, string compareText, bool ignoreCase, out int matchLength)
        {
#if SUPPORT_ENCODED_CSS
            matchLength = 0;

            if (AtEnd)
            {
                return(compareText.Length == 0);
            }

            if (_textProvider.Length - _index < compareText.Length)
            {
                return(false);
            }

            if (!TextHelpers.RangeCouldContainEncodedChars(_textProvider, _index, compareText.Length))
            {
                // No slashes, so no escapes, and a simple string comparison can be done

                matchLength = compareText.Length;
                return(CompareCurrentString(compareText, ignoreCase));
            }

            // There's a slash in there somewhere, so decode every character
            // (this requires no memory allocations)

            int  startPosition = Position;
            bool result        = true;

            for (int i = 0; i < compareText.Length; i++)
            {
                char        compareChar = compareText[i];
                DecodedChar decodedChar = DecodedCurrentChar;

                if (ignoreCase
                    ? (char.ToLowerInvariant(compareChar) == char.ToLowerInvariant(decodedChar.Char))
                    : (compareChar == decodedChar.Char))
                {
                    // Matching so far...
                    Advance(decodedChar.EncodedLength);
                }
                else
                {
                    result = false;
                    break;
                }
            }

            matchLength = Position - startPosition;
            Position    = startPosition;

            return(result);
#else
            matchLength = string.IsNullOrEmpty(compareText) ? 0 : compareText.Length;
            return(stream.TextProvider.CompareTo(stream.Position, compareText, ignoreCase));
#endif
        }
コード例 #2
0
        /// <summary>
        /// This is similar to string.Substring, but it deals with encoded unicode chars and escaped chars.
        /// Escaped line breaks are only valid within strings, so set "forStringToken" to true for strings.
        /// </summary>
        public static string DecodeText(ITextProvider textProvider, int start, int length, bool forStringToken)
        {
            if (RangeCouldContainEncodedChars(textProvider, start, length))
            {
                // Need to carefully investigate every character and decode it

                System.Text.StringBuilder sb = new System.Text.StringBuilder(length);
                CharacterStream           cs = new CharacterStream(textProvider);

                for (cs.Position = start; cs.Position < start + length && !cs.IsAtEnd;)
                {
                    if (forStringToken && AtEscapedNewLine(cs))
                    {
                        // Ignore this line break within a string
                        cs.Advance(1);
                        SkipNewLine(cs);
                    }
                    else
                    {
                        DecodedChar decodedChar = TextHelpers.DecodeCurrentChar(cs);

                        if (decodedChar.RequiresUtf32)
                        {
                            // http://www.w3.org/TR/CSS21/syndata.html#characters
                            //
                            // If the number is outside the range allowed by Unicode (e.g., "\110000" is above the maximum 10FFFF
                            // allowed in current Unicode), the UA may replace the escape with the "replacement character" (U+FFFD).

                            int utf32 = decodedChar.CharUtf32;

                            if ((utf32 < 0) || (utf32 > 0x10FFFF))
                            {
                                utf32 = 0xFFFD;
                            }

                            sb.Append(char.ConvertFromUtf32(utf32));
                        }
                        else
                        {
                            sb.Append(decodedChar.Char);
                        }

                        cs.Advance(decodedChar.EncodedLength);
                    }
                }

                return(sb.ToString());
            }
            else
            {
                // Nothing can possibly be encoded, so return the plain string

                return(textProvider.GetText(start, length));
            }
        }