-
Notifications
You must be signed in to change notification settings - Fork 465
Tweak Named pipe protocol #259
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using System.Text; | ||
|
|
||
| namespace GVFS.Common.NamedPipes | ||
| { | ||
| /// <summary> | ||
| /// Implements the NamedPipe protocol as described in NamedPipeServer. | ||
| /// </summary> | ||
| public class NamedPipeStreamReader | ||
| { | ||
| private const int DefaultBufferSize = 1024; | ||
| private const byte TerminatorByte = 0x3; | ||
|
|
||
| private int bufferSize; | ||
| private byte[] buffer; | ||
| private Stream stream; | ||
|
|
||
| public NamedPipeStreamReader(Stream stream, int bufferSize) | ||
| { | ||
| this.stream = stream; | ||
| this.bufferSize = bufferSize; | ||
| this.buffer = new byte[this.bufferSize]; | ||
| } | ||
|
|
||
| public NamedPipeStreamReader(Stream stream) | ||
| : this(stream, DefaultBufferSize) | ||
| { | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Read a message from the stream. | ||
| /// </summary> | ||
| /// <returns>The message read from the stream, or null if the end of the input stream has been reached. </returns> | ||
| public string ReadMessage() | ||
| { | ||
| int bytesRead = this.Read(); | ||
| if (bytesRead == 0) | ||
| { | ||
| // The end of the stream has been reached - return null to indicate this. | ||
| return null; | ||
| } | ||
|
|
||
| // If we have read in the entire message in the first read (mainline scenario), | ||
| // then just process the data directly from the buffer. | ||
| if (this.buffer[bytesRead - 1] == TerminatorByte) | ||
| { | ||
| return Encoding.UTF8.GetString(this.buffer, 0, bytesRead - 1); | ||
| } | ||
|
|
||
| // We need to process multiple chunks - collect data from multiple chunks | ||
| // into a single list | ||
| List<byte> bytes = new List<byte>(this.bufferSize * 2); | ||
|
|
||
| while (true) | ||
| { | ||
| bool encounteredTerminatorByte = this.buffer[bytesRead - 1] == TerminatorByte; | ||
| int lengthToCopy = encounteredTerminatorByte ? bytesRead - 1 : bytesRead; | ||
|
|
||
| bytes.AddRange(new ArraySegment<byte>(this.buffer, 0, lengthToCopy)); | ||
| if (encounteredTerminatorByte) | ||
| { | ||
| break; | ||
| } | ||
|
|
||
| bytesRead = this.Read(); | ||
|
|
||
| if (bytesRead == 0) | ||
| { | ||
| // We have read a partial message (the last byte received does not indicate that | ||
| // this was the end of the message), but the stream has been closed. Throw an exception | ||
| // and let upper layer deal with this condition. | ||
|
|
||
| throw new IOException("Incomplete message read from stream. The end of the stream was reached without the expected terminating byte."); | ||
| } | ||
| } | ||
|
|
||
| return Encoding.UTF8.GetString(bytes.ToArray()); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Read the next chunk of bytes from the stream. | ||
| /// </summary> | ||
| /// <returns>The number of bytes read.</returns> | ||
| private int Read() | ||
| { | ||
| return this.stream.Read(this.buffer, 0, this.buffer.Length); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| using System.IO; | ||
| using System.Text; | ||
|
|
||
| namespace GVFS.Common.NamedPipes | ||
| { | ||
| public class NamedPipeStreamWriter | ||
| { | ||
| private const byte TerminatorByte = 0x3; | ||
| private const string TerminatorByteString = "\x3"; | ||
| private Stream stream; | ||
|
|
||
| public NamedPipeStreamWriter(Stream stream) | ||
| { | ||
| this.stream = stream; | ||
| } | ||
|
|
||
| public void WriteMessage(string message) | ||
| { | ||
| byte[] byteBuffer = Encoding.UTF8.GetBytes(message + TerminatorByteString); | ||
| this.stream.Write(byteBuffer, 0, byteBuffer.Length); | ||
| this.stream.Flush(); | ||
| } | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,6 +63,16 @@ public void UpdateIndexRemoveAddFileOpenForWrite() | |
| GitHelpers.InvokeGitAgainstGVFSRepo(this.Enlistment.RepoRoot, "update-index --add Test_ConflictTests/AddedFiles/AddedByBothDifferentContent.txt"); | ||
| } | ||
|
|
||
| [TestCase] | ||
| [Category(Categories.MacTODO.M4)] | ||
|
Member
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. Does this fail on Mac? If so, what's the error (out of curiosity)?
Member
Author
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 have not tried running this on the Mac - I will test and see what happens (or remove this, if possible)
Member
Author
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. This test fails on the "cleanup" code (not related to the protocol changes). After "resetting" the repository, there are unexpected changes in the test repository. Because of this (and because the failure is not related to the protocol changes), I will leave this as a to for Mac |
||
| public void UpdateIndexWithCacheInfo() | ||
| { | ||
| // Update Protocol.md with the contents from blob 583f1... | ||
| string command = $"update-index --cacheinfo 100644 \"583f1a56db7cc884d54534c5d9c56b93a1e00a2b\n\" Protocol.md"; | ||
|
|
||
| this.ValidateGitCommand(command); | ||
| } | ||
|
|
||
| protected override void CreateEnlistment() | ||
| { | ||
| base.CreateEnlistment(); | ||
|
|
||
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.
Should we log the partial message?