Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
UnmanagedMemoryStream.cs
Go to the documentation of this file.
4
5namespace System.IO;
6
8{
10
11 private unsafe byte* _mem;
12
13 private long _length;
14
15 private long _capacity;
16
17 private long _position;
18
19 private long _offset;
20
22
23 private bool _isOpen;
24
26
27 public override bool CanRead
28 {
29 get
30 {
31 if (_isOpen)
32 {
33 return (_access & FileAccess.Read) != 0;
34 }
35 return false;
36 }
37 }
38
39 public override bool CanSeek => _isOpen;
40
41 public override bool CanWrite
42 {
43 get
44 {
45 if (_isOpen)
46 {
47 return (_access & FileAccess.Write) != 0;
48 }
49 return false;
50 }
51 }
52
53 public override long Length
54 {
55 get
56 {
58 return Interlocked.Read(ref _length);
59 }
60 }
61
62 public long Capacity
63 {
64 get
65 {
67 return _capacity;
68 }
69 }
70
71 public override long Position
72 {
73 get
74 {
75 if (!CanSeek)
76 {
78 }
79 return Interlocked.Read(ref _position);
80 }
81 set
82 {
83 if (value < 0)
84 {
86 }
87 if (!CanSeek)
88 {
90 }
92 }
93 }
94
95 [CLSCompliant(false)]
96 public unsafe byte* PositionPointer
97 {
98 get
99 {
100 if (_buffer != null)
101 {
103 }
105 long num = Interlocked.Read(ref _position);
106 if (num > _capacity)
107 {
109 }
110 return _mem + num;
111 }
112 set
113 {
114 if (_buffer != null)
115 {
117 }
119 if (value < _mem)
120 {
122 }
123 long num = (long)value - (long)_mem;
124 if (num < 0)
125 {
127 }
129 }
130 }
131
133 {
134 }
135
140
142 {
143 Initialize(buffer, offset, length, access);
144 }
145
146 protected unsafe void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access)
147 {
148 if (buffer == null)
149 {
150 throw new ArgumentNullException("buffer");
151 }
152 if (offset < 0)
153 {
155 }
156 if (length < 0)
157 {
159 }
160 if (buffer.ByteLength < (ulong)(offset + length))
161 {
163 }
164 if (access < FileAccess.Read || access > FileAccess.ReadWrite)
165 {
166 throw new ArgumentOutOfRangeException("access");
167 }
168 if (_isOpen)
169 {
171 }
172 byte* pointer = null;
173 try
174 {
175 buffer.AcquirePointer(ref pointer);
176 if (pointer + offset + length < pointer)
177 {
179 }
180 }
181 finally
182 {
183 if (pointer != null)
184 {
185 buffer.ReleasePointer();
186 }
187 }
188 _offset = offset;
189 _buffer = buffer;
190 _length = length;
192 _access = access;
193 _isOpen = true;
194 }
195
196 [CLSCompliant(false)]
197 public unsafe UnmanagedMemoryStream(byte* pointer, long length)
198 {
200 }
201
202 [CLSCompliant(false)]
203 public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access)
204 {
206 }
207
208 [CLSCompliant(false)]
209 protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access)
210 {
211 if (pointer == null)
212 {
213 throw new ArgumentNullException("pointer");
214 }
215 if (length < 0 || capacity < 0)
216 {
217 throw new ArgumentOutOfRangeException((length < 0) ? "length" : "capacity", SR.ArgumentOutOfRange_NeedNonNegNum);
218 }
219 if (length > capacity)
220 {
222 }
223 if ((nuint)((long)pointer + capacity) < (nuint)pointer)
224 {
226 }
227 if (access < FileAccess.Read || access > FileAccess.ReadWrite)
228 {
230 }
231 if (_isOpen)
232 {
234 }
235 _mem = pointer;
236 _offset = 0L;
237 _length = length;
239 _access = access;
240 _isOpen = true;
241 }
242
243 protected unsafe override void Dispose(bool disposing)
244 {
245 _isOpen = false;
246 _mem = null;
247 base.Dispose(disposing);
248 }
249
250 private void EnsureNotClosed()
251 {
252 if (!_isOpen)
253 {
255 }
256 }
257
258 private void EnsureReadable()
259 {
260 if (!CanRead)
261 {
263 }
264 }
265
266 private void EnsureWriteable()
267 {
268 if (!CanWrite)
269 {
271 }
272 }
273
274 public override void Flush()
275 {
277 }
278
280 {
281 if (cancellationToken.IsCancellationRequested)
282 {
284 }
285 try
286 {
287 Flush();
288 return Task.CompletedTask;
289 }
290 catch (Exception exception)
291 {
293 }
294 }
295
296 public override int Read(byte[] buffer, int offset, int count)
297 {
299 return ReadCore(new Span<byte>(buffer, offset, count));
300 }
301
302 public override int Read(Span<byte> buffer)
303 {
304 if (GetType() == typeof(UnmanagedMemoryStream))
305 {
306 return ReadCore(buffer);
307 }
308 return base.Read(buffer);
309 }
310
311 internal unsafe int ReadCore(Span<byte> buffer)
312 {
315 long num = Interlocked.Read(ref _position);
316 long num2 = Interlocked.Read(ref _length);
317 long num3 = Math.Min(num2 - num, buffer.Length);
318 if (num3 <= 0)
319 {
320 return 0;
321 }
322 int num4 = (int)num3;
323 if (num4 < 0)
324 {
325 return 0;
326 }
327 if (_buffer != null)
328 {
329 byte* pointer = null;
330 try
331 {
333 Buffer.Memmove(ref MemoryMarshal.GetReference(buffer), ref (pointer + num)[_offset], (nuint)num4);
334 }
335 finally
336 {
337 if (pointer != null)
338 {
340 }
341 }
342 }
343 else
344 {
345 Buffer.Memmove(ref MemoryMarshal.GetReference(buffer), ref _mem[num], (nuint)num4);
346 }
347 Interlocked.Exchange(ref _position, num + num3);
348 return num4;
349 }
350
352 {
354 if (cancellationToken.IsCancellationRequested)
355 {
357 }
358 try
359 {
360 int num = Read(buffer, offset, count);
361 Task<int> lastReadTask = _lastReadTask;
362 return (lastReadTask != null && lastReadTask.Result == num) ? lastReadTask : (_lastReadTask = Task.FromResult(num));
363 }
364 catch (Exception exception)
365 {
366 return Task.FromException<int>(exception);
367 }
368 }
369
371 {
372 if (cancellationToken.IsCancellationRequested)
373 {
375 }
376 try
377 {
378 ArraySegment<byte> segment;
379 return new ValueTask<int>(MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)buffer, out segment) ? Read(segment.Array, segment.Offset, segment.Count) : Read(buffer.Span));
380 }
381 catch (Exception exception)
382 {
383 return ValueTask.FromException<int>(exception);
384 }
385 }
386
387 public unsafe override int ReadByte()
388 {
391 long num = Interlocked.Read(ref _position);
392 long num2 = Interlocked.Read(ref _length);
393 if (num >= num2)
394 {
395 return -1;
396 }
397 Interlocked.Exchange(ref _position, num + 1);
398 if (_buffer != null)
399 {
400 byte* pointer = null;
401 try
402 {
404 return (pointer + num)[_offset];
405 }
406 finally
407 {
408 if (pointer != null)
409 {
411 }
412 }
413 }
414 return _mem[num];
415 }
416
417 public override long Seek(long offset, SeekOrigin loc)
418 {
420 switch (loc)
421 {
422 case SeekOrigin.Begin:
423 if (offset < 0)
424 {
426 }
428 break;
429 case SeekOrigin.Current:
430 {
431 long num2 = Interlocked.Read(ref _position);
432 if (offset + num2 < 0)
433 {
435 }
437 break;
438 }
439 case SeekOrigin.End:
440 {
441 long num = Interlocked.Read(ref _length);
442 if (num + offset < 0)
443 {
445 }
447 break;
448 }
449 default:
451 }
452 return Interlocked.Read(ref _position);
453 }
454
455 public unsafe override void SetLength(long value)
456 {
457 if (value < 0)
458 {
460 }
461 if (_buffer != null)
462 {
464 }
467 if (value > _capacity)
468 {
470 }
471 long num = Interlocked.Read(ref _position);
472 long num2 = Interlocked.Read(ref _length);
473 if (value > num2)
474 {
475 Buffer.ZeroMemory(_mem + num2, (nuint)(value - num2));
476 }
478 if (num > value)
479 {
481 }
482 }
483
484 public override void Write(byte[] buffer, int offset, int count)
485 {
488 }
489
490 public override void Write(ReadOnlySpan<byte> buffer)
491 {
492 if (GetType() == typeof(UnmanagedMemoryStream))
493 {
495 }
496 else
497 {
498 base.Write(buffer);
499 }
500 }
501
502 internal unsafe void WriteCore(ReadOnlySpan<byte> buffer)
503 {
506 long num = Interlocked.Read(ref _position);
507 long num2 = Interlocked.Read(ref _length);
508 long num3 = num + buffer.Length;
509 if (num3 < 0)
510 {
512 }
513 if (num3 > _capacity)
514 {
516 }
517 if (_buffer == null)
518 {
519 if (num > num2)
520 {
521 Buffer.ZeroMemory(_mem + num2, (nuint)(num - num2));
522 }
523 if (num3 > num2)
524 {
525 Interlocked.Exchange(ref _length, num3);
526 }
527 }
528 if (_buffer != null)
529 {
530 long num4 = _capacity - num;
531 if (num4 < buffer.Length)
532 {
534 }
535 byte* pointer = null;
536 try
537 {
539 Buffer.Memmove(ref (pointer + num)[_offset], ref MemoryMarshal.GetReference(buffer), (nuint)buffer.Length);
540 }
541 finally
542 {
543 if (pointer != null)
544 {
546 }
547 }
548 }
549 else
550 {
551 Buffer.Memmove(ref _mem[num], ref MemoryMarshal.GetReference(buffer), (nuint)buffer.Length);
552 }
553 Interlocked.Exchange(ref _position, num3);
554 }
555
557 {
559 if (cancellationToken.IsCancellationRequested)
560 {
562 }
563 try
564 {
566 return Task.CompletedTask;
567 }
568 catch (Exception exception)
569 {
571 }
572 }
573
575 {
576 if (cancellationToken.IsCancellationRequested)
577 {
579 }
580 try
581 {
582 if (MemoryMarshal.TryGetArray(buffer, out var segment))
583 {
584 Write(segment.Array, segment.Offset, segment.Count);
585 }
586 else
587 {
588 Write(buffer.Span);
589 }
590 return default(ValueTask);
591 }
592 catch (Exception exception)
593 {
595 }
596 }
597
598 public unsafe override void WriteByte(byte value)
599 {
602 long num = Interlocked.Read(ref _position);
603 long num2 = Interlocked.Read(ref _length);
604 long num3 = num + 1;
605 if (num >= num2)
606 {
607 if (num3 < 0)
608 {
610 }
611 if (num3 > _capacity)
612 {
614 }
615 if (_buffer == null)
616 {
617 if (num > num2)
618 {
619 Buffer.ZeroMemory(_mem + num2, (nuint)(num - num2));
620 }
621 Interlocked.Exchange(ref _length, num3);
622 }
623 }
624 if (_buffer != null)
625 {
626 byte* pointer = null;
627 try
628 {
630 (pointer + num)[_offset] = value;
631 }
632 finally
633 {
634 if (pointer != null)
635 {
637 }
638 }
639 }
640 else
641 {
642 _mem[num] = value;
643 }
644 Interlocked.Exchange(ref _position, num3);
645 }
646}
static unsafe void ZeroMemory(byte *dest, nuint len)
Definition Buffer.cs:188
static void Memmove(ref byte dest, ref byte src, nuint len)
Definition Buffer.cs:215
static void ValidateBufferArguments(byte[] buffer, int offset, int count)
Definition Stream.cs:1044
unsafe void WriteCore(ReadOnlySpan< byte > buffer)
override void Write(ReadOnlySpan< byte > buffer)
unsafe override void WriteByte(byte value)
unsafe void Initialize(byte *pointer, long length, long capacity, FileAccess access)
unsafe UnmanagedMemoryStream(byte *pointer, long length)
unsafe void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access)
override ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length)
unsafe int ReadCore(Span< byte > buffer)
override long Seek(long offset, SeekOrigin loc)
override int Read(byte[] buffer, int offset, int count)
UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access)
override int Read(Span< byte > buffer)
override void Write(byte[] buffer, int offset, int count)
unsafe override void SetLength(long value)
override Task< int > ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
override Task FlushAsync(CancellationToken cancellationToken)
unsafe override void Dispose(bool disposing)
unsafe UnmanagedMemoryStream(byte *pointer, long length, long capacity, FileAccess access)
override ValueTask WriteAsync(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
static byte Min(byte val1, byte val2)
Definition Math.cs:912
unsafe void AcquirePointer(ref byte *pointer)
Definition SafeBuffer.cs:58
static string Arg_BufferTooSmall
Definition SR.cs:42
static string ArgumentOutOfRange_UnmanagedMemStreamWrapAround
Definition SR.cs:1118
static string IO_SeekBeforeBegin
Definition SR.cs:140
static string InvalidOperation_CalledTwice
Definition SR.cs:1412
static string ArgumentOutOfRange_Enum
Definition SR.cs:18
static string ArgumentOutOfRange_LengthGreaterThanCapacity
Definition SR.cs:1050
static string Argument_InvalidSafeBufferOffLen
Definition SR.cs:734
static string NotSupported_UmsSafeBuffer
Definition SR.cs:1722
static string IO_StreamTooLong
Definition SR.cs:1586
static string ArgumentOutOfRange_UnmanagedMemStreamLength
Definition SR.cs:1116
static string Argument_InvalidSeekOrigin
Definition SR.cs:736
static string IndexOutOfRange_UMSPosition
Definition SR.cs:1364
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
static string IO_FixedCapacity
Definition SR.cs:1572
Definition SR.cs:7
static int Exchange(ref int location1, int value)
static long Read(ref long location)
static Task FromException(Exception exception)
Definition Task.cs:3341
static Task FromCanceled(CancellationToken cancellationToken)
Definition Task.cs:3363
static Task CompletedTask
Definition Task.cs:1120
static void ThrowNotSupportedException_UnwritableStream()
static void ThrowObjectDisposedException_StreamClosed(string objectName)
static void ThrowNotSupportedException_UnreadableStream()
static ValueTask FromCanceled(CancellationToken cancellationToken)
Definition ValueTask.cs:180
static ValueTask FromException(Exception exception)
Definition ValueTask.cs:190