Пример #1
0
        /// <summary>
        ///     Iterates through all values in the matrix or jagged array and finds maximum length required
        ///     to show any of the values contained.
        /// </summary>
        /// <param name="array">Matrix or jagged array through which this method will iterate.</param>
        /// <returns>Number of characters sufficient to receive any formatted value contained in <paramref name="array" />.</returns>
        private int GetMaxValueLength(Array array)
        {
            var maxLength = 0;

            if (IsMultiLinedFormat)
            {
                var sfi = new ScalarFormatInfo(this);
                sfi.ShowDataType     = false;
                sfi.ShowInstanceName = false;

                if (array.Rank == 2)
                {
                    maxLength = sfi.GetMaxValueLength(array.GetEnumerator());
                }
                else
                {
                    // In jagged array we have to iterate through rows manually

                    var rowsEnumerator = array.GetEnumerator();
                    while (rowsEnumerator.MoveNext())
                    {
                        var row          = (Array)rowsEnumerator.Current;
                        var curMaxLength = sfi.GetMaxValueLength(row.GetEnumerator());
                        maxLength = Math.Max(maxLength, curMaxLength);
                    }
                }
            }

            return(maxLength);
        }
Пример #2
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);
        }
Пример #3
0
        /// <summary>
        ///     Gets value indicating whether this format provider can be applied to specified data type or not.
        ///     This format provider is applicable to matrices (arrays of rank 2) and to jagged arrays, but only
        ///     if element type is supported by ScalarFormatInfo format provider.
        /// </summary>
        /// <param name="dataType">Data type agianst which this format provider is tested.</param>
        /// <returns>true if this format provider is applicable; otherwise false.</returns>
        internal override bool IsFormatApplicable(Type dataType)
        {
            var elementType = GetElementType(dataType);

            var applicable = false;

            if (elementType != null)
            {
                // Existence of elementType proves that dataType is matrix or jagged array
                var sfi = new ScalarFormatInfo(this);
                applicable = sfi.IsFormatApplicable(elementType);
            }

            return(applicable);
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #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 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;

            var formatters        = new List <VerboseFormatInfoBase>();
            var singleLinedFormat = SingleLinedFormat;

            if (arg != null || InstanceDataType != null)
            {
                var type = GetInstanceType(arg);

                var sfi = new ScalarFormatInfo(this);
                sfi.MaximumFormattedLength = maxLength;

                if (sfi.IsFormatApplicable(type))
                {
                    if (IsMultiLinedFormat)
                    {
                        var singleLinedSfi = new ScalarFormatInfo(this);
                        FormatInfoUtils.CopyFormatting(singleLinedFormat, singleLinedSfi);
                        singleLinedSfi.CombineMaximumFormattedLength(FormatInfoUtils.DefaultMaxFormattedLength);
                        formatters.Add(singleLinedSfi);
                    }

                    formatters.Add(sfi);
                }

                if (formatters.Count == 0)
                {
                    var dfi = new DictionaryFormatInfo(this);
                    dfi.MaximumFormattedLength = maxLength;

                    if (dfi.IsFormatApplicable(type))
                    {
                        if (IsMultiLinedFormat)
                        {
                            var singleLinedDfi = new DictionaryFormatInfo(this);
                            FormatInfoUtils.CopyFormatting(singleLinedFormat, singleLinedDfi);
                            singleLinedDfi.CombineMaximumFormattedLength(FormatInfoUtils.DefaultMaxFormattedLength);
                            formatters.Add(singleLinedDfi);
                        }
                        formatters.Add(dfi);
                    }
                }

                if (formatters.Count == 0)
                {
                    var cmfi = new CompactMatrixFormatInfo(this);
                    cmfi.MaximumFormattedLength = maxLength;

                    if (cmfi.IsFormatApplicable(type))
                    {
                        //if (IsMultiLinedFormat)   // Uncomment these lines to enable inlining compactly presented matrices; that operation is not suggested
                        //{
                        //    CompactMatrixFormatInfo singleLinedCmfi = new CompactMatrixFormatInfo(this);
                        //    FormatInfoUtils.CopyFormatting(singleLinedFormat, singleLinedCmfi);
                        //    singleLinedCmfi.CombineMaximumFormattedLength(FormatInfoUtils.DefaultMaxFormattedLength);
                        //    formatters.Add(singleLinedCmfi);
                        //}
                        formatters.Add(cmfi);
                    }
                }

                if (formatters.Count == 0)
                {
                    var cafi = new CompactArrayFormatInfo(this);
                    cafi.MaximumFormattedLength = maxLength;

                    if (cafi.IsFormatApplicable(type))
                    {
                        if (IsMultiLinedFormat)
                        {
                            var singleLinedCafi = new CompactArrayFormatInfo(this);
                            FormatInfoUtils.CopyFormatting(singleLinedFormat, singleLinedCafi);
                            singleLinedCafi.CombineMaximumFormattedLength(FormatInfoUtils.DefaultMaxFormattedLength);
                            formatters.Add(singleLinedCafi);
                        }
                        formatters.Add(cafi);
                    }
                }

                if (formatters.Count == 0)
                {
                    var afi = new ArrayFormatInfo(this);
                    afi.MaximumFormattedLength = maxLength;

                    if (afi.IsFormatApplicable(type))
                    {
                        if (IsMultiLinedFormat)
                        {
                            var singleLinedAfi = new ArrayFormatInfo(this);
                            FormatInfoUtils.CopyFormatting(singleLinedFormat, singleLinedAfi);
                            singleLinedAfi.CombineMaximumFormattedLength(FormatInfoUtils.DefaultMaxFormattedLength);
                            formatters.Add(singleLinedAfi);
                        }
                        formatters.Add(afi);
                    }
                }

                if (formatters.Count == 0)
                {
                    var efi = new EnumerableFormatInfo(this);
                    efi.MaximumFormattedLength = maxLength;

                    if (efi.IsFormatApplicable(type))
                    {
                        if (IsMultiLinedFormat)
                        {
                            var singleLinedEfi = new EnumerableFormatInfo(this);
                            FormatInfoUtils.CopyFormatting(singleLinedFormat, singleLinedEfi);
                            singleLinedEfi.CombineMaximumFormattedLength(FormatInfoUtils.DefaultMaxFormattedLength);
                            formatters.Add(singleLinedEfi);
                        }
                        formatters.Add(efi);
                    }
                }

                if (formatters.Count == 0)
                {
                    if (IsMultiLinedFormat)
                    {
                        var singleLinedGfi = new GeneralFormatInfo(this);
                        FormatInfoUtils.CopyFormatting(singleLinedFormat, singleLinedGfi);
                        singleLinedGfi.CombineMaximumFormattedLength(FormatInfoUtils.DefaultMaxFormattedLength);
                        formatters.Add(singleLinedGfi);
                    }

                    var gfi = new GeneralFormatInfo(this);
                    gfi.MaximumFormattedLength = maxLength;

                    formatters.Add(gfi);
                }
            }

            if (formatters.Count > 0)
            {
                success = success && FormatInfoUtils.BestTryFormat(sb, format, arg, formatters, ref maxLength);
            }

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

            return(success);
        }
Пример #7
0
 /// <summary>
 ///     Copy constructor which initializes new instance and copies common values from another instance of this class.
 /// </summary>
 /// <param name="other">Instance from which common values should be copied.</param>
 public ScalarFormatInfo(ScalarFormatInfo other)
     : base(other)
 {
     _fieldLength = other._fieldLength;
 }
Пример #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">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);
        }