예제 #1
0
        /// <summary>
        /// Parse a template.
        /// </summary>
        /// <param name="template">Template to be parsed.</param>
        /// <exception cref="ArgumentNullException">When <paramref name="template"/> is null.</exception>
        /// <returns>Template, never null</returns>
        public static Template Parse(string template)
        {
            if (template == null)
            {
                throw new ArgumentNullException(nameof(template));
            }

            bool           isPositional = true;
            List <Literal> literals     = new List <Literal>();
            List <Hole>    holes        = new List <Hole>();

            TemplateEnumerator templateEnumerator = new TemplateEnumerator(template);

            while (templateEnumerator.MoveNext())
            {
                if (templateEnumerator.Current.Literal.Skip == 0)
                {
                    literals.Add(templateEnumerator.Current.Literal);
                }
                else
                {
                    literals.Add(templateEnumerator.Current.Literal);
                    holes.Add(templateEnumerator.Current.Hole);
                    if (templateEnumerator.Current.Hole.Index == -1)
                    {
                        isPositional = false;
                    }
                }
            }

            Debug.Assert(holes.Count == literals.Count(x => x.Skip > 0));
            return(new Template(template, isPositional, literals, holes));
        }
예제 #2
0
        /// <summary>
        /// Create MessageTemplateParameter from <paramref name="parameters"/>
        /// </summary>
        /// <param name="message"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private IList <MessageTemplateParameter> CreateParameters(string message, object[] parameters)
        {
            try
            {
                List <MessageTemplateParameter> templateParameters = new List <MessageTemplateParameter>(parameters.Length);

                int holeIndex = 0;
                TemplateEnumerator templateEnumerator = new TemplateEnumerator(message);
                while (templateEnumerator.MoveNext())
                {
                    if (templateEnumerator.Current.Literal.Skip != 0)
                    {
                        var hole = templateEnumerator.Current.Hole;
                        if (hole.Index == -1)
                        {
                            templateParameters.Add(new MessageTemplateParameter(hole.Name, parameters[holeIndex++], hole.Format, hole.CaptureType));
                        }
                        else
                        {
                            templateParameters.Add(new MessageTemplateParameter(hole.Name, parameters[hole.Index], hole.Format, hole.CaptureType));
                        }
                    }
                }
                return(templateParameters);
            }
            catch (Exception ex)
            {
                InternalLogger.Warn(ex, "Error when parsing a message.");
                return(Internal.ArrayHelper.Empty <MessageTemplateParameter>());
            }
        }
예제 #3
0
        /// <summary>
        /// Create MessageTemplateParameter from <paramref name="parameters"/>
        /// </summary>
        /// <param name="template"></param>
        /// <param name="parameters"></param>
        /// <param name="isPositional"></param>
        /// <param name="isValidTemplate"></param>
        /// <returns></returns>
        private static IList <MessageTemplateParameter> ParseMessageTemplate(string template, object[] parameters, out bool isPositional, out bool isValidTemplate)
        {
            isPositional    = true;
            isValidTemplate = true;

            List <MessageTemplateParameter> templateParameters = new List <MessageTemplateParameter>(parameters.Length);

            try
            {
                short holeIndex = 0;
                TemplateEnumerator templateEnumerator = new TemplateEnumerator(template);
                while (templateEnumerator.MoveNext())
                {
                    if (templateEnumerator.Current.Literal.Skip != 0)
                    {
                        var hole = templateEnumerator.Current.Hole;
                        if (hole.Index != -1 && isPositional)
                        {
                            holeIndex++;
                            var value = GetHoleValueSafe(parameters, hole.Index);
                            templateParameters.Add(new MessageTemplateParameter(hole.Name, value, hole.Format, hole.CaptureType));
                        }
                        else
                        {
                            if (isPositional)
                            {
                                isPositional = false;
                                if (holeIndex != 0)
                                {
                                    // rewind and try again
                                    templateEnumerator = new TemplateEnumerator(template);
                                    holeIndex          = 0;
                                    templateParameters.Clear();
                                    continue;
                                }
                            }

                            var value = GetHoleValueSafe(parameters, holeIndex);
                            templateParameters.Add(new MessageTemplateParameter(hole.Name, value, hole.Format, hole.CaptureType));
                            holeIndex++;
                        }
                    }
                }

                if (templateParameters.Count != parameters.Length)
                {
                    isValidTemplate = false;
                }

                return(templateParameters);
            }
            catch (Exception ex)
            {
                isValidTemplate = false;
                InternalLogger.Warn(ex, "Error when parsing a message.");
                return(templateParameters);
            }
        }
