// // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. // // This file contain implementations details that are subject to change without notice. // Use at your own risk. // namespace Microsoft.VisualStudio.Text.Implementation { using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; using Microsoft.VisualStudio.Utilities; /// /// Base class for all varieties of Text Snapshots. /// internal abstract class BaseSnapshot : ITextSnapshot, ITextSnapshot2 { #region State and Construction protected readonly ITextVersion2 version; private readonly IContentType contentType; internal readonly StringRebuilder Content; internal readonly ITextImage cachingContent; protected BaseSnapshot(ITextVersion2 version, StringRebuilder content) { this.version = version; this.Content = content; this.cachingContent = CachingTextImage.Create(this.Content, version.ImageVersion); // we must extract the content type here, because the content type of the text buffer may change later. this.contentType = version.TextBuffer.ContentType; } #endregion #region ITextSnapshot implementations public ITextBuffer TextBuffer { get { return this.TextBufferHelper; } } public IContentType ContentType { get { return this.contentType; } } public ITextVersion Version { get { return this.version; } } public string GetText(int startIndex, int length) { return GetText(new Span(startIndex, length)); } public string GetText() { return GetText(new Span(0, this.Length)); } #region Point and Span factories public ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode) { return this.version.CreateTrackingPoint(position, trackingMode); } public ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) { return this.version.CreateTrackingPoint(position, trackingMode, trackingFidelity); } public ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode) { return this.version.CreateTrackingSpan(start, length, trackingMode); } public ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) { return this.version.CreateTrackingSpan(start, length, trackingMode, trackingFidelity); } public ITrackingSpan CreateTrackingSpan(Span span, SpanTrackingMode trackingMode) { return this.version.CreateTrackingSpan(span, trackingMode, TrackingFidelityMode.Forward); } public ITrackingSpan CreateTrackingSpan(Span span, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) { return this.version.CreateTrackingSpan(span, trackingMode, trackingFidelity); } #endregion #endregion #region ITextSnapshot2 implementations public void SaveToFile(string filePath, bool replaceFile, Encoding encoding) { FileUtilities.SaveSnapshot(this, replaceFile ? FileMode.Create : FileMode.CreateNew, encoding, filePath); } #endregion #region ITextSnapshot abstract methods protected abstract ITextBuffer TextBufferHelper { get; } public int Length { get { return this.cachingContent.Length; } } public int LineCount { get { return this.cachingContent.LineCount; } } public string GetText(Span span) { return this.cachingContent.GetText(span); } public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) { this.cachingContent.CopyTo(sourceIndex, destination, destinationIndex, count); } public char[] ToCharArray(int startIndex, int length) { return this.cachingContent.ToCharArray(startIndex, length); } public char this[int position] { get { return this.cachingContent[position]; } } public ITextSnapshotLine GetLineFromLineNumber(int lineNumber) { TextImageLine lineSpan = this.cachingContent.GetLineFromLineNumber(lineNumber); return new TextSnapshotLine(this, lineSpan); } public ITextSnapshotLine GetLineFromPosition(int position) { int lineNumber = this.cachingContent.GetLineNumberFromPosition(position); return this.GetLineFromLineNumber(lineNumber); } public int GetLineNumberFromPosition(int position) { return this.cachingContent.GetLineNumberFromPosition(position); } public IEnumerable Lines { get { // this is a naive implementation int lineCount = this.cachingContent.LineCount; for (int line = 0; line < lineCount; ++line) { yield return GetLineFromLineNumber(line); } } } public void Write(System.IO.TextWriter writer) { this.cachingContent.Write(writer, new Span(0, this.cachingContent.Length)); } public void Write(System.IO.TextWriter writer, Span span) { this.cachingContent.Write(writer, span); } #endregion public ITextImage TextImage => this.cachingContent; public override string ToString() { return string.Format( CultureInfo.InvariantCulture, "version: {0} lines: {1} length: {2} \r\n content: {3}", Version.VersionNumber, LineCount, Length, Utilities.TextUtilities.Escape(this.GetText(0, Math.Min(40, this.Length)))); } #if _DEBUG internal string DebugOnly_AllText { get { return this.GetText(0, Math.Min(this.Length, 1024*1024)); } } #endif } }