forked from chronoxor/NetCoreServer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBuffer.cs
More file actions
154 lines (137 loc) · 4.68 KB
/
Copy pathBuffer.cs
File metadata and controls
154 lines (137 loc) · 4.68 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Diagnostics;
using System.Text;
namespace NetCoreServer
{
/// <summary>
/// Dynamic byte buffer
/// </summary>
public class Buffer
{
private byte[] _data;
private long _size;
private long _offset;
/// <summary>
/// Is the buffer empty?
/// </summary>
public bool IsEmpty => (_data == null) || (_size == 0);
/// <summary>
/// Bytes memory buffer
/// </summary>
public byte[] Data => _data;
/// <summary>
/// Bytes memory buffer capacity
/// </summary>
public long Capacity => _data.Length;
/// <summary>
/// Bytes memory buffer size
/// </summary>
public long Size => _size;
/// <summary>
/// Bytes memory buffer offset
/// </summary>
public long Offset => _offset;
/// <summary>
/// Initialize a new expandable buffer with zero capacity
/// </summary>
public Buffer() { _data = new byte[0]; _size = 0; _offset = 0; }
/// <summary>
/// Initialize a new expandable buffer with the given capacity
/// </summary>
public Buffer(long capacity) { _data = new byte[capacity]; _size = 0; _offset = 0; }
#region Memory buffer methods
// Clear the current buffer and its offset
public void Clear()
{
_size = 0;
_offset = 0;
}
/// <summary>
/// Remove the buffer of the given offset and size
/// </summary>
public void Remove(long offset, long size)
{
Debug.Assert(((offset + size) <= Size), "Invalid offset & size!");
if ((offset + size) > Size)
throw new ArgumentException("Invalid offset & size!", nameof(offset));
Array.Copy(_data, offset + size, _data, offset, _size - size - offset);
_size -= size;
if (_offset >= (offset + size))
_offset -= size;
else if (_offset >= offset)
{
_offset -= _offset - offset;
if (_offset > Size)
_offset = Size;
}
}
/// <summary>
/// Reserve the buffer of the given capacity
/// </summary>
public void Reserve(long capacity)
{
Debug.Assert((capacity >= 0), "Invalid reserve capacity!");
if (capacity < 0)
throw new ArgumentException("Invalid reserve capacity!", nameof(capacity));
if (capacity > Capacity)
{
byte[] data = new byte[Math.Max(capacity, 2 * Capacity)];
Array.Copy(_data, 0, data, 0, _size);
_data = data;
}
}
// Resize the current buffer
public void Resize(long size)
{
Reserve(size);
_size = size;
if (_offset > _size)
_offset = _size;
}
// Shift the current buffer offset
public void Shift(long offset) { _offset += offset; }
// Unshift the current buffer offset
public void Unshift(long offset) { _offset -= offset; }
#endregion
#region Buffer I/O methods
/// <summary>
/// Append the given buffer
/// </summary>
/// <param name="buffer">Buffer to append</param>
/// <returns>Count of append bytes</returns>
public long Append(byte[] buffer)
{
Reserve(_size + buffer.Length);
Array.Copy(buffer, 0, _data, _size, buffer.Length);
_size += buffer.Length;
return buffer.Length;
}
/// <summary>
/// Append the given buffer fragment
/// </summary>
/// <param name="buffer">Buffer to append</param>
/// <param name="offset">Buffer offset</param>
/// <param name="size">Buffer size</param>
/// <returns>Count of append bytes</returns>
public long Append(byte[] buffer, long offset, long size)
{
Reserve(_size + size);
Array.Copy(buffer, offset, _data, _size, size);
_size += size;
return size;
}
/// <summary>
/// Append the given text in UTF-8 encoding
/// </summary>
/// <param name="text">Text to append</param>
/// <returns>Count of append bytes</returns>
public long Append(string text)
{
Reserve(_size + Encoding.UTF8.GetMaxByteCount(text.Length));
long result = Encoding.UTF8.GetBytes(text, 0, text.Length, _data, (int)_size);
_size += result;
return result;
}
#endregion
}
}