public override string GetText(Span span) { if (span.End > this.Length) { throw new ArgumentOutOfRangeException("span"); } if (span.End <= _left.Length) { return(_left.GetText(span)); } else if (span.Start >= _left.Length) { return(_right.GetText(new Span(span.Start - _left.Length, span.Length))); } else { char[] result = new char[span.Length]; int leftLength = _left.Length - span.Start; _left.CopyTo(span.Start, result, 0, leftLength); _right.CopyTo(0, result, leftLength, span.Length - leftLength); return(new string(result)); } }
/// <summary> /// Consolidate two string rebuilders, taking advantage of the fact that they have already extracted the line breaks. /// </summary> public static StringRebuilder Consolidate(StringRebuilder left, StringRebuilder right) { Debug.Assert(left.Length > 0); Debug.Assert(right.Length > 0); int length = left.Length + right.Length; char[] result = new char[length]; left.CopyTo(0, result, 0, left.Length); right.CopyTo(0, result, left.Length, right.Length); ILineBreaks lineBreaks; if ((left.LineBreakCount == 0) && (right.LineBreakCount == 0)) { lineBreaks = LineBreakManager.Empty; //_lineBreakSpan defaults to 0, 0 which is what we want } else { ILineBreaksEditor breaks = LineBreakManager.CreateLineBreakEditor(length, left.LineBreakCount + right.LineBreakCount); int offset = 0; if ((result[left.Length] == '\n') && (result[left.Length - 1] == '\r')) { //We have a \r\n spanning the seam ... add that as a special linebreak later. offset = 1; } int leftLines = left.LineBreakCount - offset; for (int i = 0; (i < leftLines); ++i) { Span extent; int lineBreakLength; left.GetLineFromLineNumber(i, out extent, out lineBreakLength); breaks.Add(extent.End, lineBreakLength); } if (offset == 1) { breaks.Add(left.Length - 1, 2); } for (int i = offset; (i < right.LineBreakCount); ++i) { Span extent; int lineBreakLength; right.GetLineFromLineNumber(i, out extent, out lineBreakLength); breaks.Add(extent.End + left.Length, lineBreakLength); } lineBreaks = breaks; } return(StringRebuilderForChars.Create(result, length, lineBreaks)); }
/// <summary> /// Consolidate two string rebuilders, taking advantage of the fact that they have already extracted the line breaks. /// </summary> public static SimpleStringRebuilder Create(StringRebuilder left, StringRebuilder right) { Debug.Assert(left.Length > 0); Debug.Assert(right.Length > 0); int length = left.Length + right.Length; char[] result = new char[length]; left.CopyTo(0, result, 0, left.Length); right.CopyTo(0, result, left.Length, right.Length); string text = new string(result); int[] lineBreaks; if ((left.LineBreakCount == 0) && (right.LineBreakCount == 0)) { lineBreaks = _emptyLineBreaks; //_lineBreakSpan defaults to 0, 0 which is what we want } else { int offset = 0; if ((text[left.Length] == '\n') && (text[left.Length - 1] == '\r')) { //We have a \r\n spanning the seam ... add that as a special linebreak later. offset = 1; } lineBreaks = new int[left.LineBreakCount + right.LineBreakCount - offset]; int lastLineBreak = 0; int leftLines = left.LineBreakCount - offset; for (int i = 0; (i < leftLines); ++i) { LineSpan lineSpan = left.GetLineFromLineNumber(i); lineBreaks[lastLineBreak++] = lineSpan.End; } if (offset == 1) { lineBreaks[lastLineBreak++] = left.Length - 1; } for (int i = offset; (i < right.LineBreakCount); ++i) { LineSpan lineSpan = right.GetLineFromLineNumber(i); lineBreaks[lastLineBreak++] = lineSpan.End + left.Length; } } return(new SimpleStringRebuilder(SimpleTextStorage.Create(text, lineBreaks))); }