Esempio n. 1
0
 /// <summary>
 /// Reads content of a source file.
 /// </summary>
 /// <param name="file">Source file information.</param>
 /// <param name="diagnostics">Storage for diagnostics.</param>
 /// <param name="encoding">Encoding to use or 'null' for autodetect/default</param>
 /// <param name="checksumAlgorithm">Hash algorithm used to calculate file checksum.</param>
 /// <param name="normalizedFilePath">If given <paramref name="file"/> opens successfully, set to normalized absolute path of the file, null otherwise.</param>
 /// <returns>File content or null on failure.</returns>
 internal SourceText ReadFileContent(CommandLineSourceFile file, IList <DiagnosticInfo> diagnostics, Encoding encoding, SourceHashAlgorithm checksumAlgorithm, out string normalizedFilePath)
 {
     try
     {
         // PERF: Using a very small buffer size for the FileStream opens up an optimization within EncodedStringText where
         // we read the entire FileStream into a byte array in one shot. For files that are actually smaller than the buffer
         // size, FileStream.Read still allocates the internal buffer.
         using (var data = PortableShim.FileStream.Create(file.Path, PortableShim.FileMode.Open, PortableShim.FileAccess.Read, PortableShim.FileShare.ReadWrite, bufferSize: 1, options: PortableShim.FileOptions.None))
         {
             normalizedFilePath = (string)PortableShim.FileStream.Name.GetValue(data);
             return(EncodedStringText.Create(data, encoding, checksumAlgorithm));
         }
     }
     catch (Exception e)
     {
         diagnostics.Add(ToFileReadDiagnostics(e, file));
         normalizedFilePath = null;
         return(null);
     }
 }
Esempio n. 2
0
        public static SourceText GetEmbeddedSource(this MetadataReader reader, DocumentHandle document)
        {
            byte[] bytes = (from handle in reader.GetCustomDebugInformation(document)
                            let cdi = reader.GetCustomDebugInformation(handle)
                                      where reader.GetGuid(cdi.Kind) == PortableCustomDebugInfoKinds.EmbeddedSource
                                      select reader.GetBlobBytes(cdi.Value)).SingleOrDefault();

            if (bytes == null)
            {
                return(null);
            }

            int uncompressedSize = BitConverter.ToInt32(bytes, 0);
            var stream           = new MemoryStream(bytes, sizeof(int), bytes.Length - sizeof(int));

            if (uncompressedSize != 0)
            {
                var decompressed = new MemoryStream(uncompressedSize);

                using (var deflater = new DeflateStream(stream, CompressionMode.Decompress))
                {
                    deflater.CopyTo(decompressed);
                }

                if (decompressed.Length != uncompressedSize)
                {
                    throw new InvalidDataException();
                }

                stream = decompressed;
            }

            using (stream)
            {
                return(EncodedStringText.Create(stream));
            }
        }
        public Task <TextLoader?> LoadSourceDocumentAsync(SourceDocument sourceDocument, Encoding?defaultEncoding, CancellationToken cancellationToken)
        {
            // First we try getting "local" files, either from embedded source or a local file on disk
            var stream = TryGetEmbeddedSourceStream(sourceDocument) ??
                         TryGetFileStream(sourceDocument);

            if (stream is not null)
            {
                using (stream)
                {
                    var encoding = defaultEncoding ?? Encoding.UTF8;
                    try
                    {
                        var sourceText = EncodedStringText.Create(stream, defaultEncoding: encoding, checksumAlgorithm: sourceDocument.HashAlgorithm);

                        var fileChecksum = sourceText.GetChecksum();
                        if (fileChecksum.SequenceEqual(sourceDocument.Checksum))
                        {
                            var textAndVersion = TextAndVersion.Create(sourceText, VersionStamp.Default, sourceDocument.FilePath);
                            var textLoader     = TextLoader.From(textAndVersion);
                            return(Task.FromResult <TextLoader?>(textLoader));
                        }
                    }
                    catch (IOException)
                    {
                        // TODO: Log message to inform the user what went wrong: https://github.com/dotnet/roslyn/issues/57352
                    }
                }
            }

            // TODO: Call the debugger to download the file
            // Maybe they'll download to a temp file, in which case this method could return a string
            // or maybe they'll return a stream, in which case we could create a new StreamTextLoader

            return(Task.FromResult <TextLoader?>(null));
        }
