mscorlib(4.0.0.0) API with additions
StringBuilder.cs
1 using System.Diagnostics;
6 using System.Security;
7 
8 namespace System.Text
9 {
11  [Serializable]
12  [ComVisible(true)]
13  [__DynamicallyInvokable]
14  public sealed class StringBuilder : ISerializable
15  {
16  internal char[] m_ChunkChars;
17 
18  internal StringBuilder m_ChunkPrevious;
19 
20  internal int m_ChunkLength;
21 
22  internal int m_ChunkOffset;
23 
24  internal int m_MaxCapacity;
25 
26  internal const int DefaultCapacity = 16;
27 
28  private const string CapacityField = "Capacity";
29 
30  private const string MaxCapacityField = "m_MaxCapacity";
31 
32  private const string StringValueField = "m_StringValue";
33 
34  private const string ThreadIDField = "m_currentThread";
35 
36  internal const int MaxChunkSize = 8000;
37 
41  [__DynamicallyInvokable]
42  public int Capacity
43  {
44  [__DynamicallyInvokable]
45  get
46  {
47  return m_ChunkChars.Length + m_ChunkOffset;
48  }
49  [__DynamicallyInvokable]
50  set
51  {
52  if (value < 0)
53  {
54  throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
55  }
56  if (value > MaxCapacity)
57  {
58  throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
59  }
60  if (value < Length)
61  {
62  throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
63  }
64  if (Capacity != value)
65  {
66  int num = value - m_ChunkOffset;
67  char[] array = new char[num];
68  Array.Copy(m_ChunkChars, array, m_ChunkLength);
69  m_ChunkChars = array;
70  }
71  }
72  }
73 
76  [__DynamicallyInvokable]
77  public int MaxCapacity
78  {
79  [__DynamicallyInvokable]
80  get
81  {
82  return m_MaxCapacity;
83  }
84  }
85 
89  [__DynamicallyInvokable]
90  public int Length
91  {
92  [__DynamicallyInvokable]
93  get
94  {
95  return m_ChunkOffset + m_ChunkLength;
96  }
97  [__DynamicallyInvokable]
98  set
99  {
100  if (value < 0)
101  {
102  throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
103  }
104  if (value > MaxCapacity)
105  {
106  throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
107  }
108  int capacity = Capacity;
109  if (value == 0 && m_ChunkPrevious == null)
110  {
111  m_ChunkLength = 0;
112  m_ChunkOffset = 0;
113  return;
114  }
115  int num = value - Length;
116  if (num > 0)
117  {
118  Append('\0', num);
119  return;
120  }
121  StringBuilder stringBuilder = FindChunkForIndex(value);
122  if (stringBuilder != this)
123  {
124  int num2 = capacity - stringBuilder.m_ChunkOffset;
125  char[] array = new char[num2];
126  Array.Copy(stringBuilder.m_ChunkChars, array, stringBuilder.m_ChunkLength);
127  m_ChunkChars = array;
128  m_ChunkPrevious = stringBuilder.m_ChunkPrevious;
129  m_ChunkOffset = stringBuilder.m_ChunkOffset;
130  }
131  m_ChunkLength = value - stringBuilder.m_ChunkOffset;
132  }
133  }
134 
142  [IndexerName("Chars")]
143  [__DynamicallyInvokable]
144  public char this[int index]
145  {
146  [__DynamicallyInvokable]
147  get
148  {
149  StringBuilder stringBuilder = this;
150  do
151  {
152  int num = index - stringBuilder.m_ChunkOffset;
153  if (num >= 0)
154  {
155  if (num >= stringBuilder.m_ChunkLength)
156  {
157  throw new IndexOutOfRangeException();
158  }
159  return stringBuilder.m_ChunkChars[num];
160  }
161  stringBuilder = stringBuilder.m_ChunkPrevious;
162  }
163  while (stringBuilder != null);
164  throw new IndexOutOfRangeException();
165  }
166  [__DynamicallyInvokable]
167  set
168  {
169  StringBuilder stringBuilder = this;
170  do
171  {
172  int num = index - stringBuilder.m_ChunkOffset;
173  if (num >= 0)
174  {
175  if (num >= stringBuilder.m_ChunkLength)
176  {
177  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
178  }
179  stringBuilder.m_ChunkChars[num] = value;
180  return;
181  }
182  stringBuilder = stringBuilder.m_ChunkPrevious;
183  }
184  while (stringBuilder != null);
185  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
186  }
187  }
188 
190  [__DynamicallyInvokable]
191  public StringBuilder()
192  : this(16)
193  {
194  }
195 
200  [__DynamicallyInvokable]
201  public StringBuilder(int capacity)
202  : this(string.Empty, capacity)
203  {
204  }
205 
208  [__DynamicallyInvokable]
209  public StringBuilder(string value)
210  : this(value, 16)
211  {
212  }
213 
219  [__DynamicallyInvokable]
220  public StringBuilder(string value, int capacity)
221  : this(value, 0, value?.Length ?? 0, capacity)
222  {
223  }
224 
233  [SecuritySafeCritical]
234  [__DynamicallyInvokable]
235  public unsafe StringBuilder(string value, int startIndex, int length, int capacity)
236  {
237  if (capacity < 0)
238  {
239  throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "capacity"));
240  }
241  if (length < 0)
242  {
243  throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "length"));
244  }
245  if (startIndex < 0)
246  {
247  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
248  }
249  if (value == null)
250  {
251  value = string.Empty;
252  }
253  if (startIndex > value.Length - length)
254  {
255  throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
256  }
257  m_MaxCapacity = int.MaxValue;
258  if (capacity == 0)
259  {
260  capacity = 16;
261  }
262  if (capacity < length)
263  {
264  capacity = length;
265  }
266  m_ChunkChars = new char[capacity];
267  m_ChunkLength = length;
268  fixed (char* ptr = value)
269  {
270  ThreadSafeCopy(ptr + startIndex, m_ChunkChars, 0, length);
271  }
272  }
273 
279  [__DynamicallyInvokable]
280  public StringBuilder(int capacity, int maxCapacity)
281  {
282  if (capacity > maxCapacity)
283  {
284  throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
285  }
286  if (maxCapacity < 1)
287  {
288  throw new ArgumentOutOfRangeException("maxCapacity", Environment.GetResourceString("ArgumentOutOfRange_SmallMaxCapacity"));
289  }
290  if (capacity < 0)
291  {
292  throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "capacity"));
293  }
294  if (capacity == 0)
295  {
296  capacity = Math.Min(16, maxCapacity);
297  }
298  m_MaxCapacity = maxCapacity;
299  m_ChunkChars = new char[capacity];
300  }
301 
302  [SecurityCritical]
303  private StringBuilder(SerializationInfo info, StreamingContext context)
304  {
305  if (info == null)
306  {
307  throw new ArgumentNullException("info");
308  }
309  int num = 0;
310  string text = null;
311  int num2 = int.MaxValue;
312  bool flag = false;
313  SerializationInfoEnumerator enumerator = info.GetEnumerator();
314  while (enumerator.MoveNext())
315  {
316  switch (enumerator.Name)
317  {
318  case "m_MaxCapacity":
319  num2 = info.GetInt32("m_MaxCapacity");
320  break;
321  case "m_StringValue":
322  text = info.GetString("m_StringValue");
323  break;
324  case "Capacity":
325  num = info.GetInt32("Capacity");
326  flag = true;
327  break;
328  }
329  }
330  if (text == null)
331  {
332  text = string.Empty;
333  }
334  if (num2 < 1 || text.Length > num2)
335  {
336  throw new SerializationException(Environment.GetResourceString("Serialization_StringBuilderMaxCapacity"));
337  }
338  if (!flag)
339  {
340  num = 16;
341  if (num < text.Length)
342  {
343  num = text.Length;
344  }
345  if (num > num2)
346  {
347  num = num2;
348  }
349  }
350  if (num < 0 || num < text.Length || num > num2)
351  {
352  throw new SerializationException(Environment.GetResourceString("Serialization_StringBuilderCapacity"));
353  }
354  m_MaxCapacity = num2;
355  m_ChunkChars = new char[num];
356  text.CopyTo(0, m_ChunkChars, 0, text.Length);
357  m_ChunkLength = text.Length;
358  m_ChunkPrevious = null;
359  }
360 
366  [SecurityCritical]
368  {
369  if (info == null)
370  {
371  throw new ArgumentNullException("info");
372  }
373  info.AddValue("m_MaxCapacity", m_MaxCapacity);
374  info.AddValue("Capacity", Capacity);
375  info.AddValue("m_StringValue", ToString());
376  info.AddValue("m_currentThread", 0);
377  }
378 
379  [Conditional("_DEBUG")]
380  private void VerifyClassInvariant()
381  {
382  StringBuilder stringBuilder = this;
383  int maxCapacity = m_MaxCapacity;
384  while (true)
385  {
386  StringBuilder chunkPrevious = stringBuilder.m_ChunkPrevious;
387  if (chunkPrevious != null)
388  {
389  stringBuilder = chunkPrevious;
390  continue;
391  }
392  break;
393  }
394  }
395 
401  [__DynamicallyInvokable]
402  public int EnsureCapacity(int capacity)
403  {
404  if (capacity < 0)
405  {
406  throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
407  }
408  if (Capacity < capacity)
409  {
410  Capacity = capacity;
411  }
412  return Capacity;
413  }
414 
417  [SecuritySafeCritical]
418  [__DynamicallyInvokable]
419  public unsafe override string ToString()
420  {
421  if (Length == 0)
422  {
423  return string.Empty;
424  }
425  string text = string.FastAllocateString(Length);
426  StringBuilder stringBuilder = this;
427  fixed (char* ptr = text)
428  {
429  do
430  {
431  if (stringBuilder.m_ChunkLength > 0)
432  {
433  char[] chunkChars = stringBuilder.m_ChunkChars;
434  int chunkOffset = stringBuilder.m_ChunkOffset;
435  int chunkLength = stringBuilder.m_ChunkLength;
436  if ((uint)(chunkLength + chunkOffset) > text.Length || (uint)chunkLength > (uint)chunkChars.Length)
437  {
438  throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
439  }
440  char[] array = chunkChars;
441  fixed (char* smem = array)
442  {
443  string.wstrcpy(ptr + chunkOffset, smem, chunkLength);
444  }
445  }
446  stringBuilder = stringBuilder.m_ChunkPrevious;
447  }
448  while (stringBuilder != null);
449  }
450  return text;
451  }
452 
459  [SecuritySafeCritical]
460  [__DynamicallyInvokable]
461  public unsafe string ToString(int startIndex, int length)
462  {
463  int length2 = Length;
464  if (startIndex < 0)
465  {
466  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
467  }
468  if (startIndex > length2)
469  {
470  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
471  }
472  if (length < 0)
473  {
474  throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
475  }
476  if (startIndex > length2 - length)
477  {
478  throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
479  }
480  StringBuilder stringBuilder = this;
481  int num = startIndex + length;
482  string text = string.FastAllocateString(length);
483  int num2 = length;
484  fixed (char* ptr = text)
485  {
486  while (num2 > 0)
487  {
488  int num3 = num - stringBuilder.m_ChunkOffset;
489  if (num3 >= 0)
490  {
491  if (num3 > stringBuilder.m_ChunkLength)
492  {
493  num3 = stringBuilder.m_ChunkLength;
494  }
495  int num4 = num2;
496  int num5 = num4;
497  int num6 = num3 - num4;
498  if (num6 < 0)
499  {
500  num5 += num6;
501  num6 = 0;
502  }
503  num2 -= num5;
504  if (num5 > 0)
505  {
506  char[] chunkChars = stringBuilder.m_ChunkChars;
507  if ((uint)(num5 + num2) > length || (uint)(num5 + num6) > (uint)chunkChars.Length)
508  {
509  throw new ArgumentOutOfRangeException("chunkCount", Environment.GetResourceString("ArgumentOutOfRange_Index"));
510  }
511  fixed (char* smem = &chunkChars[num6])
512  {
513  string.wstrcpy(ptr + num2, smem, num5);
514  }
515  }
516  }
517  stringBuilder = stringBuilder.m_ChunkPrevious;
518  }
519  }
520  return text;
521  }
522 
525  [__DynamicallyInvokable]
527  {
528  Length = 0;
529  return this;
530  }
531 
539  [__DynamicallyInvokable]
540  public StringBuilder Append(char value, int repeatCount)
541  {
542  if (repeatCount < 0)
543  {
544  throw new ArgumentOutOfRangeException("repeatCount", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
545  }
546  if (repeatCount == 0)
547  {
548  return this;
549  }
550  int num = m_ChunkLength;
551  while (repeatCount > 0)
552  {
553  if (num < m_ChunkChars.Length)
554  {
555  m_ChunkChars[num++] = value;
556  repeatCount--;
557  }
558  else
559  {
560  m_ChunkLength = num;
561  ExpandByABlock(repeatCount);
562  num = 0;
563  }
564  }
565  m_ChunkLength = num;
566  return this;
567  }
568 
580  [SecuritySafeCritical]
581  [__DynamicallyInvokable]
582  public unsafe StringBuilder Append(char[] value, int startIndex, int charCount)
583  {
584  if (startIndex < 0)
585  {
586  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
587  }
588  if (charCount < 0)
589  {
590  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
591  }
592  if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && charCount == 0)
593  {
594  return this;
595  }
596  if (value == null)
597  {
598  if (startIndex == 0 && charCount == 0)
599  {
600  return this;
601  }
602  throw new ArgumentNullException("value");
603  }
604  if (charCount > value.Length - startIndex)
605  {
606  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
607  }
608  if (charCount == 0)
609  {
610  return this;
611  }
612  fixed (char* value2 = &value[startIndex])
613  {
614  Append(value2, charCount);
615  }
616  return this;
617  }
618 
623  [SecuritySafeCritical]
624  [__DynamicallyInvokable]
625  public unsafe StringBuilder Append(string value)
626  {
627  if (value != null)
628  {
629  char[] chunkChars = m_ChunkChars;
630  int chunkLength = m_ChunkLength;
631  int length = value.Length;
632  int num = chunkLength + length;
633  if (num < chunkChars.Length)
634  {
635  if (length <= 2)
636  {
637  if (length > 0)
638  {
639  chunkChars[chunkLength] = value[0];
640  }
641  if (length > 1)
642  {
643  chunkChars[chunkLength + 1] = value[1];
644  }
645  }
646  else
647  {
648  fixed (char* smem = value)
649  {
650  fixed (char* dmem = &chunkChars[chunkLength])
651  {
652  string.wstrcpy(dmem, smem, length);
653  }
654  }
655  }
656  m_ChunkLength = num;
657  }
658  else
659  {
660  AppendHelper(value);
661  }
662  }
663  return this;
664  }
665 
666  [SecuritySafeCritical]
667  private unsafe void AppendHelper(string value)
668  {
669  fixed (char* value2 = value)
670  {
671  Append(value2, value.Length);
672  }
673  }
674 
675  [MethodImpl(MethodImplOptions.InternalCall)]
676  [SecurityCritical]
677  internal unsafe extern void ReplaceBufferInternal(char* newBuffer, int newLength);
678 
679  [MethodImpl(MethodImplOptions.InternalCall)]
680  [SecurityCritical]
681  internal unsafe extern void ReplaceBufferAnsiInternal(sbyte* newBuffer, int newLength);
682 
694  [SecuritySafeCritical]
695  [__DynamicallyInvokable]
696  public unsafe StringBuilder Append(string value, int startIndex, int count)
697  {
698  if (startIndex < 0)
699  {
700  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
701  }
702  if (count < 0)
703  {
704  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
705  }
706  if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && count == 0)
707  {
708  return this;
709  }
710  if (value == null)
711  {
712  if (startIndex == 0 && count == 0)
713  {
714  return this;
715  }
716  throw new ArgumentNullException("value");
717  }
718  if (count == 0)
719  {
720  return this;
721  }
722  if (startIndex > value.Length - count)
723  {
724  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
725  }
726  fixed (char* ptr = value)
727  {
728  Append(ptr + startIndex, count);
729  }
730  return this;
731  }
732 
736  [ComVisible(false)]
737  [__DynamicallyInvokable]
739  {
740  return Append(Environment.NewLine);
741  }
742 
747  [ComVisible(false)]
748  [__DynamicallyInvokable]
749  public StringBuilder AppendLine(string value)
750  {
751  Append(value);
752  return Append(Environment.NewLine);
753  }
754 
768  [ComVisible(false)]
769  [SecuritySafeCritical]
770  [__DynamicallyInvokable]
771  public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
772  {
773  if (destination == null)
774  {
775  throw new ArgumentNullException("destination");
776  }
777  if (count < 0)
778  {
779  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("Arg_NegativeArgCount"));
780  }
781  if (destinationIndex < 0)
782  {
783  throw new ArgumentOutOfRangeException("destinationIndex", Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "destinationIndex"));
784  }
785  if (destinationIndex > destination.Length - count)
786  {
787  throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_OffsetOut"));
788  }
789  if ((uint)sourceIndex > (uint)Length)
790  {
791  throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
792  }
793  if (sourceIndex > Length - count)
794  {
795  throw new ArgumentException(Environment.GetResourceString("Arg_LongerThanSrcString"));
796  }
797  StringBuilder stringBuilder = this;
798  int num = sourceIndex + count;
799  int num2 = destinationIndex + count;
800  while (count > 0)
801  {
802  int num3 = num - stringBuilder.m_ChunkOffset;
803  if (num3 >= 0)
804  {
805  if (num3 > stringBuilder.m_ChunkLength)
806  {
807  num3 = stringBuilder.m_ChunkLength;
808  }
809  int num4 = count;
810  int num5 = num3 - count;
811  if (num5 < 0)
812  {
813  num4 += num5;
814  num5 = 0;
815  }
816  num2 -= num4;
817  count -= num4;
818  ThreadSafeCopy(stringBuilder.m_ChunkChars, num5, destination, num2, num4);
819  }
820  stringBuilder = stringBuilder.m_ChunkPrevious;
821  }
822  }
823 
833  [SecuritySafeCritical]
834  [__DynamicallyInvokable]
835  public unsafe StringBuilder Insert(int index, string value, int count)
836  {
837  if (count < 0)
838  {
839  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
840  }
841  int length = Length;
842  if ((uint)index > (uint)length)
843  {
844  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
845  }
846  if (value == null || value.Length == 0 || count == 0)
847  {
848  return this;
849  }
850  long num = (long)value.Length * (long)count;
851  if (num > MaxCapacity - Length)
852  {
853  throw new OutOfMemoryException();
854  }
855  MakeRoom(index, (int)num, out StringBuilder chunk, out int indexInChunk, doneMoveFollowingChars: false);
856  fixed (char* value2 = value)
857  {
858  while (count > 0)
859  {
860  ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, value2, value.Length);
861  count--;
862  }
863  }
864  return this;
865  }
866 
872  [__DynamicallyInvokable]
873  public StringBuilder Remove(int startIndex, int length)
874  {
875  if (length < 0)
876  {
877  throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
878  }
879  if (startIndex < 0)
880  {
881  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
882  }
883  if (length > Length - startIndex)
884  {
885  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
886  }
887  if (Length == length && startIndex == 0)
888  {
889  Length = 0;
890  return this;
891  }
892  if (length > 0)
893  {
894  Remove(startIndex, length, out StringBuilder _, out int _);
895  }
896  return this;
897  }
898 
903  [__DynamicallyInvokable]
904  public StringBuilder Append(bool value)
905  {
906  return Append(value.ToString());
907  }
908 
913  [CLSCompliant(false)]
914  [__DynamicallyInvokable]
915  public StringBuilder Append(sbyte value)
916  {
917  return Append(value.ToString(CultureInfo.CurrentCulture));
918  }
919 
924  [__DynamicallyInvokable]
925  public StringBuilder Append(byte value)
926  {
927  return Append(value.ToString(CultureInfo.CurrentCulture));
928  }
929 
934  [__DynamicallyInvokable]
935  public StringBuilder Append(char value)
936  {
937  if (m_ChunkLength < m_ChunkChars.Length)
938  {
939  m_ChunkChars[m_ChunkLength++] = value;
940  }
941  else
942  {
943  Append(value, 1);
944  }
945  return this;
946  }
947 
952  [__DynamicallyInvokable]
953  public StringBuilder Append(short value)
954  {
955  return Append(value.ToString(CultureInfo.CurrentCulture));
956  }
957 
962  [__DynamicallyInvokable]
963  public StringBuilder Append(int value)
964  {
965  return Append(value.ToString(CultureInfo.CurrentCulture));
966  }
967 
972  [__DynamicallyInvokable]
973  public StringBuilder Append(long value)
974  {
975  return Append(value.ToString(CultureInfo.CurrentCulture));
976  }
977 
982  [__DynamicallyInvokable]
983  public StringBuilder Append(float value)
984  {
985  return Append(value.ToString(CultureInfo.CurrentCulture));
986  }
987 
992  [__DynamicallyInvokable]
993  public StringBuilder Append(double value)
994  {
995  return Append(value.ToString(CultureInfo.CurrentCulture));
996  }
997 
1002  [__DynamicallyInvokable]
1003  public StringBuilder Append(decimal value)
1004  {
1005  return Append(value.ToString(CultureInfo.CurrentCulture));
1006  }
1007 
1012  [CLSCompliant(false)]
1013  [__DynamicallyInvokable]
1014  public StringBuilder Append(ushort value)
1015  {
1016  return Append(value.ToString(CultureInfo.CurrentCulture));
1017  }
1018 
1023  [CLSCompliant(false)]
1024  [__DynamicallyInvokable]
1025  public StringBuilder Append(uint value)
1026  {
1027  return Append(value.ToString(CultureInfo.CurrentCulture));
1028  }
1029 
1034  [CLSCompliant(false)]
1035  [__DynamicallyInvokable]
1036  public StringBuilder Append(ulong value)
1037  {
1038  return Append(value.ToString(CultureInfo.CurrentCulture));
1039  }
1040 
1045  [__DynamicallyInvokable]
1046  public StringBuilder Append(object value)
1047  {
1048  if (value == null)
1049  {
1050  return this;
1051  }
1052  return Append(value.ToString());
1053  }
1054 
1059  [SecuritySafeCritical]
1060  [__DynamicallyInvokable]
1061  public unsafe StringBuilder Append(char[] value)
1062  {
1063  if (value != null && value.Length != 0)
1064  {
1065  fixed (char* value2 = &value[0])
1066  {
1067  Append(value2, value.Length);
1068  }
1069  }
1070  return this;
1071  }
1072 
1079  [SecuritySafeCritical]
1080  [__DynamicallyInvokable]
1081  public unsafe StringBuilder Insert(int index, string value)
1082  {
1083  if ((uint)index > (uint)Length)
1084  {
1085  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1086  }
1087  if (value != null)
1088  {
1089  fixed (char* value2 = value)
1090  {
1091  Insert(index, value2, value.Length);
1092  }
1093  }
1094  return this;
1095  }
1096 
1104  [__DynamicallyInvokable]
1105  public StringBuilder Insert(int index, bool value)
1106  {
1107  return Insert(index, value.ToString(), 1);
1108  }
1109 
1117  [CLSCompliant(false)]
1118  [__DynamicallyInvokable]
1119  public StringBuilder Insert(int index, sbyte value)
1120  {
1121  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1122  }
1123 
1131  [__DynamicallyInvokable]
1132  public StringBuilder Insert(int index, byte value)
1133  {
1134  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1135  }
1136 
1144  [__DynamicallyInvokable]
1145  public StringBuilder Insert(int index, short value)
1146  {
1147  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1148  }
1149 
1156  [SecuritySafeCritical]
1157  [__DynamicallyInvokable]
1158  public unsafe StringBuilder Insert(int index, char value)
1159  {
1160  Insert(index, &value, 1);
1161  return this;
1162  }
1163 
1170  [__DynamicallyInvokable]
1171  public StringBuilder Insert(int index, char[] value)
1172  {
1173  if ((uint)index > (uint)Length)
1174  {
1175  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1176  }
1177  if (value != null)
1178  {
1179  Insert(index, value, 0, value.Length);
1180  }
1181  return this;
1182  }
1183 
1196  [SecuritySafeCritical]
1197  [__DynamicallyInvokable]
1198  public unsafe StringBuilder Insert(int index, char[] value, int startIndex, int charCount)
1199  {
1200  int length = Length;
1201  if ((uint)index > (uint)length)
1202  {
1203  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1204  }
1205  if (value == null)
1206  {
1207  if (startIndex == 0 && charCount == 0)
1208  {
1209  return this;
1210  }
1211  throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_String"));
1212  }
1213  if (startIndex < 0)
1214  {
1215  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
1216  }
1217  if (charCount < 0)
1218  {
1219  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
1220  }
1221  if (startIndex > value.Length - charCount)
1222  {
1223  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1224  }
1225  if (charCount > 0)
1226  {
1227  fixed (char* value2 = &value[startIndex])
1228  {
1229  Insert(index, value2, charCount);
1230  }
1231  }
1232  return this;
1233  }
1234 
1242  [__DynamicallyInvokable]
1243  public StringBuilder Insert(int index, int value)
1244  {
1245  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1246  }
1247 
1255  [__DynamicallyInvokable]
1256  public StringBuilder Insert(int index, long value)
1257  {
1258  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1259  }
1260 
1268  [__DynamicallyInvokable]
1269  public StringBuilder Insert(int index, float value)
1270  {
1271  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1272  }
1273 
1281  [__DynamicallyInvokable]
1282  public StringBuilder Insert(int index, double value)
1283  {
1284  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1285  }
1286 
1294  [__DynamicallyInvokable]
1295  public StringBuilder Insert(int index, decimal value)
1296  {
1297  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1298  }
1299 
1307  [CLSCompliant(false)]
1308  [__DynamicallyInvokable]
1309  public StringBuilder Insert(int index, ushort value)
1310  {
1311  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1312  }
1313 
1321  [CLSCompliant(false)]
1322  [__DynamicallyInvokable]
1323  public StringBuilder Insert(int index, uint value)
1324  {
1325  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1326  }
1327 
1335  [CLSCompliant(false)]
1336  [__DynamicallyInvokable]
1337  public StringBuilder Insert(int index, ulong value)
1338  {
1339  return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
1340  }
1341 
1349  [__DynamicallyInvokable]
1350  public StringBuilder Insert(int index, object value)
1351  {
1352  if (value == null)
1353  {
1354  return this;
1355  }
1356  return Insert(index, value.ToString(), 1);
1357  }
1358 
1368  [__DynamicallyInvokable]
1369  public StringBuilder AppendFormat(string format, object arg0)
1370  {
1371  return AppendFormatHelper(null, format, new ParamsArray(arg0));
1372  }
1373 
1384  [__DynamicallyInvokable]
1385  public StringBuilder AppendFormat(string format, object arg0, object arg1)
1386  {
1387  return AppendFormatHelper(null, format, new ParamsArray(arg0, arg1));
1388  }
1389 
1401  [__DynamicallyInvokable]
1402  public StringBuilder AppendFormat(string format, object arg0, object arg1, object arg2)
1403  {
1404  return AppendFormatHelper(null, format, new ParamsArray(arg0, arg1, arg2));
1405  }
1406 
1416  [__DynamicallyInvokable]
1417  public StringBuilder AppendFormat(string format, params object[] args)
1418  {
1419  if (args == null)
1420  {
1421  throw new ArgumentNullException((format == null) ? "format" : "args");
1422  }
1423  return AppendFormatHelper(null, format, new ParamsArray(args));
1424  }
1425 
1436  [__DynamicallyInvokable]
1437  public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0)
1438  {
1439  return AppendFormatHelper(provider, format, new ParamsArray(arg0));
1440  }
1441 
1453  [__DynamicallyInvokable]
1454  public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1)
1455  {
1456  return AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1));
1457  }
1458 
1471  [__DynamicallyInvokable]
1472  public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1, object arg2)
1473  {
1474  return AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1, arg2));
1475  }
1476 
1487  [__DynamicallyInvokable]
1488  public StringBuilder AppendFormat(IFormatProvider provider, string format, params object[] args)
1489  {
1490  if (args == null)
1491  {
1492  throw new ArgumentNullException((format == null) ? "format" : "args");
1493  }
1494  return AppendFormatHelper(provider, format, new ParamsArray(args));
1495  }
1496 
1497  private static void FormatError()
1498  {
1499  throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
1500  }
1501 
1502  internal StringBuilder AppendFormatHelper(IFormatProvider provider, string format, ParamsArray args)
1503  {
1504  if (format == null)
1505  {
1506  throw new ArgumentNullException("format");
1507  }
1508  int num = 0;
1509  int length = format.Length;
1510  char c = '\0';
1511  ICustomFormatter customFormatter = null;
1512  if (provider != null)
1513  {
1514  customFormatter = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter));
1515  }
1516  while (true)
1517  {
1518  int num2 = num;
1519  int num3 = num;
1520  while (num < length)
1521  {
1522  c = format[num];
1523  num++;
1524  if (c == '}')
1525  {
1526  if (num < length && format[num] == '}')
1527  {
1528  num++;
1529  }
1530  else
1531  {
1532  FormatError();
1533  }
1534  }
1535  if (c == '{')
1536  {
1537  if (num >= length || format[num] != '{')
1538  {
1539  num--;
1540  break;
1541  }
1542  num++;
1543  }
1544  Append(c);
1545  }
1546  if (num == length)
1547  {
1548  break;
1549  }
1550  num++;
1551  if (num == length || (c = format[num]) < '0' || c > '9')
1552  {
1553  FormatError();
1554  }
1555  int num4 = 0;
1556  do
1557  {
1558  num4 = num4 * 10 + c - 48;
1559  num++;
1560  if (num == length)
1561  {
1562  FormatError();
1563  }
1564  c = format[num];
1565  }
1566  while (c >= '0' && c <= '9' && num4 < 1000000);
1567  if (num4 >= args.Length)
1568  {
1569  throw new FormatException(Environment.GetResourceString("Format_IndexOutOfRange"));
1570  }
1571  for (; num < length; num++)
1572  {
1573  if ((c = format[num]) != ' ')
1574  {
1575  break;
1576  }
1577  }
1578  bool flag = false;
1579  int num5 = 0;
1580  if (c == ',')
1581  {
1582  for (num++; num < length && format[num] == ' '; num++)
1583  {
1584  }
1585  if (num == length)
1586  {
1587  FormatError();
1588  }
1589  c = format[num];
1590  if (c == '-')
1591  {
1592  flag = true;
1593  num++;
1594  if (num == length)
1595  {
1596  FormatError();
1597  }
1598  c = format[num];
1599  }
1600  if (c < '0' || c > '9')
1601  {
1602  FormatError();
1603  }
1604  do
1605  {
1606  num5 = num5 * 10 + c - 48;
1607  num++;
1608  if (num == length)
1609  {
1610  FormatError();
1611  }
1612  c = format[num];
1613  }
1614  while (c >= '0' && c <= '9' && num5 < 1000000);
1615  }
1616  for (; num < length; num++)
1617  {
1618  if ((c = format[num]) != ' ')
1619  {
1620  break;
1621  }
1622  }
1623  object obj = args[num4];
1624  StringBuilder stringBuilder = null;
1625  if (c == ':')
1626  {
1627  num++;
1628  num2 = num;
1629  num3 = num;
1630  while (true)
1631  {
1632  if (num == length)
1633  {
1634  FormatError();
1635  }
1636  c = format[num];
1637  num++;
1638  if (c == '{')
1639  {
1640  if (num < length && format[num] == '{')
1641  {
1642  num++;
1643  }
1644  else
1645  {
1646  FormatError();
1647  }
1648  }
1649  else if (c == '}')
1650  {
1651  if (num >= length || format[num] != '}')
1652  {
1653  break;
1654  }
1655  num++;
1656  }
1657  if (stringBuilder == null)
1658  {
1659  stringBuilder = new StringBuilder();
1660  }
1661  stringBuilder.Append(c);
1662  }
1663  num--;
1664  }
1665  if (c != '}')
1666  {
1667  FormatError();
1668  }
1669  num++;
1670  string text = null;
1671  string text2 = null;
1672  if (customFormatter != null)
1673  {
1674  if (stringBuilder != null)
1675  {
1676  text = stringBuilder.ToString();
1677  }
1678  text2 = customFormatter.Format(text, obj, provider);
1679  }
1680  if (text2 == null)
1681  {
1682  IFormattable formattable = obj as IFormattable;
1683  if (formattable != null)
1684  {
1685  if (text == null && stringBuilder != null)
1686  {
1687  text = stringBuilder.ToString();
1688  }
1689  text2 = formattable.ToString(text, provider);
1690  }
1691  else if (obj != null)
1692  {
1693  text2 = obj.ToString();
1694  }
1695  }
1696  if (text2 == null)
1697  {
1698  text2 = string.Empty;
1699  }
1700  int num6 = num5 - text2.Length;
1701  if (!flag && num6 > 0)
1702  {
1703  Append(' ', num6);
1704  }
1705  Append(text2);
1706  if (flag && num6 > 0)
1707  {
1708  Append(' ', num6);
1709  }
1710  }
1711  return this;
1712  }
1713 
1722  [__DynamicallyInvokable]
1723  public StringBuilder Replace(string oldValue, string newValue)
1724  {
1725  return Replace(oldValue, newValue, 0, Length);
1726  }
1727 
1732  [__DynamicallyInvokable]
1733  public bool Equals(StringBuilder sb)
1734  {
1735  if (sb == null)
1736  {
1737  return false;
1738  }
1739  if (Capacity != sb.Capacity || MaxCapacity != sb.MaxCapacity || Length != sb.Length)
1740  {
1741  return false;
1742  }
1743  if (sb == this)
1744  {
1745  return true;
1746  }
1747  StringBuilder stringBuilder = this;
1748  int num = stringBuilder.m_ChunkLength;
1749  StringBuilder stringBuilder2 = sb;
1750  int num2 = stringBuilder2.m_ChunkLength;
1751  do
1752  {
1753  num--;
1754  num2--;
1755  while (num < 0)
1756  {
1757  stringBuilder = stringBuilder.m_ChunkPrevious;
1758  if (stringBuilder == null)
1759  {
1760  break;
1761  }
1762  num = stringBuilder.m_ChunkLength + num;
1763  }
1764  while (num2 < 0)
1765  {
1766  stringBuilder2 = stringBuilder2.m_ChunkPrevious;
1767  if (stringBuilder2 == null)
1768  {
1769  break;
1770  }
1771  num2 = stringBuilder2.m_ChunkLength + num2;
1772  }
1773  if (num < 0)
1774  {
1775  return num2 < 0;
1776  }
1777  if (num2 < 0)
1778  {
1779  return false;
1780  }
1781  }
1782  while (stringBuilder.m_ChunkChars[num] == stringBuilder2.m_ChunkChars[num2]);
1783  return false;
1784  }
1785 
1798  [__DynamicallyInvokable]
1799  public StringBuilder Replace(string oldValue, string newValue, int startIndex, int count)
1800  {
1801  int length = Length;
1802  if ((uint)startIndex > (uint)length)
1803  {
1804  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1805  }
1806  if (count < 0 || startIndex > length - count)
1807  {
1808  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1809  }
1810  if (oldValue == null)
1811  {
1812  throw new ArgumentNullException("oldValue");
1813  }
1814  if (oldValue.Length == 0)
1815  {
1816  throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "oldValue");
1817  }
1818  if (newValue == null)
1819  {
1820  newValue = "";
1821  }
1822  int num = newValue.Length - oldValue.Length;
1823  int[] array = null;
1824  int num2 = 0;
1825  StringBuilder stringBuilder = FindChunkForIndex(startIndex);
1826  int num3 = startIndex - stringBuilder.m_ChunkOffset;
1827  while (count > 0)
1828  {
1829  if (StartsWith(stringBuilder, num3, count, oldValue))
1830  {
1831  if (array == null)
1832  {
1833  array = new int[5];
1834  }
1835  else if (num2 >= array.Length)
1836  {
1837  int[] array2 = new int[array.Length * 3 / 2 + 4];
1838  Array.Copy(array, array2, array.Length);
1839  array = array2;
1840  }
1841  array[num2++] = num3;
1842  num3 += oldValue.Length;
1843  count -= oldValue.Length;
1844  }
1845  else
1846  {
1847  num3++;
1848  count--;
1849  }
1850  if (num3 >= stringBuilder.m_ChunkLength || count == 0)
1851  {
1852  int num5 = num3 + stringBuilder.m_ChunkOffset;
1853  int num6 = num5;
1854  ReplaceAllInChunk(array, num2, stringBuilder, oldValue.Length, newValue);
1855  num5 += (newValue.Length - oldValue.Length) * num2;
1856  num2 = 0;
1857  stringBuilder = FindChunkForIndex(num5);
1858  num3 = num5 - stringBuilder.m_ChunkOffset;
1859  }
1860  }
1861  return this;
1862  }
1863 
1868  [__DynamicallyInvokable]
1869  public StringBuilder Replace(char oldChar, char newChar)
1870  {
1871  return Replace(oldChar, newChar, 0, Length);
1872  }
1873 
1883  [__DynamicallyInvokable]
1884  public StringBuilder Replace(char oldChar, char newChar, int startIndex, int count)
1885  {
1886  int length = Length;
1887  if ((uint)startIndex > (uint)length)
1888  {
1889  throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1890  }
1891  if (count < 0 || startIndex > length - count)
1892  {
1893  throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1894  }
1895  int num = startIndex + count;
1896  StringBuilder stringBuilder = this;
1897  while (true)
1898  {
1899  int num2 = num - stringBuilder.m_ChunkOffset;
1900  int num3 = startIndex - stringBuilder.m_ChunkOffset;
1901  if (num2 >= 0)
1902  {
1903  int i = Math.Max(num3, 0);
1904  for (int num4 = Math.Min(stringBuilder.m_ChunkLength, num2); i < num4; i++)
1905  {
1906  if (stringBuilder.m_ChunkChars[i] == oldChar)
1907  {
1908  stringBuilder.m_ChunkChars[i] = newChar;
1909  }
1910  }
1911  }
1912  if (num3 >= 0)
1913  {
1914  break;
1915  }
1916  stringBuilder = stringBuilder.m_ChunkPrevious;
1917  }
1918  return this;
1919  }
1920 
1930  [SecurityCritical]
1931  [CLSCompliant(false)]
1932  public unsafe StringBuilder Append(char* value, int valueCount)
1933  {
1934  if (valueCount < 0)
1935  {
1936  throw new ArgumentOutOfRangeException("valueCount", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
1937  }
1938  int num = valueCount + m_ChunkLength;
1939  if (num <= m_ChunkChars.Length)
1940  {
1941  ThreadSafeCopy(value, m_ChunkChars, m_ChunkLength, valueCount);
1942  m_ChunkLength = num;
1943  }
1944  else
1945  {
1946  int num2 = m_ChunkChars.Length - m_ChunkLength;
1947  if (num2 > 0)
1948  {
1949  ThreadSafeCopy(value, m_ChunkChars, m_ChunkLength, num2);
1950  m_ChunkLength = m_ChunkChars.Length;
1951  }
1952  int num3 = valueCount - num2;
1953  ExpandByABlock(num3);
1954  ThreadSafeCopy(value + num2, m_ChunkChars, 0, num3);
1955  m_ChunkLength = num3;
1956  }
1957  return this;
1958  }
1959 
1960  [SecurityCritical]
1961  private unsafe void Insert(int index, char* value, int valueCount)
1962  {
1963  if ((uint)index > (uint)Length)
1964  {
1965  throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1966  }
1967  if (valueCount > 0)
1968  {
1969  MakeRoom(index, valueCount, out StringBuilder chunk, out int indexInChunk, doneMoveFollowingChars: false);
1970  ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, value, valueCount);
1971  }
1972  }
1973 
1974  [SecuritySafeCritical]
1975  private unsafe void ReplaceAllInChunk(int[] replacements, int replacementsCount, StringBuilder sourceChunk, int removeCount, string value)
1976  {
1977  if (replacementsCount > 0)
1978  {
1979  fixed (char* value2 = value)
1980  {
1981  int num = (value.Length - removeCount) * replacementsCount;
1982  StringBuilder chunk = sourceChunk;
1983  int indexInChunk = replacements[0];
1984  if (num > 0)
1985  {
1986  MakeRoom(chunk.m_ChunkOffset + indexInChunk, num, out chunk, out indexInChunk, doneMoveFollowingChars: true);
1987  }
1988  int num2 = 0;
1989  while (true)
1990  {
1991  ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, value2, value.Length);
1992  int num3 = replacements[num2] + removeCount;
1993  num2++;
1994  if (num2 >= replacementsCount)
1995  {
1996  break;
1997  }
1998  int num4 = replacements[num2];
1999  if (num != 0)
2000  {
2001  fixed (char* value3 = &sourceChunk.m_ChunkChars[num3])
2002  {
2003  ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, value3, num4 - num3);
2004  }
2005  }
2006  else
2007  {
2008  indexInChunk += num4 - num3;
2009  }
2010  }
2011  if (num < 0)
2012  {
2013  Remove(chunk.m_ChunkOffset + indexInChunk, -num, out chunk, out indexInChunk);
2014  }
2015  }
2016  }
2017  }
2018 
2019  private bool StartsWith(StringBuilder chunk, int indexInChunk, int count, string value)
2020  {
2021  for (int i = 0; i < value.Length; i++)
2022  {
2023  if (count == 0)
2024  {
2025  return false;
2026  }
2027  if (indexInChunk >= chunk.m_ChunkLength)
2028  {
2029  chunk = Next(chunk);
2030  if (chunk == null)
2031  {
2032  return false;
2033  }
2034  indexInChunk = 0;
2035  }
2036  if (value[i] != chunk.m_ChunkChars[indexInChunk])
2037  {
2038  return false;
2039  }
2040  indexInChunk++;
2041  count--;
2042  }
2043  return true;
2044  }
2045 
2046  [SecurityCritical]
2047  private unsafe void ReplaceInPlaceAtChunk(ref StringBuilder chunk, ref int indexInChunk, char* value, int count)
2048  {
2049  if (count == 0)
2050  {
2051  return;
2052  }
2053  while (true)
2054  {
2055  int val = chunk.m_ChunkLength - indexInChunk;
2056  int num = Math.Min(val, count);
2057  ThreadSafeCopy(value, chunk.m_ChunkChars, indexInChunk, num);
2058  indexInChunk += num;
2059  if (indexInChunk >= chunk.m_ChunkLength)
2060  {
2061  chunk = Next(chunk);
2062  indexInChunk = 0;
2063  }
2064  count -= num;
2065  if (count != 0)
2066  {
2067  value += num;
2068  continue;
2069  }
2070  break;
2071  }
2072  }
2073 
2074  [SecurityCritical]
2075  private unsafe static void ThreadSafeCopy(char* sourcePtr, char[] destination, int destinationIndex, int count)
2076  {
2077  if (count > 0)
2078  {
2079  if ((uint)destinationIndex > (uint)destination.Length || destinationIndex + count > destination.Length)
2080  {
2081  throw new ArgumentOutOfRangeException("destinationIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2082  }
2083  fixed (char* dmem = &destination[destinationIndex])
2084  {
2085  string.wstrcpy(dmem, sourcePtr, count);
2086  }
2087  }
2088  }
2089 
2090  [SecurityCritical]
2091  private unsafe static void ThreadSafeCopy(char[] source, int sourceIndex, char[] destination, int destinationIndex, int count)
2092  {
2093  if (count > 0)
2094  {
2095  if ((uint)sourceIndex > (uint)source.Length || sourceIndex + count > source.Length)
2096  {
2097  throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2098  }
2099  fixed (char* sourcePtr = &source[sourceIndex])
2100  {
2101  ThreadSafeCopy(sourcePtr, destination, destinationIndex, count);
2102  }
2103  }
2104  }
2105 
2106  [SecurityCritical]
2107  internal unsafe void InternalCopy(IntPtr dest, int len)
2108  {
2109  if (len != 0)
2110  {
2111  bool flag = true;
2112  byte* ptr = (byte*)dest.ToPointer();
2113  StringBuilder stringBuilder = FindChunkForByte(len);
2114  do
2115  {
2116  int num = stringBuilder.m_ChunkOffset * 2;
2117  int len2 = stringBuilder.m_ChunkLength * 2;
2118  fixed (char* ptr2 = &stringBuilder.m_ChunkChars[0])
2119  {
2120  byte* src = (byte*)ptr2;
2121  if (flag)
2122  {
2123  flag = false;
2124  Buffer.Memcpy(ptr + num, src, len - num);
2125  }
2126  else
2127  {
2128  Buffer.Memcpy(ptr + num, src, len2);
2129  }
2130  }
2131  stringBuilder = stringBuilder.m_ChunkPrevious;
2132  }
2133  while (stringBuilder != null);
2134  }
2135  }
2136 
2137  private StringBuilder FindChunkForIndex(int index)
2138  {
2139  StringBuilder stringBuilder = this;
2140  while (stringBuilder.m_ChunkOffset > index)
2141  {
2142  stringBuilder = stringBuilder.m_ChunkPrevious;
2143  }
2144  return stringBuilder;
2145  }
2146 
2147  private StringBuilder FindChunkForByte(int byteIndex)
2148  {
2149  StringBuilder stringBuilder = this;
2150  while (stringBuilder.m_ChunkOffset * 2 > byteIndex)
2151  {
2152  stringBuilder = stringBuilder.m_ChunkPrevious;
2153  }
2154  return stringBuilder;
2155  }
2156 
2157  private StringBuilder Next(StringBuilder chunk)
2158  {
2159  if (chunk == this)
2160  {
2161  return null;
2162  }
2163  return FindChunkForIndex(chunk.m_ChunkOffset + chunk.m_ChunkLength);
2164  }
2165 
2166  private void ExpandByABlock(int minBlockCharCount)
2167  {
2168  if (minBlockCharCount + Length < minBlockCharCount || minBlockCharCount + Length > m_MaxCapacity)
2169  {
2170  throw new ArgumentOutOfRangeException("requiredLength", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
2171  }
2172  int num = Math.Max(minBlockCharCount, Math.Min(Length, 8000));
2173  m_ChunkPrevious = new StringBuilder(this);
2174  m_ChunkOffset += m_ChunkLength;
2175  m_ChunkLength = 0;
2176  if (m_ChunkOffset + num < num)
2177  {
2178  m_ChunkChars = null;
2179  throw new OutOfMemoryException();
2180  }
2181  m_ChunkChars = new char[num];
2182  }
2183 
2184  private StringBuilder(StringBuilder from)
2185  {
2186  m_ChunkLength = from.m_ChunkLength;
2187  m_ChunkOffset = from.m_ChunkOffset;
2188  m_ChunkChars = from.m_ChunkChars;
2189  m_ChunkPrevious = from.m_ChunkPrevious;
2190  m_MaxCapacity = from.m_MaxCapacity;
2191  }
2192 
2193  [SecuritySafeCritical]
2194  private unsafe void MakeRoom(int index, int count, out StringBuilder chunk, out int indexInChunk, bool doneMoveFollowingChars)
2195  {
2196  if (count + Length < count || count + Length > m_MaxCapacity)
2197  {
2198  throw new ArgumentOutOfRangeException("requiredLength", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
2199  }
2200  chunk = this;
2201  while (chunk.m_ChunkOffset > index)
2202  {
2203  chunk.m_ChunkOffset += count;
2204  chunk = chunk.m_ChunkPrevious;
2205  }
2206  indexInChunk = index - chunk.m_ChunkOffset;
2207  if (!doneMoveFollowingChars && chunk.m_ChunkLength <= 32 && chunk.m_ChunkChars.Length - chunk.m_ChunkLength >= count)
2208  {
2209  int num = chunk.m_ChunkLength;
2210  while (num > indexInChunk)
2211  {
2212  num--;
2213  chunk.m_ChunkChars[num + count] = chunk.m_ChunkChars[num];
2214  }
2215  chunk.m_ChunkLength += count;
2216  return;
2217  }
2218  StringBuilder stringBuilder = new StringBuilder(Math.Max(count, 16), chunk.m_MaxCapacity, chunk.m_ChunkPrevious);
2219  stringBuilder.m_ChunkLength = count;
2220  int num2 = Math.Min(count, indexInChunk);
2221  if (num2 > 0)
2222  {
2223  char[] chunkChars = chunk.m_ChunkChars;
2224  fixed (char* ptr = chunkChars)
2225  {
2226  ThreadSafeCopy(ptr, stringBuilder.m_ChunkChars, 0, num2);
2227  int num3 = indexInChunk - num2;
2228  if (num3 >= 0)
2229  {
2230  ThreadSafeCopy(ptr + num2, chunk.m_ChunkChars, 0, num3);
2231  indexInChunk = num3;
2232  }
2233  }
2234  }
2235  chunk.m_ChunkPrevious = stringBuilder;
2236  chunk.m_ChunkOffset += count;
2237  if (num2 < count)
2238  {
2239  chunk = stringBuilder;
2240  indexInChunk = num2;
2241  }
2242  }
2243 
2244  private StringBuilder(int size, int maxCapacity, StringBuilder previousBlock)
2245  {
2246  m_ChunkChars = new char[size];
2247  m_MaxCapacity = maxCapacity;
2248  m_ChunkPrevious = previousBlock;
2249  if (previousBlock != null)
2250  {
2251  m_ChunkOffset = previousBlock.m_ChunkOffset + previousBlock.m_ChunkLength;
2252  }
2253  }
2254 
2255  [SecuritySafeCritical]
2256  private void Remove(int startIndex, int count, out StringBuilder chunk, out int indexInChunk)
2257  {
2258  int num = startIndex + count;
2259  chunk = this;
2260  StringBuilder stringBuilder = null;
2261  int num2 = 0;
2262  while (true)
2263  {
2264  if (num - chunk.m_ChunkOffset >= 0)
2265  {
2266  if (stringBuilder == null)
2267  {
2268  stringBuilder = chunk;
2269  num2 = num - stringBuilder.m_ChunkOffset;
2270  }
2271  if (startIndex - chunk.m_ChunkOffset >= 0)
2272  {
2273  break;
2274  }
2275  }
2276  else
2277  {
2278  chunk.m_ChunkOffset -= count;
2279  }
2280  chunk = chunk.m_ChunkPrevious;
2281  }
2282  indexInChunk = startIndex - chunk.m_ChunkOffset;
2283  int num3 = indexInChunk;
2284  int count2 = stringBuilder.m_ChunkLength - num2;
2285  if (stringBuilder != chunk)
2286  {
2287  num3 = 0;
2288  chunk.m_ChunkLength = indexInChunk;
2289  stringBuilder.m_ChunkPrevious = chunk;
2290  stringBuilder.m_ChunkOffset = chunk.m_ChunkOffset + chunk.m_ChunkLength;
2291  if (indexInChunk == 0)
2292  {
2293  stringBuilder.m_ChunkPrevious = chunk.m_ChunkPrevious;
2294  chunk = stringBuilder;
2295  }
2296  }
2297  stringBuilder.m_ChunkLength -= num2 - num3;
2298  if (num3 != num2)
2299  {
2300  ThreadSafeCopy(stringBuilder.m_ChunkChars, num2, stringBuilder.m_ChunkChars, num3, count2);
2301  }
2302  }
2303  }
2304 }
static string NewLine
Gets the newline string defined for this environment.
Definition: Environment.cs:449
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
StringBuilder AppendFormat(string format, params object[] args)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder Insert(int index, short value)
Inserts the string representation of a specified 16-bit signed integer into this instance at the spec...
unsafe override string ToString()
Converts the value of this instance to a T:System.String.
StringBuilder Append(byte value)
Appends the string representation of a specified 8-bit unsigned integer to this instance.
unsafe StringBuilder Insert(int index, string value, int count)
Inserts one or more copies of a specified string into this instance at the specified character positi...
object GetFormat(Type formatType)
Returns an object that provides formatting services for the specified type.
StringBuilder Insert(int index, ulong value)
Inserts the string representation of a 64-bit unsigned integer into this instance at the specified ch...
StringBuilder AppendFormat(IFormatProvider provider, string format, params object[] args)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder()
Initializes a new instance of the T:System.Text.StringBuilder class.
StringBuilder(int capacity, int maxCapacity)
Initializes a new instance of the T:System.Text.StringBuilder class that starts with a specified capa...
StringBuilder Append(int value)
Appends the string representation of a specified 32-bit signed integer to this instance.
static sbyte Min(sbyte val1, sbyte val2)
Returns the smaller of two 8-bit signed integers.
Definition: Math.cs:762
StringBuilder Append(ushort value)
Appends the string representation of a specified 16-bit unsigned integer to this instance.
Definition: __Canon.cs:3
bool Equals(StringBuilder sb)
Returns a value indicating whether this instance is equal to a specified object.
The exception that is thrown when the value of an argument is outside the allowable range of values a...
StringBuilder Insert(int index, ushort value)
Inserts the string representation of a 16-bit unsigned integer into this instance at the specified ch...
int EnsureCapacity(int capacity)
Ensures that the capacity of this instance of T:System.Text.StringBuilder is at least the specified v...
Provides a mechanism for retrieving an object to control formatting.
unsafe StringBuilder Append(char *value, int valueCount)
Appends an array of Unicode characters starting at a specified address to this instance.
StringBuilder AppendFormat(string format, object arg0, object arg1)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder Append(bool value)
Appends the string representation of a specified Boolean value to this instance.
StringBuilder AppendLine()
Appends the default line terminator to the end of the current T:System.Text.StringBuilder object.
StringBuilder Insert(int index, decimal value)
Inserts the string representation of a decimal number into this instance at the specified character p...
Describes the source and destination of a given serialized stream, and provides an additional caller-...
StringBuilder Insert(int index, object value)
Inserts the string representation of an object into this instance at the specified character position...
unsafe StringBuilder Append(char[] value)
Appends the string representation of the Unicode characters in a specified array to this instance.
StringBuilder Append(long value)
Appends the string representation of a specified 64-bit signed integer to this instance.
StringBuilder AppendFormat(string format, object arg0)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder Append(ulong value)
Appends the string representation of a specified 64-bit unsigned integer to this instance.
StringBuilder AppendLine(string value)
Appends a copy of the specified string followed by the default line terminator to the end of the curr...
StringBuilder Insert(int index, bool value)
Inserts the string representation of a Boolean value into this instance at the specified character po...
StringBuilder(int capacity)
Initializes a new instance of the T:System.Text.StringBuilder class using the specified capacity.
StringBuilder Append(uint value)
Appends the string representation of a specified 32-bit unsigned integer to this instance.
unsafe StringBuilder Append(string value)
Appends a copy of the specified string to this instance.
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
Copies the characters from a specified segment of this instance to a specified segment of a destinati...
StringBuilder Append(char value, int repeatCount)
Appends a specified number of copies of the string representation of a Unicode character to this inst...
The exception that is thrown when the format of an argument is invalid, or when a composite format st...
The exception that is thrown when an attempt is made to access an element of an array or collection w...
StringBuilder Append(object value)
Appends the string representation of a specified object to this instance.
StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder Append(sbyte value)
Appends the string representation of a specified 8-bit signed integer to this instance.
StringBuilder Append(decimal value)
Appends the string representation of a specified decimal number to this instance.
StringBuilder(string value)
Initializes a new instance of the T:System.Text.StringBuilder class using the specified string.
static sbyte Max(sbyte val1, sbyte val2)
Returns the larger of two 8-bit signed integers.
Definition: Math.cs:581
unsafe string ToString(int startIndex, int length)
Converts the value of a substring of this instance to a T:System.String.
int Length
Gets or sets the length of the current T:System.Text.StringBuilder object.
StringBuilder Insert(int index, sbyte value)
Inserts the string representation of a specified 8-bit signed integer into this instance at the speci...
unsafe StringBuilder Append(string value, int startIndex, int count)
Appends a copy of a specified substring to this instance.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition: Array.cs:17
The exception that is thrown when there is not enough memory to continue the execution of a program.
The exception thrown when an error occurs during serialization or deserialization.
MethodImplOptions
Defines the details of how a method is implemented.
StringBuilder Append(double value)
Appends the string representation of a specified double-precision floating-point number to this insta...
int MaxCapacity
Gets the maximum capacity of this instance.
Stores all the data needed to serialize or deserialize an object. This class cannot be inherited.
StringBuilder Insert(int index, int value)
Inserts the string representation of a specified 32-bit signed integer into this instance at the spec...
Represents a mutable string of characters. This class cannot be inherited.To browse the ....
StringBuilder Replace(char oldChar, char newChar, int startIndex, int count)
Replaces, within a substring of this instance, all occurrences of a specified character with another ...
StringBuilder AppendFormat(string format, object arg0, object arg1, object arg2)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder Append(float value)
Appends the string representation of a specified single-precision floating-point number to this insta...
StringBuilder Insert(int index, double value)
Inserts the string representation of a double-precision floating-point number into this instance at t...
static CultureInfo CurrentCulture
Gets or sets the T:System.Globalization.CultureInfo object that represents the culture used by the cu...
Definition: CultureInfo.cs:120
The exception that is thrown when one of the arguments provided to a method is not valid.
StringBuilder Append(short value)
Appends the string representation of a specified 16-bit signed integer to this instance.
StringBuilder Append(char value)
Appends the string representation of a specified T:System.Char object to this instance.
unsafe StringBuilder Insert(int index, string value)
Inserts a string into this instance at the specified character position.
static void Copy(Array sourceArray, Array destinationArray, int length)
Copies a range of elements from an T:System.Array starting at the first element and pastes them into ...
Definition: Array.cs:1275
Allows an object to control its own serialization and deserialization.
Definition: ISerializable.cs:8
unsafe StringBuilder Insert(int index, char value)
Inserts the string representation of a specified Unicode character into this instance at the specifie...
unsafe StringBuilder(string value, int startIndex, int length, int capacity)
Initializes a new instance of the T:System.Text.StringBuilder class from the specified substring and ...
int Capacity
Gets or sets the maximum number of characters that can be contained in the memory allocated by the cu...
StringBuilder Replace(string oldValue, string newValue)
Replaces all occurrences of a specified string in this instance with another specified string.
StringBuilder Insert(int index, long value)
Inserts the string representation of a 64-bit signed integer into this instance at the specified char...
unsafe StringBuilder Insert(int index, char[] value, int startIndex, int charCount)
Inserts the string representation of a specified subarray of Unicode characters into this instance at...
StringBuilder Replace(char oldChar, char newChar)
Replaces all occurrences of a specified character in this instance with another specified character.
Specifies that the class can be serialized.
string Name
Gets the name for the item currently being examined.
StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder Clear()
Removes all characters from the current T:System.Text.StringBuilder instance.
Provides information about a specific culture (called a locale for unmanaged code development)....
Definition: CultureInfo.cs:16
Provides constants and static methods for trigonometric, logarithmic, and other common mathematical f...
Definition: Math.cs:10
StringBuilder Replace(string oldValue, string newValue, int startIndex, int count)
Replaces, within a substring of this instance, all occurrences of a specified string with another spe...
A conditional operation, such as a > b ? a : b in C# or If(a > b, a, b) in Visual Basic.
StringBuilder Insert(int index, float value)
Inserts the string representation of a single-precision floating point number into this instance at t...
Provides a formatter-friendly mechanism for parsing the data in T:System.Runtime.Serialization....
StringBuilder Insert(int index, char[] value)
Inserts the string representation of a specified array of Unicode characters into this instance at th...
void GetObjectData(SerializationInfo info, StreamingContext context)
Populates a T:System.Runtime.Serialization.SerializationInfo with the data needed to serialize the ta...
StringBuilder Insert(int index, uint value)
Inserts the string representation of a 32-bit unsigned integer into this instance at the specified ch...
StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1, object arg2)
Appends the string returned by processing a composite format string, which contains zero or more form...
StringBuilder Insert(int index, byte value)
Inserts the string representation of a specified 8-bit unsigned integer into this instance at the spe...
StringBuilder Remove(int startIndex, int length)
Removes the specified range of characters from this instance.
unsafe StringBuilder Append(char[] value, int startIndex, int charCount)
Appends the string representation of a specified subarray of Unicode characters to this instance.
bool MoveNext()
Updates the enumerator to the next item.