forked from pythonnet/pythonnet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRawMemUtils.cs
More file actions
140 lines (118 loc) · 3.33 KB
/
RawMemUtils.cs
File metadata and controls
140 lines (118 loc) · 3.33 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
namespace Python.Runtime
{
using System;
public static class RawMemUtils
{
public static unsafe bool CopyMemBlocks(IntPtr src, IntPtr dest, int size)
{
// XOR with 64 bit step
var p64_1 = (ulong*)src;
var p64_2 = (ulong*)dest;
int c64count = size >> 3;
int i = 0;
while (i <c64count)
{
p64_2[i] = p64_1[i];
i++;
}
var pn1 = (byte*)(src + (size & ~7));
var pn2 = (byte*)(dest + (size & ~7));
if ((size & 4) != 0)
{
*(uint*)pn2 = *(uint*)pn1;
pn1 += 4;
pn2 += 4;
}
if ((size & 2) != 0)
{
*(ushort*)pn2 = *(ushort*)pn1;
pn1 += 2;
pn2 += 2;
}
if ((size & 1) != 0)
{
*pn2 = *pn1;
}
return true;
}
public static unsafe bool CompareMemBlocks(IntPtr ptr1, IntPtr ptr2, int size)
{
// XOR with 64 bit step
var p64_1 = (ulong*)ptr1;
var p64_2 = (ulong*)ptr2;
var pn1 = (byte*)(ptr1 + (size & ~7));
var pn2 = (byte*)(ptr2 + (size & ~7));
while (p64_1 < pn1)
{
if (*p64_1 != *p64_2)
{
return false;
}
p64_1++;
p64_2++;
}
if ((size & 4) != 0)
{
if (*(uint*)pn1 != *(uint*)pn2)
{
return false;
}
pn1 += 4;
pn2 += 4;
}
if ((size & 2) != 0)
{
if (*(ushort*)pn1 != *(ushort*)pn2)
{
return false;
}
pn1 += 2;
pn2 += 2;
}
if ((size & 1) != 0)
{
if (*pn1 != *pn2)
{
return false;
}
}
return true;
}
/// <summary>
/// Calculating simple 32 bit xor hash for raw memory.
/// </summary>
/// <param name="mem">Memory pointer.</param>
/// <param name="size">Size to hash.</param>
/// <returns>32 bit hash the in signed int format.</returns>
public static unsafe int FastXorHash(IntPtr mem, int size)
{
unchecked
{
// XOR with 64 bit step
ulong r64 = 0;
var p64 = (ulong*)mem;
var pn = (byte*)(mem + (size & ~7));
while (p64 < pn)
{
r64 ^= *p64++;
}
uint r32 = (uint)r64 ^ (uint)(r64 >> 32);
if ((size & 4) != 0)
{
r32 ^= *(uint*)pn;
pn += 4;
}
if ((size & 2) != 0)
{
r32 ^= *(ushort*)pn;
pn += 2;
}
if ((size & 1) != 0)
{
r32 ^= *pn;
}
return (int)r32;
}
}
}
}