1 #Region "Microsoft.VisualBasic::5119d8d8de1b620492f979ed09180d9e, Microsoft.VisualBasic.Core\Extensions\Reflection\Marshal\IntPtr(Of T).vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Delegate Sub
35     
36     
37     '     Delegate Sub
38     
39     
40     '     Class IntPtr
41     
42     '         Properties: Scan0
43     
44     '         Constructor: (+2 OverloadsSub New
45     
46     '         FunctionToString
47     
48     '         Sub: __unsafeWrite, (+2 Overloads) Dispose, (+2 Overloads) Write
49     
50     '         Operators: -, +
51     
52     
53     
54     
55     
56     ' /********************************************************************************/
57
58 #End Region
59
60 Imports System.Runtime.CompilerServices
61
62 Namespace Emit.Marshal
63
64     ''' <summary>
65     ''' 读取原始的内存数据的操作
66     ''' </summary>
67     ''' <typeparam name="T"></typeparam>
68     ''' <param name="source"></param>
69     ''' <param name="destination"></param>
70     ''' <param name="startIndex"></param>
71     ''' <param name="length"></param>
72     Public Delegate Sub UnsafeCopys(Of T)(source As System.IntPtr, destination As T(), startIndex As Integer, length As Integer)
73     ''' <summary>
74     ''' 向原始的内存数据执行写入操作的函数指针
75     ''' </summary>
76     ''' <typeparam name="T"></typeparam>
77     ''' <param name="destination"></param>
78     ''' <param name="startIndex"></param>
79     ''' <param name="source"></param>
80     ''' <param name="length"></param>
81     Public Delegate Sub UnsafeWrite(Of T)(destination As T(), startIndex As Integer, source As System.IntPtr, length As Integer)
82
83     ''' <summary>
84     ''' Unmanaged Memory pointer in VisualBasic language.(内存指针)
85     ''' </summary>
86     ''' <typeparam name="T"></typeparam>
87     ''' <remarks>只不过这个对象是封装了写内存操作的</remarks>
88     Public Class IntPtr(Of T) : Inherits Pointer(Of T)
89         Implements IDisposable
90
91         ''' <summary>
92         ''' The position in the memory region of the first byte for read.(第一个位置)
93         ''' </summary>
94         ''' <returns></returns>
95         Public ReadOnly Property Scan0 As System.IntPtr
96
97         ''' <summary>
98         ''' ```vbnet
99         ''' Public Delegate Sub UnsafeWrite(Of T)(destination As T(), startIndex As Integer, source As System.IntPtr, length As Integer)
100         ''' ```
101         ''' </summary>
102         ReadOnly __writeMemory As UnsafeWrite(Of T)
103
104         ''' <summary>
105         ''' 
106         ''' </summary>
107         ''' <param name="p"></param>
108         ''' <param name="chunkSize"></param>
109         ''' <param name="unsafeCopys">
110         ''' ```vbnet
111         ''' Public Sub UnsafeCopys(Of <typeparamref name="T"/>)(source As <see cref="System.IntPtr"/>, destination As <typeparamref name="T"/>(), startIndex As <see cref="Integer"/>, length As <see cref="Integer"/>)
112         ''' ```
113         ''' </param>
114         ''' <param name="unsafeWrite">
115         ''' ```vbnet
116         ''' Public Sub UnsafeWrite(Of <typeparamref name="T"/>)(destination As <typeparamref name="T"/>(), startIndex As <see cref="Integer"/>, source As <see cref="System.IntPtr"/>, length As <see cref="Integer"/>)
117         ''' ```
118         ''' </param>
119         Sub New(p As System.IntPtr, chunkSize As Integer, unsafeCopys As UnsafeCopys(Of T), unsafeWrite As UnsafeWrite(Of T))
120             __writeMemory = unsafeWrite
121             Scan0 = p
122             buffer = New T(chunkSize - 1) {}
123             Call unsafeCopys(Scan0, buffer, 0, buffer.Length)
124         End Sub
125
126         ''' <summary>
127         ''' 方便进行数组操作的
128         ''' </summary>
129         ''' <param name="raw"></param>
130         ''' <param name="p"></param>
131         Sub New(ByRef raw As T(), Optional p As System.IntPtr = Nothing)
132             Call MyBase.New(raw)
133             Scan0 = p
134         End Sub
135
136         <MethodImpl(MethodImplOptions.AggressiveInlining)>
137         Private Sub __unsafeWrite(p As System.IntPtr)
138             Call __writeMemory(buffer, 0, p, buffer.Length)
139         End Sub
140
141         ''' <summary>
142         ''' Unsafe write memory
143         ''' </summary>
144         ''' 
145         <MethodImpl(MethodImplOptions.AggressiveInlining)>
146         Public Sub Write()
147             Call __unsafeWrite(Scan0)
148         End Sub
149
150         ''' <summary>
151         ''' Please be carefull by using this method, if the memory region size of <see cref="Scan0"/> 
152         ''' in this memory pointer is larger than <paramref name="des"/>, this method will caused 
153         ''' exception.
154         ''' </summary>
155         ''' <param name="des"></param>
156         <MethodImpl(MethodImplOptions.AggressiveInlining)>
157         Public Sub Write(des As System.IntPtr)
158             Call __unsafeWrite(des)
159         End Sub
160
161         Public Overrides Function ToString() As String
162             Return $"* {GetType(T).Name} + {__index} --> {Current}  // {Scan0.ToString}"
163         End Function
164
165         ''' <summary>
166         ''' Move forward the current position of this memory pointer <paramref name="ptr"/> by a specific step <paramref name="d"/>
167         ''' </summary>
168         ''' <param name="ptr"></param>
169         ''' <param name="d"></param>
170         ''' <returns></returns>
171         Public Overloads Shared Operator +(ptr As IntPtr(Of T), d As IntegerAs IntPtr(Of T)
172             ptr.__index += d
173             Return ptr
174         End Operator
175
176         ''' <summary>
177         ''' Move backward the current position of this memory pointer <paramref name="ptr"/> by a specific step <paramref name="d"/>
178         ''' </summary>
179         ''' <param name="ptr"></param>
180         ''' <param name="d"></param>
181         ''' <returns></returns>
182         Public Overloads Shared Operator -(ptr As IntPtr(Of T), d As IntegerAs IntPtr(Of T)
183             ptr.__index -= d
184             Return ptr
185         End Operator
186
187 #Region "IDisposable Support"
188         Private disposedValue As Boolean To detect redundant calls
189
190         ' IDisposable
191         Protected Overridable Sub Dispose(disposing As Boolean)
192             If Not Me.disposedValue Then
193                 If disposing Then
194                     ' TODO: dispose managed state (managed objects).
195                     Call Write()
196                 End If
197
198                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
199                 ' TODO: set large fields to null.
200             End If
201             Me.disposedValue = True
202         End Sub
203
204         ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
205         'Protected Overrides Sub Finalize()
206         '    ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
207         '    Dispose(False)
208         '    MyBase.Finalize()
209         'End Sub
210
211         ' This code added by Visual Basic to correctly implement the disposable pattern.
212         Public Sub Dispose() Implements IDisposable.Dispose
213             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
214             Dispose(True)
215             ' TODO: uncomment the following line if Finalize() is overridden above.
216             ' GC.SuppressFinalize(Me)
217         End Sub
218 #End Region
219     End Class
220 End Namespace