2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * This class merges two underlying streams (one for reading, the other
32 * for writing) into a single Stream object. It can also optionally dump
33 * all read and written bytes, in hexadecimal, on an provided text
34 * stream (for debugging purposes).
37 public class MergeStream : Stream {
42 * Text stream on which to write an hexadecimal dump of the data
43 * which is read from or written to this stream. If null (the
44 * default), then no dump is written.
46 public TextWriter Debug {
51 * Create this stream over the two underlying substreams:
52 * 'subIn', from which data is read, and 'subOut', to which data
53 * is written. The two substreams may be the same object.
55 public MergeStream(Stream subIn, Stream subOut)
61 public override int ReadByte()
63 int x = subIn.ReadByte();
66 Debug.WriteLine("recv:");
67 Debug.WriteLine(" {0:x2}", x);
69 Debug.WriteLine("recv: EOF");
75 public override int Read(byte[] buf, int off, int len)
77 int rlen = subIn.Read(buf, off, len);
80 Debug.WriteLine("recv: EOF");
83 for (int i = 0; i < rlen; i ++) {
87 } else if ((i & 7) == 0) {
92 Debug.Write("{0:x2}", buf[i]);
100 public override void WriteByte(byte x)
103 Debug.WriteLine("send:");
104 Debug.WriteLine(" {0:x2}", x);
109 public override void Write(byte[] buf, int off, int len)
112 Debug.Write("send:");
113 for (int i = 0; i < len; i ++) {
117 } else if ((i & 7) == 0) {
122 Debug.Write("{0:x2}", buf[i]);
126 subOut.Write(buf, off, len);
129 public override void Flush()
134 public override void Close()
136 Exception ex1 = null, ex2 = null;
139 } catch (Exception ex) {
144 } catch (Exception ex) {
149 } else if (ex1 != null) {
154 public override long Seek(long off, SeekOrigin origin)
156 throw new NotSupportedException();
159 public override void SetLength(long len)
161 throw new NotSupportedException();
164 public override bool CanRead {
166 return subIn.CanRead;
170 public override bool CanWrite {
172 return subOut.CanWrite;
176 public override bool CanSeek {
182 public override long Length {
184 throw new NotSupportedException();
188 public override long Position {
190 throw new NotSupportedException();
193 throw new NotSupportedException();