1010 TYPE_CHECKING ,
1111 Union ,
1212 Tuple ,
13+ Iterator
1314)
1415from .exceptions import InvalidSizeError
1516from _pointers import add_ref , remove_ref
@@ -69,7 +70,7 @@ def _as_parameter_(self):
6970 return self ._address
7071
7172
72- class _BaseCPointer (Pointer [Any ]):
73+ class _BaseCPointer (Pointer [Any ], Generic [ T ] ):
7374 def __init__ (self , address : int , size : int ):
7475 super ().__init__ (address , int , True )
7576 self ._size = size
@@ -79,6 +80,15 @@ def size(self):
7980 """Size of the pointer."""
8081 return self ._size
8182
83+ # i need to repeat these for type safety
84+ def __iter__ (self ) -> Iterator [T ]:
85+ """Dereference the pointer."""
86+ return iter ({self .dereference ()})
87+
88+ def __invert__ (self ) -> T :
89+ """Dereference the pointer."""
90+ return self .dereference ()
91+
8292 def _make_stream_and_ptr (
8393 self ,
8494 data : "_BaseCPointer" ,
@@ -180,7 +190,7 @@ def __lshift__(self, data: Any):
180190 return self
181191
182192
183- class VoidPointer (_BaseCPointer ):
193+ class VoidPointer (_BaseCPointer [ int ] ):
184194 """Class representing a void pointer to a C object."""
185195
186196 @property
@@ -201,28 +211,34 @@ def __rich__(self):
201211 )
202212
203213
204- class TypedCPointer (_BaseCPointer , Generic [T ]):
214+ class TypedCPointer (_BaseCPointer [ T ] , Generic [T ]):
205215 """Class representing a pointer with a known type."""
206216
207217 def __init__ (
208218 self ,
209219 address : int ,
210220 data_type : Type [T ],
211221 size : int ,
222+ alternate_method : bool = True
212223 ):
224+ self ._alt = alternate_method
213225 super ().__init__ (address , size )
214226 self ._type = data_type
215227
216228 @property
217- def _as_parameter_ (self ):
229+ def _as_parameter_ (self ) -> "ctypes.pointer[ctypes._CData]" :
218230 ctype = self .get_mapped (self .type )
219231 deref = ctype .from_address (self .address )
220232 return ctypes .pointer (deref )
221233
222- def dereference (self ) -> Optional [ T ] :
234+ def dereference (self ) -> T :
223235 """Dereference the pointer."""
224236 ctype = self .get_mapped (self .type )
225- ptr = ctype .from_address (self .address )
237+ ptr = (
238+ ctype .from_address (self .address )
239+ if not self ._alt else
240+ ctype (self .address )
241+ )
226242 return ptr .value # type: ignore
227243
228244 def move (self , data : Pointer , unsafe : bool = False ) -> None :
@@ -239,8 +255,11 @@ def __rich__(self):
239255 return f"<[green]typed c[/green] pointer to [cyan]{ hex (self .address )} [/cyan]>" # noqa
240256
241257 def __del__ (self ):
242- super ().__del__ ()
243- remove_ref (~ self )
258+ if self .type is not str :
259+ super ().__del__ ()
260+ remove_ref (~ self )
261+
262+
244263
245264
246265def cast (ptr : VoidPointer , data_type : Type [T ]) -> TypedCPointer [T ]:
@@ -251,7 +270,7 @@ def cast(ptr: VoidPointer, data_type: Type[T]) -> TypedCPointer[T]:
251270def to_c_ptr (data : T ) -> TypedCPointer [T ]:
252271 """Convert a python type to a pointer to a C type."""
253272 ct = TypedCPointer .map_type (
254- data if not isinstance ( data , str ) else data . encode () ,
273+ data ,
255274 )
256275
257276 add_ref (ct )
@@ -260,8 +279,9 @@ def to_c_ptr(data: T) -> TypedCPointer[T]:
260279
261280 return TypedCPointer (
262281 address ,
263- typ if typ is not str else bytes , # type: ignore
264- ctypes .sizeof (ct )
282+ typ ,
283+ ctypes .sizeof (ct ),
284+ False
265285 )
266286
267287
0 commit comments