我们都知道StringBuilder是在内部维护一个字符数组的,所以我们也是从字符数组里下手用于做我们的string缓冲,而在C#里能够快速操作字符数组的也许就需要使用微软不推荐使用的“指针”了(呵呵,别头痛,虽然我也对指针很头痛,但这里用的指针很简单,你可以看成是一个数组的int索引编号值)
因我的文字表达能力很差,所以我直接提供代码,希望各位能够看懂
注:以下代码并非真正个人原创,我只是在原作者的基础上修改并加强部分功能(有中文注解的则是本人所加功能)
如果编译以下代码必须将unsafe打开,否则不能编译
using System;
using System.IO;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Kingthy.Library.Text
{
/**//// <summary>
/// TextBuilder : 类似于StringBuilder的字符串处理类
/// </summary>
public sealed class TextBuilder
{
构造函数#region 构造函数
public TextBuilder()
{
}
public TextBuilder(int initialCapacity)
{
if (initialCapacity < PaddingSize)
{
initialCapacity = PaddingSize;
}
this.EnsureCapacityInternal(initialCapacity);
}
public TextBuilder(string s) : this(s.ToCharArray(), 0, s.Length)
{
}
public TextBuilder(char[] chars) : this(chars, 0, chars.Length)
{
}
public TextBuilder(char[] chars, int startIndex, int length)
{
if (length != 0)
{
this.EnsureCapacityInternal(length);
TextBuilder.UnsafeCopyChars(this._data, 0, chars, startIndex, length);
this._length = length;
}
}
#endregion
从文件载入数据#region 从文件载入数据
/**//// <summary>
/// 从文本文件载入
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static TextBuilder FromFile(string fileName)
{
return TextBuilder.FromFile(fileName,System.Text.Encoding.Default);
}
/**//// <summary>
/// 从文本文件载入
/// </summary>
/// <param name="fileName"></param>
/// <param name="charset"></param>
/// <returns></returns>
public static TextBuilder FromFile(string fileName,System.Text.Encoding charset)
{
TextBuilder text = null;
StreamReader stream = null;
try
{
stream = new StreamReader(fileName,charset);
text = new TextBuilder(stream.ReadToEnd());
}
catch
{
text = null;
}
finally
{
if(stream != null)stream.Close();
}
return text;
}
#endregion
添加字符#region 添加字符
public TextBuilder Append(string s)
{
return this.Append(s.ToCharArray(), 0, s.Length);
}
public TextBuilder Append(char[] chars)
{
return this.Append(chars, 0, chars.Length);
}
public TextBuilder Append(char ch)
{
this.EnsureCapacityInternal(this._length + 1);
this._data[this._length++] = ch;
this.MakeDirty();
return this;
}
public TextBuilder Append(char[] chars, int length)
{
return this.Append(chars, 0, length);
}
public TextBuilder Append(string s, int length)
{
return this.Append(s.ToCharArray(0, length), 0, length);
}
public TextBuilder Append(string s, int startIndex, int length)
{
return this.Append(s.ToCharArray(startIndex, length), 0, length);
}
public TextBuilder Append(char[] chars, int startIndex, int length)
{
if(length < 1)return this;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((startIndex < 0) || (chars.Length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
this.EnsureCapacityInternal(this._length + length);
TextBuilder.UnsafeCopyChars(this._data, this._length, chars, startIndex, length);
this._length += length;
this.MakeDirty();
return this;
}
//添加字符并添加新的一行
public TextBuilder AppendLine(string s)
{
return this.AppendLine(s.ToCharArray(), 0, s.Length);
}
public TextBuilder AppendLine(char[] chars)
{
return this.AppendLine(chars, 0, chars.Length);
}
public TextBuilder AppendLine(char ch)
{
string newLine = string.Concat(ch,System.Environment.NewLine);
this.EnsureCapacityInternal(this._length + newLine.Length);
for(int i=0; i<newLine.Length; i++)
{
this._data[this._length++] = newLine[i];
}
this.MakeDirty();
return this;
}
public TextBuilder AppendLine(char[] chars, int length)
{
return this.AppendLine(chars, 0, length);
}
public TextBuilder AppendLine(string s, int length)
{
return this.AppendLine(s.ToCharArray(0, length), 0, length);
}
public TextBuilder AppendLine(string s, int startIndex, int length)
{
return this.AppendLine(s.ToCharArray(startIndex, length), 0, length);
}
public TextBuilder AppendLine(char[] chars, int startIndex, int length)
{
if(length < 1)return this;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((startIndex < 0) || (chars.Length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
//取得换行符
string newLine = System.Environment.NewLine;
this.EnsureCapacityInternal(this._length + length + newLine.Length);
TextBuilder.UnsafeCopyChars(this._data, this._length, chars, startIndex, length);
this._length += length;
//添加新的一行
for(int i=0; i<newLine.Length; i++)
{
this._data[this._length++] = newLine[i];
}
this.MakeDirty();
return this;
}
#endregion
清空字符#region 清空字符
public void Clear()
{
this._length = 0;
this._data = new char[0];
this.MakeDirty();
}
#endregion
从某字符串里拷贝#region 从某字符串里拷贝
public void Copy(char ch)
{
this.EnsureCapacityInternal(1);
this._data[0] = ch;
this._length = 1;
this.MakeDirty();
}
public void Copy(string s)
{
this.Copy(s.ToCharArray(), 0, s.Length);
}
public void Copy(char[] chars)
{
this.Copy(chars, 0, chars.Length);
}
public void Copy(string s, int length)
{
this.Copy(s.ToCharArray(0, length), 0, length);
}
public void Copy(char[] chars, int length)
{
this.Copy(chars, 0, length);
}
public void Copy(char[] chars, int startIndex, int length)
{
if(length < 1)return;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((startIndex < 0) || (chars.Length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
this.EnsureCapacityInternal(length);
TextBuilder.UnsafeCopyChars(this._data, 0, chars, startIndex, length);
this.MakeDirty();
this._length = length;
}
public void Copy(string s, int startIndex, int length)
{
this.Copy(s.ToCharArray(startIndex, length), 0, length);
}
#endregion
删除字符#region 删除字符
public bool Delete(int startIndex)
{
if ((startIndex < 0) || (this._data == null))
{
return false;
}
this._length = startIndex;
this.MakeDirty();
return true;
}
public bool Delete(int startIndex, int length)
{
if (((startIndex < 0) || (this._data == null)) || (startIndex > this.Length))
{
return false;
}
this.ShiftCharsLeft(this._data, startIndex, this.Length, length);
this._length -= length;
this.MakeDirty();
return true;
}
#endregion
重新设置容量#region 重新设置容量
private void EnsureCapacityInternal(int capacity)
{
if (this._length < capacity)
{
if (capacity > PaddingSize)
{
int num1 = PaddingSize - (capacity % PaddingSize);
capacity += num1;
}
else
{
capacity = PaddingSize;
}
char[] chArray1 = new char[capacity];
if (this._length != 0)
{
TextBuilder.UnsafeCopyChars(chArray1, 0, this._data, 0, this._length);
}
this._data = chArray1;
this._capacity = capacity;
}
}
#endregion
插入字符#region 插入字符
public void Insert(int index, char c)
{
if ((index < 0) || (index > this._length))
{
throw new ArgumentOutOfRangeException("index");
}
this.Capacity = (this._length + 1);
this.ShiftCharsRight(this._data, index, this._length, 1);
this._data[index] = c;
this._length++;
this.MakeDirty();
}
public void Insert(int index, char[] chars)
{
if (chars == null)
{
throw new ArgumentNullException("chars");
}
this.Insert(index, chars, 0, chars.Length);
}
public void Insert(int index, string s)
{
this.Insert(index, s.ToCharArray());
}
public void Insert(int index, char[] chars, int start, int length)
{
if(length < 1)return;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((index < 0) || (index > this._length))
{
throw new ArgumentOutOfRangeException("index");
}
this.Capacity = this._length + length;
this.ShiftCharsRight(this._data, index, this._length, length);
Array.Copy(chars, start, this._data, index, length);
this._length += length;
this.MakeDirty();
}
#endregion
查找字符#region 查找字符
public int IndexOf(char ch)
{
if (this._length != 0)
{
return TextBuilder.UnsafeIndexOf(this._data, 0, this._length, ch);
}
return -1;
}
public int IndexOf(string s)
{
return this.IndexOf(s, 0, false);
}
public int IndexOf(string s, bool ignoreCase)
{
return this.IndexOf(s, 0, ignoreCase);
}
public int IndexOf(string s, int startIndex, bool ignoreCase)
{
if (s == null)
{
throw new ArgumentNullException();
}
int num1 = s.Length;
if (num1 == 0)
{
return 0;
}
if (this._length >= num1)
{
char[] chArray1 = s.ToCharArray();
int num2 = this._length - num1;
if (!ignoreCase)
{
for (int num6 = startIndex; num6 <= num2; num6++)
{
if (TextBuilder.UnsafeCompareChars(this._data, num6, this._length - num6, chArray1, 0, num1) == 0)
{
return num6;
}
}
}
else
{
for (int num7 = startIndex; num7 <= num2; num7++)
{
if (TextBuilder.UnsafeCompareCharsIgnoreCase(this._data, num7, this._length - num7, chArray1, 0, num1) == 0)
{
return num7;
}
}
}
}
return -1;
}
public int IndexOfAny(char[] chars)
{
if (chars == null)
{
throw new ArgumentNullException();
}
if (this._length != 0)
{
int num1 = chars.Length;
for (int num3 = 0; num3 < num1; num3++)
{
int num2 = TextBuilder.UnsafeIndexOf(this._data, 0, this._length, chars[num3]);
if (num2 != -1)
{
return num2;
}
}
}
return -1;
}
#endregion
判断字符是否相等#region 判断字符是否相等
/**//// <summary>
/// 判断是否以某字符开头
/// </summary>
/// <param name="equalString">要判断的字符</param>
/// <returns></returns>
public bool StartWith(string equalString)
{
return this.StartWith(equalString,false);
}
public bool StartWith(string equalString,bool ignoreCase)
{
return this.InWith(0,equalString,ignoreCase);
}
/**//// <summary>
/// 判断字符是否相同并区分大小写
/// </summary>
/// <param name="startIndex">起始索引位置</param>
/// <param name="equalString">要判断的字符</param>
/// <returns></returns>
public bool InWith(int startIndex,string equalString)
{
return this.InWith(startIndex,equalString,false);
}
/**//// <summary>
/// 判断字符是否相同
/// </summary>
/// <param name="startIndex">起始索引位置</param>
/// <param name="equalString">要判断的字符</param>
/// <param name="ignoreCase">是否不区分大小写</param>
/// <returns></returns>
public bool InWith(int startIndex, string equalString,bool ignoreCase)
{
if(equalString == null || equalString.Length < 1)return false;
if(startIndex < 0)return false;
if((startIndex + equalString.Length) > this._length)return false;
if(ignoreCase)
{
return (UnsafeCompareCharsIgnoreCase(this._data,startIndex,equalString.Length,equalString.ToCharArray(),0,equalString.Length) == 0);
}
else
{
return (UnsafeCompareChars(this._data,startIndex,equalString.Length,equalString.ToCharArray(),0,equalString.Length) == 0);
}
}
/**//// <summary>
/// 判断是否以某字符结尾
/// </summary>
/// <param name="equalString">要判断的字符</param>
/// <returns></returns>
public bool EndWith(string equalString)
{
return this.EndWith(equalString,false);
}
public bool EndWith(string equalString,bool ignoreCase)
{
if(equalString == null || equalString.Length < 1)return false;
if(equalString.Length > this._length)return false;
return this.InWith((this._length - equalString.Length),equalString,ignoreCase);
}
#endregion
从后面查找字符#region 从后面查找字符
public int LastIndexOf(char ch)
{
if (this._length != 0)
{
return TextBuilder.UnsafeLastIndexOf(this._data, 0, this._length, ch);
}
return -1;
}
public int LastIndexOf(string s)
{
return this.LastIndexOf(s, this._length, false);
}
public int LastIndexOf(string s, bool ignoreCase)
{
return this.LastIndexOf(s, this._length, ignoreCase);
}
public int LastIndexOf(string s, int startIndex, bool ignoreCase)
{
if (s == null)
{
throw new ArgumentNullException();
}
int num1 = s.Length;
if (num1 == 0)
{
return 0;
}
if (this._length >= num1)
{
char[] chArray1 = s.ToCharArray();
int num2 = Math.Min(this._length - num1, startIndex);
if (!ignoreCase)
{
for (int num6 = num2; num6 >= 0; num6--)
{
if (TextBuilder.UnsafeCompareChars(this._data, num6, this._length - num6, chArray1, 0, num1) == 0)
{
return num6;
}
}
}
else
{
for (int num7 = num2; num7 >= 0; num7--)
{
if (TextBuilder.UnsafeCompareCharsIgnoreCase(this._data, num7, this._length - num7, chArray1, 0, num1) == 0)
{
return num7;
}
}
}
}
return -1;
}
public int LastIndexOfAny(char[] chars)
{
if (chars == null)
{
throw new ArgumentNullException();
}
if (this._length != 0)
{
int num1 = chars.Length;
for (int num3 = 0; num3 < num1; num3++)
{
int num2 = TextBuilder.UnsafeLastIndexOf(this._data, 0, this._length, chars[num3]);
if (num2 != -1)
{
return num2;
}
}
}
return -1;
}
#endregion
获取某部分字符#region 获取某部分字符
public string SubString(int startIndex, int length)
{
if(startIndex < 0 || length < 1)return string.Empty;
length = Math.Min(length,this._length - startIndex);
return new string(this.ToCharArray(startIndex, length));
}
public string SubStr(int startIndex, int endIndex)
{
if(startIndex < 0 || endIndex < startIndex)return string.Empty;
return SubString(startIndex, (endIndex - startIndex) + 1);
}
public override string ToString()
{
if (this._cachedString == null)
{
if (this._length != 0)
{
this._cachedString = new string(this._data, 0, this._length);
}
else
{
this._cachedString = string.Empty;
}
}
return this._cachedString;
}
#endregion
返回字符#region 返回字符
public char[] ToCharArray()
{
return this.ToCharArrayInternal(0, this._length);
}
public char[] ToCharArray(int startIndex, int length)
{
if ((startIndex < 0) || (this._length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
return this.ToCharArrayInternal(startIndex, length);
}
private char[] ToCharArrayInternal(int startIndex, int length)
{
if (length == 0)
{
return new char[0];
}
char[] chArray1 = new char[length];
TextBuilder.UnsafeCopyChars(chArray1, 0, this._data, startIndex, length);
return chArray1;
}
#endregion
替换字符#region 替换字符
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
public void Replace(string find, string replacement)
{
this.Replace(find,replacement,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="startIndex">起始位置</param>
public void Replace(string find, string replacement, int startIndex)
{
this.Replace(find,replacement,startIndex,false,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="ignoreCase">是否不区分大小字</param>
public void Replace(string find, string replacement, bool ignoreCase)
{
this.Replace(find,replacement,0,ignoreCase,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="startIndex">起始位置</param>
/// <param name="ignoreCase">是否不区分大小字</param>
public void Replace(string find, string replacement, int startIndex, bool ignoreCase)
{
this.Replace(find,replacement,startIndex,ignoreCase,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="startIndex">起始位置</param>
/// <param name="ignoreCase">是否不区分大小字</param>
/// <param name="replaceCount">替换字数.如果小于1则替换全部</param>
public void Replace(string find, string replacement, int startIndex, bool ignoreCase, int replaceCount)
{
if (find == null || replacement == null)
{
throw new ArgumentNullException();
}
if(find.Length > this._length)return;
//取得缓存数组的数量
int bufferlen = replacement.Length - find.Length;
if(bufferlen > 0)
{
bufferlen = this._length + (this._length / find.Length) * bufferlen;
}
else
{
bufferlen = this._length;
}
char[] buffer = new char[0];
int c = 0;
int index = 0,sourceIndex = 0,descIndex = 0;
while(true)
{
index = IndexOf(find,startIndex,ignoreCase);
if(index >= 0)
{
//第一次则初始化缓存数组
if(c == 0)buffer = new char[bufferlen];
//复制原始数据[不包括已查找到的数据]
Array.Copy(this._data,sourceIndex,buffer,descIndex,(index - sourceIndex));
//复制新数据
descIndex += (index - sourceIndex);
if(replacement.Length > 0)
{
Array.Copy(replacement.ToCharArray(),0,buffer,descIndex,replacement.Length);
descIndex += replacement.Length;
}
//移动指针
sourceIndex = index + find.Length;
startIndex = sourceIndex;
c ++;
if(startIndex > this._length || (replaceCount > 0 && c >= replaceCount))break;
}
else
{
break;
}
}
if(c > 0)
{
if(startIndex < this._length)
{
//拷贝后面的数据
Array.Copy(this._data,sourceIndex,buffer,descIndex,(this._length - sourceIndex));
descIndex += (this._length - sourceIndex);
}
this._data = buffer;
this._length = descIndex;
this.MakeDirty();
}
}
#endregion
私有处理函数#region 私有处理函数
private void MakeDirty()
{
this._cachedString = null;
}
private void ShiftCharsLeft(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
Array.Copy(chars, startIndex + shiftAmount, chars, startIndex, endIndex - (shiftAmount + startIndex));
}
private void ShiftCharsRight(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
Array.Copy(chars, startIndex, chars, startIndex + shiftAmount, endIndex - startIndex);
}
private static unsafe int UnsafeCompareChars(char[] chars1, int startIndex1, int length1, char[] chars2, int startIndex2, int length2)
{
fixed (char* chRef1 = chars1)
{
fixed (char* chRef2 = chars2)
{
char* chPtr1 = chRef1 + startIndex1;
char* chPtr2 = chRef2 + startIndex2;
int num1 = 0;
int num2 = 0;
while ((num1 < length1) && (num2 < length2))
{
if (chPtr1[0] != chPtr2[0])
{
return (chPtr1[0] - chPtr2[0]);
}
num1++;
num2++;
chPtr1++;
chPtr2++;
}
if (num1 == num2)
{
return 0;
}
if (num1 < length1)
{
return 1;
}
return -1;
}
}
}
private static unsafe int UnsafeCompareCharsIgnoreCase(char[] chars1, int startIndex1, int length1, char[] chars2, int startIndex2, int length2)
{
fixed (char* chRef1 = chars1)
{
fixed (char* chRef2 = chars2)
{
char* chPtr1 = chRef1 + startIndex1;
char* chPtr2 = chRef2 + startIndex2;
int num1 = 0;
int num2 = 0;
while ((num1 < length1) && (num2 < length2))
{
if (char.ToUpper(chPtr1[0]) != char.ToUpper(chPtr2[0]))
{
return (chPtr1[0] - chPtr2[0]);
}
num1++;
num2++;
chPtr1++;
chPtr2++;
}
if (num1 == num2)
{
return 0;
}
if (num1 < length1)
{
return 1;
}
return -1;
}
}
}
private static unsafe void UnsafeCopyBytes(byte[] destBytes, int destStartIndex, byte[] srcBytes, int srcStartIndex, int length)
{
fixed (byte* numRef1 = destBytes)
{
fixed (byte* numRef2 = srcBytes)
{
byte* numPtr1 = numRef1 + destStartIndex;
byte* numPtr2 = numRef2 + srcStartIndex;
for (int num1 = 0; num1 < length; num1++)
{
*(numPtr1++) = *(numPtr2++);
}
}
}
}
private static unsafe void UnsafeCopyChars(char[] destChars, int destStartIndex, char[] srcChars, int srcStartIndex, int length)
{
fixed (char* chRef1 = destChars)
{
fixed (char* chRef2 = srcChars)
{
char* chPtr1 = chRef1 + destStartIndex;
char* chPtr2 = chRef2 + srcStartIndex;
for (int num1 = 0; num1 < length; num1++)
{
chPtr1[0] = chPtr2[0];
chPtr1++;
chPtr2++;
}
}
}
}
private static unsafe int UnsafeIndexOf(char[] chars, int startIndex, int length, char ch)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = chRef1 + startIndex;
int num1 = startIndex;
while (num1 < length)
{
if (chPtr1[0] == ch)
{
return num1;
}
num1++;
chPtr1++;
}
}
return -1;
}
private static unsafe int UnsafeLastIndexOf(char[] chars, int startIndex, int length, char ch)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = chRef1 + (length - 1);
int num1 = length - 1;
while (num1 >= startIndex)
{
if (chPtr1[0] == ch)
{
return num1;
}
num1--;
chPtr1--;
}
}
return -1;
}
private static unsafe void UnsafeShiftCharsLeft(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = chRef1 + startIndex;
char* chPtr2 = (chRef1 + endIndex) - (shiftAmount * 2);
while (chPtr1 < chPtr2)
{
chPtr1[0] = chPtr1[shiftAmount];
chPtr1++;
}
}
}
private static unsafe void UnsafeShiftCharsRight(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = (chRef1 + startIndex) + (shiftAmount * 2);
for (char* chPtr2 = ((chRef1 + endIndex) + (shiftAmount * 2)) - (1 * 2); chPtr2 >= chPtr1; chPtr2--)
{
chPtr2[0] = *(chPtr2 - shiftAmount);
}
}
}
#endregion
属性#region 属性
public bool IsEmpty
{
get
{
return (this._length == 0);
}
}
public char this[int index]
{
get
{
if ((index < 0) || (index >= this._length))
{
throw new ArgumentOutOfRangeException();
}
return this._data[index];
}
set
{
if ((index < 0) || (index >= this._length))
{
throw new ArgumentOutOfRangeException();
}
this._data[index] = value;
this.MakeDirty();
}
}
/**//// <summary>
/// 设置或返回初始容量
/// </summary>
public int Capacity
{
get
{
return _capacity;
}
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException();
}
this.EnsureCapacityInternal(value);
}
}
/**//// <summary>
/// 设置或返回当前存储字符的长度
/// </summary>
public int Length
{
get
{
return this._length;
}
set
{
if (value < 0)
{
throw new ArgumentOutOfRangeException();
}
if (this._length > value)
{
this._length = value;
this.MakeDirty();
}
}
}
#endregion
// Fields
private string _cachedString;
private char[] _data;
private int _length;
private int _capacity;
private const int PaddingSize = 0x10;
}
}
using System.IO;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Kingthy.Library.Text
{
/**//// <summary>
/// TextBuilder : 类似于StringBuilder的字符串处理类
/// </summary>
public sealed class TextBuilder
{
构造函数#region 构造函数
public TextBuilder()
{
}
public TextBuilder(int initialCapacity)
{
if (initialCapacity < PaddingSize)
{
initialCapacity = PaddingSize;
}
this.EnsureCapacityInternal(initialCapacity);
}
public TextBuilder(string s) : this(s.ToCharArray(), 0, s.Length)
{
}
public TextBuilder(char[] chars) : this(chars, 0, chars.Length)
{
}
public TextBuilder(char[] chars, int startIndex, int length)
{
if (length != 0)
{
this.EnsureCapacityInternal(length);
TextBuilder.UnsafeCopyChars(this._data, 0, chars, startIndex, length);
this._length = length;
}
}
#endregion
从文件载入数据#region 从文件载入数据
/**//// <summary>
/// 从文本文件载入
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static TextBuilder FromFile(string fileName)
{
return TextBuilder.FromFile(fileName,System.Text.Encoding.Default);
}
/**//// <summary>
/// 从文本文件载入
/// </summary>
/// <param name="fileName"></param>
/// <param name="charset"></param>
/// <returns></returns>
public static TextBuilder FromFile(string fileName,System.Text.Encoding charset)
{
TextBuilder text = null;
StreamReader stream = null;
try
{
stream = new StreamReader(fileName,charset);
text = new TextBuilder(stream.ReadToEnd());
}
catch
{
text = null;
}
finally
{
if(stream != null)stream.Close();
}
return text;
}
#endregion
添加字符#region 添加字符
public TextBuilder Append(string s)
{
return this.Append(s.ToCharArray(), 0, s.Length);
}
public TextBuilder Append(char[] chars)
{
return this.Append(chars, 0, chars.Length);
}
public TextBuilder Append(char ch)
{
this.EnsureCapacityInternal(this._length + 1);
this._data[this._length++] = ch;
this.MakeDirty();
return this;
}
public TextBuilder Append(char[] chars, int length)
{
return this.Append(chars, 0, length);
}
public TextBuilder Append(string s, int length)
{
return this.Append(s.ToCharArray(0, length), 0, length);
}
public TextBuilder Append(string s, int startIndex, int length)
{
return this.Append(s.ToCharArray(startIndex, length), 0, length);
}
public TextBuilder Append(char[] chars, int startIndex, int length)
{
if(length < 1)return this;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((startIndex < 0) || (chars.Length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
this.EnsureCapacityInternal(this._length + length);
TextBuilder.UnsafeCopyChars(this._data, this._length, chars, startIndex, length);
this._length += length;
this.MakeDirty();
return this;
}
//添加字符并添加新的一行
public TextBuilder AppendLine(string s)
{
return this.AppendLine(s.ToCharArray(), 0, s.Length);
}
public TextBuilder AppendLine(char[] chars)
{
return this.AppendLine(chars, 0, chars.Length);
}
public TextBuilder AppendLine(char ch)
{
string newLine = string.Concat(ch,System.Environment.NewLine);
this.EnsureCapacityInternal(this._length + newLine.Length);
for(int i=0; i<newLine.Length; i++)
{
this._data[this._length++] = newLine[i];
}
this.MakeDirty();
return this;
}
public TextBuilder AppendLine(char[] chars, int length)
{
return this.AppendLine(chars, 0, length);
}
public TextBuilder AppendLine(string s, int length)
{
return this.AppendLine(s.ToCharArray(0, length), 0, length);
}
public TextBuilder AppendLine(string s, int startIndex, int length)
{
return this.AppendLine(s.ToCharArray(startIndex, length), 0, length);
}
public TextBuilder AppendLine(char[] chars, int startIndex, int length)
{
if(length < 1)return this;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((startIndex < 0) || (chars.Length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
//取得换行符
string newLine = System.Environment.NewLine;
this.EnsureCapacityInternal(this._length + length + newLine.Length);
TextBuilder.UnsafeCopyChars(this._data, this._length, chars, startIndex, length);
this._length += length;
//添加新的一行
for(int i=0; i<newLine.Length; i++)
{
this._data[this._length++] = newLine[i];
}
this.MakeDirty();
return this;
}
#endregion
清空字符#region 清空字符
public void Clear()
{
this._length = 0;
this._data = new char[0];
this.MakeDirty();
}
#endregion
从某字符串里拷贝#region 从某字符串里拷贝
public void Copy(char ch)
{
this.EnsureCapacityInternal(1);
this._data[0] = ch;
this._length = 1;
this.MakeDirty();
}
public void Copy(string s)
{
this.Copy(s.ToCharArray(), 0, s.Length);
}
public void Copy(char[] chars)
{
this.Copy(chars, 0, chars.Length);
}
public void Copy(string s, int length)
{
this.Copy(s.ToCharArray(0, length), 0, length);
}
public void Copy(char[] chars, int length)
{
this.Copy(chars, 0, length);
}
public void Copy(char[] chars, int startIndex, int length)
{
if(length < 1)return;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((startIndex < 0) || (chars.Length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
this.EnsureCapacityInternal(length);
TextBuilder.UnsafeCopyChars(this._data, 0, chars, startIndex, length);
this.MakeDirty();
this._length = length;
}
public void Copy(string s, int startIndex, int length)
{
this.Copy(s.ToCharArray(startIndex, length), 0, length);
}
#endregion
删除字符#region 删除字符
public bool Delete(int startIndex)
{
if ((startIndex < 0) || (this._data == null))
{
return false;
}
this._length = startIndex;
this.MakeDirty();
return true;
}
public bool Delete(int startIndex, int length)
{
if (((startIndex < 0) || (this._data == null)) || (startIndex > this.Length))
{
return false;
}
this.ShiftCharsLeft(this._data, startIndex, this.Length, length);
this._length -= length;
this.MakeDirty();
return true;
}
#endregion
重新设置容量#region 重新设置容量
private void EnsureCapacityInternal(int capacity)
{
if (this._length < capacity)
{
if (capacity > PaddingSize)
{
int num1 = PaddingSize - (capacity % PaddingSize);
capacity += num1;
}
else
{
capacity = PaddingSize;
}
char[] chArray1 = new char[capacity];
if (this._length != 0)
{
TextBuilder.UnsafeCopyChars(chArray1, 0, this._data, 0, this._length);
}
this._data = chArray1;
this._capacity = capacity;
}
}
#endregion
插入字符#region 插入字符
public void Insert(int index, char c)
{
if ((index < 0) || (index > this._length))
{
throw new ArgumentOutOfRangeException("index");
}
this.Capacity = (this._length + 1);
this.ShiftCharsRight(this._data, index, this._length, 1);
this._data[index] = c;
this._length++;
this.MakeDirty();
}
public void Insert(int index, char[] chars)
{
if (chars == null)
{
throw new ArgumentNullException("chars");
}
this.Insert(index, chars, 0, chars.Length);
}
public void Insert(int index, string s)
{
this.Insert(index, s.ToCharArray());
}
public void Insert(int index, char[] chars, int start, int length)
{
if(length < 1)return;
if (chars == null)
{
throw new ArgumentNullException("chars");
}
if ((index < 0) || (index > this._length))
{
throw new ArgumentOutOfRangeException("index");
}
this.Capacity = this._length + length;
this.ShiftCharsRight(this._data, index, this._length, length);
Array.Copy(chars, start, this._data, index, length);
this._length += length;
this.MakeDirty();
}
#endregion
查找字符#region 查找字符
public int IndexOf(char ch)
{
if (this._length != 0)
{
return TextBuilder.UnsafeIndexOf(this._data, 0, this._length, ch);
}
return -1;
}
public int IndexOf(string s)
{
return this.IndexOf(s, 0, false);
}
public int IndexOf(string s, bool ignoreCase)
{
return this.IndexOf(s, 0, ignoreCase);
}
public int IndexOf(string s, int startIndex, bool ignoreCase)
{
if (s == null)
{
throw new ArgumentNullException();
}
int num1 = s.Length;
if (num1 == 0)
{
return 0;
}
if (this._length >= num1)
{
char[] chArray1 = s.ToCharArray();
int num2 = this._length - num1;
if (!ignoreCase)
{
for (int num6 = startIndex; num6 <= num2; num6++)
{
if (TextBuilder.UnsafeCompareChars(this._data, num6, this._length - num6, chArray1, 0, num1) == 0)
{
return num6;
}
}
}
else
{
for (int num7 = startIndex; num7 <= num2; num7++)
{
if (TextBuilder.UnsafeCompareCharsIgnoreCase(this._data, num7, this._length - num7, chArray1, 0, num1) == 0)
{
return num7;
}
}
}
}
return -1;
}
public int IndexOfAny(char[] chars)
{
if (chars == null)
{
throw new ArgumentNullException();
}
if (this._length != 0)
{
int num1 = chars.Length;
for (int num3 = 0; num3 < num1; num3++)
{
int num2 = TextBuilder.UnsafeIndexOf(this._data, 0, this._length, chars[num3]);
if (num2 != -1)
{
return num2;
}
}
}
return -1;
}
#endregion
判断字符是否相等#region 判断字符是否相等
/**//// <summary>
/// 判断是否以某字符开头
/// </summary>
/// <param name="equalString">要判断的字符</param>
/// <returns></returns>
public bool StartWith(string equalString)
{
return this.StartWith(equalString,false);
}
public bool StartWith(string equalString,bool ignoreCase)
{
return this.InWith(0,equalString,ignoreCase);
}
/**//// <summary>
/// 判断字符是否相同并区分大小写
/// </summary>
/// <param name="startIndex">起始索引位置</param>
/// <param name="equalString">要判断的字符</param>
/// <returns></returns>
public bool InWith(int startIndex,string equalString)
{
return this.InWith(startIndex,equalString,false);
}
/**//// <summary>
/// 判断字符是否相同
/// </summary>
/// <param name="startIndex">起始索引位置</param>
/// <param name="equalString">要判断的字符</param>
/// <param name="ignoreCase">是否不区分大小写</param>
/// <returns></returns>
public bool InWith(int startIndex, string equalString,bool ignoreCase)
{
if(equalString == null || equalString.Length < 1)return false;
if(startIndex < 0)return false;
if((startIndex + equalString.Length) > this._length)return false;
if(ignoreCase)
{
return (UnsafeCompareCharsIgnoreCase(this._data,startIndex,equalString.Length,equalString.ToCharArray(),0,equalString.Length) == 0);
}
else
{
return (UnsafeCompareChars(this._data,startIndex,equalString.Length,equalString.ToCharArray(),0,equalString.Length) == 0);
}
}
/**//// <summary>
/// 判断是否以某字符结尾
/// </summary>
/// <param name="equalString">要判断的字符</param>
/// <returns></returns>
public bool EndWith(string equalString)
{
return this.EndWith(equalString,false);
}
public bool EndWith(string equalString,bool ignoreCase)
{
if(equalString == null || equalString.Length < 1)return false;
if(equalString.Length > this._length)return false;
return this.InWith((this._length - equalString.Length),equalString,ignoreCase);
}
#endregion
从后面查找字符#region 从后面查找字符
public int LastIndexOf(char ch)
{
if (this._length != 0)
{
return TextBuilder.UnsafeLastIndexOf(this._data, 0, this._length, ch);
}
return -1;
}
public int LastIndexOf(string s)
{
return this.LastIndexOf(s, this._length, false);
}
public int LastIndexOf(string s, bool ignoreCase)
{
return this.LastIndexOf(s, this._length, ignoreCase);
}
public int LastIndexOf(string s, int startIndex, bool ignoreCase)
{
if (s == null)
{
throw new ArgumentNullException();
}
int num1 = s.Length;
if (num1 == 0)
{
return 0;
}
if (this._length >= num1)
{
char[] chArray1 = s.ToCharArray();
int num2 = Math.Min(this._length - num1, startIndex);
if (!ignoreCase)
{
for (int num6 = num2; num6 >= 0; num6--)
{
if (TextBuilder.UnsafeCompareChars(this._data, num6, this._length - num6, chArray1, 0, num1) == 0)
{
return num6;
}
}
}
else
{
for (int num7 = num2; num7 >= 0; num7--)
{
if (TextBuilder.UnsafeCompareCharsIgnoreCase(this._data, num7, this._length - num7, chArray1, 0, num1) == 0)
{
return num7;
}
}
}
}
return -1;
}
public int LastIndexOfAny(char[] chars)
{
if (chars == null)
{
throw new ArgumentNullException();
}
if (this._length != 0)
{
int num1 = chars.Length;
for (int num3 = 0; num3 < num1; num3++)
{
int num2 = TextBuilder.UnsafeLastIndexOf(this._data, 0, this._length, chars[num3]);
if (num2 != -1)
{
return num2;
}
}
}
return -1;
}
#endregion
获取某部分字符#region 获取某部分字符
public string SubString(int startIndex, int length)
{
if(startIndex < 0 || length < 1)return string.Empty;
length = Math.Min(length,this._length - startIndex);
return new string(this.ToCharArray(startIndex, length));
}
public string SubStr(int startIndex, int endIndex)
{
if(startIndex < 0 || endIndex < startIndex)return string.Empty;
return SubString(startIndex, (endIndex - startIndex) + 1);
}
public override string ToString()
{
if (this._cachedString == null)
{
if (this._length != 0)
{
this._cachedString = new string(this._data, 0, this._length);
}
else
{
this._cachedString = string.Empty;
}
}
return this._cachedString;
}
#endregion
返回字符#region 返回字符
public char[] ToCharArray()
{
return this.ToCharArrayInternal(0, this._length);
}
public char[] ToCharArray(int startIndex, int length)
{
if ((startIndex < 0) || (this._length < (startIndex + length)))
{
throw new ArgumentOutOfRangeException();
}
return this.ToCharArrayInternal(startIndex, length);
}
private char[] ToCharArrayInternal(int startIndex, int length)
{
if (length == 0)
{
return new char[0];
}
char[] chArray1 = new char[length];
TextBuilder.UnsafeCopyChars(chArray1, 0, this._data, startIndex, length);
return chArray1;
}
#endregion
替换字符#region 替换字符
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
public void Replace(string find, string replacement)
{
this.Replace(find,replacement,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="startIndex">起始位置</param>
public void Replace(string find, string replacement, int startIndex)
{
this.Replace(find,replacement,startIndex,false,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="ignoreCase">是否不区分大小字</param>
public void Replace(string find, string replacement, bool ignoreCase)
{
this.Replace(find,replacement,0,ignoreCase,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="startIndex">起始位置</param>
/// <param name="ignoreCase">是否不区分大小字</param>
public void Replace(string find, string replacement, int startIndex, bool ignoreCase)
{
this.Replace(find,replacement,startIndex,ignoreCase,0);
}
/**//// <summary>
/// 替换字符
/// </summary>
/// <param name="find">要查找的字符</param>
/// <param name="replacement">要替换的字符</param>
/// <param name="startIndex">起始位置</param>
/// <param name="ignoreCase">是否不区分大小字</param>
/// <param name="replaceCount">替换字数.如果小于1则替换全部</param>
public void Replace(string find, string replacement, int startIndex, bool ignoreCase, int replaceCount)
{
if (find == null || replacement == null)
{
throw new ArgumentNullException();
}
if(find.Length > this._length)return;
//取得缓存数组的数量
int bufferlen = replacement.Length - find.Length;
if(bufferlen > 0)
{
bufferlen = this._length + (this._length / find.Length) * bufferlen;
}
else
{
bufferlen = this._length;
}
char[] buffer = new char[0];
int c = 0;
int index = 0,sourceIndex = 0,descIndex = 0;
while(true)
{
index = IndexOf(find,startIndex,ignoreCase);
if(index >= 0)
{
//第一次则初始化缓存数组
if(c == 0)buffer = new char[bufferlen];
//复制原始数据[不包括已查找到的数据]
Array.Copy(this._data,sourceIndex,buffer,descIndex,(index - sourceIndex));
//复制新数据
descIndex += (index - sourceIndex);
if(replacement.Length > 0)
{
Array.Copy(replacement.ToCharArray(),0,buffer,descIndex,replacement.Length);
descIndex += replacement.Length;
}
//移动指针
sourceIndex = index + find.Length;
startIndex = sourceIndex;
c ++;
if(startIndex > this._length || (replaceCount > 0 && c >= replaceCount))break;
}
else
{
break;
}
}
if(c > 0)
{
if(startIndex < this._length)
{
//拷贝后面的数据
Array.Copy(this._data,sourceIndex,buffer,descIndex,(this._length - sourceIndex));
descIndex += (this._length - sourceIndex);
}
this._data = buffer;
this._length = descIndex;
this.MakeDirty();
}
}
#endregion
私有处理函数#region 私有处理函数
private void MakeDirty()
{
this._cachedString = null;
}
private void ShiftCharsLeft(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
Array.Copy(chars, startIndex + shiftAmount, chars, startIndex, endIndex - (shiftAmount + startIndex));
}
private void ShiftCharsRight(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
Array.Copy(chars, startIndex, chars, startIndex + shiftAmount, endIndex - startIndex);
}
private static unsafe int UnsafeCompareChars(char[] chars1, int startIndex1, int length1, char[] chars2, int startIndex2, int length2)
{
fixed (char* chRef1 = chars1)
{
fixed (char* chRef2 = chars2)
{
char* chPtr1 = chRef1 + startIndex1;
char* chPtr2 = chRef2 + startIndex2;
int num1 = 0;
int num2 = 0;
while ((num1 < length1) && (num2 < length2))
{
if (chPtr1[0] != chPtr2[0])
{
return (chPtr1[0] - chPtr2[0]);
}
num1++;
num2++;
chPtr1++;
chPtr2++;
}
if (num1 == num2)
{
return 0;
}
if (num1 < length1)
{
return 1;
}
return -1;
}
}
}
private static unsafe int UnsafeCompareCharsIgnoreCase(char[] chars1, int startIndex1, int length1, char[] chars2, int startIndex2, int length2)
{
fixed (char* chRef1 = chars1)
{
fixed (char* chRef2 = chars2)
{
char* chPtr1 = chRef1 + startIndex1;
char* chPtr2 = chRef2 + startIndex2;
int num1 = 0;
int num2 = 0;
while ((num1 < length1) && (num2 < length2))
{
if (char.ToUpper(chPtr1[0]) != char.ToUpper(chPtr2[0]))
{
return (chPtr1[0] - chPtr2[0]);
}
num1++;
num2++;
chPtr1++;
chPtr2++;
}
if (num1 == num2)
{
return 0;
}
if (num1 < length1)
{
return 1;
}
return -1;
}
}
}
private static unsafe void UnsafeCopyBytes(byte[] destBytes, int destStartIndex, byte[] srcBytes, int srcStartIndex, int length)
{
fixed (byte* numRef1 = destBytes)
{
fixed (byte* numRef2 = srcBytes)
{
byte* numPtr1 = numRef1 + destStartIndex;
byte* numPtr2 = numRef2 + srcStartIndex;
for (int num1 = 0; num1 < length; num1++)
{
*(numPtr1++) = *(numPtr2++);
}
}
}
}
private static unsafe void UnsafeCopyChars(char[] destChars, int destStartIndex, char[] srcChars, int srcStartIndex, int length)
{
fixed (char* chRef1 = destChars)
{
fixed (char* chRef2 = srcChars)
{
char* chPtr1 = chRef1 + destStartIndex;
char* chPtr2 = chRef2 + srcStartIndex;
for (int num1 = 0; num1 < length; num1++)
{
chPtr1[0] = chPtr2[0];
chPtr1++;
chPtr2++;
}
}
}
}
private static unsafe int UnsafeIndexOf(char[] chars, int startIndex, int length, char ch)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = chRef1 + startIndex;
int num1 = startIndex;
while (num1 < length)
{
if (chPtr1[0] == ch)
{
return num1;
}
num1++;
chPtr1++;
}
}
return -1;
}
private static unsafe int UnsafeLastIndexOf(char[] chars, int startIndex, int length, char ch)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = chRef1 + (length - 1);
int num1 = length - 1;
while (num1 >= startIndex)
{
if (chPtr1[0] == ch)
{
return num1;
}
num1--;
chPtr1--;
}
}
return -1;
}
private static unsafe void UnsafeShiftCharsLeft(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = chRef1 + startIndex;
char* chPtr2 = (chRef1 + endIndex) - (shiftAmount * 2);
while (chPtr1 < chPtr2)
{
chPtr1[0] = chPtr1[shiftAmount];
chPtr1++;
}
}
}
private static unsafe void UnsafeShiftCharsRight(char[] chars, int startIndex, int endIndex, int shiftAmount)
{
fixed (char* chRef1 = chars)
{
char* chPtr1 = (chRef1 + startIndex) + (shiftAmount * 2);
for (char* chPtr2 = ((chRef1 + endIndex) + (shiftAmount * 2)) - (1 * 2); chPtr2 >= chPtr1; chPtr2--)
{
chPtr2[0] = *(chPtr2 - shiftAmount);
}
}
}
#endregion
属性#region 属性
public bool IsEmpty
{
get
{
return (this._length == 0);
}
}
public char this[int index]
{
get
{
if ((index < 0) || (index >= this._length))
{
throw new ArgumentOutOfRangeException();
}
return this._data[index];
}
set
{
if ((index < 0) || (index >= this._length))
{
throw new ArgumentOutOfRangeException();
}
this._data[index] = value;
this.MakeDirty();
}
}
/**//// <summary>
/// 设置或返回初始容量
/// </summary>
public int Capacity
{
get
{
return _capacity;
}
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException();
}
this.EnsureCapacityInternal(value);
}
}
/**//// <summary>
/// 设置或返回当前存储字符的长度
/// </summary>
public int Length
{
get
{
return this._length;
}
set
{
if (value < 0)
{
throw new ArgumentOutOfRangeException();
}
if (this._length > value)
{
this._length = value;
this.MakeDirty();
}
}
}
#endregion
// Fields
private string _cachedString;
private char[] _data;
private int _length;
private int _capacity;
private const int PaddingSize = 0x10;
}
}