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