Esempio n. 4
0
        private static SourceText CreateMemoryStreamBasedEncodedText(
            byte[] bytes,
            Encoding readEncodingOpt,
            SourceHashAlgorithm algorithm = SourceHashAlgorithm.Sha1
            )
        {
            // For testing purposes, create a bigger buffer so that we verify
            // that the implementation only uses the part that's covered by the stream and not the entire array.
            byte[] buffer = new byte[bytes.Length + 10];
            bytes.CopyTo(buffer, 0);

            using (
                var stream = new MemoryStream(
                    buffer,
                    0,
                    bytes.Length,
                    writable: true,
                    publiclyVisible: true
                    )
                )
            {
                return(EncodedStringText.Create(stream, readEncodingOpt, algorithm));
            }
        }
Esempio n. 5
0
 /// <summary>
 /// Reads the contents of <paramref name="resolvedPath"/> and returns a <see cref="SourceText"/>.
 /// </summary>
 /// <param name="resolvedPath">Path returned by <see cref="ResolveReference(string, string)"/>.</param>
 public virtual SourceText ReadText(string resolvedPath)
 {
     using var stream = OpenRead(resolvedPath);
     return(EncodedStringText.Create(stream));
 }
 public static SourceText Create(Stream stream, Encoding defaultEncoding)
 => EncodedStringText.Create(stream, defaultEncoding);
Esempio n. 7
0
 public SourceText CreateText(Stream stream, Encoding?defaultEncoding, CancellationToken cancellationToken = default)
 {
     cancellationToken.ThrowIfCancellationRequested();
     return(EncodedStringText.Create(stream, defaultEncoding));
 }
Esempio n. 8
0
        public void Decode_NonUtf8()
        {
            // Unicode text with extended characters that map to interesting code points in CodePage 1252.
            var text = "abc def baz aeiouy \u20ac\u2019\u00a4\u00b6\u00c9\u00db\u00ed\u00ff";

            // The same text encoded in CodePage 1252 which happens to be an illegal sequence if decoded as Utf-8.
            var bytes = new byte[]
            {
                0x61,
                0x62,
                0x63,
                0x20,
                0x64,
                0x65,
                0x66,
                0x20,
                0x62,
                0x61,
                0x7a,
                0x20,
                0x61,
                0x65,
                0x69,
                0x6f,
                0x75,
                0x79,
                0x20,
                0x80,
                0x92,
                0xA4,
                0xB6,
                0xC9,
                0xDB,
                0xED,
                0xFF
            };

            var utf8 = new UTF8Encoding(false, true);

            // bytes should not decode to UTF-8
            using (var stream = new MemoryStream(bytes))
            {
                Assert.Throws <DecoderFallbackException>(
                    () =>
                {
                    EncodedStringText.TestAccessor.Decode(
                        stream,
                        utf8,
                        SourceHashAlgorithm.Sha1,
                        throwIfBinaryDetected: false,
                        canBeEmbedded: false
                        );
                }
                    );

                Assert.True(stream.CanRead);
            }

            // Detect encoding should correctly pick CodePage 1252
            using (var stream = new MemoryStream(bytes))
            {
                var sourceText = EncodedStringText.Create(stream);
                Assert.Equal(text, sourceText.ToString());

                // Check for a complete Encoding implementation.
                Assert.Equal(1252, sourceText.Encoding.CodePage);
                Assert.NotNull(sourceText.Encoding.GetEncoder());
                Assert.NotNull(sourceText.Encoding.GetDecoder());
                Assert.Equal(2, sourceText.Encoding.GetMaxByteCount(1));
                Assert.Equal(1, sourceText.Encoding.GetMaxCharCount(1));
                Assert.Equal(text, sourceText.Encoding.GetString(bytes));

                Assert.True(stream.CanRead);
            }
        }