using System; using System.Collections.Generic; using System.Text; namespace FastReport.Utils { /// /// Fast alternative of StringBuilder. /// public class FastString { #region Constants private const int INIT_CAPACITY = 32; #endregion Constants #region Fields /* private char[] chars = null; private int count = 0; private int capacity = 0; private List repList = null; */ private string result = ""; StringBuilder sb; private bool done = false; #endregion Fields #region Properties /// /// Gets the Length of string. /// public int Length { get { return sb.Length; } set { sb.Length = value; done = false; } } /// /// Gets or sets the chars of string. /// /// /// Char value public char this[int index] { get { if (index >= 0 && index < sb.Length) return sb[index]; else throw new IndexOutOfRangeException(); } set { if (index >= 0 && index < sb.Length) sb[index] = value; else throw new IndexOutOfRangeException(); done = false; } } /// /// Gets StringBuilder /// public StringBuilder StringBuilder { get { return sb; } } #endregion Properties #region Private Methods /* /// /// Reallocate internal array. /// /// Additional length. private void ReAlloc(int addLength) { if (count + addLength > capacity) { capacity = (capacity + addLength) > capacity * 2 ? capacity + addLength : capacity * 2; //Array.Resize(ref chars, capacity); char[] newChars = new char[capacity]; Array.Copy(chars, newChars, chars.Length); chars = newChars; } }*/ /// /// Initialize the new array for chars. /// /// Length of initial array. private void Init(int iniCapacity) { sb = new StringBuilder(iniCapacity); //chars = new char[iniCapacity]; //capacity = iniCapacity; } #endregion Private Methods #region Public Methods /// /// Checks the empty array. /// /// True if string is empty. public bool IsEmpty() { return sb.Length == 0; } /// /// Converts the array in string. /// /// String value. public override string ToString() { if (!done) { result = sb.ToString(); //result = new string(chars, 0, count); done = true; } return result; } /// /// Clears the string. /// /// FastString object. public FastString Clear() { //count = 0; sb.Clear(); done = false; return this; } /// /// Appends the string by string value. /// /// String value. /// FastString object. public FastString Append(string value) { if (!String.IsNullOrEmpty(value)) { /* ReAlloc(value.Length); value.CopyTo(0, chars, count, value.Length); count += value.Length;*/ sb.Append(value); done = false; } return this; } /// /// Appends the string by string value. /// /// String value. /// FastString object. public FastString AppendLine(string value) { /* ReAlloc(value.Length + 2); value.CopyTo(0, chars, count, value.Length); count += value.Length + 2; chars[count - 2] = '\r'; chars[count - 1] = '\n';*/ sb.AppendLine(value); done = false; return this; } /// /// Append formatted string. /// /// /// /// public FastString AppendFormat(String format, params Object[] args) { /* string value = String.Format(format, args); ReAlloc(value.Length); value.CopyTo(0, chars, count, value.Length); count += value.Length;*/ sb.AppendFormat(format, args); done = false; return this; } /// /// Appends new line. /// /// FastString object. public FastString AppendLine() { /* ReAlloc(2); count += 2; chars[count - 2] = '\r'; chars[count - 1] = '\n';*/ sb.AppendLine(); done = false; return this; } /// /// Appends the string by char value. /// /// Char value. /// FastString object. public FastString Append(char value) { //ReAlloc(1); //chars[count++] = value; sb.Append(value); done = false; return this; } /// /// Appends the another FastString object. /// /// FastString object. /// FastString object. public FastString Append(FastString fastString) { if (fastString != null) { sb.Append(fastString.StringBuilder); done = false; } return this; } /// /// Appends the string by object data. /// /// Object value. /// FastString object. public FastString Append(object value) { sb.Append(value); done = false; //Append(value.ToString()); return this; } /// /// Copies the substring in char array. /// /// Start index in source. /// Destination array. /// Destination index. /// Count of chars public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) { sb.CopyTo(sourceIndex, destination, destinationIndex, count); //Array.Copy(chars, sourceIndex, destination, destinationIndex, count); } /// /// Removes substring. /// /// Start index of removed string. /// Length of removed string. /// FastString object. public FastString Remove(int startIndex, int length) { sb.Remove(startIndex, length); /* if (startIndex >= 0 && (length + startIndex) <= count) { int len = count - length - startIndex; for (int i = 0; i < len; i++) chars[startIndex + i] = chars[startIndex + i + length]; count -= length; done = false; }*/ done = false; return this; } /// /// Inserts string. /// /// Start index in existing string. /// Value of inserting string. /// FastString object. public FastString Insert(int startIndex, string value) { sb.Insert(startIndex, value); /* if (value != null && value.Length > 0 && startIndex >= 0 && startIndex <= count) { int countToMove = count - startIndex; ReAlloc(value.Length); count += value.Length; for (int i = count - 1; i > count - countToMove - 1; i--) chars[i] = chars[i - value.Length]; value.CopyTo(0, chars, startIndex, value.Length); }*/ done = false; return this; } /// /// Replacing the substring on other. /// /// Old string value. /// New string value. /// FastString object. public FastString Replace(string oldValue, string newValue) { sb.Replace(oldValue, newValue); /* if (count == 0) return this; if (repList == null) repList = new List(); for (int i = 0; i < count; i++) { bool isRep = false; if (chars[i] == oldValue[0]) { int k = 1; while (k < oldValue.Length && chars[i + k] == oldValue[k]) k++; isRep = (k >= oldValue.Length); } if (isRep) { i += oldValue.Length - 1; if (newValue != null) for (int k = 0; k < newValue.Length; k++) repList.Add(newValue[k]); } else repList.Add(chars[i]); } ReAlloc(repList.Count - count); for (int k = 0; k < repList.Count; k++) chars[k] = repList[k]; count = repList.Count; repList.Clear(); */ done = false; return this; } /// /// Index of substring. /// /// Substring for search. /// Sarting position for search. /// Position of substring. public int IndexOf(string value, int startIndex) { if (!String.IsNullOrEmpty(value) && startIndex >= 0 && startIndex < sb.Length) { int valueIndex = 0; for (int i = startIndex; i < sb.Length; i++) { if (sb[i] == value[valueIndex]) { valueIndex++; if (valueIndex == value.Length) return i; } else valueIndex = 0; } } return -1; } /// /// Compare of substring in position. /// /// Starting index for comparsion. /// Value for compare. /// True if substring is identical in position. public bool SubstringCompare(int startIndex, string value) { if (!String.IsNullOrEmpty(value) && startIndex >= 0 && startIndex < sb.Length) { int valueIndex = 0; for (int i = 0; i < value.Length; i++) { if (sb[startIndex + i] == value[i]) { valueIndex++; if (valueIndex == value.Length) return true; } else valueIndex = 0; } } return false; } /// /// Returns the substring. /// /// Starting index. /// Length of substring. /// Substring. public string Substring(int startIndex, int length) { char[] result = new char[length]; sb.CopyTo(startIndex, result, 0, length); return new string(result); /* if (startIndex + length > count) return new string(chars, startIndex, count - startIndex); else return new string(chars, startIndex, length);*/ } #endregion Public Methods #region Constructors /// /// Creates the new FastString object with initial capacity. /// /// Initial capacity. public FastString(int initCapacity) { Init(initCapacity); } /// /// Creates the new FastString object with default capacity. /// public FastString() { Init(INIT_CAPACITY); } /// /// Creates the new FastString object from initial string. /// /// public FastString(string initValue) { if (!string.IsNullOrEmpty(initValue)) { Init(initValue.Length); Append(initValue); } else Init(0); } #endregion Constructors } public class FastStringWithPool : FastString { Dictionary pool; public FastStringWithPool(Dictionary pool): base() { this.pool = pool; } public override string ToString() { string baseResult = base.ToString(); string result; if (pool.TryGetValue(baseResult, out result)) return result; return pool[baseResult] = baseResult; } } }