Skip to content

Commit a417d5c

Browse files
committed
1 parent 6d79468 commit a417d5c

31 files changed

+3487
-41
lines changed
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace PvPGameServer
6+
{
7+
public class FastBinaryRead
8+
{
9+
public static bool Boolean(byte[] bytes, int offset)
10+
{
11+
return (bytes[offset] == 0) ? false : true;
12+
}
13+
public static bool Boolean(ReadOnlySpan<byte> bytes, int offset)
14+
{
15+
return (bytes[offset] == 0) ? false : true;
16+
}
17+
18+
public static byte Byte(byte[] bytes, int offset)
19+
{
20+
return bytes[offset];
21+
}
22+
public static byte Byte(ReadOnlySpan<byte> bytes, int offset)
23+
{
24+
return bytes[offset];
25+
}
26+
27+
public static byte[] Bytes(byte[] bytes, int offset, int count)
28+
{
29+
var dest = new byte[count];
30+
Buffer.BlockCopy(bytes, offset, dest, 0, count);
31+
return dest;
32+
}
33+
34+
public static sbyte SByte(byte[] bytes, int offset)
35+
{
36+
return (sbyte)bytes[offset];
37+
}
38+
public static sbyte SByte(ReadOnlySpan<byte> bytes, int offset)
39+
{
40+
return (sbyte)bytes[offset];
41+
}
42+
43+
public static unsafe float Single(byte[] bytes, int offset)
44+
{
45+
if (offset % 4 == 0)
46+
{
47+
fixed (byte* ptr = bytes)
48+
{
49+
return *(float*)(ptr + offset);
50+
}
51+
}
52+
else
53+
{
54+
uint num = (uint)((int)bytes[offset] | (int)bytes[offset + 1] << 8 | (int)bytes[offset + 2] << 16 | (int)bytes[offset + 3] << 24);
55+
return *(float*)(&num);
56+
}
57+
}
58+
public static unsafe float Single(ReadOnlySpan<byte> bytes, int offset)
59+
{
60+
if (offset % 4 == 0)
61+
{
62+
fixed (byte* ptr = bytes)
63+
{
64+
return *(float*)(ptr + offset);
65+
}
66+
}
67+
else
68+
{
69+
uint num = (uint)((int)bytes[offset] | (int)bytes[offset + 1] << 8 | (int)bytes[offset + 2] << 16 | (int)bytes[offset + 3] << 24);
70+
return *(float*)(&num);
71+
}
72+
}
73+
74+
public static unsafe double Double(byte[] bytes, int offset)
75+
{
76+
if (offset % 8 == 0)
77+
{
78+
fixed (byte* ptr = bytes)
79+
{
80+
return *(double*)(ptr + offset);
81+
}
82+
}
83+
else
84+
{
85+
uint num = (uint)((int)bytes[offset] | (int)bytes[offset + 1] << 8 | (int)bytes[offset + 2] << 16 | (int)bytes[offset + 3] << 24);
86+
ulong num2 = (ulong)((int)bytes[offset + 4] | (int)bytes[offset + 5] << 8 | (int)bytes[offset + 6] << 16 | (int)bytes[offset + 7] << 24) << 32 | (ulong)num;
87+
return *(double*)(&num2);
88+
}
89+
}
90+
public static unsafe double Double(ReadOnlySpan<byte> bytes, int offset)
91+
{
92+
if (offset % 8 == 0)
93+
{
94+
fixed (byte* ptr = bytes)
95+
{
96+
return *(double*)(ptr + offset);
97+
}
98+
}
99+
else
100+
{
101+
uint num = (uint)((int)bytes[offset] | (int)bytes[offset + 1] << 8 | (int)bytes[offset + 2] << 16 | (int)bytes[offset + 3] << 24);
102+
ulong num2 = (ulong)((int)bytes[offset + 4] | (int)bytes[offset + 5] << 8 | (int)bytes[offset + 6] << 16 | (int)bytes[offset + 7] << 24) << 32 | (ulong)num;
103+
return *(double*)(&num2);
104+
}
105+
}
106+
107+
public static unsafe short Int16(byte[] bytes, int offset)
108+
{
109+
fixed (byte* ptr = bytes)
110+
{
111+
return *(short*)(ptr + offset);
112+
}
113+
}
114+
public static unsafe short Int16(ReadOnlySpan<byte> bytes, int offset)
115+
{
116+
fixed (byte* ptr = bytes)
117+
{
118+
return *(short*)(ptr + offset);
119+
}
120+
}
121+
122+
public static unsafe int Int32(byte[] bytes, int offset)
123+
{
124+
fixed (byte* ptr = bytes)
125+
{
126+
return *(int*)(ptr + offset);
127+
}
128+
}
129+
public static unsafe int Int32(ReadOnlySpan<byte> bytes, int offset)
130+
{
131+
fixed (byte* ptr = bytes)
132+
{
133+
return *(int*)(ptr + offset);
134+
}
135+
}
136+
137+
public static unsafe long Int64(byte[] bytes, int offset)
138+
{
139+
fixed (byte* ptr = bytes)
140+
{
141+
return *(long*)(ptr + offset);
142+
}
143+
}
144+
public static unsafe long Int64(ReadOnlySpan<byte> bytes, int offset)
145+
{
146+
fixed (byte* ptr = bytes)
147+
{
148+
return *(long*)(ptr + offset);
149+
}
150+
}
151+
152+
public static unsafe ushort UInt16(byte[] bytes, int offset)
153+
{
154+
fixed (byte* ptr = bytes)
155+
{
156+
return *(ushort*)(ptr + offset);
157+
}
158+
}
159+
public static unsafe ushort UInt16(ReadOnlySpan<byte> bytes, int offset)
160+
{
161+
fixed (byte* ptr = bytes)
162+
{
163+
return *(ushort*)(ptr + offset);
164+
}
165+
}
166+
167+
public static unsafe uint UInt32(byte[] bytes, int offset)
168+
{
169+
fixed (byte* ptr = bytes)
170+
{
171+
return *(uint*)(ptr + offset);
172+
}
173+
}
174+
public static unsafe uint UInt32(ReadOnlySpan<byte> bytes, int offset)
175+
{
176+
fixed (byte* ptr = bytes)
177+
{
178+
return *(uint*)(ptr + offset);
179+
}
180+
}
181+
182+
public static unsafe ulong UInt64(byte[] bytes, int offset)
183+
{
184+
fixed (byte* ptr = bytes)
185+
{
186+
return *(ulong*)(ptr + offset);
187+
}
188+
}
189+
public static unsafe ulong UInt64(ReadOnlySpan<byte> bytes, int offset)
190+
{
191+
fixed (byte* ptr = bytes)
192+
{
193+
return *(ulong*)(ptr + offset);
194+
}
195+
}
196+
197+
public static char Char(byte[] bytes, int offset)
198+
{
199+
return (char)FastBinaryRead.UInt16(bytes, offset);
200+
}
201+
public static char Char(ReadOnlySpan<byte> bytes, int offset)
202+
{
203+
return (char)FastBinaryRead.UInt16(bytes, offset);
204+
}
205+
206+
public static string String(byte[] bytes, int offset, int count)
207+
{
208+
return StringEncoding.UTF8.GetString(bytes, offset, count);
209+
}
210+
211+
public static unsafe decimal Decimal(byte[] bytes, int offset)
212+
{
213+
fixed (byte* ptr = bytes)
214+
{
215+
return *(Decimal*)(ptr + offset);
216+
}
217+
}
218+
public static unsafe decimal Decimal(ReadOnlySpan<byte> bytes, int offset)
219+
{
220+
fixed (byte* ptr = bytes)
221+
{
222+
return *(Decimal*)(ptr + offset);
223+
}
224+
}
225+
226+
public static unsafe Guid Guid(byte[] bytes, int offset)
227+
{
228+
fixed (byte* ptr = bytes)
229+
{
230+
return *(Guid*)(ptr + offset);
231+
}
232+
}
233+
public static unsafe Guid Guid(ReadOnlySpan<byte> bytes, int offset)
234+
{
235+
fixed (byte* ptr = bytes)
236+
{
237+
return *(Guid*)(ptr + offset);
238+
}
239+
}
240+
241+
#region Timestamp/Duration
242+
public static unsafe TimeSpan TimeSpan(ref byte[] bytes, int offset)
243+
{
244+
checked
245+
{
246+
fixed (byte* ptr = bytes)
247+
{
248+
var seconds = *(long*)(ptr + offset);
249+
var nanos = *(int*)(ptr + offset + 8);
250+
251+
if (!Duration.IsNormalized(seconds, nanos))
252+
{
253+
throw new InvalidOperationException("Duration was not a valid normalized duration");
254+
}
255+
long ticks = seconds * System.TimeSpan.TicksPerSecond + nanos / Duration.NanosecondsPerTick;
256+
return System.TimeSpan.FromTicks(ticks);
257+
}
258+
}
259+
}
260+
261+
public static unsafe DateTime DateTime(ref byte[] bytes, int offset)
262+
{
263+
fixed (byte* ptr = bytes)
264+
{
265+
var seconds = *(long*)(ptr + offset);
266+
var nanos = *(int*)(ptr + offset + 8);
267+
268+
if (!Timestamp.IsNormalized(seconds, nanos))
269+
{
270+
throw new InvalidOperationException(string.Format(@"Timestamp contains invalid values: Seconds={0}; Nanos={1}", seconds, nanos));
271+
}
272+
return Timestamp.UnixEpoch.AddSeconds(seconds).AddTicks(nanos / Duration.NanosecondsPerTick);
273+
}
274+
}
275+
276+
internal static class Timestamp
277+
{
278+
internal static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
279+
internal const long BclSecondsAtUnixEpoch = 62135596800;
280+
internal const long UnixSecondsAtBclMaxValue = 253402300799;
281+
internal const long UnixSecondsAtBclMinValue = -BclSecondsAtUnixEpoch;
282+
internal const int MaxNanos = Duration.NanosecondsPerSecond - 1;
283+
284+
internal static bool IsNormalized(long seconds, int nanoseconds)
285+
{
286+
return nanoseconds >= 0 &&
287+
nanoseconds <= MaxNanos &&
288+
seconds >= UnixSecondsAtBclMinValue &&
289+
seconds <= UnixSecondsAtBclMaxValue;
290+
}
291+
}
292+
293+
internal static class Duration
294+
{
295+
public const int NanosecondsPerSecond = 1000000000;
296+
public const int NanosecondsPerTick = 100;
297+
public const long MaxSeconds = 315576000000L;
298+
public const long MinSeconds = -315576000000L;
299+
internal const int MaxNanoseconds = NanosecondsPerSecond - 1;
300+
internal const int MinNanoseconds = -NanosecondsPerSecond + 1;
301+
302+
internal static bool IsNormalized(long seconds, int nanoseconds)
303+
{
304+
// Simple boundaries
305+
if (seconds < MinSeconds || seconds > MaxSeconds ||
306+
nanoseconds < MinNanoseconds || nanoseconds > MaxNanoseconds)
307+
{
308+
return false;
309+
}
310+
// We only have a problem is one is strictly negative and the other is
311+
// strictly positive.
312+
return Math.Sign(seconds) * Math.Sign(nanoseconds) != -1;
313+
}
314+
}
315+
#endregion
316+
}
317+
318+
internal static class StringEncoding
319+
{
320+
public static Encoding UTF8 = new UTF8Encoding(false);
321+
}
322+
}

0 commit comments

Comments
 (0)