@@ -6,12 +6,12 @@ use std::ops::{Deref, DerefMut};
6
6
7
7
use num_traits:: ToPrimitive ;
8
8
9
- use crate :: function:: { OptionalArg , PyFuncArgs } ;
10
- use crate :: pyobject:: { PyContext , PyObjectRef , PyRef , PyResult , PyValue , TypeProtocol } ;
9
+ use crate :: function:: OptionalArg ;
10
+ use crate :: pyobject:: { PyContext , PyObjectRef , PyRef , PyResult , PyValue } ;
11
11
use crate :: vm:: VirtualMachine ;
12
12
13
13
use super :: objint;
14
- use super :: objtype:: { self , PyClassRef } ;
14
+ use super :: objtype:: PyClassRef ;
15
15
16
16
#[ derive( Debug ) ]
17
17
pub struct PyByteArray {
@@ -63,22 +63,22 @@ pub fn init(context: &PyContext) {
63
63
64
64
extend_class ! ( context, bytearray_type, {
65
65
"__doc__" => context. new_str( bytearray_doc. to_string( ) ) ,
66
- "__eq__" => context. new_rustfunc( bytearray_eq) ,
67
- "__len__" => context. new_rustfunc( bytesarray_len) ,
68
66
"__new__" => context. new_rustfunc( bytearray_new) ,
69
- "__repr__" => context. new_rustfunc( bytearray_repr) ,
70
- "clear" => context. new_rustfunc( bytearray_clear) ,
71
- "isalnum" => context. new_rustfunc( bytearray_isalnum) ,
72
- "isalpha" => context. new_rustfunc( bytearray_isalpha) ,
73
- "isascii" => context. new_rustfunc( bytearray_isascii) ,
74
- "isdigit" => context. new_rustfunc( bytearray_isdigit) ,
75
- "islower" => context. new_rustfunc( bytearray_islower) ,
76
- "isspace" => context. new_rustfunc( bytearray_isspace) ,
77
- "istitle" =>context. new_rustfunc( bytearray_istitle) ,
78
- "isupper" => context. new_rustfunc( bytearray_isupper) ,
79
- "lower" => context. new_rustfunc( bytearray_lower) ,
80
- "pop" => context. new_rustfunc( bytearray_pop) ,
81
- "upper" => context. new_rustfunc( bytearray_upper)
67
+ "__eq__" => context. new_rustfunc( PyByteArrayRef :: eq) ,
68
+ "__len__" => context. new_rustfunc( PyByteArrayRef :: len) ,
69
+ "__repr__" => context. new_rustfunc( PyByteArrayRef :: repr) ,
70
+ "clear" => context. new_rustfunc( PyByteArrayRef :: clear) ,
71
+ "isalnum" => context. new_rustfunc( PyByteArrayRef :: isalnum) ,
72
+ "isalpha" => context. new_rustfunc( PyByteArrayRef :: isalpha) ,
73
+ "isascii" => context. new_rustfunc( PyByteArrayRef :: isascii) ,
74
+ "isdigit" => context. new_rustfunc( PyByteArrayRef :: isdigit) ,
75
+ "islower" => context. new_rustfunc( PyByteArrayRef :: islower) ,
76
+ "isspace" => context. new_rustfunc( PyByteArrayRef :: isspace) ,
77
+ "istitle" =>context. new_rustfunc( PyByteArrayRef :: istitle) ,
78
+ "isupper" => context. new_rustfunc( PyByteArrayRef :: isupper) ,
79
+ "lower" => context. new_rustfunc( PyByteArrayRef :: lower) ,
80
+ "pop" => context. new_rustfunc( PyByteArrayRef :: pop) ,
81
+ "upper" => context. new_rustfunc( PyByteArrayRef :: upper)
82
82
} ) ;
83
83
}
84
84
@@ -107,89 +107,69 @@ fn bytearray_new(
107
107
PyByteArray :: new ( value) . into_ref_with_type ( vm, cls. clone ( ) )
108
108
}
109
109
110
- fn bytesarray_len ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
111
- arg_check ! ( vm, args, required = [ ( a, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
112
-
113
- let byte_vec = get_value ( a) . to_vec ( ) ;
114
- Ok ( vm. ctx . new_int ( byte_vec. len ( ) ) )
115
- }
116
-
117
- fn bytearray_eq ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
118
- arg_check ! (
119
- vm,
120
- args,
121
- required = [ ( a, Some ( vm. ctx. bytearray_type( ) ) ) , ( b, None ) ]
122
- ) ;
110
+ impl PyByteArrayRef {
111
+ fn len ( self , _vm : & VirtualMachine ) -> usize {
112
+ self . value . borrow ( ) . len ( )
113
+ }
123
114
124
- let result = if objtype:: isinstance ( b, & vm. ctx . bytearray_type ( ) ) {
125
- get_value ( a) . to_vec ( ) == get_value ( b) . to_vec ( )
126
- } else {
127
- false
128
- } ;
129
- Ok ( vm. ctx . new_bool ( result) )
130
- }
115
+ fn eq ( self , other : PyObjectRef , vm : & VirtualMachine ) -> PyObjectRef {
116
+ if let Ok ( other) = other. downcast :: < PyByteArray > ( ) {
117
+ vm. ctx
118
+ . new_bool ( self . value . borrow ( ) . as_slice ( ) == other. value . borrow ( ) . as_slice ( ) )
119
+ } else {
120
+ vm. ctx . not_implemented ( )
121
+ }
122
+ }
131
123
132
- fn bytearray_isalnum ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
133
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
134
- let bytes = get_value ( zelf) ;
135
- Ok ( vm. new_bool ( !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_alphanumeric ( ) ) ) )
136
- }
124
+ fn isalnum ( self , _vm : & VirtualMachine ) -> bool {
125
+ let bytes = self . value . borrow ( ) ;
126
+ !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_alphanumeric ( ) )
127
+ }
137
128
138
- fn bytearray_isalpha ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
139
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
140
- let bytes = get_value ( zelf) ;
141
- Ok ( vm. new_bool ( !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_alphabetic ( ) ) ) )
142
- }
129
+ fn isalpha ( self , _vm : & VirtualMachine ) -> bool {
130
+ let bytes = self . value . borrow ( ) ;
131
+ !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_alphabetic ( ) )
132
+ }
143
133
144
- fn bytearray_isascii ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
145
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
146
- let bytes = get_value ( zelf) ;
147
- Ok ( vm. new_bool ( !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_ascii ( ) ) ) )
148
- }
134
+ fn isascii ( self , _vm : & VirtualMachine ) -> bool {
135
+ let bytes = self . value . borrow ( ) ;
136
+ !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_ascii ( ) )
137
+ }
149
138
150
- fn bytearray_isdigit ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
151
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
152
- let bytes = get_value ( zelf) ;
153
- Ok ( vm. new_bool ( !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_digit ( 10 ) ) ) )
154
- }
139
+ fn isdigit ( self , _vm : & VirtualMachine ) -> bool {
140
+ let bytes = self . value . borrow ( ) ;
141
+ !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_digit ( 10 ) )
142
+ }
155
143
156
- fn bytearray_islower ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
157
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
158
- let bytes = get_value ( zelf) ;
159
- Ok ( vm. new_bool (
144
+ fn islower ( self , _vm : & VirtualMachine ) -> bool {
145
+ let bytes = self . value . borrow ( ) ;
160
146
!bytes. is_empty ( )
161
147
&& bytes
162
148
. iter ( )
163
149
. filter ( |x| !char:: from ( * * x) . is_whitespace ( ) )
164
- . all ( |x| char:: from ( * x) . is_lowercase ( ) ) ,
165
- ) )
166
- }
150
+ . all ( |x| char:: from ( * x) . is_lowercase ( ) )
151
+ }
167
152
168
- fn bytearray_isspace ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
169
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
170
- let bytes = get_value ( zelf) ;
171
- Ok ( vm. new_bool ( !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_whitespace ( ) ) ) )
172
- }
153
+ fn isspace ( self , _vm : & VirtualMachine ) -> bool {
154
+ let bytes = self . value . borrow ( ) ;
155
+ !bytes. is_empty ( ) && bytes. iter ( ) . all ( |x| char:: from ( * x) . is_whitespace ( ) )
156
+ }
173
157
174
- fn bytearray_isupper ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
175
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
176
- let bytes = get_value ( zelf) ;
177
- Ok ( vm. new_bool (
158
+ fn isupper ( self , _vm : & VirtualMachine ) -> bool {
159
+ let bytes = self . value . borrow ( ) ;
178
160
!bytes. is_empty ( )
179
161
&& bytes
180
162
. iter ( )
181
163
. filter ( |x| !char:: from ( * * x) . is_whitespace ( ) )
182
- . all ( |x| char:: from ( * x) . is_uppercase ( ) ) ,
183
- ) )
184
- }
164
+ . all ( |x| char:: from ( * x) . is_uppercase ( ) )
165
+ }
185
166
186
- fn bytearray_istitle ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
187
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
188
- let bytes = get_value ( zelf) ;
167
+ fn istitle ( self , _vm : & VirtualMachine ) -> bool {
168
+ let bytes = self . value . borrow ( ) ;
169
+ if bytes. is_empty ( ) {
170
+ return false ;
171
+ }
189
172
190
- if bytes. is_empty ( ) {
191
- Ok ( vm. new_bool ( false ) )
192
- } else {
193
173
let mut iter = bytes. iter ( ) . peekable ( ) ;
194
174
let mut prev_cased = false ;
195
175
@@ -198,21 +178,52 @@ fn bytearray_istitle(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
198
178
let next = if let Some ( k) = iter. peek ( ) {
199
179
char:: from ( * * k)
200
180
} else if current. is_uppercase ( ) {
201
- return Ok ( vm . new_bool ( !prev_cased) ) ;
181
+ return !prev_cased;
202
182
} else {
203
- return Ok ( vm . new_bool ( prev_cased) ) ;
183
+ return prev_cased;
204
184
} ;
205
185
206
186
if ( is_cased ( current) && next. is_uppercase ( ) && !prev_cased)
207
187
|| ( !is_cased ( current) && next. is_lowercase ( ) )
208
188
{
209
- return Ok ( vm . new_bool ( false ) ) ;
189
+ return false ;
210
190
}
211
191
212
192
prev_cased = is_cased ( current) ;
213
193
}
214
194
215
- Ok ( vm. new_bool ( true ) )
195
+ true
196
+ }
197
+
198
+ fn repr ( self , _vm : & VirtualMachine ) -> String {
199
+ let bytes = self . value . borrow ( ) ;
200
+ let data = String :: from_utf8 ( bytes. to_vec ( ) ) . unwrap_or_else ( |_| to_hex ( & bytes. to_vec ( ) ) ) ;
201
+ format ! ( "bytearray(b'{}')" , data)
202
+ }
203
+
204
+ fn clear ( self , _vm : & VirtualMachine ) {
205
+ self . value . borrow_mut ( ) . clear ( ) ;
206
+ }
207
+
208
+ fn pop ( self , vm : & VirtualMachine ) -> PyResult < u8 > {
209
+ let mut bytes = self . value . borrow_mut ( ) ;
210
+ bytes
211
+ . pop ( )
212
+ . ok_or_else ( || vm. new_index_error ( "pop from empty bytearray" . to_string ( ) ) )
213
+ }
214
+
215
+ fn lower ( self , _vm : & VirtualMachine ) -> PyByteArray {
216
+ let bytes = self . value . borrow ( ) . clone ( ) . to_ascii_lowercase ( ) ;
217
+ PyByteArray {
218
+ value : RefCell :: new ( bytes) ,
219
+ }
220
+ }
221
+
222
+ fn upper ( self , _vm : & VirtualMachine ) -> PyByteArray {
223
+ let bytes = self . value . borrow ( ) . clone ( ) . to_ascii_uppercase ( ) ;
224
+ PyByteArray {
225
+ value : RefCell :: new ( bytes) ,
226
+ }
216
227
}
217
228
}
218
229
@@ -222,7 +233,7 @@ fn is_cased(c: char) -> bool {
222
233
}
223
234
224
235
/*
225
- fn bytearray_getitem (vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
236
+ fn getitem (vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
226
237
arg_check!(
227
238
vm,
228
239
args,
@@ -239,56 +250,19 @@ fn set_value(obj: &PyObjectRef, value: Vec<u8>) {
239
250
*/
240
251
241
252
/// Return a lowercase hex representation of a bytearray
242
- fn bytearray_to_hex ( bytearray : & [ u8 ] ) -> String {
253
+ fn to_hex ( bytearray : & [ u8 ] ) -> String {
243
254
bytearray. iter ( ) . fold ( String :: new ( ) , |mut s, b| {
244
255
let _ = write ! ( s, "\\ x{:02x}" , b) ;
245
256
s
246
257
} )
247
258
}
248
259
249
- fn bytearray_repr ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
250
- arg_check ! ( vm, args, required = [ ( obj, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
251
- let value = get_value ( obj) ;
252
- let data =
253
- String :: from_utf8 ( value. to_vec ( ) ) . unwrap_or_else ( |_| bytearray_to_hex ( & value. to_vec ( ) ) ) ;
254
- Ok ( vm. new_str ( format ! ( "bytearray(b'{}')" , data) ) )
255
- }
256
-
257
- fn bytearray_clear ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
258
- arg_check ! ( vm, args, required = [ ( zelf, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
259
- get_mut_value ( zelf) . clear ( ) ;
260
- Ok ( vm. get_none ( ) )
261
- }
262
-
263
- fn bytearray_pop ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
264
- arg_check ! ( vm, args, required = [ ( obj, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
265
- let mut value = get_mut_value ( obj) ;
266
-
267
- if let Some ( i) = value. pop ( ) {
268
- Ok ( vm. ctx . new_int ( i) )
269
- } else {
270
- Err ( vm. new_index_error ( "pop from empty bytearray" . to_string ( ) ) )
271
- }
272
- }
273
-
274
- fn bytearray_lower ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
275
- arg_check ! ( vm, args, required = [ ( obj, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
276
- let value = get_value ( obj) . to_vec ( ) . to_ascii_lowercase ( ) ;
277
- Ok ( vm. ctx . new_bytearray ( value) )
278
- }
279
-
280
- fn bytearray_upper ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
281
- arg_check ! ( vm, args, required = [ ( obj, Some ( vm. ctx. bytearray_type( ) ) ) ] ) ;
282
- let value = get_value ( obj) . to_vec ( ) . to_ascii_uppercase ( ) ;
283
- Ok ( vm. ctx . new_bytearray ( value) )
284
- }
285
-
286
260
#[ cfg( test) ]
287
261
mod tests {
288
262
use super :: * ;
289
263
290
264
#[ test]
291
265
fn bytearray_to_hex_formatting ( ) {
292
- assert_eq ! ( & bytearray_to_hex ( & [ 11u8 , 222u8 ] ) , "\\ x0b\\ xde" ) ;
266
+ assert_eq ! ( & to_hex ( & [ 11u8 , 222u8 ] ) , "\\ x0b\\ xde" ) ;
293
267
}
294
268
}
0 commit comments