@@ -111,6 +111,7 @@ use vec;
111
111
use vec:: { OwnedVector , OwnedCopyableVector , ImmutableVector , MutableVector } ;
112
112
use default:: Default ;
113
113
use send_str:: { SendStr , SendStrOwned } ;
114
+ use unstable:: raw:: Repr ;
114
115
115
116
/*
116
117
Section: Conditions
@@ -382,11 +383,7 @@ impl<'a> Iterator<(uint, char)> for CharOffsetIterator<'a> {
382
383
fn next ( & mut self ) -> Option < ( uint , char ) > {
383
384
// Compute the byte offset by using the pointer offset between
384
385
// the original string slice and the iterator's remaining part
385
- let offset = self . string . as_imm_buf ( |a, _| {
386
- self . iter . string . as_imm_buf ( |b, _| {
387
- b as uint - a as uint
388
- } )
389
- } ) ;
386
+ let offset = self . iter . string . as_ptr ( ) as uint - self . string . as_ptr ( ) as uint ;
390
387
self . iter . next ( ) . map ( |ch| ( offset, ch) )
391
388
}
392
389
@@ -400,11 +397,8 @@ impl<'a> DoubleEndedIterator<(uint, char)> for CharOffsetIterator<'a> {
400
397
#[ inline]
401
398
fn next_back ( & mut self ) -> Option < ( uint , char ) > {
402
399
self . iter . next_back ( ) . map ( |ch| {
403
- let offset = self . string . as_imm_buf ( |a, _| {
404
- self . iter . string . as_imm_buf ( |b, len| {
405
- b as uint - a as uint + len
406
- } )
407
- } ) ;
400
+ let offset = self . iter . string . len ( ) +
401
+ self . iter . string . as_ptr ( ) as uint - self . string . as_ptr ( ) as uint ;
408
402
( offset, ch)
409
403
} )
410
404
}
@@ -748,41 +742,30 @@ pub fn replace(s: &str, from: &str, to: &str) -> ~str {
748
742
Section: Comparing strings
749
743
*/
750
744
745
+ // share the implementation of the lang-item vs. non-lang-item
746
+ // eq_slice.
747
+ #[ inline]
748
+ fn eq_slice_ ( a : & str , b : & str ) -> bool {
749
+ a. len ( ) == b. len ( ) && unsafe {
750
+ libc:: memcmp ( a. as_ptr ( ) as * libc:: c_void ,
751
+ b. as_ptr ( ) as * libc:: c_void ,
752
+ a. len ( ) as libc:: size_t ) == 0
753
+ }
754
+ }
755
+
751
756
/// Bytewise slice equality
752
757
#[ cfg( not( test) ) ]
753
758
#[ lang="str_eq" ]
754
759
#[ inline]
755
760
pub fn eq_slice ( a : & str , b : & str ) -> bool {
756
- a. as_imm_buf ( |ap, alen| {
757
- b. as_imm_buf ( |bp, blen| {
758
- if ( alen != blen) { false }
759
- else {
760
- unsafe {
761
- libc:: memcmp ( ap as * libc:: c_void ,
762
- bp as * libc:: c_void ,
763
- alen as libc:: size_t ) == 0
764
- }
765
- }
766
- } )
767
- } )
761
+ eq_slice_ ( a, b)
768
762
}
769
763
770
764
/// Bytewise slice equality
771
765
#[ cfg( test) ]
772
766
#[ inline]
773
767
pub fn eq_slice ( a : & str , b : & str ) -> bool {
774
- a. as_imm_buf ( |ap, alen| {
775
- b. as_imm_buf ( |bp, blen| {
776
- if ( alen != blen) { false }
777
- else {
778
- unsafe {
779
- libc:: memcmp ( ap as * libc:: c_void ,
780
- bp as * libc:: c_void ,
781
- alen as libc:: size_t ) == 0
782
- }
783
- }
784
- } )
785
- } )
768
+ eq_slice_ ( a, b)
786
769
}
787
770
788
771
/// Bytewise string equality
@@ -1080,12 +1063,10 @@ pub mod raw {
1080
1063
/// Caller must check slice boundaries!
1081
1064
#[ inline]
1082
1065
pub unsafe fn slice_unchecked < ' a > ( s : & ' a str , begin : uint , end : uint ) -> & ' a str {
1083
- s. as_imm_buf ( |sbuf, _n| {
1084
- cast:: transmute ( Slice {
1085
- data : sbuf. offset ( begin as int ) ,
1086
- len : end - begin,
1087
- } )
1088
- } )
1066
+ cast:: transmute ( Slice {
1067
+ data : s. as_ptr ( ) . offset ( begin as int ) ,
1068
+ len : end - begin,
1069
+ } )
1089
1070
}
1090
1071
1091
1072
/// Appends a byte to a string.
@@ -1309,7 +1290,7 @@ impl<'a> Str for @str {
1309
1290
impl<'a> Container for &'a str {
1310
1291
#[inline]
1311
1292
fn len(&self) -> uint {
1312
- self.as_imm_buf(|_p, n| n)
1293
+ self.repr().len
1313
1294
}
1314
1295
}
1315
1296
@@ -1997,10 +1978,12 @@ pub trait StrSlice<'a> {
1997
1978
/// ```
1998
1979
fn subslice_offset( & self , inner: & str ) -> uint;
1999
1980
2000
- /// Work with the byte buffer and length of a slice .
1981
+ /// Return an unsafe pointer to the strings buffer .
2001
1982
///
2002
- /// The buffer does not have a null terminator.
2003
- fn as_imm_buf<T >( & self , f: |* u8 , uint| -> T ) -> T ;
1983
+ /// The caller must ensure that the string outlives this pointer,
1984
+ /// and that it is not reallocated (e.g. by pushing to the
1985
+ /// string).
1986
+ fn as_ptr( & self ) -> * u8 ;
2004
1987
}
2005
1988
2006
1989
impl <' a> StrSlice <' a> for & ' a str {
@@ -2278,15 +2261,14 @@ impl<'a> StrSlice<'a> for &'a str {
2278
2261
2279
2262
#[ inline]
2280
2263
fn to_owned( & self ) -> ~str {
2281
- self . as_imm_buf ( |src , len| {
2282
- unsafe {
2283
- let mut v = vec:: with_capacity( len) ;
2264
+ let len = self . len ( ) ;
2265
+ unsafe {
2266
+ let mut v = vec:: with_capacity( len) ;
2284
2267
2285
- ptr:: copy_memory( v. as_mut_ptr( ) , src, len) ;
2286
- v. set_len( len) ;
2287
- :: cast:: transmute( v)
2288
- }
2289
- } )
2268
+ ptr:: copy_memory( v. as_mut_ptr( ) , self . as_ptr( ) , len) ;
2269
+ v. set_len( len) ;
2270
+ :: cast:: transmute( v)
2271
+ }
2290
2272
}
2291
2273
2292
2274
#[ inline]
@@ -2482,27 +2464,19 @@ impl<'a> StrSlice<'a> for &'a str {
2482
2464
}
2483
2465
2484
2466
fn subslice_offset( & self , inner: & str ) -> uint {
2485
- self . as_imm_buf( |a, a_len| {
2486
- inner. as_imm_buf( |b, b_len| {
2487
- let a_start: uint;
2488
- let a_end: uint;
2489
- let b_start: uint;
2490
- let b_end: uint;
2491
- unsafe {
2492
- a_start = cast:: transmute( a) ; a_end = a_len + cast:: transmute( a) ;
2493
- b_start = cast:: transmute( b) ; b_end = b_len + cast:: transmute( b) ;
2494
- }
2495
- assert!( a_start <= b_start) ;
2496
- assert!( b_end <= a_end) ;
2497
- b_start - a_start
2498
- } )
2499
- } )
2467
+ let a_start = self . as_ptr( ) as uint;
2468
+ let a_end = a_start + self . len( ) ;
2469
+ let b_start = inner. as_ptr( ) as uint;
2470
+ let b_end = b_start + inner. len( ) ;
2471
+
2472
+ assert!( a_start <= b_start) ;
2473
+ assert!( b_end <= a_end) ;
2474
+ b_start - a_start
2500
2475
}
2501
2476
2502
2477
#[ inline]
2503
- fn as_imm_buf<T >( & self , f: |* u8 , uint| -> T ) -> T {
2504
- let v: & [ u8 ] = unsafe { cast:: transmute( * self ) } ;
2505
- f( v. as_ptr( ) , v. len( ) )
2478
+ fn as_ptr( & self ) -> * u8 {
2479
+ self . repr( ) . data
2506
2480
}
2507
2481
}
2508
2482
@@ -3391,19 +3365,15 @@ mod tests {
3391
3365
}
3392
3366
3393
3367
#[test]
3394
- fn test_as_imm_buf() {
3395
- " ".as_imm_buf(|_, len| assert_eq!(len, 0));
3396
-
3397
- " hello".as_imm_buf(|buf, len| {
3398
- assert_eq!(len, 5);
3399
- unsafe {
3400
- assert_eq!(*ptr::offset(buf, 0), 'h' as u8);
3401
- assert_eq!(*ptr::offset(buf, 1), 'e' as u8);
3402
- assert_eq!(*ptr::offset(buf, 2), 'l' as u8);
3403
- assert_eq!(*ptr::offset(buf, 3), 'l' as u8);
3404
- assert_eq!(*ptr::offset(buf, 4), 'o' as u8);
3405
- }
3406
- })
3368
+ fn test_as_ptr() {
3369
+ let buf = " hello".as_ptr();
3370
+ unsafe {
3371
+ assert_eq!(*ptr::offset(buf, 0), 'h' as u8);
3372
+ assert_eq!(*ptr::offset(buf, 1), 'e' as u8);
3373
+ assert_eq!(*ptr::offset(buf, 2), 'l' as u8);
3374
+ assert_eq!(*ptr::offset(buf, 3), 'l' as u8);
3375
+ assert_eq!(*ptr::offset(buf, 4), 'o' as u8);
3376
+ }
3407
3377
}
3408
3378
3409
3379
#[test]
@@ -3936,10 +3906,10 @@ mod tests {
3936
3906
assert_eq!(s.as_slice(), " ");
3937
3907
3938
3908
let mut s = ~" 12345 ";
3939
- let p = s.as_imm_buf(|p,_| p );
3909
+ let p = s.as_ptr( );
3940
3910
s.truncate(3);
3941
3911
s.push_str(" 6 ");
3942
- let p_ = s.as_imm_buf(|p,_| p );
3912
+ let p_ = s.as_ptr( );
3943
3913
assert_eq!(p_, p);
3944
3914
}
3945
3915
0 commit comments