forked from KirillOsenkov/MetadataTools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReadVirtualStream.cs
More file actions
131 lines (111 loc) · 3.01 KB
/
ReadVirtualStream.cs
File metadata and controls
131 lines (111 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Diagnostics.Runtime;
namespace Ref12.Diagnostics.Extraction
{
internal class ReadVirtualStream : Stream
{
private byte[] _tmp;
private long _pos;
private long _disp;
private long _len;
private IDataReader _dataReader;
public ReadVirtualStream(IDataReader dataReader, long displacement, long len)
{
_dataReader = dataReader;
_disp = displacement;
_len = len;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
}
public override long Length
{
get { return int.MaxValue; }
}
public override long Position
{
get
{
return _pos;
}
set
{
_pos = value;
if (_pos > _len)
_pos = _len;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (offset == 0)
{
if (Read(buffer, count, out int read))
return read;
return 0;
}
else
{
if (_tmp == null || _tmp.Length < count)
_tmp = new byte[count];
if (!Read(_tmp, count, out int read))
return 0;
Buffer.BlockCopy(_tmp, 0, buffer, offset, read);
return read;
}
}
private bool Read(byte[] buffer, int count, out int read)
{
if (_dataReader.ReadMemory((ulong)(_pos + _disp), buffer, count, out read))
{
_pos += read;
return true;
}
return false;
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
_pos = offset;
break;
case SeekOrigin.End:
_pos = _len + offset;
if (_pos > _len)
_pos = _len;
break;
case SeekOrigin.Current:
_pos += offset;
if (_pos > _len)
_pos = _len;
break;
}
return _pos;
}
public override void SetLength(long value)
{
_len = value;
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new InvalidOperationException();
}
}
}