Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
MultiMemory.cs
Go to the documentation of this file.
2
3namespace System.Net;
4
5[DefaultMember("Item")]
6internal readonly struct MultiMemory
7{
8 private readonly byte[][] _blocks;
9
10 private readonly uint _start;
11
12 private readonly uint _length;
13
14 public int Length => (int)_length;
15
16 public int BlockCount => (int)(GetBlockIndex(_start + _length + 16383) - GetBlockIndex(_start));
17
18 internal MultiMemory(byte[][] blocks, uint start, uint length)
19 {
20 if (length == 0)
21 {
22 _blocks = null;
23 _start = 0u;
24 _length = 0u;
25 }
26 else
27 {
28 _blocks = blocks;
29 _start = start;
31 }
32 }
33
34 private static uint GetBlockIndex(uint offset)
35 {
36 return offset / 16384;
37 }
38
39 private static uint GetOffsetInBlock(uint offset)
40 {
41 return offset % 16384;
42 }
43
44 public Memory<byte> GetBlock(int blockIndex)
45 {
46 if ((uint)blockIndex >= BlockCount)
47 {
48 throw new IndexOutOfRangeException();
49 }
50 uint num = ((blockIndex == 0) ? GetOffsetInBlock(_start) : 0u);
51 uint num2 = ((blockIndex == BlockCount - 1) ? (GetOffsetInBlock(_start + _length - 1) + 1) : 16384u);
52 return new Memory<byte>(_blocks[GetBlockIndex(_start) + blockIndex], (int)num, (int)(num2 - num));
53 }
54
55 public MultiMemory Slice(int start, int length)
56 {
57 if ((uint)start > _length || (uint)length > (uint)((int)_length - start))
58 {
59 throw new IndexOutOfRangeException();
60 }
61 return new MultiMemory(_blocks, _start + (uint)start, (uint)length);
62 }
63
65 {
66 if (destination.Length < _length)
67 {
68 throw new ArgumentOutOfRangeException("destination");
69 }
70 int blockCount = BlockCount;
71 for (int i = 0; i < blockCount; i++)
72 {
73 Memory<byte> block = GetBlock(i);
74 block.Span.CopyTo(destination);
75 destination = destination.Slice(block.Length);
76 }
77 }
78
80 {
81 if (_length < source.Length)
82 {
83 throw new ArgumentOutOfRangeException("source");
84 }
85 int blockCount = BlockCount;
86 for (int i = 0; i < blockCount; i++)
87 {
88 Memory<byte> block = GetBlock(i);
89 if (source.Length <= block.Length)
90 {
91 source.CopyTo(block.Span);
92 break;
93 }
94 source.Slice(0, block.Length).CopyTo(block.Span);
95 source = source.Slice(block.Length);
96 }
97 }
98}
unsafe Span< T > Span
Definition Memory.cs:28
MultiMemory Slice(int start, int length)
readonly byte[][] _blocks
Definition MultiMemory.cs:8
static uint GetOffsetInBlock(uint offset)
readonly uint _start
void CopyFrom(ReadOnlySpan< byte > source)
readonly uint _length
static uint GetBlockIndex(uint offset)
void CopyTo(Span< byte > destination)
Memory< byte > GetBlock(int blockIndex)
MultiMemory(byte[][] blocks, uint start, uint length)