@@ -15,13 +15,14 @@ mod mmap {
1515 protocol:: {
1616 BufferDescriptor , BufferMethods , PyBuffer , PyMappingMethods , PySequenceMethods ,
1717 } ,
18- sliceable:: { SaturatedSlice , SequenceIndex } ,
18+ sliceable:: { saturate_index , wrap_index , SaturatedSlice , SequenceIndex } ,
1919 types:: { AsBuffer , AsMapping , AsSequence , Constructor } ,
2020 AsObject , FromArgs , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult ,
2121 TryFromBorrowedObject , VirtualMachine ,
2222 } ;
2323 use crossbeam_utils:: atomic:: AtomicCell ;
2424 use memmap2:: { Advice , Mmap , MmapMut , MmapOptions } ;
25+ use nix:: unistd;
2526 use std:: fs:: File ;
2627 use std:: io:: Write ;
2728 use std:: ops:: { Deref , DerefMut } ;
@@ -143,7 +144,7 @@ mod mmap {
143144 struct PyMmap {
144145 closed : AtomicCell < bool > ,
145146 mmap : PyMutex < Option < MmapObj > > ,
146- _fd : RawFd ,
147+ fd : RawFd ,
147148 offset : isize ,
148149 size : AtomicCell < isize > ,
149150 pos : AtomicCell < isize > , // relative to offset
@@ -297,7 +298,7 @@ mod mmap {
297298 ) ,
298299 )
299300 } else {
300- let new_fd = nix :: unistd:: dup ( fd) . map_err ( |e| vm. new_os_error ( e. to_string ( ) ) ) ?;
301+ let new_fd = unistd:: dup ( fd) . map_err ( |e| vm. new_os_error ( e. to_string ( ) ) ) ?;
301302 let mmap = match access {
302303 AccessMode :: Default | AccessMode :: Write => MmapObj :: Write (
303304 unsafe { mmap_opt. map_mut ( fd) }
@@ -317,7 +318,7 @@ mod mmap {
317318 let m_obj = Self {
318319 closed : AtomicCell :: new ( false ) ,
319320 mmap : PyMutex :: new ( Some ( mmap) ) ,
320- _fd : fd,
321+ fd,
321322 offset,
322323 size : AtomicCell :: new ( map_size) ,
323324 pos : AtomicCell :: new ( 0 ) ,
@@ -518,28 +519,13 @@ mod mmap {
518519 fn get_find_range ( & self , options : FindOptions ) -> ( usize , usize ) {
519520 let pos = self . inner_pos ( ) ;
520521 let size = self . inner_size ( ) ;
521- let mut start = options. start . unwrap_or ( pos) ;
522- let mut end = options. end . unwrap_or ( size) ;
522+ let start = options. start . unwrap_or ( pos) ;
523+ let end = options. end . unwrap_or ( size) ;
523524
524- if start < 0 {
525- start += size;
526- }
527- if start < 0 {
528- start = 0 ;
529- } else if start > size {
530- start = size;
531- }
532-
533- if end < 0 {
534- end += size;
535- }
536- if end < 0 {
537- end = 0 ;
538- } else if end > size {
539- end = size;
540- }
541-
542- ( start as usize , end as usize )
525+ (
526+ saturate_index ( start, size. try_into ( ) . unwrap ( ) ) ,
527+ saturate_index ( end, size. try_into ( ) . unwrap ( ) ) ,
528+ )
543529 }
544530
545531 #[ pymethod]
@@ -827,8 +813,15 @@ mod mmap {
827813 }
828814
829815 #[ pymethod]
830- fn size ( & self ) -> isize {
831- self . inner_size ( )
816+ fn size ( & self , vm : & VirtualMachine ) -> PyResult < PyIntRef > {
817+ let new_fd = unistd:: dup ( self . fd ) . map_err ( |e| vm. new_os_error ( e. to_string ( ) ) ) ?;
818+ let file = unsafe { File :: from_raw_fd ( new_fd) } ;
819+ let file_len = match file. metadata ( ) {
820+ Ok ( m) => m. len ( ) ,
821+ Err ( e) => return Err ( vm. new_os_error ( e. to_string ( ) ) ) ,
822+ } ;
823+
824+ Ok ( PyInt :: from ( file_len) . into_ref ( vm) )
832825 }
833826
834827 #[ pymethod]
@@ -889,15 +882,9 @@ mod mmap {
889882 Ok ( ( ) )
890883 }
891884
892- fn get_item_by_index ( & self , mut i : isize , vm : & VirtualMachine ) -> PyResult < PyObjectRef > {
893- let size = self . inner_size ( ) ;
894-
895- if i < 0 {
896- i += size;
897- }
898- if i < 0 || i >= size {
899- return Err ( vm. new_index_error ( "mmap index out of range" . to_owned ( ) ) ) ;
900- }
885+ fn get_item_by_index ( & self , i : isize , vm : & VirtualMachine ) -> PyResult < PyObjectRef > {
886+ let i = wrap_index ( i, self . len ( ) )
887+ . ok_or_else ( || vm. new_index_error ( "mmap index out of range" . to_owned ( ) ) ) ?;
901888
902889 let b = match self . check_valid ( vm) ?. deref ( ) . as_ref ( ) . unwrap ( ) {
903890 MmapObj :: Read ( mmap) => mmap[ i as usize ] ,
@@ -973,18 +960,12 @@ mod mmap {
973960
974961 fn setitem_by_index (
975962 zelf : PyRef < Self > ,
976- mut i : isize ,
963+ i : isize ,
977964 value : PyObjectRef ,
978965 vm : & VirtualMachine ,
979966 ) -> PyResult < ( ) > {
980- let size = zelf. inner_size ( ) ;
981-
982- if i < 0 {
983- i += size;
984- }
985- if i < 0 || i >= size {
986- return Err ( vm. new_index_error ( "mmap index out of range" . to_owned ( ) ) ) ;
987- }
967+ let i = wrap_index ( i, zelf. len ( ) )
968+ . ok_or_else ( || vm. new_index_error ( "mmap index out of range" . to_owned ( ) ) ) ?;
988969
989970 zelf. check_writable ( vm) ?;
990971 let b = value_from_object ( vm, & value) ?;
0 commit comments