Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
StreamMemoryBlockProvider.cs
Go to the documentation of this file.
2using System.IO;
5
7
9{
10 internal const int MemoryMapThreshold = 16384;
11
12 private Stream _stream;
13
14 private readonly object _streamGuard;
15
16 private readonly bool _leaveOpen;
17
18 private bool _useMemoryMap;
19
20 private readonly bool _isFileStream;
21
22 private readonly long _imageStart;
23
24 private readonly int _imageSize;
25
27
28 public override int Size => _imageSize;
29
30 public StreamMemoryBlockProvider(Stream stream, long imageStart, int imageSize, bool isFileStream, bool leaveOpen)
31 {
33 _streamGuard = new object();
34 _imageStart = imageStart;
35 _imageSize = imageSize;
36 _leaveOpen = leaveOpen;
37 _isFileStream = isFileStream;
39 }
40
41 protected override void Dispose(bool disposing)
42 {
43 if (!_leaveOpen)
44 {
45 Interlocked.Exchange(ref _stream, null)?.Dispose();
46 }
47 Interlocked.Exchange(ref _lazyMemoryMap, null)?.Dispose();
48 }
49
50 internal unsafe static NativeHeapMemoryBlock ReadMemoryBlockNoLock(Stream stream, bool isFileStream, long start, int size)
51 {
52 NativeHeapMemoryBlock nativeHeapMemoryBlock = new NativeHeapMemoryBlock(size);
53 bool flag = true;
54 try
55 {
56 stream.Seek(start, SeekOrigin.Begin);
57 int num = 0;
58 if (!isFileStream || (num = FileStreamReadLightUp.ReadFile(stream, nativeHeapMemoryBlock.Pointer, size)) != size)
59 {
60 stream.CopyTo(nativeHeapMemoryBlock.Pointer + num, size - num);
61 }
62 flag = false;
63 }
64 finally
65 {
66 if (flag)
67 {
68 nativeHeapMemoryBlock.Dispose();
69 }
70 }
71 return nativeHeapMemoryBlock;
72 }
73
74 protected override AbstractMemoryBlock GetMemoryBlockImpl(int start, int size)
75 {
76 long start2 = _imageStart + start;
77 if (_useMemoryMap && size > 16384)
78 {
79 if (TryCreateMemoryMappedFileBlock(start2, size, out var block))
80 {
81 return block;
82 }
83 _useMemoryMap = false;
84 }
85 lock (_streamGuard)
86 {
87 return ReadMemoryBlockNoLock(_stream, _isFileStream, start2, size);
88 }
89 }
90
91 public override Stream GetStream(out StreamConstraints constraints)
92 {
94 return _stream;
95 }
96
97 private bool TryCreateMemoryMappedFileBlock(long start, int size, [NotNullWhen(true)] out MemoryMappedFileBlock block)
98 {
99 if (_lazyMemoryMap == null)
100 {
101 IDisposable disposable;
102 lock (_streamGuard)
103 {
105 }
106 if (disposable == null)
107 {
108 block = null;
109 return false;
110 }
111 if (Interlocked.CompareExchange(ref _lazyMemoryMap, disposable, null) != null)
112 {
113 disposable.Dispose();
114 }
115 }
117 if (disposable2 == null)
118 {
119 block = null;
120 return false;
121 }
122 if (!MemoryMapLightUp.TryGetSafeBufferAndPointerOffset(disposable2, out SafeBuffer safeBuffer, out long offset))
123 {
124 block = null;
125 return false;
126 }
127 block = new MemoryMappedFileBlock(disposable2, safeBuffer, offset, size);
128 return true;
129 }
130}
static unsafe int ReadFile(Stream stream, byte *buffer, int size)
static IDisposable CreateMemoryMap(Stream stream)
static bool TryGetSafeBufferAndPointerOffset(object accessor, out SafeBuffer safeBuffer, out long offset)
static IDisposable CreateViewAccessor(object memoryMap, long start, int size)
StreamMemoryBlockProvider(Stream stream, long imageStart, int imageSize, bool isFileStream, bool leaveOpen)
static unsafe NativeHeapMemoryBlock ReadMemoryBlockNoLock(Stream stream, bool isFileStream, long start, int size)
override AbstractMemoryBlock GetMemoryBlockImpl(int start, int size)
bool TryCreateMemoryMappedFileBlock(long start, int size, [NotNullWhen(true)] out MemoryMappedFileBlock block)
override Stream GetStream(out StreamConstraints constraints)
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)