1
1
#![ allow( clippy:: cargo_common_metadata) ]
2
2
3
+ use core:: ffi:: {
4
+ c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
5
+ c_ulong, c_ulonglong, c_ushort, c_void,
6
+ } ;
7
+
3
8
use libffi:: middle:: { Cif , Type } ;
4
9
use mlua:: prelude:: * ;
5
10
6
11
use crate :: carr:: CArr ;
7
12
use crate :: chelper:: get_ensured_size;
8
13
use crate :: cptr:: CPtr ;
14
+ use crate :: ffihelper:: get_ptr_from_userdata;
15
+ use crate :: platform:: CHAR_IS_SIGNED ;
9
16
// use libffi::raw::{ffi_cif, ffi_ptrarray_to_raw};
10
17
11
18
pub struct CType {
12
19
libffi_cif : Cif ,
13
20
libffi_type : Type ,
14
21
size : usize ,
15
22
name : Option < String > ,
23
+
24
+ // Write converted data from luavalue into some ptr
25
+ pub luavalue_into_ptr : fn ( value : LuaValue , ptr : * mut c_void ) -> LuaResult < ( ) > ,
26
+
27
+ // Read luavalue from some ptr
28
+ pub ptr_into_luavalue : fn ( lua : & Lua , ptr : * mut c_void ) -> LuaResult < LuaValue > ,
16
29
}
17
30
18
31
impl CType {
19
- pub fn new ( libffi_type : Type , name : Option < String > ) -> LuaResult < Self > {
32
+ pub fn new (
33
+ libffi_type : Type ,
34
+ name : Option < String > ,
35
+ luavalue_into_ptr : fn ( value : LuaValue , ptr : * mut c_void ) -> LuaResult < ( ) > ,
36
+ ptr_into_luavalue : fn ( lua : & Lua , ptr : * mut c_void ) -> LuaResult < LuaValue > ,
37
+ ) -> LuaResult < Self > {
20
38
let libffi_cfi = Cif :: new ( vec ! [ libffi_type. clone( ) ] , Type :: void ( ) ) ;
21
39
let size = get_ensured_size ( libffi_type. as_raw_ptr ( ) ) ?;
22
40
Ok ( Self {
23
41
libffi_cif : libffi_cfi,
24
42
libffi_type,
25
43
size,
26
44
name,
45
+ luavalue_into_ptr,
46
+ ptr_into_luavalue,
27
47
} )
28
48
}
29
49
@@ -37,6 +57,30 @@ impl CType {
37
57
None => String :: from ( "unnamed" ) ,
38
58
}
39
59
}
60
+
61
+ // Read data from ptr and convert it into luavalue
62
+ pub unsafe fn read_ptr < ' lua > (
63
+ & self ,
64
+ lua : & ' lua Lua ,
65
+ userdata : LuaAnyUserData < ' lua > ,
66
+ offset : Option < isize > ,
67
+ ) -> LuaResult < LuaValue < ' lua > > {
68
+ let ptr = unsafe { get_ptr_from_userdata ( & userdata, offset) ? } ;
69
+ let value = ( self . ptr_into_luavalue ) ( lua, ptr) ?;
70
+ Ok ( value)
71
+ }
72
+
73
+ // Write converted data from luavalue into ptr
74
+ pub unsafe fn write_ptr < ' lua > (
75
+ & self ,
76
+ luavalue : LuaValue < ' lua > ,
77
+ userdata : LuaAnyUserData < ' lua > ,
78
+ offset : Option < isize > ,
79
+ ) -> LuaResult < ( ) > {
80
+ let ptr = unsafe { get_ptr_from_userdata ( & userdata, offset) ? } ;
81
+ ( self . luavalue_into_ptr ) ( luavalue, ptr) ?;
82
+ Ok ( ( ) )
83
+ }
40
84
}
41
85
42
86
impl LuaUserData for CType {
@@ -49,6 +93,20 @@ impl LuaUserData for CType {
49
93
let pointer = CPtr :: from_lua_userdata ( lua, & this) ?;
50
94
Ok ( pointer)
51
95
} ) ;
96
+ methods. add_method (
97
+ "from" ,
98
+ |lua, ctype, ( userdata, offset) : ( LuaAnyUserData , Option < isize > ) | {
99
+ let value = unsafe { ctype. read_ptr ( lua, userdata, offset) ? } ;
100
+ Ok ( value)
101
+ } ,
102
+ ) ;
103
+ methods. add_method (
104
+ "into" ,
105
+ |_, ctype, ( value, userdata, offset) : ( LuaValue , LuaAnyUserData , Option < isize > ) | {
106
+ unsafe { ctype. write_ptr ( value, userdata, offset) ? } ;
107
+ Ok ( ( ) )
108
+ } ,
109
+ ) ;
52
110
methods. add_function ( "arr" , |lua, ( this, length) : ( LuaAnyUserData , usize ) | {
53
111
let carr = CArr :: from_lua_userdata ( lua, & this, length) ?;
54
112
Ok ( carr)
@@ -64,48 +122,62 @@ impl LuaUserData for CType {
64
122
pub fn create_all_types ( lua : & Lua ) -> LuaResult < Vec < ( & ' static str , LuaValue ) > > {
65
123
Ok ( vec ! [
66
124
(
67
- "u8" ,
68
- CType :: new( Type :: u8 ( ) , Some ( String :: from( "u8" ) ) ) ?. into_lua( lua) ?,
69
- ) ,
70
- (
71
- "u16" ,
72
- CType :: new( Type :: u16 ( ) , Some ( String :: from( "u16" ) ) ) ?. into_lua( lua) ?,
73
- ) ,
74
- (
75
- "u32" ,
76
- CType :: new( Type :: u32 ( ) , Some ( String :: from( "u32" ) ) ) ?. into_lua( lua) ?,
77
- ) ,
78
- (
79
- "u64" ,
80
- CType :: new( Type :: u64 ( ) , Some ( String :: from( "u64" ) ) ) ?. into_lua( lua) ?,
81
- ) ,
82
- (
83
- "i8" ,
84
- CType :: new( Type :: i8 ( ) , Some ( String :: from( "i8" ) ) ) ?. into_lua( lua) ?,
85
- ) ,
86
- (
87
- "i16" ,
88
- CType :: new( Type :: i16 ( ) , Some ( String :: from( "i16" ) ) ) ?. into_lua( lua) ?,
89
- ) ,
90
- (
91
- "i32" ,
92
- CType :: new( Type :: i32 ( ) , Some ( String :: from( "i32" ) ) ) ?. into_lua( lua) ?,
93
- ) ,
94
- (
95
- "i64" ,
96
- CType :: new( Type :: i64 ( ) , Some ( String :: from( "i64" ) ) ) ?. into_lua( lua) ?,
97
- ) ,
98
- (
99
- "f32" ,
100
- CType :: new( Type :: f32 ( ) , Some ( String :: from( "f32" ) ) ) ?. into_lua( lua) ?,
101
- ) ,
102
- (
103
- "f64" ,
104
- CType :: new( Type :: f64 ( ) , Some ( String :: from( "f64" ) ) ) ?. into_lua( lua) ?,
125
+ "int" ,
126
+ CType :: new(
127
+ Type :: c_int( ) ,
128
+ Some ( String :: from( "int" ) ) ,
129
+ |data, ptr| {
130
+ let value = match data {
131
+ LuaValue :: Integer ( t) => t,
132
+ _ => {
133
+ return Err ( LuaError :: external( format!(
134
+ "Integer expected, got {}" ,
135
+ data. type_name( )
136
+ ) ) )
137
+ }
138
+ } as c_int;
139
+ unsafe {
140
+ * ( ptr. cast:: <c_int>( ) ) = value;
141
+ }
142
+ Ok ( ( ) )
143
+ } ,
144
+ |lua: & Lua , ptr: * mut c_void| {
145
+ let value = unsafe { ( * ptr. cast:: <c_int>( ) ) . into_lua( lua) ? } ;
146
+ Ok ( value)
147
+ } ,
148
+ ) ?
149
+ . into_lua( lua) ?,
105
150
) ,
106
151
(
107
- "void" ,
108
- CType :: new( Type :: void( ) , Some ( String :: from( "void" ) ) ) ?. into_lua( lua) ?,
152
+ "char" ,
153
+ CType :: new(
154
+ if CHAR_IS_SIGNED {
155
+ Type :: c_schar( )
156
+ } else {
157
+ Type :: c_uchar( )
158
+ } ,
159
+ Some ( String :: from( "char" ) ) ,
160
+ |data, ptr| {
161
+ let value = match data {
162
+ LuaValue :: Integer ( t) => t,
163
+ _ => {
164
+ return Err ( LuaError :: external( format!(
165
+ "Integer expected, got {}" ,
166
+ data. type_name( )
167
+ ) ) )
168
+ }
169
+ } as c_char;
170
+ unsafe {
171
+ * ( ptr. cast:: <c_char>( ) ) = value;
172
+ }
173
+ Ok ( ( ) )
174
+ } ,
175
+ |lua: & Lua , ptr: * mut c_void| {
176
+ let value = unsafe { ( * ptr. cast:: <c_char>( ) ) . into_lua( lua) ? } ;
177
+ Ok ( value)
178
+ } ,
179
+ ) ?
180
+ . into_lua( lua) ?,
109
181
) ,
110
182
] )
111
183
}
0 commit comments