Ejemplo n.º 1
0
        /// <summary>
        /// Try to make a callback in a transactional way.
        /// </summary>
        /// <param name="delegate">The callback to perform the match.</param>
        /// <returns>true if the match could be made, false if not.</returns>
        protected bool TryMake(TryMakeDelegate @delegate)
        {
            var checkpoint = Enumerator.Checkpoint();

            if (@delegate() == false)
            {
                checkpoint.Rollback();
                return(false);
            }

            checkpoint.Dispose();
            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Try to make a callback in a transactional way.
        /// </summary>
        /// <param name="delegate">The callback to perform the match.</param>
        /// <param name="found">The parameter that was returned from the matching function.</param>
        /// <returns>true if the match could be made, false if not.</returns>
        protected bool TryMake <TOut>(TryMakeDelegate <TOut> @delegate, out TOut found)
        {
            var checkpoint = Enumerator.Checkpoint();

            if (@delegate(out found) == false)
            {
                checkpoint.Rollback();
                return(false);
            }

            checkpoint.Dispose();
            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Try to take the tokens in sequence.
        /// </summary>
        /// <param name="tokens">The list of tokens to take in sequence.</param>
        /// <returns>true if the given list of tokens could be made in sequence, false if not.</returns>
        protected bool TryTakeTokens(params Token[] tokens)
        {
            var checkpoint = Enumerator.Checkpoint();

            foreach (var token in tokens)
            {
                if (Enumerator.Take() != token)
                {
                    checkpoint.Rollback();
                    return(false);
                }
            }

            checkpoint.Dispose();
            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Try to extract IPv6 address. https://tools.ietf.org/html/rfc4291 section 2.2 used for specification.
        /// </summary>
        /// <param name="address">Extracted Ipv6 address</param>
        /// <returns>true if a valid Ipv6 address can be extracted</returns>
        public bool TryMakeIpv6AddressLiteral(out string address)
        {
            address = null;
            if ((TryMake(TryMakeIpVersion, out int ipVersion) == false) || ipVersion != 6)
            {
                return(false);
            }
            var hasDoubleColumn = false;
            var hexPartCount    = 0;
            var hasIpv4Part     = false;
            var wasColon        = false;

            var token   = Enumerator.Peek();
            var builder = new System.Text.StringBuilder();

            while (token.Kind == TokenKind.Number || token.Kind == TokenKind.Text || token == Tokens.Colon)
            {
                using (var cp = Enumerator.Checkpoint())
                {
                    Enumerator.Take();
                    // Alternate form with mixed IPv6 and IPv4 formats. See https://tools.ietf.org/html/rfc4291 section 2.2 item 3
                    if (token.Kind == TokenKind.Number && Enumerator.Peek() == Tokens.Period)
                    {
                        cp.Rollback();
                        if (TryMake(TryMakeIpv4AddressLiteral, out string ipv4))
                        {
                            hasIpv4Part = true;
                            builder.Append(ipv4);
                            break;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        cp.Rollback();
                    }
                }

                if (token == Tokens.Colon)
                {
                    if (wasColon)
                    {
                        // Double column is allowed only once
                        if (hasDoubleColumn)
                        {
                            return(false);
                        }
                        hasDoubleColumn = true;
                    }
                    builder.Append(token.Text);
                    wasColon = true;
                    Enumerator.Take();
                }
                else
                {
                    if (wasColon == false && builder.Length > 0)
                    {
                        return(false);
                    }
                    wasColon = false;
                    if (TryMake(TryMake16BitsHexNumber, out string hexNumber))
                    {
                        builder.Append(hexNumber);
                        hexPartCount++;
                    }
                    else
                    {
                        return(false);
                    }
                }
                token = Enumerator.Peek();
            }

            address = builder.ToString();

            var maxAllowedParts = (hasIpv4Part ? 6 : 8) - Math.Sign(hasDoubleColumn ? 1 : 0);

            if ((hasDoubleColumn && hexPartCount > maxAllowedParts) || (!hasDoubleColumn && hexPartCount != maxAllowedParts))
            {
                return(false);
            }

            return(true);
        }