/// <summary> /// Combines contiguous segments with lengths that are each less than or equal to the specified segment size. /// </summary> private static void CombineSegments(ArrayBuilder <SourceText> segments, int segmentSize) { for (int i = 0; i < segments.Count - 1; i++) { if (segments[i].Length <= segmentSize) { int combinedLength = segments[i].Length; // count how many contiguous segments are reducible int count = 1; for (int j = i + 1; j < segments.Count; j++) { if (segments[j].Length <= segmentSize) { count++; combinedLength += segments[j].Length; } } // if we've got at least two, then combine them into a single text if (count > 1) { var encoding = segments[i].Encoding; var algorithm = segments[i].ChecksumAlgorithm; var writer = SourceTextWriter.Create(encoding, algorithm, combinedLength); while (count > 0) { segments[i].Write(writer); segments.RemoveAt(i); count--; } var newText = writer.ToSourceText(); segments.Insert(i, newText); } } } }
/// <summary> /// Trim excessive inaccessible text. /// </summary> private static void TrimInaccessibleText(ArrayBuilder <SourceText> segments) { int length, size; ComputeLengthAndStorageSize(segments, out length, out size); // if more than half of the storage is unused, compress into a single new segment if (length < size / 2) { var encoding = segments[0].Encoding; var algorithm = segments[0].ChecksumAlgorithm; var writer = SourceTextWriter.Create(encoding, algorithm, length); foreach (var segment in segments) { segment.Write(writer); } segments.Clear(); segments.Add(writer.ToSourceText()); } }