/// <summary> /// Constructs a <see cref="SourceText"/> from stream content. /// </summary> /// <param name="stream">Stream. The stream must be seekable.</param> /// <param name="encoding"> /// Data encoding to use if the stream doesn't start with Byte Order Mark specifying the encoding. /// <see cref="Encoding.UTF8"/> if not specified. /// </param> /// <param name="checksumAlgorithm"> /// Hash algorithm to use to calculate checksum of the text that's saved to PDB. /// </param> /// <param name="throwIfBinaryDetected">If the decoded text contains at least two consecutive NUL /// characters, then an <see cref="InvalidDataException"/> is thrown.</param> /// <param name="canBeEmbedded">True if the text can be passed to <see cref="EmbeddedText.FromSource"/> and be embedded in a PDB.</param> /// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception> /// <exception cref="ArgumentException"> /// <paramref name="stream"/> doesn't support reading or seeking. /// <paramref name="checksumAlgorithm"/> is not supported. /// </exception> /// <exception cref="DecoderFallbackException">If the given encoding is set to use a throwing decoder as a fallback</exception> /// <exception cref="InvalidDataException">Two consecutive NUL characters were detected in the decoded text and <paramref name="throwIfBinaryDetected"/> was true.</exception> /// <exception cref="IOException">An I/O error occurs.</exception> /// <remarks>Reads from the beginning of the stream. Leaves the stream open.</remarks> public static SourceText From( Stream stream, Encoding encoding = null, SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithm.Sha1, bool throwIfBinaryDetected = false, bool canBeEmbedded = false) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (!stream.CanRead || !stream.CanSeek) { throw new ArgumentException(CodeAnalysisResources.StreamMustSupportReadAndSeek, nameof(stream)); } ValidateChecksumAlgorithm(checksumAlgorithm); encoding = encoding ?? s_utf8EncodingWithNoBOM; // If the resulting string would end up on the large object heap, then use LargeEncodedText. if (encoding.GetMaxCharCountOrThrowIfHuge(stream) >= LargeObjectHeapLimitInChars) { return(LargeText.Decode(stream, encoding, checksumAlgorithm, throwIfBinaryDetected, canBeEmbedded)); } string text = Decode(stream, encoding, out encoding); if (throwIfBinaryDetected && IsBinary(text)) { throw new InvalidDataException(); } // We must compute the checksum and embedded text blob now while we still have the original bytes in hand. // We cannot re-encode to obtain checksum and blob as the encoding is not guaranteed to round-trip. // NOTE: RoslynP does not support embedded text if (canBeEmbedded) { throw new ArgumentException("RoslynP does not support embedded text"); } var checksum = CalculateChecksum(stream, checksumAlgorithm); var embeddedTextBlob = default(ImmutableArray <byte>); return(new StringText(text, encoding, checksum, checksumAlgorithm, embeddedTextBlob)); }
/// <summary> /// Constructs a <see cref="SourceText"/> from text in a string. /// </summary> /// <param name="reader">TextReader</param> /// <param name="length">length of content from <paramref name="reader"/></param> /// <param name="encoding"> /// Encoding of the file that the <paramref name="reader"/> was read from or is going to be saved to. /// <c>null</c> if the encoding is unspecified. /// If the encoding is not specified the resulting <see cref="SourceText"/> isn't debuggable. /// If an encoding-less <see cref="SourceText"/> is written to a file a <see cref="Encoding.UTF8"/> shall be used as a default. /// </param> /// <param name="checksumAlgorithm"> /// Hash algorithm to use to calculate checksum of the text that's saved to PDB. /// </param> /// <exception cref="ArgumentNullException"><paramref name="reader"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="checksumAlgorithm"/> is not supported.</exception> public static SourceText From( TextReader reader, int length, Encoding encoding = null, SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithm.Sha1) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } // If the resulting string would end up on the large object heap, then use LargeEncodedText. if (length >= LargeObjectHeapLimitInChars) { return(LargeText.Decode(reader, length, encoding, checksumAlgorithm)); } string text = reader.ReadToEnd(); return(From(text, encoding, checksumAlgorithm)); }