forked from andrewkirillov/AForge.NET
-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathSystemTools.cs
164 lines (148 loc) · 5.32 KB
/
SystemTools.cs
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
155
156
157
158
159
160
161
162
163
164
// AForge Core Library
// AForge.NET framework
// http://www.aforgenet.com/framework/
//
// Copyright © AForge.NET, 2007-2011
// contacts@aforgenet.com
//
namespace AForge
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Set of systems tools.
/// </summary>
///
/// <remarks><para>The class is a container of different system tools, which are used
/// across the framework. Some of these tools are platform specific, so their
/// implementation is different on different platform, like .NET and Mono.</para>
/// </remarks>
///
public static class SystemTools
{
/// <summary>
/// Copy block of unmanaged memory.
/// </summary>
///
/// <param name="dst">Destination pointer.</param>
/// <param name="src">Source pointer.</param>
/// <param name="count">Memory block's length to copy.</param>
///
/// <returns>Return's value of <paramref name="dst"/> - pointer to destination.</returns>
///
/// <remarks><para>This function is required because of the fact that .NET does
/// not provide any way to copy unmanaged blocks, but provides only methods to
/// copy from unmanaged memory to managed memory and vise versa.</para></remarks>
///
public static IntPtr CopyUnmanagedMemory( IntPtr dst, IntPtr src, int count )
{
unsafe
{
CopyUnmanagedMemory( (byte*) dst.ToPointer( ), (byte*) src.ToPointer( ), count );
}
return dst;
}
/// <summary>
/// Copy block of unmanaged memory.
/// </summary>
///
/// <param name="dst">Destination pointer.</param>
/// <param name="src">Source pointer.</param>
/// <param name="count">Memory block's length to copy.</param>
///
/// <returns>Return's value of <paramref name="dst"/> - pointer to destination.</returns>
///
/// <remarks><para>This function is required because of the fact that .NET does
/// not provide any way to copy unmanaged blocks, but provides only methods to
/// copy from unmanaged memory to managed memory and vise versa.</para></remarks>
///
public static unsafe byte* CopyUnmanagedMemory( byte* dst, byte* src, int count )
{
#if !MONO
return memcpy( dst, src, count );
#else
int countUint = count >> 2;
int countByte = count & 3;
uint* dstUint = (uint*) dst;
uint* srcUint = (uint*) src;
while ( countUint-- != 0 )
{
*dstUint++ = *srcUint++;
}
byte* dstByte = (byte*) dstUint;
byte* srcByte = (byte*) srcUint;
while ( countByte-- != 0 )
{
*dstByte++ = *srcByte++;
}
return dst;
#endif
}
/// <summary>
/// Fill memory region with specified value.
/// </summary>
///
/// <param name="dst">Destination pointer.</param>
/// <param name="filler">Filler byte's value.</param>
/// <param name="count">Memory block's length to fill.</param>
///
/// <returns>Return's value of <paramref name="dst"/> - pointer to destination.</returns>
///
public static IntPtr SetUnmanagedMemory( IntPtr dst, int filler, int count )
{
unsafe
{
SetUnmanagedMemory( (byte*) dst.ToPointer( ), filler, count );
}
return dst;
}
/// <summary>
/// Fill memory region with specified value.
/// </summary>
///
/// <param name="dst">Destination pointer.</param>
/// <param name="filler">Filler byte's value.</param>
/// <param name="count">Memory block's length to fill.</param>
///
/// <returns>Return's value of <paramref name="dst"/> - pointer to destination.</returns>
///
public static unsafe byte* SetUnmanagedMemory( byte* dst, int filler, int count )
{
#if !MONO
return memset( dst, filler, count );
#else
int countUint = count >> 2;
int countByte = count & 3;
byte fillerByte = (byte) filler;
uint fiilerUint = (uint) filler | ( (uint) filler << 8 ) |
( (uint) filler << 16 );// |
//( (uint) filler << 24 );
uint* dstUint = (uint*) dst;
while ( countUint-- != 0 )
{
*dstUint++ = fiilerUint;
}
byte* dstByte = (byte*) dstUint;
while ( countByte-- != 0 )
{
*dstByte++ = fillerByte;
}
return dst;
#endif
}
#if !MONO
// Win32 memory copy function
[DllImport( "ntdll.dll", CallingConvention = CallingConvention.Cdecl )]
private static unsafe extern byte* memcpy(
byte* dst,
byte* src,
int count );
// Win32 memory set function
[DllImport( "ntdll.dll", CallingConvention = CallingConvention.Cdecl )]
private static unsafe extern byte* memset(
byte* dst,
int filler,
int count );
#endif
}
}