[Mono.Profiler.Log] Load entire buffers before processing them.
[mono.git] / mcs / class / Mono.Profiler.Log / Mono.Profiler.Log / LogReader.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 using System.Text;
8
9 namespace Mono.Profiler.Log {
10
11         sealed class LogReader : IDisposable {
12
13                 static readonly Encoding _encoding = Encoding.UTF8;
14
15                 readonly BinaryReader _reader;
16
17                 byte[] _stringBuffer = new byte [1024];
18
19                 public LogReader (Stream stream, bool leaveOpen)
20                 {
21                         _reader = new BinaryReader (stream, _encoding, leaveOpen);
22                 }
23
24                 public void Dispose ()
25                 {
26                         _reader.Dispose ();
27                 }
28
29                 public byte[] ReadBytes (int count)
30                 {
31                         var bytes = new byte [count];
32
33                         // BinaryReader.ReadBytes doesn't necessarily read the specified
34                         // amount of bytes, so just do it this way.
35                         for (var i = 0; i < bytes.Length; i++)
36                                 bytes [i] = ReadByte ();
37
38                         return bytes;
39                 }
40
41                 public byte ReadByte ()
42                 {
43                         return _reader.ReadByte ();
44                 }
45
46                 public ushort ReadUInt16 ()
47                 {
48                         return _reader.ReadUInt16 ();
49                 }
50
51                 public int ReadInt32 ()
52                 {
53                         return _reader.ReadInt32 ();
54                 }
55
56                 public long ReadInt64 ()
57                 {
58                         return _reader.ReadInt64 ();
59                 }
60
61                 public ulong ReadUInt64 ()
62                 {
63                         return _reader.ReadUInt64 ();
64                 }
65
66                 public double ReadDouble ()
67                 {
68                         return _reader.ReadDouble ();
69                 }
70
71                 public string ReadHeaderString ()
72                 {
73                         return _encoding.GetString (ReadBytes (ReadInt32 ()));
74                 }
75
76                 public string ReadCString ()
77                 {
78                         var pos = 0;
79
80                         byte val;
81
82                         while ((val = ReadByte ()) != 0) {
83                                 if (pos == _stringBuffer.Length)
84                                         Array.Resize (ref _stringBuffer, System.Math.Max (_stringBuffer.Length * 2, pos + 1));
85
86                                 _stringBuffer [pos++] = val;
87                         }
88
89                         return _encoding.GetString (_stringBuffer, 0, pos);
90                 }
91
92                 public long ReadSLeb128 ()
93                 {
94                         long result = 0;
95                         var shift = 0;
96
97                         while (true) {
98                                 var b = ReadByte ();
99
100                                 result |= (long) (b & 0x7f) << shift;
101                                 shift += 7;
102
103                                 if ((b & 0x80) != 0x80) {
104                                         if (shift < sizeof (long) * 8 && (b & 0x40) == 0x40)
105                                                 result |= -(1L << shift);
106
107                                         break;
108                                 }
109                         }
110
111                         return result;
112                 }
113
114                 public ulong ReadULeb128 ()
115                 {
116                         ulong result = 0;
117                         var shift = 0;
118
119                         while (true) {
120                                 var b = ReadByte ();
121
122                                 result |= (ulong) (b & 0x7f) << shift;
123
124                                 if ((b & 0x80) != 0x80)
125                                         break;
126
127                                 shift += 7;
128                         }
129
130                         return result;
131                 }
132         }
133 }