|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Zigrem.Text
{
/// <summary>
/// Acts like a StringBuilder, with the added benefits that strings
/// can be added to the beginning of the builder+ without a significant
/// performance hit and a builder+ can be added to another builder+ without
/// a significant performance hit.
/// </summary>
public partial class StringBuilderPlus
{
#region Delegates
private delegate void AffixDelegate(IString str);
#endregion
#region Variables
private LinkedList<IString> strings;
private int length;
#endregion
#region Properties
/// <summary>
/// The strings this builder+ is composed of.
/// </summary>
private LinkedList<IString> Strings
{
get
{
return this.strings;
}
set
{
this.strings = value;
}
}
/// <summary>
/// Returns the string stored by this builder+.
/// </summary>
public string Value
{
get
{
string str;
if (this.Strings.Count == 0)
{
str = null;
}
else
{
StringBuilder builder = this.ToBuilder();
str = builder.ToString();
this.Strings.Clear();
this.Strings.AddLast(new PlainString(str));
}
return str;
}
}
/// <summary>
/// The length of the string stored by this builder+.
/// </summary>
public int Length
{
get
{
return this.length;
}
private set
{
this.length = value;
}
}
#endregion
#region Constructors
/// <summary>
/// Creates a builder+ that contains a null string.
/// </summary>
public StringBuilderPlus()
: this(null as string)
{
}
/// <summary>
/// Creates a builder+ that contains the specified string.
/// </summary>
/// <param name="str">The initial string.</param>
public StringBuilderPlus(string str)
{
this.Strings = new LinkedList<IString>();
if (str == null)
{
this.Length = 0;
}
else
{
this.Suffix(str);
this.Length = str.Length;
}
}
#endregion
#region Methods
/// <summary>
/// Adds the specified builder+ to the beginning of this builder+.
/// </summary>
/// <param name="builder">The builder+ to prefix.</param>
public void Prefix(StringBuilderPlus builder)
{
this.Affix(builder, AffixType.Before);
}
/// <summary>
/// Adds the specified builder+ to the end of this builder+.
/// </summary>
/// <param name="builder">The builder+ to suffix.</param>
public void Suffix(StringBuilderPlus builder)
{
this.Affix(builder, AffixType.After);
}
/// <summary>
/// Adds the specified string to the beginning of this builder+.
/// </summary>
/// <param name="str">The string to prefix.</param>
public void Prefix(string str)
{
this.Affix(str, AffixType.Before);
}
/// <summary>
/// Adds the specified string to the end of this builder=.
/// </summary>
/// <param name="str">The string to suffix.</param>
public void Suffix(string str)
{
this.Affix(str, AffixType.After);
}
/// <summary>
/// Affixes a string to the beginning or end of this builder+.
/// </summary>
/// <param name="str">The string to affix.</param>
/// <param name="type">Prefix or suffix?</param>
private void Affix(string str, AffixType type)
{
// Prefix or suffix?
AffixDelegate affix;
if (type == AffixType.Before)
{
affix = new AffixDelegate(delegate(IString val)
{
this.Strings.AddFirst(val);
});
}
else
{
affix = new AffixDelegate(delegate(IString val)
{
this.Strings.AddLast(val);
});
}
// Nulls and empties require special handling.
if (str != null)
{
if (str == string.Empty)
{
// Optimization: avoid affixing empty strings.
if (this.Strings.Count == 0)
{
affix(PlainString.Empty);
}
}
else
{
affix(new PlainString(str));
}
this.Length = this.Length + str.Length;
}
}
/// <summary>
/// Affixes a builder+ to the beginning or end of this builder+.
/// </summary>
/// <param name="builder">The builder+ to affix.</param>
/// <param name="type">Prefix or suffix?</param>
private void Affix(StringBuilderPlus builder, AffixType type)
{
// Prefix or suffix?
AffixDelegate affix;
if (type == AffixType.Before)
{
affix = new AffixDelegate(delegate(IString val)
{
this.Strings.AddFirst(val);
});
}
else
{
affix = new AffixDelegate(delegate(IString val)
{
this.Strings.AddLast(val);
});
}
// Wrap collection and affix.
if (builder != null && builder.Strings.Count > 0)
{
StringsWrapper wrapper = new StringsWrapper(builder.Strings, builder.Length);
builder.Strings = new LinkedList<IString>();
builder.Strings.AddLast(wrapper);
affix(wrapper);
this.Length = this.Length + builder.Length;
}
}
/// <summary>
/// Appends all the strings this builder+ contains to a string builder.
/// </summary>
/// <param name="builder">The string builder to append to.</param>
public void AppendTo(StringBuilder builder)
{
foreach (IString str in this.Strings)
{
str.AppendTo(builder);
}
}
/// <summary>
/// Creates a string builder from this builder+.
/// </summary>
/// <returns>The string builder.</returns>
public StringBuilder ToBuilder()
{
StringBuilder builder = new StringBuilder();
this.AppendTo(builder);
return builder;
}
/// <summary>
/// Returns the string stored by this builder+.
/// </summary>
/// <returns>The string.</returns>
public override string ToString()
{
return this.Value;
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.