Ejemplo n.º 1
0
        /// <summary>
        /// Replaces named template items in a specified string
        /// with the string representation of a corresponding named object
        /// provided by the passed function.
        /// A specified parameter supplies culture-specific formatting information.
        /// </summary>
        /// <param name="provider">An object that supplies culture-specific formatting information.</param>
        /// <param name="template">A template string (see Remarks).</param>
        /// <param name="tryGetArgumentValue">An function that supplies named objects to format.</param>
        /// <returns>A copy of template in which the template items have been replaced
        /// by the string representation of the corresponding objects supplied by getValue.</returns>
        /// <exception cref="ArgumentNullException">template or the getValue callback is null.</exception>
        /// <exception cref="FormatException">template is invalid,
        /// or one of the named template items cannot be provided
        /// (getValue returns false when that item is requested).</exception>
        /// <remarks>
        /// <para>
        /// Note that argument names may or may not be case-sensitive depending on the
        /// comparer used by the dictionary. To get case-insensitive behaviour, use
        /// a dictionary that has a case-insensitive comparer.
        /// </para>
        /// <para>
        /// For implementations where a user-supplied template is used to format
        /// arguments provided by the system it is recommended that arguments
        /// are case-insensitive.
        /// </para>
        /// </remarks>
        public static string Format(IFormatProvider?provider, string template, TryGetArgumentValue tryGetArgumentValue)
        {
            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            if (tryGetArgumentValue == null)
            {
                throw new ArgumentNullException("tryGetArgumentValue");
            }

            char[] chArray = template.ToCharArray(0, template.Length);
            int    index   = 0;
            int    length  = chArray.Length;
            char   ch      = '\0';

            ICustomFormatter?formatter = null;

            if (provider != null)
            {
                formatter = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter));
            }

            StringBuilder builder = new StringBuilder();

            while (index < length)
            {
                ch = chArray[index];
                index++;
                if (ch == '}')
                {
                    if ((index < length) && (chArray[index] == '}'))
                    {
                        // Literal close curly brace
                        builder.Append('}');
                        index++;
                    }
                    else
                    {
                        throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                    }
                }
                else if (ch == '{')
                {
                    if ((index < length) && (chArray[index] == '{'))
                    {
                        // Literal open curly brace
                        builder.Append('{');
                        index++;
                    }
                    else
                    {
                        // Template item:
                        if (index == length)
                        {
                            throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                        }

                        // Argument name
                        int nameStart = index;
                        ch = chArray[index];
                        index++;
                        if (!(ch == '_' ||
                              ch == '@' ||
                              ((ch >= 'a') && (ch <= 'z')) ||
                              ((ch >= 'A') && (ch <= 'Z'))))
                        {
                            throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                        }

                        while ((index < length) &&
                               (ch == '.' || ch == '-' || ch == '_' || ch == '@' ||
                                ((ch >= '0') && (ch <= '9')) ||
                                ((ch >= 'a') && (ch <= 'z')) ||
                                ((ch >= 'A') && (ch <= 'Z'))))
                        {
                            ch = chArray[index];
                            index++;
                        }

                        int nameEnd = index - 1;
                        if (nameEnd == nameStart)
                        {
                            throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                        }

                        string argumentName = new string(chArray, nameStart, nameEnd - nameStart);
                        object?arg;
                        if (!tryGetArgumentValue(argumentName, out arg))
                        {
                            throw new FormatException(Resource_StringTemplate.StringTemplate_ArgumentNotFound);
                        }

                        // Skip blanks
                        while ((index < length) && (ch == ' '))
                        {
                            ch = chArray[index];
                            index++;
                        }

                        // Argument alignment
                        int  width     = 0;
                        bool leftAlign = false;
                        if (ch == ',')
                        {
                            if (index == length)
                            {
                                throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                            }

                            ch = chArray[index];
                            index++;
                            while ((index < length) && (ch == ' '))
                            {
                                ch = chArray[index];
                                index++;
                            }

                            if (index == length)
                            {
                                throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                            }

                            if (ch == '-')
                            {
                                leftAlign = true;
                                if (index == length)
                                {
                                    throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                                }

                                ch = chArray[index];
                                index++;
                            }

                            if ((ch < '0') || (ch > '9'))
                            {
                                throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                            }

                            while ((index < length) && (ch >= '0') && (ch <= '9'))
                            {
                                // TODO: What if number too large for Int32, i.e. throw exception
                                width = width * 10 + (ch - 0x30);
                                ch    = chArray[index];
                                index++;
                            }
                        }

                        // Skip blanks
                        while ((index < length) && (ch == ' '))
                        {
                            ch = chArray[index];
                            index++;
                        }

                        // Format string
                        string?formatString = null;
                        if (ch == ':')
                        {
                            if (index == length)
                            {
                                throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                            }

                            int formatStart = index;
                            ch = chArray[index];
                            index++;
                            while ((index < length) && (ch != '{') && (ch != '}'))
                            {
                                ch = chArray[index];
                                index++;
                            }

                            int formatEnd = index - 1;
                            if (formatEnd >= formatStart)
                            {
                                formatString = new string(chArray, formatStart, formatEnd - formatStart);
                            }
                        }

                        // Insert formatted argument
                        if (ch != '}')
                        {
                            throw new FormatException(Resource_StringTemplate.StringTemplate_InvalidString);
                        }

                        string?argumentValue = null;
                        if (formatter != null)
                        {
                            argumentValue = formatter.Format(formatString, arg, provider);
                        }

                        if (argumentValue == null)
                        {
                            if (arg is IFormattable)
                            {
                                argumentValue = ((IFormattable)arg).ToString(formatString, provider);
                            }
                            else if (arg != null)
                            {
                                argumentValue = arg.ToString();
                            }
                        }

                        if (argumentValue == null)
                        {
                            argumentValue = string.Empty;
                        }

                        int paddingCount = width - argumentValue.Length;
                        if (!leftAlign && (paddingCount > 0))
                        {
                            builder.Append(' ', paddingCount);
                        }

                        builder.Append(argumentValue);
                        if (leftAlign && (paddingCount > 0))
                        {
                            builder.Append(' ', paddingCount);
                        }
                    }
                }
                else
                {
                    // Literal -- scan up until next curly brace
                    int literalStart = index - 1;
                    while (index < length)
                    {
                        ch = chArray[index];
                        if (ch == '{' || ch == '}')
                        {
                            break;
                        }

                        index++;
                    }

                    builder.Append(chArray, literalStart, index - literalStart);
                }
            }

            return(builder.ToString());
        }
