1+ use std:: io;
2+
13#[ cfg( feature = "serde" ) ]
24use serde:: ser:: { Serialize , Serializer } ;
35
@@ -50,20 +52,33 @@ impl Buffer {
5052 #[ track_caller]
5153 pub fn write_bytes ( & self , offset : usize , bytes : & [ u8 ] ) {
5254 let lua = self . 0 . lua . lock ( ) ;
53- let data = unsafe {
54- let ( buf, size) = self . as_raw_parts ( & lua) ;
55- std:: slice:: from_raw_parts_mut ( buf, size)
56- } ;
55+ let data = self . as_slice_mut ( & lua) ;
5756 data[ offset..offset + bytes. len ( ) ] . copy_from_slice ( bytes) ;
5857 }
5958
59+ /// Returns an adaptor implementing [`io::Read`], [`io::Write`] and [`io::Seek`] over the
60+ /// buffer.
61+ ///
62+ /// Buffer operations are infallible, none of the read/write functions will return a Err.
63+ pub fn cursor ( self ) -> impl io:: Read + io:: Write + io:: Seek {
64+ BufferCursor ( self , 0 )
65+ }
66+
6067 pub ( crate ) fn as_slice ( & self , lua : & RawLua ) -> & [ u8 ] {
6168 unsafe {
6269 let ( buf, size) = self . as_raw_parts ( lua) ;
6370 std:: slice:: from_raw_parts ( buf, size)
6471 }
6572 }
6673
74+ #[ allow( clippy:: mut_from_ref) ]
75+ fn as_slice_mut ( & self , lua : & RawLua ) -> & mut [ u8 ] {
76+ unsafe {
77+ let ( buf, size) = self . as_raw_parts ( lua) ;
78+ std:: slice:: from_raw_parts_mut ( buf, size)
79+ }
80+ }
81+
6782 #[ cfg( feature = "luau" ) ]
6883 unsafe fn as_raw_parts ( & self , lua : & RawLua ) -> ( * mut u8 , usize ) {
6984 let mut size = 0usize ;
@@ -78,6 +93,66 @@ impl Buffer {
7893 }
7994}
8095
96+ struct BufferCursor ( Buffer , usize ) ;
97+
98+ impl io:: Read for BufferCursor {
99+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
100+ let lua = self . 0 . 0 . lua . lock ( ) ;
101+ let data = self . 0 . as_slice ( & lua) ;
102+ if self . 1 == data. len ( ) {
103+ return Ok ( 0 ) ;
104+ }
105+ let len = buf. len ( ) . min ( data. len ( ) - self . 1 ) ;
106+ buf[ ..len] . copy_from_slice ( & data[ self . 1 ..self . 1 + len] ) ;
107+ self . 1 += len;
108+ Ok ( len)
109+ }
110+ }
111+
112+ impl io:: Write for BufferCursor {
113+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
114+ let lua = self . 0 . 0 . lua . lock ( ) ;
115+ let data = self . 0 . as_slice_mut ( & lua) ;
116+ if self . 1 == data. len ( ) {
117+ return Ok ( 0 ) ;
118+ }
119+ let len = buf. len ( ) . min ( data. len ( ) - self . 1 ) ;
120+ data[ self . 1 ..self . 1 + len] . copy_from_slice ( & buf[ ..len] ) ;
121+ self . 1 += len;
122+ Ok ( len)
123+ }
124+
125+ fn flush ( & mut self ) -> io:: Result < ( ) > {
126+ Ok ( ( ) )
127+ }
128+ }
129+
130+ impl io:: Seek for BufferCursor {
131+ fn seek ( & mut self , pos : io:: SeekFrom ) -> io:: Result < u64 > {
132+ let lua = self . 0 . 0 . lua . lock ( ) ;
133+ let data = self . 0 . as_slice ( & lua) ;
134+ let new_offset = match pos {
135+ io:: SeekFrom :: Start ( offset) => offset as i64 ,
136+ io:: SeekFrom :: End ( offset) => data. len ( ) as i64 + offset,
137+ io:: SeekFrom :: Current ( offset) => self . 1 as i64 + offset,
138+ } ;
139+ if new_offset < 0 {
140+ return Err ( io:: Error :: new (
141+ io:: ErrorKind :: InvalidInput ,
142+ "invalid seek to a negative position" ,
143+ ) ) ;
144+ }
145+ if new_offset as usize > data. len ( ) {
146+ return Err ( io:: Error :: new (
147+ io:: ErrorKind :: InvalidInput ,
148+ "invalid seek to a position beyond the end of the buffer" ,
149+ ) ) ;
150+ }
151+ self . 1 = new_offset as usize ;
152+ Ok ( self . 1 as u64 )
153+ }
154+ }
155+
81156#[ cfg( feature = "serde" ) ]
82157impl Serialize for Buffer {
83158 fn serialize < S : Serializer > ( & self , serializer : S ) -> std:: result:: Result < S :: Ok , S :: Error > {
0 commit comments