[Mono.Profiler.Log] Fix excessive byte array allocations.
[mono.git] / mcs / class / Mono.Profiler.Log / Mono.Profiler.Log / LogStream.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 using System;
6 using System.IO;
7
8 namespace Mono.Profiler.Log {
9
10         public class LogStream : Stream {
11
12                 public Stream BaseStream { get; }
13
14                 public virtual bool EndOfStream => BaseStream.Position == BaseStream.Length;
15
16                 public override bool CanRead => true;
17
18                 public override bool CanSeek => false;
19
20                 public override bool CanWrite => false;
21
22                 public override long Length => throw new NotSupportedException ();
23
24                 public override long Position {
25                         get => throw new NotSupportedException ();
26                         set => throw new NotSupportedException ();
27                 }
28
29                 readonly byte[] _byteBuffer = new byte [1];
30
31                 public LogStream (Stream baseStream)
32                 {
33                         if (baseStream == null)
34                                 throw new ArgumentNullException (nameof (baseStream));
35
36                         if (!baseStream.CanRead)
37                                 throw new ArgumentException ("Stream does not support reading.", nameof (baseStream));
38
39                         BaseStream = baseStream;
40                 }
41
42                 protected override void Dispose (bool disposing)
43                 {
44                         if (disposing)
45                                 BaseStream.Dispose ();
46                 }
47
48                 public override void Flush ()
49                 {
50                         throw new NotSupportedException ();
51                 }
52
53                 public override int ReadByte ()
54                 {
55                         // The base method on Stream is extremely inefficient in that it
56                         // allocates a 1-byte array for every call. Simply use a private
57                         // buffer instead.
58                         return Read (_byteBuffer, 0, sizeof (byte)) == 0 ? -1 : _byteBuffer [0];
59                 }
60
61                 public override int Read (byte[] buffer, int offset, int count)
62                 {
63                         return BaseStream.Read (buffer, offset, count);
64                 }
65
66                 public override long Seek (long offset, SeekOrigin origin)
67                 {
68                         throw new NotSupportedException ();
69                 }
70
71                 public override void SetLength (long value)
72                 {
73                         throw new NotSupportedException ();
74                 }
75
76                 public override void Write (byte[] buffer, int offset, int count)
77                 {
78                         throw new NotSupportedException ();
79                 }
80         }
81 }