-
Notifications
You must be signed in to change notification settings - Fork 587
/
Copy pathBlobStream.cs
72 lines (65 loc) · 2.09 KB
/
BlobStream.cs
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
// dnlib: See LICENSE.txt for more info
using System;
using dnlib.IO;
namespace dnlib.DotNet.MD {
/// <summary>
/// Represents the #Blob stream
/// </summary>
public sealed class BlobStream : HeapStream {
/// <inheritdoc/>
public BlobStream() {
}
/// <inheritdoc/>
public BlobStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader)
: base(mdReaderFactory, metadataBaseOffset, streamHeader) {
}
/// <summary>
/// Reads data
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns>The data or <c>null</c> if invalid offset</returns>
public byte[] Read(uint offset) {
// The CLR has a special check for offset 0. It always interprets it as
// 0-length data, even if that first byte isn't 0 at all.
if (offset == 0)
return Array2.Empty<byte>();
if (!TryCreateReader(offset, out var reader))
return null;
return reader.ToArray();
}
/// <summary>
/// Reads data just like <see cref="Read"/>, but returns an empty array if
/// offset is invalid
/// </summary>
/// <param name="offset">Offset of data</param>
/// <returns>The data</returns>
public byte[] ReadNoNull(uint offset) => Read(offset) ?? Array2.Empty<byte>();
/// <summary>
/// Creates a reader that can access a blob
/// </summary>
/// <param name="offset">Offset of blob</param>
/// <returns>A new stream</returns>
public DataReader CreateReader(uint offset) {
TryCreateReader(offset, out var reader);
return reader;
}
/// <summary>
/// Creates a reader that can access a blob or returns false on failure
/// </summary>
/// <param name="offset">Offset of blob</param>
/// <param name="reader">Updated with the reader</param>
/// <returns></returns>
public bool TryCreateReader(uint offset, out DataReader reader) {
reader = dataReader;
if (!IsValidOffset(offset))
return false;
reader.Position = offset;
if (!reader.TryReadCompressedUInt32(out uint length))
return false;
if (!reader.CanRead(length))
return false;
reader = reader.Slice(reader.Position, length);
return true;
}
}
}