using System;
using System.Collections.Generic;
using System.Text;
namespace Netron.Diagramming.Core {
///
/// (Describe usage of "L:300" format string.)
///
public interface IShowable : IFormattable {
//TODO: wonder if we should use TextWriters instead of StringBuilders?
///
/// Format this
using at most approximately rest
chars and
/// append the result, possibly truncated, to stringbuilder.
/// Subtract the actual number of used chars from rest
.
///
///
///
///
/// True if the appended formatted string was complete (not truncated).
bool Show(StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider);
}
// ------------------------------------------------------------
// Static helper methods for Showing collections
///
///
///
public static class Showing {
///
/// Show Object obj
by appending it to stringbuilder
///
///
///
///
///
/// True if obj
was shown completely.
public static bool Show(Object obj, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider) {
if (rest <= 0)
return false;
else if (obj is IShowable)
return ((IShowable)obj).Show(stringbuilder, ref rest, formatProvider);
int oldLength = stringbuilder.Length;
stringbuilder.AppendFormat(formatProvider, "{0}", obj);
rest -= (stringbuilder.Length - oldLength);
return true;
}
///
///
///
///
///
///
///
public static String ShowString(IShowable showable, String format, IFormatProvider formatProvider) {
int rest = maxLength(format);
StringBuilder sb = new StringBuilder();
showable.Show(sb, ref rest, formatProvider);
return sb.ToString();
}
///
///
///
///
///
static int maxLength(String format) {
//TODO: validate format string
if (format == null)
return 80;
if (format.Length > 1 && format.StartsWith("L")) {
return int.Parse(format.Substring(1));
} else
return int.MaxValue;
}
///
///
///
///
///
///
///
///
/// True if collection was shown completely
public static bool ShowCollectionValue(ICollectionBase items, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider) {
string startdelim = "{ ", enddelim = " }";
bool showIndexes = false;
//TODO: do not test here at run time, but select code at compile time
// perhaps by delivering the print type to this metod
if (items is IList) {
startdelim = "[ ";
enddelim = " ]";
} else if (items is ICollection) {
startdelim = "{{ ";
enddelim = " }}";
}
stringbuilder.Append(startdelim);
rest -= 2 * startdelim.Length;
bool first = true;
bool complete = true;
int index = 0;
{
foreach (T x in items) {
complete = false;
if (rest <= 0)
break;
if (first)
first = false;
else {
stringbuilder.Append(", ");
rest -= 2;
}
if (showIndexes) {
string indexString = string.Format("{0}:", index++);
stringbuilder.Append(indexString);
rest -= indexString.Length;
}
complete = Showing.Show(x, stringbuilder, ref rest, formatProvider);
}
}
if (!complete) {
stringbuilder.Append("...");
rest -= 3;
}
stringbuilder.Append(enddelim);
return complete;
}
///
///
///
///
///
///
///
///
///
///
///
public static bool ShowDictionary(IDictionary dictionary, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider) {
stringbuilder.Append("{ ");
rest -= 4; // Account for "( " and " )"
bool first = true;
bool complete = true;
foreach (KeyValuePair p in dictionary) {
complete = false;
if (rest <= 0)
break;
if (first)
first = false;
else {
stringbuilder.Append(", ");
rest -= 2;
}
complete = Showing.Show(p, stringbuilder, ref rest, formatProvider);
}
if (!complete) {
stringbuilder.Append("...");
rest -= 3;
}
stringbuilder.Append(" }");
return complete;
}
}
}