Esempio n. 1
0
        /// <summary>
        ///     Formats user friendly representation of the name of the given matrix or jagged array type.
        /// </summary>
        /// <param name="type">Type for which user friendly representation of the name is required.</param>
        /// <param name="instance">
        ///     Instance for which friendly type name is appended.
        ///     This argument is used to gather additional information which might not be available from the type information.
        ///     This argument may be null if instance is not available.
        /// </param>
        /// <param name="sb">
        ///     String builder to which user friendly representation of the name of <paramref name="type" /> is appended.
        ///     If <paramref name="type" /> is null then nothing is appended to this string builder.
        /// </param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to this method to append to string builder. Negative value indicates
        ///     unlimited number of characters allowed. Method fails and returns false if it could not perform the task within given number of
        ///     characters.
        ///     On output contains remaining number of characters allowed.
        /// </param>
        /// <returns>
        ///     true if method has successfully appended friendly name of the data type within given number of characters allowed; otherwise
        ///     false.
        /// </returns>
        internal override bool AppendFriendlyTypeName(Type type, object instance, StringBuilder sb, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (type != null)
            {
                var elementType = GetElementType(type);
                if (elementType != null)
                {
                    var sfi = new ScalarFormatInfo();
                    success = success && sfi.AppendFriendlyTypeName(elementType, null, sb, ref maxLength);
                }
            }

            var rows     = 0;
            var lowCols  = 0;
            var highCols = 0;

            if (instance != null)
            {
                GetDimensions((Array)instance, out rows, out lowCols, out highCols);
            }

            success = FormatInfoUtils.TryAppendChar(this, sb, '[', success, ref maxLength);
            if (instance != null)
            {
                success = FormatInfoUtils.TryAppendString(this, sb, rows.ToString("0"), success, ref maxLength);
            }
            success = FormatInfoUtils.TryAppendChar(this, sb, ']', success, ref maxLength);

            success = FormatInfoUtils.TryAppendChar(this, sb, '[', success, ref maxLength);
            if (instance != null)
            {
                success = FormatInfoUtils.TryAppendString(this, sb, lowCols.ToString("0"), success, ref maxLength);
                if (highCols != lowCols)
                {
                    success = FormatInfoUtils.TryAppendChar(this, sb, '-', success, ref maxLength);
                    success = FormatInfoUtils.TryAppendString(this, sb, highCols.ToString("0"), success, ref maxLength);
                }
            }
            success = FormatInfoUtils.TryAppendChar(this, sb, ']', success, ref maxLength);

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 2
0
        /// <summary>
        ///     Appends formatted presentation of a given character to the given string builder.
        /// </summary>
        /// <param name="sb">String builder to which formatted character is appended.</param>
        /// <param name="c">Character which should be appended to the string builder.</param>
        /// <param name="quote">Indicates whether quotation marks should be placed around the character (true) or not (false).</param>
        /// <param name="stringEscaping">
        ///     Indicates whether escaping rules for strings should be applied (true) or only simple escaping
        ///     should be applied (false). String escaping includes double quotes and backslash characters escaping.
        /// </param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting will fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters will ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        private bool FormatChar(StringBuilder sb, char c, bool quote, bool stringEscaping, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            var quotationMark = (quote ? "'" : string.Empty);

            if (c == '\n')
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("{0}\\n{0}", quotationMark), success, ref maxLength);
            }
            else if (c == '\r')
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("{0}\\r{0}", quotationMark), success, ref maxLength);
            }
            else if (c == '\t')
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("{0}\\t{0}", quotationMark), success, ref maxLength);
            }
            else if (c < ' ')
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("0x{0:X2}", (int)c), success, ref maxLength);
            }
            else if (!stringEscaping && c == '\'')
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("{0}\\'{0}", quotationMark), success, ref maxLength);
            }
            else if (stringEscaping && c == '\\')
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("{0}\\\\{0}", quotationMark), success, ref maxLength);
            }
            else if (stringEscaping && c == '"')
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("{0}\\\"{0}", quotationMark), success, ref maxLength);
            }
            else
            {
                success = FormatInfoUtils.TryAppendString(this, sb, string.Format("{1}{0}{1}", c, quotationMark), success, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 3
0
        /// <summary>
        ///     Formats friendly representation of the name of the given type.
        /// </summary>
        /// <param name="type">Type for which friendly representation of the name is required.</param>
        /// <param name="instance">
        ///     Instance for which friendly type name is appended.
        ///     This argument is used to gather additional information which might not be available
        ///     from the type information. This argument may be null if instance is not available.
        /// </param>
        /// <param name="sb">
        ///     String builder to which friendly name of <paramref name="type" /> is appended.
        ///     If <paramref name="type" /> is null then nothing is appended to this string builder.
        /// </param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to this method
        ///     to append to string builder. Negative value indicates unlimited number of characters allowed.
        ///     Method fails and returns false if it could not perform the task within given number
        ///     of characters. On output contains remaining number of characters allowed.
        /// </param>
        /// <returns>
        ///     true if method has successfully appended friendly name of the data type
        ///     within given number of characters allowed; otherwise false.
        /// </returns>
        internal override bool AppendFriendlyTypeName(Type type, object instance, StringBuilder sb, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (type != null)
            {
                type = type.GetElementType();                 // For arrays print element type rather than array type
            }

            if (success)
            {
                var sfi = new ScalarFormatInfo(this);
                success = sfi.AppendFriendlyTypeName(type, null, sb, ref maxLength);
                // Use scalar format info because it can write simple data types in a more compact way
            }

            // Now append dimensions of the array
            // If instance is null then dimensions cannot be determined and braces will remain empty, like int[].
            // Otherwise, if instance is present, dimensions will be fully shown, like int[3, 4, 2] in case of three-dimensional array.

            success = FormatInfoUtils.TryAppendChar(this, sb, '[', success, ref maxLength);

            if (instance != null)
            {
                var dimensions = GetDimensions(instance);
                for (var i = 0; success && i < dimensions.Length; i++)
                {
                    if (i > 0)
                    {
                        success = FormatInfoUtils.TryAppendString(this, sb, ", ", success, ref maxLength);
                    }
                    success = FormatInfoUtils.TryAppendString(this, sb, dimensions[i].ToString("0"), success, ref maxLength);
                }
            }

            success = FormatInfoUtils.TryAppendChar(this, sb, ']', success, ref maxLength);

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 4
0
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using
        ///     specified format and culture-specific formatting information.
        /// </summary>
        /// <param name="sb">String builder to which formatted string should be appended.</param>
        /// <param name="format">
        ///     A format string containing formatting specifications;
        ///     ignored in this instance.
        /// </param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about current instance.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Single-lined formatting
        ///     will fail (and return false) if this number of characters is breached.
        ///     Multi-lined formatters ignore this parameter. Negative value indicates that formatter has unlimited
        ///     space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if string representation of <paramref name="arg" /> has been successfully
        ///     appended to <paramref name="sb" /> within given number of allowed characters; otherwise false.
        /// </returns>
        internal override bool Format(StringBuilder sb, string format, object arg,
                                      IFormatProvider formatProvider, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (PushCurrentObject(arg))
            {
                if (success)
                {
                    success = AppendInstanceTypeName(arg, sb, ref maxLength);
                }

                var dimensions = GetDimensions(arg);

                success = FormatInfoUtils.TryAppendSpaceIfNeeded(this, sb, success, ref maxLength);
                success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);

                if (MaximumDepth > 0)
                {
                    MaximumDepth--;

                    success = success && RecursiveAppendDimension(sb, (Array)arg, new List <int>(), ref maxLength);

                    MaximumDepth++;
                }

                success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);

                PopCurrentObject();
            }
            else
            {
                success = success && FormatInfoUtils.ReportInfiniteLoop(sb, arg, InstanceName, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;                 // Remove any characters appended to string builder in an unsuccessful attempt
            }

            return(success);
        }
Esempio n. 5
0
        /// <summary>
        ///     Formats user friendly representation of the name of the given type. Override in derived classes to implement specific
        ///     friendly names for known types handled by derived classes. Make sure that overridden implementations call base class
        ///     implementation in case that they cannot resolve type name.
        /// </summary>
        /// <param name="type">Type for which user friendly representation of the name is required.</param>
        /// <param name="instance">
        ///     Instance for which friendly type name is appended.
        ///     Use this argument to gather additional information which might not be available from the type information.
        ///     This argument may be null if instance is not available.
        /// </param>
        /// <param name="sb">
        ///     String builder to which user friendly representation of the name of <paramref name="type" /> is appended.
        ///     If <paramref name="type" /> is null then nothing is appended to this string builder.
        /// </param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to this method to append to string builder.
        ///     Negative value indicates unlimited number of characters allowed.
        ///     Method fails and returns false if it could not perform the task within given number of characters.
        ///     On output contains remaining number of characters allowed.
        /// </param>
        /// <returns>
        ///     true if method has successfully appended friendly name of the data type within given number of characters allowed; otherwise
        ///     false.
        /// </returns>
        internal virtual bool AppendFriendlyTypeName(Type type, object instance, StringBuilder sb, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (type != null)
            {
                var typeName     = type.Name;
                var backQuotePos = typeName.IndexOf('`');
                if (backQuotePos >= 0)
                {
                    typeName = typeName.Substring(0, backQuotePos);
                }

                success = FormatInfoUtils.TryAppendString(this, sb, typeName, success, ref maxLength);

                if (success && type.IsGenericType)
                {
                    var genericArguments = type.GetGenericArguments();

                    success = FormatInfoUtils.TryAppendString(this, sb, "<", success, ref maxLength);

                    for (var i = 0; success && i < genericArguments.Length; i++)
                    {
                        if (i > 0)
                        {
                            success = FormatInfoUtils.TryAppendString(this, sb, ", ", success, ref maxLength);
                        }
                        success = success && AppendFriendlyTypeName(genericArguments[i], null, sb, ref maxLength);
                    }

                    success = FormatInfoUtils.TryAppendString(this, sb, ">", success, ref maxLength);
                }
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 6
0
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using
        ///     specified format and culture-specific formatting information.
        /// </summary>
        /// <param name="sb">String builder to which formatted string should be appended.</param>
        /// <param name="format">A format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting will fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters will ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        internal override bool Format(StringBuilder sb, string format, object arg, IFormatProvider formatProvider, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (PushCurrentObject(arg))
            {
                if (ShowDataType)
                {
                    var instanceType = GetInstanceType(arg);
                    success = success && AppendFriendlyTypeName(instanceType, arg, sb, ref maxLength);
                }

                if (sb.Length > originalLength)
                {
                    success = FormatInfoUtils.TryAppendChar(this, sb, ' ', success, ref maxLength);
                }
                success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);

                if (arg != null)
                {
                    IncIndentationLevel(true);

                    var array = (Array)arg;
                    var rows  = array.GetLength(0);

                    var cafi = new CompactArrayFormatInfo(this);
                    cafi.ShowItemsOnly = true;
                    cafi.FieldLength   = GetMaxValueLength(array);

                    var rowNumberFormatProvider = new ScalarFormatInfo(VerboseFormatInfo.SingleLinedFormat);
                    rowNumberFormatProvider.ShowDataType     = false;
                    rowNumberFormatProvider.ShowInstanceName = false;
                    if (IsMultiLinedFormat)
                    {
                        rowNumberFormatProvider.FieldLength = rowNumberFormatProvider.GetValueLength(rows);
                    }

                    for (var i = 0; i < rows; i++)
                    {
                        if (i == rows - 1)
                        {
                            DecIndentationLevel();
                            IncIndentationLevel(false);                             // There are no more rows in the matrix

                            cafi.DecIndentationLevel();
                            cafi.IncIndentationLevel(false);
                        }

                        success = success && FormatLinePrefix(sb, true, i == rows - 1, false, 0, ref maxLength);
                        success = FormatInfoUtils.TryAppendString(this, sb, "Row ", success, ref maxLength);
                        success = success && rowNumberFormatProvider.Format(sb, null, i, rowNumberFormatProvider, ref maxLength);

                        success = FormatInfoUtils.TryAppendChar(this, sb, ' ', success, ref maxLength);
                        success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);

                        // Now we should append row content, which is obtained differently in case of matrix and in case of jagged array
                        if (array.Rank == 1)
                        {
                            // Array is jagged
                            var row = (Array)array.GetValue(i);
                            cafi.ShowLastDimension = false;
                            success = success && cafi.Format(sb, null, row, cafi, ref maxLength);
                        }
                        else
                        {
                            // Array is a matrix
                            cafi.HeadingIndices    = new[] { i };
                            cafi.ShowLastDimension = true;
                            success             = success && cafi.Format(sb, null, array, cafi, ref maxLength);
                            cafi.HeadingIndices = null;
                        }

                        success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);
                    }

                    DecIndentationLevel();
                }

                success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);

                PopCurrentObject();
            }
            else
            {
                success = success && FormatInfoUtils.ReportInfiniteLoop(sb, arg, InstanceName, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using
        ///     specified format and culture-specific formatting information.
        /// </summary>
        /// <param name="sb">String builder to which formatted string should be appended.</param>
        /// <param name="format">A format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting should fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters should ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        internal override bool Format(StringBuilder sb, string format, object arg, IFormatProvider formatProvider, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (PushCurrentObject(arg))
            {
                if (ShowDataType && !_showValuesOnly)
                {
                    success = success && AppendInstanceTypeName(arg, sb, ref maxLength);
                }

                if (ShowInstanceName && !string.IsNullOrEmpty(InstanceName) && !_showValuesOnly)
                {
                    success = FormatInfoUtils.TryAppendSpaceIfNeeded(this, sb, success, ref maxLength);
                    success = FormatInfoUtils.TryAppendString(this, sb, InstanceName, success, ref maxLength);
                }

                if (!_showValuesOnly)
                {
                    success = FormatInfoUtils.TryAppendSpaceIfNeeded(this, sb, success, ref maxLength);
                    success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);
                }

                Type enumeratedType = null;
                var  enumerator     = GetEnumerator(arg, ref enumeratedType);

                var itemFormatter = new VerboseFormatInfo(this);

                var value        = new object[2];
                var valueFetched = new bool[2];

                valueFetched[0] = GetNextValue(enumerator, ref value[0]);
                if (valueFetched[0])
                {
                    valueFetched[1] = GetNextValue(enumerator, ref value[1]);
                }

                var itemPos = 0;

                while (valueFetched[0])
                {
                    IncIndentationLevel(valueFetched[1]);
                    itemFormatter.IncIndentationLevel(valueFetched[1]);

                    var valueName = string.Format("Item[{0}]", itemPos++);

                    itemFormatter.InstanceDataType = enumeratedType;
                    itemFormatter.InstanceName     = valueName;

                    success = success && FormatLinePrefix(sb, itemPos == 0, !valueFetched[1], false, 0, ref maxLength);
                    success = success && itemFormatter.Format(sb, null, value[0], itemFormatter, ref maxLength);

                    valueFetched[0] = valueFetched[1];
                    value[0]        = value[1];

                    valueFetched[1] = GetNextValue(enumerator, ref value[1]);

                    itemFormatter.DecIndentationLevel();
                    DecIndentationLevel();
                }

                if (!_showValuesOnly)
                {
                    success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);
                }

                PopCurrentObject();
            }
            else
            {
                success = success && FormatInfoUtils.ReportInfiniteLoop(sb, arg, InstanceName, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 8
0
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using
        ///     specified format and culture-specific formatting information.
        /// </summary>
        /// <param name="sb">String builder to which formatted string should be appended.</param>
        /// <param name="format">Format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting will fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters will ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        internal override bool Format(StringBuilder sb, string format, object arg, IFormatProvider formatProvider, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (PushCurrentObject(arg))
            {
                if (ShowDataType)
                {
                    success = success && AppendInstanceTypeName(arg, sb, ref maxLength);
                }

                if (!string.IsNullOrEmpty(InstanceName))
                {
                    var name = string.Format("{0}{1}{2}={2}", sb.Length > originalLength ? " " : "", InstanceName, IsMultiLinedFormat ? " " : "");
                    success = FormatInfoUtils.TryAppendString(this, sb, name, success, ref maxLength);
                }
                else if (sb.Length > originalLength)
                {
                    success = FormatInfoUtils.TryAppendChar(this, sb, ' ', success, ref maxLength);
                }

                var argType = GetInstanceType(arg);

                if (arg == null)
                {
                    success = FormatInfoUtils.TryAppendString(this, sb, FormatInfoUtils.DefaultNullFormatted, success, ref maxLength);
                }
                else if (arg is char)
                {
                    success = success && FormatChar(sb, (char)arg, true, false, ref maxLength);
                }
                else if (arg is string)
                {
                    success = success && FormatString(sb, (string)arg, true, ref maxLength);
                }
                else if (arg is Boolean)
                {
                    success = FormatInfoUtils.TryAppendString(this, sb, ((bool)arg) ? "true" : "false", success, ref maxLength);
                }
                else if (argType.IsEnum)
                {
                    var plainName = Enum.GetName(argType, arg);

                    if (plainName != null)
                    {
                        success = FormatInfoUtils.TryAppendString(this, sb, plainName, success, ref maxLength);
                    }
                    else
                    {
                        success = success && AppendEnumFlags((Enum)arg, sb, ref maxLength);                          // arg is an OR-ed combination of values
                    }
                }
                else
                {
                    success = FormatInfoUtils.TryAppendString(this, sb, arg.ToString(), success, ref maxLength);
                }

                while (success && sb.Length - originalLength < _fieldLength)
                {
                    success = FormatInfoUtils.TryAppendChar(this, sb, ' ', success, ref maxLength);
                }

                PopCurrentObject();
            }
            else
            {
                success = success && FormatInfoUtils.ReportInfiniteLoop(sb, arg, InstanceName, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 9
0
        /// <summary>
        ///     Appends user friendly name for the given data type and appends it to string builder.
        /// </summary>
        /// <param name="type">Data type for which user friendly name is requested.</param>
        /// <param name="instance">
        ///     Instance for which friendly type name is appended.
        ///     Use this argument to gather additional information which might not be available from the type information.
        ///     This argument may be null if instance is not available.
        /// </param>
        /// <param name="sb">String builder to which data type name should be appended.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting will fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters will ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available.
        ///     On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        internal override bool AppendFriendlyTypeName(Type type, object instance, StringBuilder sb, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (type == typeof(SByte))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "sbyte", success, ref maxLength);
            }
            else if (type == typeof(Byte))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "byte", success, ref maxLength);
            }
            else if (type == typeof(Int16))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "short", success, ref maxLength);
            }
            else if (type == typeof(UInt16))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "ushort", success, ref maxLength);
            }
            else if (type == typeof(Int32))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "int", success, ref maxLength);
            }
            else if (type == typeof(UInt32))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "uint", success, ref maxLength);
            }
            else if (type == typeof(Int64))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "long", success, ref maxLength);
            }
            else if (type == typeof(UInt64))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "ulong", success, ref maxLength);
            }
            else if (type == typeof(float))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "float", success, ref maxLength);
            }
            else if (type == typeof(Double))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "double", success, ref maxLength);
            }
            else if (type == typeof(Decimal))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "decimal", success, ref maxLength);
            }
            else if (type == typeof(char))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "char", success, ref maxLength);
            }
            else if (type == typeof(String))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "string", success, ref maxLength);
            }
            else if (type == typeof(Boolean))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "bool", success, ref maxLength);
            }
            else if (type == typeof(DateTime))
            {
                success = FormatInfoUtils.TryAppendString(this, sb, "DateTime", success, ref maxLength);
            }
            else if (type.IsEnum)
            {
                success = FormatInfoUtils.TryAppendString(this, sb, type.Name, success, ref maxLength);
            }
            else
            {
                success = success && base.AppendFriendlyTypeName(type, instance, sb, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 10
0
        /// <summary>
        ///     Appends names of enumeration constants that are present in the OR-ed value.
        /// </summary>
        /// <param name="value">Enumeration value which is possibly a combination of multiple OR-ed values.</param>
        /// <param name="sb">String builder to which enumeration value names should be appended.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting will fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters will ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        private bool AppendEnumFlags(Enum value, StringBuilder sb, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            var enumType       = value.GetType();
            var underlyingType = Enum.GetUnderlyingType(enumType);

            // The following code tries to recover flags in a flagged enum value
            // in .NET 4.0 this can be done much easier using Enum.HasFlag instance-level method, but with some unpredictable outcomes
            // e.g. if enumeration defines Left, Right and Both=Left | Right; then Both might be shown as Left | Right | Both which is avoided by this function

            var    isInt64     = false;
            var    isUint64    = false;
            Int64  int64Value  = 0;
            UInt64 uint64Value = 0;

            if (underlyingType == typeof(sbyte) || underlyingType == typeof(Int16) || underlyingType == typeof(Int32) ||
                underlyingType == typeof(Int64))
            {
                isInt64    = true;
                int64Value = ((IConvertible)value).ToInt64(null);
            }
            else if (underlyingType == typeof(byte) || underlyingType == typeof(UInt16) || underlyingType == typeof(UInt32) ||
                     underlyingType == typeof(UInt64))
            {
                isUint64    = true;
                uint64Value = ((IConvertible)value).ToUInt64(null);
            }

            Int64  constructedInt64Value  = 0;
            UInt64 constructedUint64Value = 0;

            var values = Enum.GetValues(enumType);
            var constructionComplete = false;
            var flags = new List <object>();            // Enumeration values that are incorporated in OR-ed value

            foreach (var simpleValue in values)
            {
                if (isInt64)
                {
                    var curInt64Value = ((IConvertible)simpleValue).ToInt64(null);

                    if ((int64Value & curInt64Value) == curInt64Value && (constructedInt64Value & curInt64Value) != curInt64Value)
                    {
                        // simpleValue is part of the resulting OR-ed value and is not included in currently constructed value (or is not completely included)

                        constructedInt64Value = constructedInt64Value | curInt64Value;
                        flags.Add(simpleValue);

                        if (constructedInt64Value == int64Value)
                        {
                            constructionComplete = true;
                            break;
                        }
                    }
                }
                else if (isUint64)
                {
                    var curUint64Value = ((IConvertible)simpleValue).ToUInt64(null);

                    if ((uint64Value & curUint64Value) == curUint64Value && (constructedUint64Value & curUint64Value) != curUint64Value)
                    {
                        // simpleValue is part of the resulting OR-ed value and is not included in currently constructed value (or is not completely included)

                        constructedUint64Value = constructedUint64Value | curUint64Value;
                        flags.Add(simpleValue);

                        if (constructedUint64Value == uint64Value)
                        {
                            constructionComplete = true;
                            break;
                        }
                    }
                }
            }

            if (!constructionComplete)
            {
                success = FormatInfoUtils.TryAppendString(this, sb, value.ToString(), success, ref maxLength);
                // Append it as number or whatever Enum.ToString() makes out of this value
            }
            else
            {
                var isFirst = true;

                foreach (var simpleValue in flags)
                {
                    if (!isFirst)
                    {
                        success = FormatInfoUtils.TryAppendChar(this, sb, '+', success, ref maxLength);
                    }
                    isFirst = false;

                    success = FormatInfoUtils.TryAppendString(this, sb, Enum.GetName(enumType, simpleValue), success, ref maxLength);

                    if (!success)
                    {
                        break;
                    }
                }
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 11
0
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using
        ///     specified format and culture-specific formatting information.
        /// </summary>
        /// <param name="sb">String builder to which formatted string should be appended.</param>
        /// <param name="format">A format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting should fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters should ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        internal override bool Format(StringBuilder sb, string format, object arg, IFormatProvider formatProvider, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (PushCurrentObject(arg))
            {
                if (arg == null)
                {
                    success = FormatInfoUtils.TryAppendString(this, sb, FormatInfoUtils.DefaultNullFormatted, success, ref maxLength);
                }
                else
                {
                    var keys      = GetKeysCollection(arg);
                    var keyType   = GetDeclaredKeyValueType(arg, true);
                    var valueType = GetDeclaredKeyValueType(arg, false);

                    var sfi = new ScalarFormatInfo(this);
                    success = success && sfi.AppendInstanceTypeName(arg, sb, ref maxLength);
                    // Using scalar format info to append type name ensures that scalar types will be
                    // represented with their short forms rather than CTS names which are less readable

                    if (!string.IsNullOrEmpty(InstanceName))
                    {
                        success = FormatInfoUtils.TryAppendSpaceIfNeeded(this, sb, success, ref maxLength);
                        success = FormatInfoUtils.TryAppendString(this, sb, InstanceName, success, ref maxLength);
                    }

                    if (IsMultiLinedFormat)
                    {
                        success = FormatInfoUtils.TryAppendSpaceIfNeeded(this, sb, success, ref maxLength);
                        success = FormatInfoUtils.TryAppendString(this, sb, "= ", success, ref maxLength);
                    }
                    else
                    {
                        success = FormatInfoUtils.TryAppendChar(this, sb, '=', success, ref maxLength);
                    }

                    success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);

                    if (MaximumDepth > 0)
                    {
                        MaximumDepth--;

                        var enumerator = keys.GetEnumerator();

                        var isFirstValue = true;

                        var key        = new object[2];
                        var keyFetched = new bool[2];

                        keyFetched[0] = enumerator.MoveNext();
                        if (keyFetched[0])
                        {
                            key[0]        = enumerator.Current;
                            keyFetched[1] = enumerator.MoveNext();
                            if (keyFetched[1])
                            {
                                key[1] = enumerator.Current;
                            }
                        }

                        VerboseFormatInfoBase containedItemsFormat = new VerboseFormatInfo(this);

                        var itemPos = 0;

                        while (keyFetched[0])
                        {
                            IncIndentationLevel(keyFetched[1]);
                            containedItemsFormat.IncIndentationLevel(keyFetched[1]);

                            success      = success && FormatLinePrefix(sb, isFirstValue, !keyFetched[1], false, 0, ref maxLength);
                            isFirstValue = false;

                            success = FormatInfoUtils.TryAppendString(this, sb, "Item[", success, ref maxLength);
                            success = FormatInfoUtils.TryAppendString(this, sb, itemPos.ToString("0"), success, ref maxLength);
                            itemPos++;
                            success = FormatInfoUtils.TryAppendString(this, sb, "] = ", success, ref maxLength);
                            success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);

                            containedItemsFormat.IncIndentationLevel(true);
                            IncIndentationLevel(true);

                            success = success && FormatLinePrefix(sb, true, false, false, 0, ref maxLength);
                            containedItemsFormat.InstanceDataType = keyType;
                            containedItemsFormat.InstanceName     = "Key";
                            success = success && containedItemsFormat.Format(sb, null, key[0], containedItemsFormat, ref maxLength);

                            DecIndentationLevel();
                            containedItemsFormat.DecIndentationLevel();

                            containedItemsFormat.IncIndentationLevel(false);
                            IncIndentationLevel(false);

                            var value = GetValue(arg, key[0]);

                            success = success && FormatLinePrefix(sb, false, true, false, 0, ref maxLength);
                            containedItemsFormat.InstanceDataType = valueType;
                            containedItemsFormat.InstanceName     = "Value";
                            success = success && containedItemsFormat.Format(sb, null, value, containedItemsFormat, ref maxLength);

                            DecIndentationLevel();
                            containedItemsFormat.DecIndentationLevel();

                            success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);

                            key[0]        = key[1];
                            keyFetched[0] = keyFetched[1];

                            if (keyFetched[0])
                            {
                                keyFetched[1] = enumerator.MoveNext();
                                if (keyFetched[1])
                                {
                                    key[1] = enumerator.Current;
                                }
                            }

                            containedItemsFormat.DecIndentationLevel();
                            DecIndentationLevel();
                        }

                        MaximumDepth++;
                    }                     // if (MaximumDepth > 0)

                    success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);
                }

                PopCurrentObject();
            }
            else
            {
                success = success && FormatInfoUtils.ReportInfiniteLoop(sb, arg, InstanceName, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 12
0
        /// <summary>
        ///     Appends all fields that should be placed before next contained value is appended to the output.
        ///     In single-lined formats that will only be the field delimiter.
        ///     In multi-lined formats that may include indentation strings.
        /// </summary>
        /// <param name="sb">
        ///     String builder which ends with a field after which strings that are used to
        ///     delimit successive fields should be appended.
        /// </param>
        /// <param name="firstValueFollows">
        ///     Indicates whether next value to be formatted is the first contained value
        ///     under the current instance (true) or other fields at the same level have already been appended to the output (false).
        /// </param>
        /// <param name="lastValueFollows">
        ///     Indicates whether next value is the last one (true) or there are more values to follow (false).
        ///     Ignored if this format provider is single-lined.
        /// </param>
        /// <param name="skipRightMostIndentationString">
        ///     Indicates whether right-most indentation string should be replaced with normal indentation string
        ///     (true) or not (false). This stands for last right most indentation string as well.
        /// </param>
        /// <param name="padLineToLength">
        ///     Indicates required length of the line in multi-lined formats. If string created by applying
        ///     all prefixes and delimiters is shorter than this value then it is right-padded with blank spaces until this length is reached.
        /// </param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to be appended to string builder by this function.
        ///     Negative value indicates unlimited number. If this function cannot fit the content into this number of characters
        ///     then it fails and returns false. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if function has successfully appended specified content to the string builder without breaching the allowed
        ///     number of characters specified by parameter <paramref name="maxLength" />; otherwise false.
        /// </returns>
        internal bool FormatLinePrefix(StringBuilder sb, bool firstValueFollows, bool lastValueFollows, bool skipRightMostIndentationString,
                                       int padLineToLength, ref int maxLength)
        {
            var originalLength = sb.Length;
            var success        = true;

            if (firstValueFollows && _isMultiLinedFormat)
            {
                success = FormatInfoUtils.TryAppendString(this, sb, Environment.NewLine, success, ref maxLength);
            }
            else if (!firstValueFollows)
            {
                success = FormatInfoUtils.TryAppendString(this, sb, _fieldDelimiter, success, ref maxLength);
            }

            if (_isMultiLinedFormat)
            {
                success = FormatInfoUtils.TryAppendString(this, sb, _linePrefix, success, ref maxLength);

                for (var i = 0; success && i < IndentationLevel; i++)
                {
                    string indentString     = null;
                    string lastIndentString = null;

                    if (IsIndentationLevelOccupied(i + 1))
                    {
                        indentString     = IndentationString;
                        lastIndentString = LastIndentationString;
                    }
                    else
                    {
                        indentString = string.Empty;
                        for (var j = 0; j < IndentationString.Length; j++)
                        {
                            if (IndentationString[j] == '\t')
                            {
                                indentString += '\t';
                            }
                            else
                            {
                                indentString += ' ';
                            }
                        }

                        lastIndentString = string.Empty;
                        for (var j = 0; j < LastIndentationString.Length; j++)
                        {
                            if (LastIndentationString[j] == '\t')
                            {
                                lastIndentString += '\t';
                            }
                            else
                            {
                                lastIndentString += ' ';
                            }
                        }
                    }

                    var rightMostIndentString     = (skipRightMostIndentationString ? indentString : RightMostIndentationString);
                    var lastRightMostIndentString = (skipRightMostIndentationString ? lastIndentString : LastRightMostIndentationString);

                    if (lastValueFollows && i == IndentationLevel - 1)
                    {
                        success = FormatInfoUtils.TryAppendString(this, sb,
                                                                  lastRightMostIndentString ?? lastIndentString ?? rightMostIndentString ?? indentString, success, ref maxLength);
                    }
                    else if (lastValueFollows)
                    {
                        success = FormatInfoUtils.TryAppendString(this, sb, lastIndentString ?? indentString, success, ref maxLength);
                    }
                    else if (i == IndentationLevel - 1)
                    {
                        success = FormatInfoUtils.TryAppendString(this, sb, rightMostIndentString ?? indentString, success, ref maxLength);
                    }
                    else
                    {
                        success = FormatInfoUtils.TryAppendString(this, sb, indentString, success, ref maxLength);
                    }
                }

                if (padLineToLength > 0)
                {
                    var lineLength = GetCurrentLineLength(sb);
                    while (success && lineLength++ < padLineToLength)
                    {
                        success = FormatInfoUtils.TryAppendChar(this, sb, ' ', success, ref maxLength);
                    }
                }
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 13
0
        /// <summary>
        ///     Appends formatted string representing part of the array provided, starting from specific location within the array.
        /// </summary>
        /// <param name="sb">String builder to which formatted string will be appended.</param>
        /// <param name="arg">Array which should be formatted into string which is appended to <paramref name="sb" />.</param>
        /// <param name="indices">
        ///     List of index values for dimensions iterated this far. In every call, this method will continue
        ///     from location within the array indicated by this parameter.
        /// </param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter.
        ///     Single-lined formatting will fail (and return false) if this number of characters is breached.
        ///     Multi-lined formatters ignore this parameter. Negative value indicates
        ///     that formatter has unlimited space available. On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        private bool RecursiveAppendDimension(StringBuilder sb, Array arg, List <int> indices, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            var dimension = arg.GetLength(indices.Count);

            if (dimension > 0)
            {
                for (var i = 0; i < dimension; i++)
                {
                    indices.Add(i);

                    IncIndentationLevel(i < dimension - 1);

                    success = success && FormatLinePrefix(sb, true, i == dimension - 1, false, 0, ref maxLength);
                    success = FormatInfoUtils.TryAppendString(this, sb, "Item[", success, ref maxLength);

                    var firstIndex = true;
                    foreach (var index in indices)
                    {
                        if (!firstIndex)
                        {
                            success = FormatInfoUtils.TryAppendString(this, sb, ", ", success, ref maxLength);
                        }
                        firstIndex = false;
                        success    = FormatInfoUtils.TryAppendString(this, sb, index.ToString("0"), success, ref maxLength);
                    }

                    success = FormatInfoUtils.TryAppendString(this, sb, "] ", success, ref maxLength);
                    success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);

                    if (indices.Count < arg.Rank)
                    {
                        success = success && RecursiveAppendDimension(sb, arg, indices, ref maxLength);
                    }
                    else
                    {
                        var value = arg.GetValue(indices.ToArray());

                        var vfi = new VerboseFormatInfo(this);
                        vfi.MaximumFormattedLength =
                            FormatInfoUtils.CombineMaxFormattedLengths(
                                RawMaximumFormattedLength,
                                FormatInfoUtils.DefaultMaxFormattedLength);

                        success = FormatInfoUtils.TryAppendChar(this, sb, ' ', success, ref maxLength);
                        success = success && vfi.Format(sb, null, value, vfi, ref maxLength);
                    }

                    success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);

                    DecIndentationLevel();

                    indices.RemoveAt(indices.Count - 1);
                }
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }
Esempio n. 14
0
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using
        ///     specified format and culture-specific formatting information.
        /// </summary>
        /// <param name="sb">String builder to which formatted string will be appended.</param>
        /// <param name="format">Format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <param name="maxLength">
        ///     Maximum number of characters allowed to the formatter. Formatting will fail (and return false)
        ///     if this number of characters is breached. Multi-lined formatters will ignore this parameter.
        ///     Negative value indicates that formatter has unlimited space available.
        ///     On output contains remaining number of characters available.
        /// </param>
        /// <returns>
        ///     true if representation of <paramref name="arg" /> has been successfully appended to <paramref name="sb" />
        ///     within given number of allowed characters; otherwise false.
        /// </returns>
        internal override bool Format(StringBuilder sb, string format, object arg, IFormatProvider formatProvider, ref int maxLength)
        {
            var success        = true;
            var originalLength = sb.Length;

            if (PushCurrentObject(arg))
            {
                if (ShowDataType)
                {
                    success = success && AppendInstanceTypeName(arg, sb, ref maxLength);
                }

                if (ShowInstanceName && !string.IsNullOrEmpty(InstanceName))
                {
                    success = FormatInfoUtils.TryAppendSpaceIfNeeded(this, sb, success, ref maxLength);
                    success = FormatInfoUtils.TryAppendString(this, sb, InstanceName, success, ref maxLength);

                    if (IsMultiLinedFormat)
                    {
                        success = FormatInfoUtils.TryAppendString(this, sb, " = ", success, ref maxLength);
                    }
                    else
                    {
                        success = FormatInfoUtils.TryAppendChar(this, sb, '=', success, ref maxLength);
                    }
                }
                else
                {
                    success = FormatInfoUtils.TryAppendSpaceIfNeeded(this, sb, success, ref maxLength);
                }

                if (arg == null)
                {
                    success = FormatInfoUtils.TryAppendString(this, sb, FormatInfoUtils.DefaultNullFormatted, success, ref maxLength);
                }
                else
                {
                    success = FormatInfoUtils.TryAppendString(this, sb, FirstContainedValuePrefix, success, ref maxLength);

                    if (MaximumDepth > 0)
                    {
                        MaximumDepth--;

                        var members = ExtractMembers(arg);

                        var vfi = new VerboseFormatInfo(this);
                        vfi.ShowDataType     = true;
                        vfi.ShowInstanceName = true;

                        for (var i = 0; success && i < members.Length; i++)
                        {
                            IncIndentationLevel(i < members.Length - 1);
                            vfi.IncIndentationLevel(i < members.Length - 1);

                            success = success && FormatLinePrefix(sb, i == 0, i == members.Length - 1, false, 0, ref maxLength);
                            vfi.InstanceDataType = members[i].DataType;
                            vfi.InstanceName     = members[i].Name;
                            success = success && vfi.Format(sb, format, members[i].Value, vfi, ref maxLength);

                            vfi.DecIndentationLevel();
                            DecIndentationLevel();
                        }

                        MaximumDepth++;
                    }

                    success = FormatInfoUtils.TryAppendString(this, sb, LastContainedValueSuffix, success, ref maxLength);
                }

                PopCurrentObject();
            }
            else
            {
                success = success && FormatInfoUtils.ReportInfiniteLoop(sb, arg, InstanceName, ref maxLength);
            }

            if (!success)
            {
                sb.Length = originalLength;
            }

            return(success);
        }