Ejemplo n.º 2
0
        public string Bind(string categoryName, LogLevel logLevel, EventId?eventId, string message,
                           Exception?exception, object[]?scopes)
        {
            TryGetArgumentValue valueProvider = delegate(string name, out object?value)
            {
                switch (name.ToUpperInvariant())
                {
                case "EVENTTYPE":
                case "LOGLEVEL":
                    value = logLevel;
                    break;

                case "SHORTLEVEL":
                case "SHORTLOGLEVEL":
                    value = GetShortLogLevel(logLevel);
                    break;

                case "FACILITY":
                    value = Facility;
                    break;

                case "SEVERITY":
                    value = GetSeverity(logLevel);
                    break;

                case "PRI":
                case "PRIORITY":
                    value = Facility * 8 + GetSeverity(logLevel);
                    break;

                case "ID":
                    value = eventId?.Id;
                    break;

                case "EVENTID":
                    value = eventId?.ToString();
                    break;

                case "MESSAGE":
                    value = message;
                    break;

                case "MESSAGEPREFIX":
                    value = FormatPrefix(message);
                    break;

                case "SOURCE":
                case "CATEGORY":
                case "CATEGORYNAME":
                    value = categoryName;
                    break;

                case "EXCEPTIONMESSAGE":
                    value = exception?.Message;
                    break;

                case "EXCEPTION":
                    value = exception;
                    break;

                case "SCOPES":
                    value = FormatScopes(scopes);
                    break;

                case "SCOPELIST":
                    value = FormatScopes(scopes, " => ", " => ");
                    break;

                default:
                    if (!_systemValueProvider.TryGetArgumentValue(name, out value))
                    {
                        value = "{" + name + "}";
                    }

                    break;
                }

                return(true);
            };
            var result = StringTemplate.Format(Template, valueProvider);

            return(result);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Replaces named template items in a specified string
 /// with the string representation of a corresponding named object
 /// provided by the passed function.
 /// A specified parameter supplies culture-specific formatting information.
 /// </summary>
 /// <param name="template">A template string (see Remarks).</param>
 /// <param name="tryGetArgumentValue">An function that supplies named objects to format.</param>
 /// <returns>A copy of template in which the template items have been replaced
 /// by the string representation of the corresponding objects supplied by getValue.</returns>
 /// <exception cref="ArgumentNullException">template or the getValue callback is null.</exception>
 /// <exception cref="FormatException">template is invalid,
 /// or one of the named template items cannot be provided
 /// (getValue returns false when that item is requested).</exception>
 /// <remarks>
 /// <para>
 /// Note that argument names may or may not be case-sensitive depending on the
 /// comparer used by the dictionary. To get case-insensitive behaviour, use
 /// a dictionary that has a case-insensitive comparer.
 /// </para>
 /// <para>
 /// For implementations where a user-supplied template is used to format
 /// arguments provided by the system it is recommended that arguments
 /// are case-insensitive.
 /// </para>
 /// </remarks>
 public static string Format(string template, TryGetArgumentValue tryGetArgumentValue)
 {
     return(Format(null, template, tryGetArgumentValue));
 }