FastString.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace FastReport.Utils
  5. {
  6. /// <summary>
  7. /// Fast alternative of StringBuilder.
  8. /// </summary>
  9. public class FastString
  10. {
  11. #region Constants
  12. private const int INIT_CAPACITY = 32;
  13. #endregion Constants
  14. #region Fields
  15. /* private char[] chars = null;
  16. private int count = 0;
  17. private int capacity = 0;
  18. private List<char> repList = null;
  19. */
  20. private string result = "";
  21. StringBuilder sb;
  22. private bool done = false;
  23. #endregion Fields
  24. #region Properties
  25. /// <summary>
  26. /// Gets the Length of string.
  27. /// </summary>
  28. public int Length
  29. {
  30. get { return sb.Length; }
  31. set
  32. {
  33. sb.Length = value;
  34. done = false;
  35. }
  36. }
  37. /// <summary>
  38. /// Gets or sets the chars of string.
  39. /// </summary>
  40. /// <param name="index"></param>
  41. /// <returns>Char value</returns>
  42. public char this[int index]
  43. {
  44. get
  45. {
  46. if (index >= 0 && index < sb.Length)
  47. return sb[index];
  48. else
  49. throw new IndexOutOfRangeException();
  50. }
  51. set
  52. {
  53. if (index >= 0 && index < sb.Length)
  54. sb[index] = value;
  55. else
  56. throw new IndexOutOfRangeException();
  57. done = false;
  58. }
  59. }
  60. /// <summary>
  61. /// Gets StringBuilder
  62. /// </summary>
  63. public StringBuilder StringBuilder
  64. {
  65. get { return sb; }
  66. }
  67. #endregion Properties
  68. #region Private Methods
  69. /* /// <summary>
  70. /// Reallocate internal array.
  71. /// </summary>
  72. /// <param name="addLength">Additional length.</param>
  73. private void ReAlloc(int addLength)
  74. {
  75. if (count + addLength > capacity)
  76. {
  77. capacity = (capacity + addLength) > capacity * 2 ? capacity + addLength : capacity * 2;
  78. //Array.Resize<char>(ref chars, capacity);
  79. char[] newChars = new char[capacity];
  80. Array.Copy(chars, newChars, chars.Length);
  81. chars = newChars;
  82. }
  83. }*/
  84. /// <summary>
  85. /// Initialize the new array for chars.
  86. /// </summary>
  87. /// <param name="iniCapacity">Length of initial array.</param>
  88. private void Init(int iniCapacity)
  89. {
  90. sb = new StringBuilder(iniCapacity);
  91. //chars = new char[iniCapacity];
  92. //capacity = iniCapacity;
  93. }
  94. #endregion Private Methods
  95. #region Public Methods
  96. /// <summary>
  97. /// Checks the empty array.
  98. /// </summary>
  99. /// <returns>True if string is empty.</returns>
  100. public bool IsEmpty()
  101. {
  102. return sb.Length == 0;
  103. }
  104. /// <summary>
  105. /// Converts the array in string.
  106. /// </summary>
  107. /// <returns>String value.</returns>
  108. public override string ToString()
  109. {
  110. if (!done)
  111. {
  112. result = sb.ToString();
  113. //result = new string(chars, 0, count);
  114. done = true;
  115. }
  116. return result;
  117. }
  118. /// <summary>
  119. /// Clears the string.
  120. /// </summary>
  121. /// <returns>FastString object.</returns>
  122. public FastString Clear()
  123. {
  124. //count = 0;
  125. sb.Clear();
  126. done = false;
  127. return this;
  128. }
  129. /// <summary>
  130. /// Appends the string by string value.
  131. /// </summary>
  132. /// <param name="value">String value.</param>
  133. /// <returns>FastString object.</returns>
  134. public FastString Append(string value)
  135. {
  136. if (!String.IsNullOrEmpty(value))
  137. {
  138. /* ReAlloc(value.Length);
  139. value.CopyTo(0, chars, count, value.Length);
  140. count += value.Length;*/
  141. sb.Append(value);
  142. done = false;
  143. }
  144. return this;
  145. }
  146. /// <summary>
  147. /// Appends the string by string value.
  148. /// </summary>
  149. /// <param name="value">String value.</param>
  150. /// <returns>FastString object.</returns>
  151. public FastString AppendLine(string value)
  152. {
  153. /* ReAlloc(value.Length + 2);
  154. value.CopyTo(0, chars, count, value.Length);
  155. count += value.Length + 2;
  156. chars[count - 2] = '\r';
  157. chars[count - 1] = '\n';*/
  158. sb.AppendLine(value);
  159. done = false;
  160. return this;
  161. }
  162. /// <summary>
  163. /// Append formatted string.
  164. /// </summary>
  165. /// <param name="format"></param>
  166. /// <param name="args"></param>
  167. /// <returns></returns>
  168. public FastString AppendFormat(String format, params Object[] args)
  169. {
  170. /* string value = String.Format(format, args);
  171. ReAlloc(value.Length);
  172. value.CopyTo(0, chars, count, value.Length);
  173. count += value.Length;*/
  174. sb.AppendFormat(format, args);
  175. done = false;
  176. return this;
  177. }
  178. /// <summary>
  179. /// Appends new line.
  180. /// </summary>
  181. /// <returns>FastString object.</returns>
  182. public FastString AppendLine()
  183. {
  184. /* ReAlloc(2);
  185. count += 2;
  186. chars[count - 2] = '\r';
  187. chars[count - 1] = '\n';*/
  188. sb.AppendLine();
  189. done = false;
  190. return this;
  191. }
  192. /// <summary>
  193. /// Appends the string by char value.
  194. /// </summary>
  195. /// <param name="value">Char value.</param>
  196. /// <returns>FastString object.</returns>
  197. public FastString Append(char value)
  198. {
  199. //ReAlloc(1);
  200. //chars[count++] = value;
  201. sb.Append(value);
  202. done = false;
  203. return this;
  204. }
  205. /// <summary>
  206. /// Appends the another FastString object.
  207. /// </summary>
  208. /// <param name="fastString">FastString object.</param>
  209. /// <returns>FastString object.</returns>
  210. public FastString Append(FastString fastString)
  211. {
  212. if (fastString != null)
  213. {
  214. sb.Append(fastString.StringBuilder);
  215. done = false;
  216. }
  217. return this;
  218. }
  219. /// <summary>
  220. /// Appends the string by object data.
  221. /// </summary>
  222. /// <param name="value">Object value.</param>
  223. /// <returns>FastString object.</returns>
  224. public FastString Append(object value)
  225. {
  226. sb.Append(value);
  227. done = false;
  228. //Append(value.ToString());
  229. return this;
  230. }
  231. /// <summary>
  232. /// Copies the substring in char array.
  233. /// </summary>
  234. /// <param name="sourceIndex">Start index in source.</param>
  235. /// <param name="destination">Destination array.</param>
  236. /// <param name="destinationIndex">Destination index.</param>
  237. /// <param name="count">Count of chars</param>
  238. public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
  239. {
  240. sb.CopyTo(sourceIndex, destination, destinationIndex, count);
  241. //Array.Copy(chars, sourceIndex, destination, destinationIndex, count);
  242. }
  243. /// <summary>
  244. /// Removes substring.
  245. /// </summary>
  246. /// <param name="startIndex">Start index of removed string.</param>
  247. /// <param name="length">Length of removed string.</param>
  248. /// <returns>FastString object.</returns>
  249. public FastString Remove(int startIndex, int length)
  250. {
  251. sb.Remove(startIndex, length);
  252. /*
  253. if (startIndex >= 0 && (length + startIndex) <= count)
  254. {
  255. int len = count - length - startIndex;
  256. for (int i = 0; i < len; i++)
  257. chars[startIndex + i] = chars[startIndex + i + length];
  258. count -= length;
  259. done = false;
  260. }*/
  261. done = false;
  262. return this;
  263. }
  264. /// <summary>
  265. /// Inserts string.
  266. /// </summary>
  267. /// <param name="startIndex">Start index in existing string.</param>
  268. /// <param name="value">Value of inserting string.</param>
  269. /// <returns>FastString object.</returns>
  270. public FastString Insert(int startIndex, string value)
  271. {
  272. sb.Insert(startIndex, value);
  273. /*
  274. if (value != null && value.Length > 0 && startIndex >= 0 && startIndex <= count)
  275. {
  276. int countToMove = count - startIndex;
  277. ReAlloc(value.Length);
  278. count += value.Length;
  279. for (int i = count - 1; i > count - countToMove - 1; i--)
  280. chars[i] = chars[i - value.Length];
  281. value.CopyTo(0, chars, startIndex, value.Length);
  282. }*/
  283. done = false;
  284. return this;
  285. }
  286. /// <summary>
  287. /// Replacing the substring on other.
  288. /// </summary>
  289. /// <param name="oldValue">Old string value.</param>
  290. /// <param name="newValue">New string value.</param>
  291. /// <returns>FastString object.</returns>
  292. public FastString Replace(string oldValue, string newValue)
  293. {
  294. sb.Replace(oldValue, newValue);
  295. /*
  296. if (count == 0)
  297. return this;
  298. if (repList == null)
  299. repList = new List<char>();
  300. for (int i = 0; i < count; i++)
  301. {
  302. bool isRep = false;
  303. if (chars[i] == oldValue[0])
  304. {
  305. int k = 1;
  306. while (k < oldValue.Length && chars[i + k] == oldValue[k])
  307. k++;
  308. isRep = (k >= oldValue.Length);
  309. }
  310. if (isRep)
  311. {
  312. i += oldValue.Length - 1;
  313. if (newValue != null)
  314. for (int k = 0; k < newValue.Length; k++)
  315. repList.Add(newValue[k]);
  316. }
  317. else
  318. repList.Add(chars[i]);
  319. }
  320. ReAlloc(repList.Count - count);
  321. for (int k = 0; k < repList.Count; k++)
  322. chars[k] = repList[k];
  323. count = repList.Count;
  324. repList.Clear();
  325. */
  326. done = false;
  327. return this;
  328. }
  329. /// <summary>
  330. /// Index of substring.
  331. /// </summary>
  332. /// <param name="value">Substring for search.</param>
  333. /// <param name="startIndex">Sarting position for search.</param>
  334. /// <returns>Position of substring.</returns>
  335. public int IndexOf(string value, int startIndex)
  336. {
  337. if (!String.IsNullOrEmpty(value) &&
  338. startIndex >= 0 &&
  339. startIndex < sb.Length)
  340. {
  341. int valueIndex = 0;
  342. for (int i = startIndex; i < sb.Length; i++)
  343. {
  344. if (sb[i] == value[valueIndex])
  345. {
  346. valueIndex++;
  347. if (valueIndex == value.Length)
  348. return i;
  349. }
  350. else
  351. valueIndex = 0;
  352. }
  353. }
  354. return -1;
  355. }
  356. /// <summary>
  357. /// Compare of substring in position.
  358. /// </summary>
  359. /// <param name="startIndex">Starting index for comparsion.</param>
  360. /// <param name="value">Value for compare.</param>
  361. /// <returns>True if substring is identical in position.</returns>
  362. public bool SubstringCompare(int startIndex, string value)
  363. {
  364. if (!String.IsNullOrEmpty(value) &&
  365. startIndex >= 0 &&
  366. startIndex < sb.Length)
  367. {
  368. int valueIndex = 0;
  369. for (int i = 0; i < value.Length; i++)
  370. {
  371. if (sb[startIndex + i] == value[i])
  372. {
  373. valueIndex++;
  374. if (valueIndex == value.Length)
  375. return true;
  376. }
  377. else
  378. valueIndex = 0;
  379. }
  380. }
  381. return false;
  382. }
  383. /// <summary>
  384. /// Returns the substring.
  385. /// </summary>
  386. /// <param name="startIndex">Starting index.</param>
  387. /// <param name="length">Length of substring.</param>
  388. /// <returns>Substring.</returns>
  389. public string Substring(int startIndex, int length)
  390. {
  391. char[] result = new char[length];
  392. sb.CopyTo(startIndex, result, 0, length);
  393. return new string(result);
  394. /* if (startIndex + length > count)
  395. return new string(chars, startIndex, count - startIndex);
  396. else
  397. return new string(chars, startIndex, length);*/
  398. }
  399. #endregion Public Methods
  400. #region Constructors
  401. /// <summary>
  402. /// Creates the new FastString object with initial capacity.
  403. /// </summary>
  404. /// <param name="initCapacity">Initial capacity.</param>
  405. public FastString(int initCapacity)
  406. {
  407. Init(initCapacity);
  408. }
  409. /// <summary>
  410. /// Creates the new FastString object with default capacity.
  411. /// </summary>
  412. public FastString()
  413. {
  414. Init(INIT_CAPACITY);
  415. }
  416. /// <summary>
  417. /// Creates the new FastString object from initial string.
  418. /// </summary>
  419. /// <param name="initValue"></param>
  420. public FastString(string initValue)
  421. {
  422. if (!string.IsNullOrEmpty(initValue))
  423. {
  424. Init(initValue.Length);
  425. Append(initValue);
  426. }
  427. else
  428. Init(0);
  429. }
  430. #endregion Constructors
  431. }
  432. public class FastStringWithPool : FastString
  433. {
  434. Dictionary<string, string> pool;
  435. public FastStringWithPool(Dictionary<string, string> pool) : base()
  436. {
  437. this.pool = pool;
  438. }
  439. public override string ToString()
  440. {
  441. string baseResult = base.ToString();
  442. string result;
  443. if (pool.TryGetValue(baseResult, out result))
  444. return result;
  445. return pool[baseResult] = baseResult;
  446. }
  447. }
  448. }