New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a version header to Object-Streams. #15794
Changes from 3 commits
01c7037
6d029f1
ecaef9a
2a71d65
e659ebe
17d8404
da1af1e
2d922f3
a5249f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,14 @@ namespace Roslyn.Utilities | |
/// </summary> | ||
internal sealed partial class StreamObjectReader : ObjectReader, IDisposable | ||
{ | ||
/// <summary> | ||
/// We start the version at something reasonably random. That way an older file, with | ||
/// some random start-bytes, has little chance of matching our version. When incrementing | ||
/// this version, just change VersionByte2. | ||
/// </summary> | ||
internal const byte VersionByte1 = 0b10101010; | ||
internal const byte VersionByte2 = 0b00000001; | ||
|
||
private readonly BinaryReader _reader; | ||
private readonly ObjectBinder _binder; | ||
private readonly bool _recursive; | ||
|
@@ -67,11 +75,11 @@ internal sealed partial class StreamObjectReader : ObjectReader, IDisposable | |
/// <param name="knownObjects">An optional list of objects assumed known by the corresponding <see cref="StreamObjectWriter"/>.</param> | ||
/// <param name="binder">A binder that provides object and type decoding.</param> | ||
/// <param name="cancellationToken"></param> | ||
public StreamObjectReader( | ||
private StreamObjectReader( | ||
Stream stream, | ||
ObjectData knownObjects = null, | ||
ObjectBinder binder = null, | ||
CancellationToken cancellationToken = default(CancellationToken)) | ||
ObjectData knownObjects, | ||
ObjectBinder binder, | ||
CancellationToken cancellationToken) | ||
{ | ||
// String serialization assumes both reader and writer to be of the same endianness. | ||
// It can be adjusted for BigEndian if needed. | ||
|
@@ -93,6 +101,30 @@ internal sealed partial class StreamObjectReader : ObjectReader, IDisposable | |
} | ||
} | ||
|
||
/// <summary> | ||
/// Attempts to create a <see cref="StreamObjectReader"/> from the provided <paramref name="stream"/>. | ||
/// If the <paramref name="stream"/> does not start with a valid header, then <code>null</code> will | ||
/// be returned. | ||
/// </summary> | ||
public static StreamObjectReader TryGetReader( | ||
Stream stream, | ||
ObjectData knownObjects = null, | ||
ObjectBinder binder = null, | ||
CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
if (stream == null) | ||
{ | ||
return null; | ||
} | ||
|
||
if (stream.ReadByte() != VersionByte1 && stream.ReadByte() != VersionByte2) | ||
{ | ||
return null; | ||
} | ||
|
||
return new StreamObjectReader(stream, knownObjects, binder, cancellationToken); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could put the read of the format (recursive, etc) byte here too and have it also return null if it doesn't match one of the known types. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could. But that indicates a true bug. That means the format changed and the version wasn't updated. That's actually a bug, and i want an exceptoin in that case. |
||
} | ||
|
||
internal static bool IsRecursive(Stream stream) | ||
{ | ||
var recursionKind = (EncodingKind)stream.ReadByte(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Composition; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading; | ||
|
@@ -139,8 +140,11 @@ private CompilationWithAnalyzers CreateAnalyzerDriver(CompilationWithAnalyzers a | |
// handling of cancellation and exception | ||
var version = await DiagnosticIncrementalAnalyzer.GetDiagnosticVersionAsync(project, cancellationToken).ConfigureAwait(false); | ||
|
||
using (var reader = new StreamObjectReader(stream)) | ||
using (var reader = StreamObjectReader.TryGetReader(stream)) | ||
{ | ||
Debug.Assert(reader != null, | ||
@"We only ge a reader for data transmitted between live processes. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. get? |
||
This data should always be correct as we're never persisting the data between sessions."); | ||
return DiagnosticResultSerializer.Deserialize(reader, analyzerMap, project, version, cancellationToken); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Binary literals FTW!