1313// limitations under the License.
1414
1515use binaryninjacore_sys:: BNFileAccessor ;
16- use std:: io:: { Read , Seek , SeekFrom , Write } ;
16+ use std:: io:: { ErrorKind , Read , Seek , SeekFrom , Write } ;
1717use std:: marker:: PhantomData ;
1818use std:: slice;
1919
20- pub struct FileAccessor < ' a > {
21- pub ( crate ) api_object : BNFileAccessor ,
22- _ref : PhantomData < & ' a mut ( ) > ,
20+ pub trait Accessor : Read + Write + Seek + Sized { }
21+
22+ impl < T : Read + Write + Seek + Sized > Accessor for T { }
23+
24+ pub struct FileAccessor < A : Accessor > {
25+ pub ( crate ) raw : BNFileAccessor ,
26+ accessor : PhantomData < A > ,
2327}
2428
25- impl < ' a > FileAccessor < ' a > {
26- pub fn new < F > ( f : & ' a mut F ) -> Self
27- where
28- F : ' a + Read + Write + Seek + Sized ,
29- {
29+ impl < A : Accessor > FileAccessor < A > {
30+ pub fn new ( accessor : A ) -> Self {
3031 use std:: os:: raw:: c_void;
3132
32- extern "C" fn cb_get_length < F > ( ctxt : * mut c_void ) -> u64
33- where
34- F : Read + Write + Seek + Sized ,
35- {
36- let f = unsafe { & mut * ( ctxt as * mut F ) } ;
33+ extern "C" fn cb_get_length < A : Accessor > ( ctxt : * mut c_void ) -> u64 {
34+ let f = unsafe { & mut * ( ctxt as * mut A ) } ;
3735
3836 f. seek ( SeekFrom :: End ( 0 ) ) . unwrap_or ( 0 )
3937 }
4038
41- extern "C" fn cb_read < F > (
39+ extern "C" fn cb_read < A : Accessor > (
4240 ctxt : * mut c_void ,
4341 dest : * mut c_void ,
4442 offset : u64 ,
4543 len : usize ,
46- ) -> usize
47- where
48- F : Read + Write + Seek + Sized ,
49- {
50- let f = unsafe { & mut * ( ctxt as * mut F ) } ;
44+ ) -> usize {
45+ let f = unsafe { & mut * ( ctxt as * mut A ) } ;
5146 let dest = unsafe { slice:: from_raw_parts_mut ( dest as * mut u8 , len) } ;
5247
5348 if f. seek ( SeekFrom :: Start ( offset) ) . is_err ( ) {
@@ -58,16 +53,13 @@ impl<'a> FileAccessor<'a> {
5853 }
5954 }
6055
61- extern "C" fn cb_write < F > (
56+ extern "C" fn cb_write < A : Accessor > (
6257 ctxt : * mut c_void ,
6358 offset : u64 ,
6459 src : * const c_void ,
6560 len : usize ,
66- ) -> usize
67- where
68- F : Read + Write + Seek + Sized ,
69- {
70- let f = unsafe { & mut * ( ctxt as * mut F ) } ;
61+ ) -> usize {
62+ let f = unsafe { & mut * ( ctxt as * mut A ) } ;
7163 let src = unsafe { slice:: from_raw_parts ( src as * const u8 , len) } ;
7264
7365 if f. seek ( SeekFrom :: Start ( offset) ) . is_err ( ) {
@@ -77,14 +69,52 @@ impl<'a> FileAccessor<'a> {
7769 }
7870 }
7971
72+ let boxed_accessor = Box :: new ( accessor) ;
73+ let leaked_accessor = Box :: leak ( boxed_accessor) ;
74+
8075 Self {
81- api_object : BNFileAccessor {
82- context : f as * mut F as * mut _ ,
83- getLength : Some ( cb_get_length :: < F > ) ,
84- read : Some ( cb_read :: < F > ) ,
85- write : Some ( cb_write :: < F > ) ,
76+ raw : BNFileAccessor {
77+ context : leaked_accessor as * mut A as * mut _ ,
78+ getLength : Some ( cb_get_length :: < A > ) ,
79+ read : Some ( cb_read :: < A > ) ,
80+ write : Some ( cb_write :: < A > ) ,
8681 } ,
87- _ref : PhantomData ,
82+ accessor : PhantomData ,
83+ }
84+ }
85+
86+ pub fn read ( & self , addr : u64 , len : usize ) -> Result < Vec < u8 > , ErrorKind > {
87+ let cb_read = self . raw . read . unwrap ( ) ;
88+ let mut buf = vec ! [ 0 ; len] ;
89+ let read_len = unsafe { cb_read ( self . raw . context , buf. as_mut_ptr ( ) as * mut _ , addr, len) } ;
90+ if read_len != len {
91+ return Err ( ErrorKind :: UnexpectedEof ) ;
92+ }
93+ Ok ( buf)
94+ }
95+
96+ pub fn write ( & self , addr : u64 , data : & [ u8 ] ) -> usize {
97+ let cb_write = self . raw . write . unwrap ( ) ;
98+ unsafe {
99+ cb_write (
100+ self . raw . context ,
101+ addr,
102+ data. as_ptr ( ) as * const _ ,
103+ data. len ( ) ,
104+ )
105+ }
106+ }
107+
108+ pub fn length ( & self ) -> u64 {
109+ let cb_get_length = self . raw . getLength . unwrap ( ) ;
110+ unsafe { cb_get_length ( self . raw . context ) }
111+ }
112+ }
113+
114+ impl < A : Accessor > Drop for FileAccessor < A > {
115+ fn drop ( & mut self ) {
116+ unsafe {
117+ let _ = Box :: from_raw ( self . raw . context as * mut A ) ;
88118 }
89119 }
90120}
0 commit comments