Beispiel #1
0
        private void ReloadBufferFromStream(Stream stream, long fileSize, EditOptions options, Encoding encoding)
        {
            using (var streamReader = new EncodedStreamReader.NonStreamClosingStreamReader(stream, encoding, detectEncodingFromByteOrderMarks: false)) {
                TextBuffer concreteBuffer = _textBuffer as TextBuffer;
                if (concreteBuffer != null)
                {
                    StringRebuilder newContent = TextImageLoader.Load(
                        streamReader,
                        fileSize,
                        out var newlineState,
                        out var leadingWhitespaceState,
                        out var longestLineLength);

                    if (!newlineState.HasConsistentLineEndings)
                    {
                        // leave a sign that line endings are inconsistent. This is rather nasty but for now
                        // we don't want to pollute the API with this factoid.
                        concreteBuffer.Properties["InconsistentLineEndings"] = true;
                    }
                    else
                    {
                        // this covers a really obscure case where on initial load the file had inconsistent line
                        // endings, but the UI settings were such that it was ignored, and since then the file has
                        // acquired consistent line endings and the UI settings have also changed.
                        concreteBuffer.Properties.RemoveProperty("InconsistentLineEndings");
                    }
                    // leave a similar sign about the longest line in the buffer.
                    concreteBuffer.Properties["LongestLineLength"] = longestLineLength;

                    concreteBuffer.ReloadContent(newContent, options, editTag: this);
                }
                else
                {
                    // we may hit this path if somebody mocks the text buffer in a test.
                    using (var edit = _textBuffer.CreateEdit(options, null, editTag: this)) {
                        if (edit.Replace(new Span(0, edit.Snapshot.Length), streamReader.ReadToEnd()))
                        {
                            edit.Apply();
                        }
                        else
                        {
                            edit.Cancel();
                        }
                    }
                }
            }
        }
Beispiel #2
0
        private void ReloadBufferFromStream(Stream stream, long fileSize, EditOptions options, Encoding encoding)
        {
            using (var streamReader = new EncodedStreamReader.NonStreamClosingStreamReader(stream, encoding, detectEncodingFromByteOrderMarks: false))
            {
                TextBuffer concreteBuffer = _textBuffer as TextBuffer;
                if (concreteBuffer != null)
                {
                    int             longestLineLength;
                    StringRebuilder newContent = TextImageLoader.Load(streamReader, fileSize, out var newlineState, out var leadingWhitespaceState, out longestLineLength);

                    // Make the call to GetWhitespaceManager to add the manager to the properties. We don't need the return value here.
                    _textDocumentFactoryService.WhitespaceManagerFactory.GetOrCreateWhitespaceManager(concreteBuffer, newlineState, leadingWhitespaceState);

                    // Leave a sign about the longest line in the buffer. This is rather nasty, but for now
                    // we don't want to pollute the API with this factoid
                    concreteBuffer.Properties["LongestLineLength"] = longestLineLength;

                    concreteBuffer.ReloadContent(newContent, options, editTag: this);
                }
                else
                {
                    // we may hit this path if somebody mocks the text buffer in a test.
                    using (var edit = _textBuffer.CreateEdit(options, null, editTag: this))
                    {
                        if (edit.Replace(new Span(0, edit.Snapshot.Length), streamReader.ReadToEnd()))
                        {
                            edit.Apply();
                        }
                        else
                        {
                            edit.Cancel();
                        }
                    }
                }
            }
        }
        public ITextDocument CreateAndLoadTextDocument(string filePath, IContentType contentType, bool attemptUtf8Detection, out bool characterSubstitutionsOccurred)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (contentType == null)
            {
                throw new ArgumentNullException(nameof(contentType));
            }

            characterSubstitutionsOccurred = false;

            Encoding    chosenEncoding = null;
            ITextBuffer buffer         = null;
            DateTime    lastModified;
            long        fileSize;

            // select matching detectors without instantiating any
            var detectors = ExtensionSelector.SelectMatchingExtensions(OrderedEncodingDetectors, contentType);

            using (Stream stream = OpenFile(filePath, out lastModified, out fileSize))
            {
                // First, look for a byte order marker and let the encoding detecters
                // suggest encodings.
                chosenEncoding = EncodedStreamReader.DetectEncoding(stream, detectors, GuardedOperations);

                // If that didn't produce a result, tentatively try to open as UTF 8.
                if (chosenEncoding == null && attemptUtf8Detection)
                {
                    try
                    {
                        var detectorEncoding = new ExtendedCharacterDetector();

                        using (StreamReader reader = new EncodedStreamReader.NonStreamClosingStreamReader(stream, detectorEncoding, false))
                        {
                            buffer = ((ITextBufferFactoryService2)BufferFactoryService).CreateTextBuffer(reader, contentType, fileSize, filePath);
                            characterSubstitutionsOccurred = false;
                        }

                        if (detectorEncoding.DecodedExtendedCharacters)
                        {
                            // Valid UTF-8 but has bytes that are not merely ASCII.
                            chosenEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
                        }
                        else
                        {
                            // Valid UTF8 but no extended characters, so it's valid ASCII.
                            // We don't use ASCII here because of the following scenario:
                            // The user with a non-ENU system encoding opens a code file with ASCII-only contents
                            chosenEncoding = DefaultEncoding;
                        }
                    }
                    catch (DecoderFallbackException)
                    {
                        // Not valid UTF-8.
                        // Proceed to the next if block to try the system's default codepage.
                        Debug.Assert(buffer == null);
                        buffer          = null;
                        stream.Position = 0;
                    }
                }

                Debug.Assert(buffer == null || chosenEncoding != null);

                // If all else didn't work, use system's default encoding.
                if (chosenEncoding == null)
                {
                    chosenEncoding = DefaultEncoding;
                }

                if (buffer == null)
                {
                    var fallbackDetector = new FallbackDetector(chosenEncoding.DecoderFallback);
                    var modifiedEncoding = (Encoding)chosenEncoding.Clone();
                    modifiedEncoding.DecoderFallback = fallbackDetector;

                    Debug.Assert(stream.Position == 0);

                    using (StreamReader reader = new EncodedStreamReader.NonStreamClosingStreamReader(stream, modifiedEncoding, detectEncodingFromByteOrderMarks: false))
                    {
                        Debug.Assert(chosenEncoding.CodePage == reader.CurrentEncoding.CodePage);
                        buffer = ((ITextBufferFactoryService2)BufferFactoryService).CreateTextBuffer(reader, contentType, fileSize, filePath);
                    }

                    characterSubstitutionsOccurred = fallbackDetector.FallbackOccurred;
                }
            }

            TextDocument textDocument = new TextDocument(buffer, filePath, lastModified, this, chosenEncoding, attemptUtf8Detection: attemptUtf8Detection);

            RaiseTextDocumentCreated(textDocument);

            return(textDocument);
        }