|
1 |
| -usecrate::common::borrow::{BorrowedValue,BorrowedValueMut}; |
2 |
| -usecrate::common::cell::{PyRwLockReadGuard,PyRwLockWriteGuard}; |
3 |
| -usecrate::obj::objbytearray::{PyByteArray,PyByteArrayRef}; |
4 |
| -usecrate::obj::objbytes::{PyBytes,PyBytesRef}; |
5 | 1 | usecrate::pyobject::PyObjectRef;
|
6 |
| -usecrate::pyobject::{BorrowValue,PyResult,TryFromObject,TypeProtocol}; |
7 |
| -usecrate::stdlib::array::{PyArray,PyArrayRef}; |
| 2 | +usecrate::pyobject::{BorrowValue,PyResult,TryFromObject}; |
8 | 3 | usecrate::vm::VirtualMachine;
|
| 4 | +usecrate::{ |
| 5 | + common::borrow::{BorrowedValue,BorrowedValueMut}, |
| 6 | + obj::objmemory::try_buffer_from_object, |
| 7 | + obj::objmemory::BufferRef, |
| 8 | +}; |
9 | 9 |
|
10 | 10 | #[derive(Debug)]
|
11 |
| -pubenumPyBytesLike{ |
12 |
| -Bytes(PyBytesRef), |
13 |
| -Bytearray(PyByteArrayRef), |
14 |
| -Array(PyArrayRef), |
15 |
| -} |
| 11 | +pubstructPyBytesLike(BufferRef); |
16 | 12 |
|
17 |
| -implTryFromObjectforPyBytesLike{ |
18 |
| -fntry_from_object(vm:&VirtualMachine,obj:PyObjectRef) ->PyResult<Self>{ |
19 |
| -match_class!(match obj{ |
20 |
| - b @PyBytes =>Ok(PyBytesLike::Bytes(b)), |
21 |
| - b @PyByteArray =>Ok(PyBytesLike::Bytearray(b)), |
22 |
| - array @PyArray =>Ok(PyBytesLike::Array(array)), |
23 |
| - obj =>Err(vm.new_type_error(format!( |
24 |
| -"a bytes-like object is required, not {}", |
25 |
| - obj.lease_class().name |
26 |
| -))), |
27 |
| -}) |
| 13 | +#[derive(Debug)] |
| 14 | +pubstructPyRwBytesLike(BufferRef); |
| 15 | + |
| 16 | +implPyBytesLike{ |
| 17 | +pubfnwith_ref<F,R>(&self,f:F) ->R |
| 18 | +where |
| 19 | +F:FnOnce(&[u8]) ->R, |
| 20 | +{ |
| 21 | +f(&*self.borrow_value()) |
28 | 22 | }
|
29 |
| -} |
30 | 23 |
|
31 |
| -impl<'a>BorrowValue<'a>forPyBytesLike{ |
32 |
| -typeBorrowed =BorrowedValue<'a,[u8]>; |
33 |
| -fnborrow_value(&'aself) ->Self::Borrowed{ |
34 |
| -matchself{ |
35 |
| -Self::Bytes(b) => b.borrow_value().into(), |
36 |
| -Self::Bytearray(b) =>{ |
37 |
| -PyRwLockReadGuard::map(b.borrow_value(), |b| b.elements.as_slice()).into() |
38 |
| -} |
39 |
| -Self::Array(a) => a.get_bytes().into(), |
40 |
| -} |
| 24 | +pubfnlen(&self) ->usize{ |
| 25 | +self.borrow_value().len() |
| 26 | +} |
| 27 | + |
| 28 | +pubfnis_empty(&self) ->bool{ |
| 29 | +self.borrow_value().is_empty() |
| 30 | +} |
| 31 | + |
| 32 | +pubfnto_cow(&self) -> std::borrow::Cow<[u8]>{ |
| 33 | +self.borrow_value().to_vec().into() |
41 | 34 | }
|
42 | 35 | }
|
43 | 36 |
|
44 |
| -implPyBytesLike{ |
| 37 | +implPyRwBytesLike{ |
| 38 | +pubfnwith_ref<F,R>(&self,f:F) ->R |
| 39 | +where |
| 40 | +F:FnOnce(&mut[u8]) ->R, |
| 41 | +{ |
| 42 | +f(&mut*self.borrow_value()) |
| 43 | +} |
| 44 | + |
45 | 45 | pubfnlen(&self) ->usize{
|
46 |
| -matchself{ |
47 |
| -PyBytesLike::Bytes(b) => b.len(), |
48 |
| -PyBytesLike::Bytearray(b) => b.borrow_value().len(), |
49 |
| -PyBytesLike::Array(array) => array.len(), |
50 |
| -} |
| 46 | +self.borrow_value().len() |
51 | 47 | }
|
52 | 48 |
|
53 | 49 | pubfnis_empty(&self) ->bool{
|
54 |
| -self.len() ==0 |
| 50 | +self.borrow_value().is_empty() |
55 | 51 | }
|
| 52 | +} |
56 | 53 |
|
57 |
| -pubfnto_cow(&self) -> std::borrow::Cow<[u8]>{ |
58 |
| -matchself{ |
59 |
| -PyBytesLike::Bytes(b) => b.borrow_value().into(), |
60 |
| -PyBytesLike::Bytearray(b) => b.borrow_value().elements.clone().into(), |
61 |
| -PyBytesLike::Array(array) => array.tobytes().into(), |
| 54 | +implTryFromObjectforPyBytesLike{ |
| 55 | +fntry_from_object(vm:&VirtualMachine,obj:PyObjectRef) ->PyResult<Self>{ |
| 56 | +let buffer =try_buffer_from_object(vm,&obj)?; |
| 57 | +if buffer.get_options().contiguous{ |
| 58 | +Ok(Self(buffer)) |
| 59 | +}else{ |
| 60 | +Err(vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned())) |
62 | 61 | }
|
63 | 62 | }
|
| 63 | +} |
64 | 64 |
|
65 |
| -#[inline] |
66 |
| -pubfnwith_ref<R>(&self,f:implFnOnce(&[u8]) ->R) ->R{ |
67 |
| -matchself{ |
68 |
| -PyBytesLike::Bytes(b) =>f(b.borrow_value()), |
69 |
| -PyBytesLike::Bytearray(b) =>f(&b.borrow_value().elements), |
70 |
| -PyBytesLike::Array(array) =>f(&*array.get_bytes()), |
71 |
| -} |
| 65 | +impl<'a>BorrowValue<'a>forPyBytesLike{ |
| 66 | +typeBorrowed =BorrowedValue<'a,[u8]>; |
| 67 | +fnborrow_value(&'aself) ->Self::Borrowed{ |
| 68 | +self.0.as_contiguous().unwrap() |
72 | 69 | }
|
73 | 70 | }
|
74 | 71 |
|
75 |
| -pub(crate)fntry_bytes_like<R>( |
| 72 | +pubfntry_bytes_like<R>( |
76 | 73 | vm:&VirtualMachine,
|
77 | 74 | obj:&PyObjectRef,
|
78 | 75 | f:implFnOnce(&[u8]) ->R,
|
79 | 76 | ) ->PyResult<R>{
|
80 |
| -let r =match_class!(match obj{ |
81 |
| - ref b @PyBytes => f(b.borrow_value()), |
82 |
| - ref b @PyByteArray => f(&b.borrow_value().elements), |
83 |
| - ref array @PyArray => f(&*array.get_bytes()), |
84 |
| - obj => |
85 |
| -returnErr(vm.new_type_error(format!( |
86 |
| -"a bytes-like object is required, not {}", |
87 |
| - obj.lease_class().name |
88 |
| -))), |
89 |
| -}); |
90 |
| -Ok(r) |
| 77 | +let buffer =try_buffer_from_object(vm, obj)?; |
| 78 | + buffer.as_contiguous().map(|x|f(&*x)).ok_or_else(||{ |
| 79 | + vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned()) |
| 80 | +}) |
91 | 81 | }
|
92 | 82 |
|
93 |
| -pubenumPyRwBytesLike{ |
94 |
| -Bytearray(PyByteArrayRef), |
95 |
| -Array(PyArrayRef), |
| 83 | +pubfntry_rw_bytes_like<R>( |
| 84 | +vm:&VirtualMachine, |
| 85 | +obj:&PyObjectRef, |
| 86 | +f:implFnOnce(&mut[u8]) ->R, |
| 87 | +) ->PyResult<R>{ |
| 88 | +let buffer =try_buffer_from_object(vm, obj)?; |
| 89 | + buffer |
| 90 | +.as_contiguous_mut() |
| 91 | +.map(|mut x|f(&mut*x)) |
| 92 | +.ok_or_else(|| vm.new_type_error("buffer is not a read-write bytes-like object".to_owned())) |
96 | 93 | }
|
97 | 94 |
|
98 | 95 | implTryFromObjectforPyRwBytesLike{
|
99 | 96 | fntry_from_object(vm:&VirtualMachine,obj:PyObjectRef) ->PyResult<Self>{
|
100 |
| -match_class!(match obj{ |
101 |
| - b @PyByteArray =>Ok(PyRwBytesLike::Bytearray(b)), |
102 |
| - array @PyArray =>Ok(PyRwBytesLike::Array(array)), |
103 |
| - obj => |
104 |
| -Err(vm.new_type_error(format!("a buffer object is required, not {}", obj.class()))), |
105 |
| -}) |
| 97 | +let buffer =try_buffer_from_object(vm,&obj)?; |
| 98 | +if !buffer.get_options().contiguous{ |
| 99 | +Err(vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned())) |
| 100 | +}elseif buffer.get_options().readonly{ |
| 101 | +Err(vm.new_type_error("buffer is not a read-write bytes-like object".to_owned())) |
| 102 | +}else{ |
| 103 | +Ok(Self(buffer)) |
| 104 | +} |
106 | 105 | }
|
107 | 106 | }
|
108 | 107 |
|
109 | 108 | impl<'a>BorrowValue<'a>forPyRwBytesLike{
|
110 | 109 | typeBorrowed =BorrowedValueMut<'a,[u8]>;
|
111 | 110 | fnborrow_value(&'aself) ->Self::Borrowed{
|
112 |
| -matchself{ |
113 |
| -Self::Bytearray(b) =>{ |
114 |
| -PyRwLockWriteGuard::map(b.borrow_value_mut(), |b| b.elements.as_mut_slice()).into() |
115 |
| -} |
116 |
| -Self::Array(a) => a.get_bytes_mut().into(), |
117 |
| -} |
118 |
| -} |
119 |
| -} |
120 |
| - |
121 |
| -implPyRwBytesLike{ |
122 |
| -pubfnlen(&self) ->usize{ |
123 |
| -matchself{ |
124 |
| -PyRwBytesLike::Bytearray(b) => b.borrow_value().len(), |
125 |
| -PyRwBytesLike::Array(array) => array.len(), |
126 |
| -} |
127 |
| -} |
128 |
| - |
129 |
| -pubfnis_empty(&self) ->bool{ |
130 |
| -self.len() ==0 |
131 |
| -} |
132 |
| - |
133 |
| -#[inline] |
134 |
| -pubfnwith_ref<R>(&self,f:implFnOnce(&mut[u8]) ->R) ->R{ |
135 |
| -matchself{ |
136 |
| -PyRwBytesLike::Bytearray(b) =>f(&mut b.borrow_value_mut().elements), |
137 |
| -PyRwBytesLike::Array(array) =>f(&mut array.get_bytes_mut()), |
138 |
| -} |
| 111 | +self.0.as_contiguous_mut().unwrap() |
139 | 112 | }
|
140 | 113 | }
|