FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
pointers.py/src/pointers/structure.py at master · ZeroIntensity/pointers.py · GitHub
ZeroIntensity
pointers.py
Repository navigation
Code
Issues
2
(2)
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
pointers.py
/
src
/
pointers
/
structure.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
211 lines (163 loc) · 5.91 KB
Breadcrumbs
pointers.py
/
src
/
pointers
/
structure.py
Copy path
File metadata and controls
211 lines (163 loc) · 5.91 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import
ctypes
from
contextlib
import
suppress
from
typing
import
Any
,
Dict
,
List
,
Optional
,
Type
,
TypeVar
,
Union
from
_pointers
import
add_ref
from
.
_utils
import
attempt_decode
,
get_mapped
,
get_py
from
.
base_pointers
import
BaseCPointer
from
.
c_pointer
import
TypedCPointer
,
VoidPointer
from
.
object_pointer
import
Pointer
from
.
util
import
RawType
,
handle
T
=
TypeVar
(
"T"
,
bound
=
"Struct"
)
__all__
=
(
"Struct"
,
"StructPointer"
,
)
class
Struct
:
"""Abstract class representing a struct."""
_hints
:
Dict
[
str
,
Any
]
_void_p
:
List
[
str
]
_internal_struct
:
Type
[
ctypes
.
Structure
]
@
classmethod
def
_convert_tc_ptr
(
cls
,
typ
:
Any
,
name
:
str
):
if
typ
is
TypedCPointer
:
raise
TypeError
(
"cannot instantiate: TypedCPointer has no type argument"
,
)
if
getattr
(
typ
,
"__origin__"
,
None
)
is
TypedCPointer
:
setattr
(
cls
,
name
,
RawType
(
ctypes
.
POINTER
(
get_mapped
(
typ
.
__args__
[
0
])),
),
)
return
typ
@
classmethod
def
_get_type
(
cls
,
ct
:
Type
[
"ctypes._CData"
],
name
:
str
,
)
->
Type
[
"ctypes._CData"
]:
attr
=
getattr
(
cls
,
name
,
None
)
if
isinstance
(
attr
,
RawType
):
return
attr
.
tp
if
ct
is
ctypes
.
c_void_p
:
cls
.
_void_p
.
append
(
name
)
return
ct
def
__init__
(
self
,
*
args
:
Any
,
do_sync
:
bool
=
True
):
class_typ
:
Type
[
Struct
]
=
type
(
self
)
if
class_typ
is
Struct
:
raise
Exception
(
"cannot instantiate Struct directly"
,
)
self
.
_existing_address
:
Optional
[
int
]
=
None
self
.
_struct
=
self
.
_internal_struct
(
*
[
i
if
not
isinstance
(
i
,
BaseCPointer
)
else
i
.
_as_parameter_
for
i
in
args
# fmt: off
]
)
if
do_sync
:
self
.
_sync
()
def
__init_subclass__
(
cls
):
hints
=
cls
.
__annotations__
cls
.
_void_p
=
[]
cls
.
_hints
=
{
k
:
cls
.
_convert_tc_ptr
(
v
,
k
)
for
k
,
v
in
hints
.
items
()
if
k
not
in
{
"_hints"
,
"_void_p"
,
"_internal_struct"
}
}
class
_InternalStruct
(
ctypes
.
Structure
):
_fields_
=
[
(
name
,
cls
.
_get_type
(
get_mapped
(
typ
),
name
),
)
for
name
,
typ
in
cls
.
_hints
.
items
()
# fmt: off
]
cls
.
_internal_struct
=
_InternalStruct
@
property
def
_as_parameter_
(
self
)
->
ctypes
.
Structure
:
return
self
.
_struct
@
classmethod
def
from_existing
(
cls
,
struct
:
ctypes
.
Structure
)
->
"Struct"
:
"""Build a new struct from an existing ctypes structure.
Args:
struct: Existing `ctypes.Structure` object
Returns:
Created struct object.
"""
instance
=
cls
(
do_sync
=
False
)
instance
.
_struct
=
struct
# type: ignore
# mypy is getting angry here for whatever reason
instance
.
_sync
()
instance
.
_existing_address
=
ctypes
.
addressof
(
struct
)
return
instance
@
handle
def
__getattribute__
(
self
,
name
:
str
):
attr
=
super
().
__getattribute__
(
name
)
with
suppress
(
AttributeError
):
hints
=
super
().
__getattribute__
(
"_hints"
)
if
(
name
in
hints
)
and
(
type
(
attr
))
is
bytes
:
attr
=
attempt_decode
(
attr
)
if
isinstance
(
attr
,
ctypes
.
_Pointer
):
# type: ignore
value
=
attr
.
contents
ct
=
type
(
value
)
if
ct
is
ctypes
.
c_void_p
:
add_ref
(
ct
)
return
VoidPointer
(
ctypes
.
addressof
(
value
),
ctypes
.
sizeof
(
value
),
)
py_type
=
get_py
(
ct
)
return
TypedCPointer
(
ctypes
.
addressof
(
value
),
py_type
,
ctypes
.
sizeof
(
value
),
False
,
)
if
name
in
super
().
__getattribute__
(
"_void_p"
):
ct
=
ctypes
.
c_void_p
(
attr
)
# type: ignore
return
VoidPointer
(
attr
,
ctypes
.
sizeof
(
ct
))
# type: ignore
return
attr
def
__setattr__
(
self
,
name
:
str
,
value
:
Any
):
if
hasattr
(
self
,
"_struct"
):
self
.
_struct
.
__setattr__
(
name
,
value
)
super
().
__setattr__
(
name
,
value
)
def
_sync
(
self
)
->
None
:
for
name
in
self
.
_hints
:
setattr
(
self
,
name
,
getattr
(
self
.
_struct
,
name
))
def
__repr__
(
self
)
->
str
:
return
f"<struct
{
type
(
self
).
__name__
}
at
{
hex
(
ctypes
.
addressof
(
self
.
_struct
))
}
>"
# noqa
@
property
def
struct
(
self
)
->
ctypes
.
Structure
:
"""Raw internal Structure object."""
return
self
.
_struct
def
get_existing_address
(
self
)
->
int
:
if
not
self
.
_existing_address
:
raise
ValueError
(
"instance has not been created from a C struct"
)
return
self
.
_existing_address
class
StructPointer
(
Pointer
[
T
]):
"""Class representing a pointer to a struct."""
def
__init__
(
self
,
address
:
int
,
existing
:
Optional
[
"Struct"
]
=
None
,
):
self
.
_existing
=
existing
super
().
__init__
(
address
,
True
)
@
property
# type: ignore
@
handle
def
_as_parameter_
(
self
,
)
->
Union
[
int
,
"ctypes._PointerLike"
]:
existing
=
self
.
_existing
if
existing
:
return
ctypes
.
pointer
(
existing
.
struct
)
return
self
.
ensure
()
def
__repr__
(
self
)
->
str
:
return
f"StructPointer(address=
{
self
.
address
}
, existing=
{
self
.
_existing
!r
}
)"
# noqa
def
__rich__
(
self
)
->
str
:
return
f"<[bold blue]pointer[/] to struct at
{
str
(
self
)
}
>"
def
get_existing_address
(
self
)
->
int
:
return
(
~
self
).
get_existing_address
()
Back
|
FazBrowse Home
|
New Git URL