Esempio n. 1
0
        /// <summary>
        /// Handles the special SPARQL escapes that can occur in a local name
        /// </summary>
        /// <remarks>
        /// Unlike <see cref="BaseTokeniser.HandleEscapes()">HandleEscapes()</see> this only unescapes unicode escapes, other escapes are simply validated and passed through for later unescaping
        /// </remarks>
        protected void HandleSparqlLocalNameEscapes()
        {
            //Grab the first character which must be a \ or %
            char next = this.SkipCharacter();

            //Stuff for Unicode/Hex escapes
            StringBuilder localOutput;

            if (next == '\\')
            {
                //Backslash based escape
                next = this.Peek();
                switch (next)
                {
                case '_':
                case '-':
                case '.':
                case '|':
                case '$':
                case '&':
                case '\'':
                case '(':
                case ')':
                case '*':
                case '+':
                case ',':
                case ';':
                case '=':
                case ':':
                case '/':
                case '?':
                case '#':
                case '@':
                case '%':
                    //Escapable Characters
                    this._output.Append('\\');
                    this.ConsumeCharacter();
                    return;

                case 'u':
                    //Need to consume the u first
                    localOutput = new StringBuilder();
                    this.SkipCharacter();

                    next = this.Peek();

                    //Try to get Four Hex Digits
                    while (localOutput.Length < 4 && this.IsHexDigit(next))
                    {
                        localOutput.Append(next);
                        this.SkipCharacter();
                        next = this.Peek();
                    }

                    //Did we get four Hex Digits
                    if (localOutput.Length != 4)
                    {
                        throw Error("Unexpected Character (Code " + (int)next + "): " + next + " encountered while trying to parse Unicode Escape from Content:\n" + this._output.ToString() + "\nThe \\u Escape must be followed by four Hex Digits");
                    }
                    else if (localOutput.ToString().Equals("0000"))
                    {
                        //Ignore the null escape
                    }
                    else
                    {
                        this._output.Append(UnicodeSpecsHelper.ConvertToChar(localOutput.ToString()));
                    }

                    return;

                case 'U':
                    //Need to consume the U first
                    localOutput = new StringBuilder();
                    this.SkipCharacter();

                    next = this.Peek();

                    //Try to get Eight Hex Digits
                    while (localOutput.Length < 8 && this.IsHexDigit(next))
                    {
                        localOutput.Append(next);
                        this.SkipCharacter();
                        next = this.Peek();
                    }

                    //Did we get eight Hex Digits
                    if (localOutput.Length != 8)
                    {
                        throw Error("Unexpected Character (Code " + (int)next + "): " + next + " encountered while trying to parse Unicode Escape from Content:\n" + this._output.ToString() + "\nThe \\U Escape must be followed by eight Hex Digits");
                    }
                    else if (localOutput.ToString().Equals("00000000"))
                    {
                        //Ignore the null escape
                    }
                    else
                    {
                        this._output.Append(UnicodeSpecsHelper.ConvertToChar(localOutput.ToString()));
                    }
                    return;

                default:
                    throw Error("Unexpected Backslash Character encountered in a Local Name, the Backslash Character can only be used for Unicode escapes (\\u and \\U) and a limited set of special characters (_-.|&'()*+,;=/?#@%) in Local Names");
                }
            }
            else if (next == '%')
            {
                localOutput = new StringBuilder();
                localOutput.Append(next);

                next = this.Peek();
                while (localOutput.Length < 3 && this.IsHexDigit(next))
                {
                    localOutput.Append(next);
                    this.SkipCharacter();
                    next = this.Peek();
                }

                //Did we get % followed by two hex digits
                if (localOutput.Length != 3)
                {
                    throw Error("Encountered a % character in a Local Name but the required two hex digits were not present after it, please use \\% if you wish to represent the percent character");
                }
#if !SILVERLIGHT
                else if (!Uri.IsHexEncoding(localOutput.ToString(), 0))
#else
                else if (SilverlightExtensions.IsHexEncoding(localOutput.ToString(), 0))
#endif
                {
                    throw Error("Invalid % encoded character encountered");
                }
                else
                {
                    this._output.Append(localOutput.ToString());
                }
            }
            else
            {
                throw Error("HandleSparqlLocalNameEscapes() was called but the next character is not a % or \\ as expected");
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Handles the complex escapes that can occur in a local name
        /// </summary>
        /// <remarks>
        /// Unlike <see cref="BaseTokeniser.HandleEscapes(TokeniserEscapeMode)">HandleEscapes()</see> this only unescapes unicode escapes, other escapes are simply validated and passed through for later unescaping
        /// </remarks>
        protected void HandleComplexLocalNameEscapes()
        {
            //Grab the first character which must be a \ or %
            char next = this.SkipCharacter();

            //Stuff for Unicode/Hex escapes

            if (next == '\\')
            {
                //Backslash based escape
                next = this.Peek();
                switch (next)
                {
                case '_':
                case '~':
                case '-':
                case '.':
                case '!':
                case '$':
                case '&':
                case '\'':
                case '(':
                case ')':
                case '*':
                case '+':
                case ',':
                case ';':
                case '=':
                case '/':
                case '?':
                case '#':
                case '@':
                case '%':
                    //Escapable Characters
                    this._output.Append('\\');
                    this.ConsumeCharacter();
                    return;

                case 'u':
                case 'U':
                    throw Error("Illegal unicode escape (\\u or \\U) in local name portion of a prefixed name");

                default:
                    throw Error("Unexpected Backslash Character encountered in a Local Name, the Backslash Character can only be used for Unicode escapes (\\u and \\U) and a limited set of special characters (_~-.!$&'()*+,;=/?#@%) in Local Names");
                }
            }
            if (next != '%')
            {
                throw Error("HandleComplexLocalNameEscapes() was called but the next character is not a % or \\ as expected");
            }
            StringBuilder localOutput = new StringBuilder();

            localOutput.Append(next);

            next = this.Peek();
            while (localOutput.Length < 3 && this.IsHexDigit(next))
            {
                localOutput.Append(next);
                this.SkipCharacter();
                next = this.Peek();
            }

            //Did we get % followed by two hex digits
            if (localOutput.Length != 3)
            {
                throw Error("Encountered a % character in a Local Name but the required two hex digits were not present after it, please use \\% if you wish to represent the percent character itself");
            }
#if !SILVERLIGHT
            if (!Uri.IsHexEncoding(localOutput.ToString(), 0))
#else
            if (SilverlightExtensions.IsHexEncoding(localOutput.ToString(), 0))
#endif
            {
                throw Error("Invalid % encoded character encountered");
            }
            this._output.Append(localOutput.ToString());
        }