2
This code is derived from jgit (http://eclipse.org/jgit).
3
Copyright owners are documented in jgit's IP log.
5
This program and the accompanying materials are made available
6
under the terms of the Eclipse Distribution License v1.0 which
7
accompanies this distribution, is reproduced below, and is
8
available at http://www.eclipse.org/org/documents/edl-v10.php
12
Redistribution and use in source and binary forms, with or
13
without modification, are permitted provided that the following
16
- Redistributions of source code must retain the above copyright
17
notice, this list of conditions and the following disclaimer.
19
- Redistributions in binary form must reproduce the above
20
copyright notice, this list of conditions and the following
21
disclaimer in the documentation and/or other materials provided
22
with the distribution.
24
- Neither the name of the Eclipse Foundation, Inc. nor the
25
names of its contributors may be used to endorse or promote
26
products derived from this software without specific prior
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49
namespace NGit.Transport
51
/// <summary>Multiplexes data and progress messages.</summary>
53
/// Multiplexes data and progress messages.
55
/// This stream is buffered at packet sizes, so the caller doesn't need to wrap
56
/// it in yet another buffered stream.
58
internal class SideBandOutputStream : OutputStream
60
internal const int CH_DATA = SideBandInputStream.CH_DATA;
62
internal const int CH_PROGRESS = SideBandInputStream.CH_PROGRESS;
64
internal const int CH_ERROR = SideBandInputStream.CH_ERROR;
66
internal const int SMALL_BUF = 1000;
68
internal const int MAX_BUF = 65520;
70
internal const int HDR_SIZE = 5;
72
private readonly OutputStream @out;
74
private readonly byte[] buffer;
77
/// Number of bytes in
78
/// <see cref="buffer">buffer</see>
79
/// that are valid data.
82
/// <see cref="HDR_SIZE">HDR_SIZE</see>
83
/// if there is no application data in the
84
/// buffer, as the packet header always appears at the start of the buffer.
88
/// <summary>Create a new stream to write side band packets.</summary>
89
/// <remarks>Create a new stream to write side band packets.</remarks>
90
/// <param name="chan">
91
/// channel number to prefix all packets with, so the remote side
92
/// can demultiplex the stream and get back the original data.
93
/// Must be in the range [0, 255].
96
/// maximum size of a data packet within the stream. The remote
97
/// side needs to agree to the packet size to prevent buffer
98
/// overflows. Must be in the range [HDR_SIZE + 1, MAX_BUF).
100
/// <param name="os">
101
/// stream that the packets are written onto. This stream should
102
/// be attached to a SideBandInputStream on the remote side.
104
internal SideBandOutputStream(int chan, int sz, OutputStream os)
106
if (chan <= 0 || chan > 255)
108
throw new ArgumentException(MessageFormat.Format(JGitText.Get().channelMustBeInRange0_255
113
throw new ArgumentException(MessageFormat.Format(JGitText.Get().packetSizeMustBeAtLeast
120
throw new ArgumentException(MessageFormat.Format(JGitText.Get().packetSizeMustBeAtMost
125
buffer = new byte[sz];
126
buffer[4] = unchecked((byte)chan);
130
/// <exception cref="System.IO.IOException"></exception>
131
internal virtual void FlushBuffer()
139
/// <exception cref="System.IO.IOException"></exception>
140
public override void Flush()
146
/// <exception cref="System.IO.IOException"></exception>
147
public override void Write(byte[] b, int off, int len)
151
int capacity = buffer.Length - cnt;
152
if (cnt == HDR_SIZE && capacity < len)
154
// Our block to write is bigger than the packet size,
155
// stream it out as-is to avoid unnecessary copies.
156
PacketLineOut.FormatLength(buffer, buffer.Length);
157
@out.Write(buffer, 0, HDR_SIZE);
158
@out.Write(b, off, capacity);
168
int n = Math.Min(len, capacity);
169
System.Array.Copy(b, off, buffer, cnt, n);
177
/// <exception cref="System.IO.IOException"></exception>
178
public override void Write(int b)
180
if (cnt == buffer.Length)
184
buffer[cnt++] = unchecked((byte)b);
187
/// <exception cref="System.IO.IOException"></exception>
188
private void WriteBuffer()
190
PacketLineOut.FormatLength(buffer, cnt);
191
@out.Write(buffer, 0, cnt);