@@ -111,6 +111,7 @@ use vec;
111111use vec:: { OwnedVector , OwnedCopyableVector , ImmutableVector , MutableVector } ;
112112use default:: Default ;
113113use send_str:: { SendStr , SendStrOwned } ;
114+ use unstable:: raw:: Repr ;
114115
115116/*
116117Section: Conditions
@@ -382,11 +383,7 @@ impl<'a> Iterator<(uint, char)> for CharOffsetIterator<'a> {
382383 fn next ( & mut self ) -> Option < ( uint , char ) > {
383384 // Compute the byte offset by using the pointer offset between
384385 // 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 ;
390387 self . iter . next ( ) . map ( |ch| ( offset, ch) )
391388 }
392389
@@ -400,11 +397,8 @@ impl<'a> DoubleEndedIterator<(uint, char)> for CharOffsetIterator<'a> {
400397 #[ inline]
401398 fn next_back ( & mut self ) -> Option < ( uint , char ) > {
402399 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 ;
408402 ( offset, ch)
409403 } )
410404 }
@@ -748,41 +742,30 @@ pub fn replace(s: &str, from: &str, to: &str) -> ~str {
748742Section: Comparing strings
749743*/
750744
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+
751756/// Bytewise slice equality
752757#[ cfg( not( test) ) ]
753758#[ lang="str_eq" ]
754759#[ inline]
755760pub 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)
768762}
769763
770764/// Bytewise slice equality
771765#[ cfg( test) ]
772766#[ inline]
773767pub 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)
786769}
787770
788771/// Bytewise string equality
@@ -1080,12 +1063,10 @@ pub mod raw {
10801063 /// Caller must check slice boundaries!
10811064 #[ inline]
10821065 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+ } )
10891070 }
10901071
10911072 /// Appends a byte to a string.
@@ -1309,7 +1290,7 @@ impl<'a> Str for @str {
13091290impl<'a> Container for &'a str {
13101291 #[inline]
13111292 fn len(&self) -> uint {
1312- self.as_imm_buf(|_p, n| n)
1293+ self.repr().len
13131294 }
13141295}
13151296
@@ -1997,10 +1978,12 @@ pub trait StrSlice<'a> {
19971978 /// ```
19981979 fn subslice_offset( & self , inner: & str ) -> uint;
19991980
2000- /// Work with the byte buffer and length of a slice .
1981+ /// Return an unsafe pointer to the strings buffer .
20011982 ///
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 ;
20041987}
20051988
20061989impl <' a> StrSlice <' a> for & ' a str {
@@ -2278,15 +2261,14 @@ impl<'a> StrSlice<'a> for &'a str {
22782261
22792262 #[ inline]
22802263 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) ;
22842267
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+ }
22902272 }
22912273
22922274 #[ inline]
@@ -2482,27 +2464,19 @@ impl<'a> StrSlice<'a> for &'a str {
24822464 }
24832465
24842466 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
25002475 }
25012476
25022477 #[ 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
25062480 }
25072481}
25082482
@@ -3391,19 +3365,15 @@ mod tests {
33913365 }
33923366
33933367 #[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+ }
34073377 }
34083378
34093379 #[test]
@@ -3936,10 +3906,10 @@ mod tests {
39363906 assert_eq!(s.as_slice(), " ");
39373907
39383908 let mut s = ~" 12345 ";
3939- let p = s.as_imm_buf(|p,_| p );
3909+ let p = s.as_ptr( );
39403910 s.truncate(3);
39413911 s.push_str(" 6 ");
3942- let p_ = s.as_imm_buf(|p,_| p );
3912+ let p_ = s.as_ptr( );
39433913 assert_eq!(p_, p);
39443914 }
39453915
0 commit comments