1
1
use bstr:: ByteSlice ;
2
2
use num_bigint:: { BigInt , ToBigInt } ;
3
- use num_integer:: Integer ;
4
3
use num_traits:: { One , Signed , ToPrimitive , Zero } ;
5
4
use std:: convert:: TryFrom ;
6
5
use std:: ops:: Range ;
@@ -179,25 +178,17 @@ impl ByteInnerFindOptions {
179
178
#[ derive( FromArgs ) ]
180
179
pub struct ByteInnerPaddingOptions {
181
180
#[ pyarg( positional_only, optional = false ) ]
182
- width : PyIntRef ,
181
+ width : isize ,
183
182
#[ pyarg( positional_only, optional = true ) ]
184
- fillbyte : OptionalArg < PyObjectRef > ,
183
+ fillchar : OptionalArg < PyObjectRef > ,
185
184
}
185
+
186
186
impl ByteInnerPaddingOptions {
187
- fn get_value ( self , fn_name : & str , len : usize , vm : & VirtualMachine ) -> PyResult < ( u8 , usize ) > {
188
- let fillbyte = if let OptionalArg :: Present ( v) = & self . fillbyte {
189
- match try_as_byte ( & v) {
190
- Some ( x) => {
191
- if x. len ( ) == 1 {
192
- x[ 0 ]
193
- } else {
194
- return Err ( vm. new_type_error ( format ! (
195
- "{}() argument 2 must be a byte string of length 1, not {}" ,
196
- fn_name, & v
197
- ) ) ) ;
198
- }
199
- }
200
- None => {
187
+ fn get_value ( self , fn_name : & str , vm : & VirtualMachine ) -> PyResult < ( isize , u8 ) > {
188
+ let fillchar = if let OptionalArg :: Present ( v) = self . fillchar {
189
+ match try_as_byte ( v. clone ( ) ) {
190
+ Some ( x) if x. len ( ) == 1 => x[ 0 ] ,
191
+ _ => {
201
192
return Err ( vm. new_type_error ( format ! (
202
193
"{}() argument 2 must be a byte string of length 1, not {}" ,
203
194
fn_name, & v
@@ -208,20 +199,7 @@ impl ByteInnerPaddingOptions {
208
199
b' ' // default is space
209
200
} ;
210
201
211
- // <0 = no change
212
- let width = if let Some ( x) = self . width . as_bigint ( ) . to_usize ( ) {
213
- if x <= len {
214
- 0
215
- } else {
216
- x
217
- }
218
- } else {
219
- 0
220
- } ;
221
-
222
- let diff: usize = if width != 0 { width - len } else { 0 } ;
223
-
224
- Ok ( ( fillbyte, diff) )
202
+ Ok ( ( self . width , fillchar) )
225
203
}
226
204
}
227
205
@@ -724,59 +702,43 @@ impl PyByteInner {
724
702
. collect :: < Vec < u8 > > ( ) )
725
703
}
726
704
727
- pub fn center (
705
+ #[ inline]
706
+ fn pad (
728
707
& self ,
729
708
options : ByteInnerPaddingOptions ,
709
+ pad : fn ( & [ u8 ] , usize , u8 ) -> Vec < u8 > ,
730
710
vm : & VirtualMachine ,
731
711
) -> PyResult < Vec < u8 > > {
732
- let ( fillbyte, diff) = options. get_value ( "center" , self . len ( ) , vm) ?;
733
-
734
- let mut ln: usize = diff / 2 ;
735
- let mut rn: usize = ln;
736
-
737
- if diff. is_odd ( ) && self . len ( ) % 2 == 0 {
738
- ln += 1
739
- }
740
-
741
- if diff. is_odd ( ) && self . len ( ) % 2 != 0 {
742
- rn += 1
743
- }
744
-
745
- // merge all
746
- let mut res = vec ! [ fillbyte; ln] ;
747
- res. extend_from_slice ( & self . elements [ ..] ) ;
748
- res. extend_from_slice ( & vec ! [ fillbyte; rn] [ ..] ) ;
712
+ let ( width, fillchar) = options. get_value ( "center" , vm) ?;
713
+ Ok ( if self . len ( ) as isize >= width {
714
+ Vec :: from ( & self . elements [ ..] )
715
+ } else {
716
+ pad ( & self . elements , width as usize , fillchar)
717
+ } )
718
+ }
749
719
750
- Ok ( res)
720
+ pub fn center (
721
+ & self ,
722
+ options : ByteInnerPaddingOptions ,
723
+ vm : & VirtualMachine ,
724
+ ) -> PyResult < Vec < u8 > > {
725
+ self . pad ( options, PyCommonString :: < u8 > :: py_center, vm)
751
726
}
752
727
753
728
pub fn ljust (
754
729
& self ,
755
730
options : ByteInnerPaddingOptions ,
756
731
vm : & VirtualMachine ,
757
732
) -> PyResult < Vec < u8 > > {
758
- let ( fillbyte, diff) = options. get_value ( "ljust" , self . len ( ) , vm) ?;
759
-
760
- // merge all
761
- let mut res = vec ! [ ] ;
762
- res. extend_from_slice ( & self . elements [ ..] ) ;
763
- res. extend_from_slice ( & vec ! [ fillbyte; diff] [ ..] ) ;
764
-
765
- Ok ( res)
733
+ self . pad ( options, PyCommonString :: < u8 > :: py_ljust, vm)
766
734
}
767
735
768
736
pub fn rjust (
769
737
& self ,
770
738
options : ByteInnerPaddingOptions ,
771
739
vm : & VirtualMachine ,
772
740
) -> PyResult < Vec < u8 > > {
773
- let ( fillbyte, diff) = options. get_value ( "rjust" , self . len ( ) , vm) ?;
774
-
775
- // merge all
776
- let mut res = vec ! [ fillbyte; diff] ;
777
- res. extend_from_slice ( & self . elements [ ..] ) ;
778
-
779
- Ok ( res)
741
+ self . pad ( options, PyCommonString :: < u8 > :: py_rjust, vm)
780
742
}
781
743
782
744
pub fn count ( & self , options : ByteInnerFindOptions , vm : & VirtualMachine ) -> PyResult < usize > {
@@ -1130,7 +1092,9 @@ impl PyByteInner {
1130
1092
{
1131
1093
return Err ( vm. new_overflow_error ( "replace bytes is too long" . to_owned ( ) ) ) ;
1132
1094
}
1133
- let result_len = self . elements . len ( ) + count * ( to. len ( ) - from. len ( ) ) ;
1095
+ let result_len = ( self . elements . len ( ) as isize
1096
+ + count as isize * ( to. len ( ) as isize - from. len ( ) as isize ) )
1097
+ as usize ;
1134
1098
1135
1099
let mut result = Vec :: with_capacity ( result_len) ;
1136
1100
let mut last_end = 0 ;
@@ -1259,8 +1223,8 @@ impl PyByteInner {
1259
1223
}
1260
1224
}
1261
1225
1262
- pub fn try_as_byte ( obj : & PyObjectRef ) -> Option < Vec < u8 > > {
1263
- match_class ! ( match obj. clone ( ) {
1226
+ pub fn try_as_byte ( obj : PyObjectRef ) -> Option < Vec < u8 > > {
1227
+ match_class ! ( match obj {
1264
1228
i @ PyBytes => Some ( i. get_value( ) . to_vec( ) ) ,
1265
1229
j @ PyByteArray => Some ( j. borrow_value( ) . elements. to_vec( ) ) ,
1266
1230
_ => None ,
@@ -1350,15 +1314,29 @@ impl PyCommonStringWrapper<[u8]> for PyByteInner {
1350
1314
const ASCII_WHITESPACES : [ u8 ; 6 ] = [ 0x20 , 0x09 , 0x0a , 0x0c , 0x0d , 0x0b ] ;
1351
1315
1352
1316
impl PyCommonString < u8 > for [ u8 ] {
1353
- fn get_slice ( & self , range : std:: ops:: Range < usize > ) -> & Self {
1317
+ type Container = Vec < u8 > ;
1318
+
1319
+ fn with_capacity ( capacity : usize ) -> Self :: Container {
1320
+ Vec :: with_capacity ( capacity)
1321
+ }
1322
+
1323
+ fn get_bytes < ' a > ( & ' a self , range : std:: ops:: Range < usize > ) -> & ' a Self {
1324
+ & self [ range]
1325
+ }
1326
+
1327
+ fn get_chars < ' a > ( & ' a self , range : std:: ops:: Range < usize > ) -> & ' a Self {
1354
1328
& self [ range]
1355
1329
}
1356
1330
1357
1331
fn is_empty ( & self ) -> bool {
1358
1332
Self :: is_empty ( self )
1359
1333
}
1360
1334
1361
- fn len ( & self ) -> usize {
1335
+ fn bytes_len ( & self ) -> usize {
1336
+ Self :: len ( self )
1337
+ }
1338
+
1339
+ fn chars_len ( & self ) -> usize {
1362
1340
Self :: len ( self )
1363
1341
}
1364
1342
@@ -1407,4 +1385,12 @@ impl PyCommonString<u8> for [u8] {
1407
1385
}
1408
1386
splited
1409
1387
}
1388
+
1389
+ fn py_pad ( & self , left : usize , right : usize , fill : u8 ) -> Self :: Container {
1390
+ let mut u = Vec :: with_capacity ( left + self . len ( ) + right) ;
1391
+ u. extend ( std:: iter:: repeat ( fill) . take ( left) ) ;
1392
+ u. extend_from_slice ( self ) ;
1393
+ u. extend ( std:: iter:: repeat ( fill) . take ( right) ) ;
1394
+ u
1395
+ }
1410
1396
}
0 commit comments