11#![ allow( clippy:: cargo_common_metadata) ]
22
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+
38use libffi:: middle:: { Cif , Type } ;
49use mlua:: prelude:: * ;
510
611use crate :: carr:: CArr ;
712use crate :: chelper:: get_ensured_size;
813use crate :: cptr:: CPtr ;
14+ use crate :: ffihelper:: get_ptr_from_userdata;
15+ use crate :: platform:: CHAR_IS_SIGNED ;
916// use libffi::raw::{ffi_cif, ffi_ptrarray_to_raw};
1017
1118pub struct CType {
1219 libffi_cif : Cif ,
1320 libffi_type : Type ,
1421 size : usize ,
1522 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 > ,
1629}
1730
1831impl 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 > {
2038 let libffi_cfi = Cif :: new ( vec ! [ libffi_type. clone( ) ] , Type :: void ( ) ) ;
2139 let size = get_ensured_size ( libffi_type. as_raw_ptr ( ) ) ?;
2240 Ok ( Self {
2341 libffi_cif : libffi_cfi,
2442 libffi_type,
2543 size,
2644 name,
45+ luavalue_into_ptr,
46+ ptr_into_luavalue,
2747 } )
2848 }
2949
@@ -37,6 +57,30 @@ impl CType {
3757 None => String :: from ( "unnamed" ) ,
3858 }
3959 }
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+ }
4084}
4185
4286impl LuaUserData for CType {
@@ -49,6 +93,20 @@ impl LuaUserData for CType {
4993 let pointer = CPtr :: from_lua_userdata ( lua, & this) ?;
5094 Ok ( pointer)
5195 } ) ;
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+ ) ;
52110 methods. add_function ( "arr" , |lua, ( this, length) : ( LuaAnyUserData , usize ) | {
53111 let carr = CArr :: from_lua_userdata ( lua, & this, length) ?;
54112 Ok ( carr)
@@ -64,48 +122,62 @@ impl LuaUserData for CType {
64122pub fn create_all_types ( lua : & Lua ) -> LuaResult < Vec < ( & ' static str , LuaValue ) > > {
65123 Ok ( vec ! [
66124 (
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) ?,
105150 ) ,
106151 (
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) ?,
109181 ) ,
110182 ] )
111183}
0 commit comments