/// <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); } }
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)); }
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)); } }
/// <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);
public SourceText CreateText(Stream stream, Encoding?defaultEncoding, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); return(EncodedStringText.Create(stream, defaultEncoding)); }
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); } }