-
Notifications
You must be signed in to change notification settings - Fork 351
Expand file tree
/
Copy pathUtil.cs
More file actions
124 lines (104 loc) · 3.98 KB
/
Util.cs
File metadata and controls
124 lines (104 loc) · 3.98 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
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace ImGuiNET
{
internal static unsafe class Util
{
internal const int StackAllocationSizeLimit = 2048;
public static string StringFromPtr(byte* ptr)
{
int characters = 0;
while (ptr[characters] != 0)
{
characters++;
}
return Encoding.UTF8.GetString(ptr, characters);
}
internal static bool AreStringsEqual(byte* a, int aLength, byte* b)
{
for (int i = 0; i < aLength; i++)
{
if (a[i] != b[i]) { return false; }
}
if (b[aLength] != 0) { return false; }
return true;
}
internal static byte* Allocate(int byteCount) => (byte*)Marshal.AllocHGlobal(byteCount);
internal static void Free(byte* ptr) => Marshal.FreeHGlobal((IntPtr)ptr);
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
internal static int CalcSizeInUtf8(ReadOnlySpan<char> s, int start, int length)
#else
internal static int CalcSizeInUtf8(string s, int start, int length)
#endif
{
if (start < 0 || length < 0 || start + length > s.Length)
{
throw new ArgumentOutOfRangeException();
}
if(s.Length == 0) return 0;
fixed (char* utf16Ptr = s)
{
return Encoding.UTF8.GetByteCount(utf16Ptr + start, length);
}
}
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
internal static int GetUtf8(ReadOnlySpan<char> s, byte* utf8Bytes, int utf8ByteCount)
{
if (s.IsEmpty)
{
return 0;
}
fixed (char* utf16Ptr = s)
{
return Encoding.UTF8.GetBytes(utf16Ptr, s.Length, utf8Bytes, utf8ByteCount);
}
}
#endif
internal static int GetUtf8(string s, byte* utf8Bytes, int utf8ByteCount)
{
fixed (char* utf16Ptr = s)
{
return Encoding.UTF8.GetBytes(utf16Ptr, s.Length, utf8Bytes, utf8ByteCount);
}
}
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
internal static int GetUtf8(ReadOnlySpan<char> s, int start, int length, byte* utf8Bytes, int utf8ByteCount)
#else
internal static int GetUtf8(string s, int start, int length, byte* utf8Bytes, int utf8ByteCount)
#endif
{
if (start < 0 || length < 0 || start + length > s.Length)
{
throw new ArgumentOutOfRangeException();
}
if (s.Length == 0) return 0;
fixed (char* utf16Ptr = s)
{
return Encoding.UTF8.GetBytes(utf16Ptr + start, length, utf8Bytes, utf8ByteCount);
}
}
internal static byte SetBits(byte oldValue, int offset, int bitCount, byte newBits)
{
var mask = (byte)((1 << bitCount) - 1 << offset);
return (byte)((oldValue & ~mask) | (newBits << offset & mask));
}
internal static ushort SetBits(ushort oldValue, int offset, int bitCount, ushort newBits)
{
var mask = (ushort)((1 << bitCount) - 1 << offset);
return (ushort)((oldValue & ~mask) | (newBits << offset & mask));
}
internal static uint SetBits(uint oldValue, int offset, int bitCount, uint newBits)
{
var mask = (uint)((1 << bitCount) - 1 << offset);
return (uint)((oldValue & ~mask) | (newBits << offset & mask));
}
internal static ulong SetBits(ulong oldValue, int offset, int bitCount, ulong newBits)
{
var mask = (ulong)((1 << bitCount) - 1 << offset);
return (ulong)((oldValue & ~mask) | (newBits << offset & mask));
}
internal static ulong GetBits(ulong value, int offset, int bitCount) =>
(value >> offset) & (1UL << bitCount) - 1;
}
}