예제 #4
0
        /// <summary>
        /// Render a template to a string.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="formatProvider">Culture.</param>
        /// <param name="parameters">Parameters for the holes.</param>
        /// <param name="forceTemplateRenderer">Do not fallback to StringBuilder.Format for positional templates.</param>
        /// <param name="sb">The String Builder destination.</param>
        /// <param name="messageTemplateParameters">Parameters for the holes.</param>
        public static void Render(this string template, IFormatProvider formatProvider, object[] parameters, bool forceTemplateRenderer, StringBuilder sb, out IList <MessageTemplateParameter> messageTemplateParameters)
        {
            int pos       = 0;
            int holeIndex = 0;

            messageTemplateParameters = null;

            TemplateEnumerator holeEnumerator = new TemplateEnumerator(template);

            while (holeEnumerator.MoveNext())
            {
                var literal = holeEnumerator.Current.Literal;
                if (holeIndex == 0 && !forceTemplateRenderer && sb.Length == 0 && literal.Skip != 0 && holeEnumerator.Current.Hole.Index != -1)
                {
                    // Not a template
                    sb.AppendFormat(formatProvider, template, parameters);
                    return;
                }

                sb.Append(template, pos, literal.Print);
                pos += literal.Print;
                if (literal.Skip == 0)
                {
                    pos++;
                }
                else
                {
                    pos += literal.Skip;
                    var hole = holeEnumerator.Current.Hole;
                    if (hole.Index != -1)
                    {
                        RenderHole(sb, hole, formatProvider, parameters[hole.Index], true);
                    }
                    else
                    {
                        var holeParameter = parameters[holeIndex];
                        if (messageTemplateParameters == null)
                        {
                            messageTemplateParameters = new MessageTemplateParameter[parameters.Length];
                        }
                        messageTemplateParameters[holeIndex++] = new MessageTemplateParameter(hole.Name, holeParameter, hole.Format, hole.CaptureType);
                        RenderHole(sb, hole, formatProvider, holeParameter);
                    }
                }
            }

            if (messageTemplateParameters != null && holeIndex != messageTemplateParameters.Count)
            {
                var truncateParameters = new MessageTemplateParameter[holeIndex];
                for (int i = 0; i < truncateParameters.Length; ++i)
                {
                    truncateParameters[i] = messageTemplateParameters[i];
                }
                messageTemplateParameters = truncateParameters;
            }
        }
예제 #5
0
        /// <summary>
        /// Render a template to a string.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="formatProvider">Culture.</param>
        /// <param name="parameters">Parameters for the holes.</param>
        /// <param name="forceTemplateRenderer">Do not fallback to StringBuilder.Format for positional templates.</param>
        /// <param name="sb">The String Builder destination.</param>
        /// <param name="messageTemplateParameters">Parameters for the holes.</param>
        public static void Render(this string template, IFormatProvider formatProvider, object[] parameters, bool forceTemplateRenderer, StringBuilder sb, out IList <MessageTemplateParameter> messageTemplateParameters)
        {
            int pos               = 0;
            int holeIndex         = 0;
            int holeStartPosition = 0;

            messageTemplateParameters = null;
            int originalLength = sb.Length;

            TemplateEnumerator templateEnumerator = new TemplateEnumerator(template);

            while (templateEnumerator.MoveNext())
            {
                if (holeIndex == 0 && !forceTemplateRenderer && templateEnumerator.Current.MaybePositionalTemplate && sb.Length == originalLength)
                {
                    // Not a structured template
                    sb.AppendFormat(formatProvider, template, parameters);
                    return;
                }

                var literal = templateEnumerator.Current.Literal;
                sb.Append(template, pos, literal.Print);
                pos += literal.Print;
                if (literal.Skip == 0)
                {
                    pos++;
                }
                else
                {
                    pos += literal.Skip;
                    var hole = templateEnumerator.Current.Hole;
                    if (hole.Alignment != 0)
                    {
                        holeStartPosition = sb.Length;
                    }
                    if (hole.Index != -1 && messageTemplateParameters == null)
                    {
                        holeIndex++;
                        RenderHole(sb, hole, formatProvider, parameters[hole.Index], true);
                    }
                    else
                    {
                        var holeParameter = parameters[holeIndex];
                        if (messageTemplateParameters == null)
                        {
                            messageTemplateParameters = new MessageTemplateParameter[parameters.Length];
                            if (holeIndex != 0)
                            {
                                // rewind and try again
                                templateEnumerator = new TemplateEnumerator(template);
                                sb.Length          = originalLength;
                                holeIndex          = 0;
                                pos = 0;
                                continue;
                            }
                        }
                        messageTemplateParameters[holeIndex++] = new MessageTemplateParameter(hole.Name, holeParameter, hole.Format, hole.CaptureType);
                        RenderHole(sb, hole, formatProvider, holeParameter);
                    }
                    if (hole.Alignment != 0)
                    {
                        RenderPadding(sb, hole.Alignment, holeStartPosition);
                    }
                }
            }

            if (messageTemplateParameters != null && holeIndex != messageTemplateParameters.Count)
            {
                var truncateParameters = new MessageTemplateParameter[holeIndex];
                for (int i = 0; i < truncateParameters.Length; ++i)
                {
                    truncateParameters[i] = messageTemplateParameters[i];
                }
                messageTemplateParameters = truncateParameters;
            }
        }