@@ -22,8 +22,7 @@ use char;
22
22
use char:: Char ;
23
23
use clone:: { Clone , DeepClone } ;
24
24
use container:: { Container , Mutable } ;
25
- use num:: Times ;
26
- use iter:: { Iterator , FromIterator , Extendable } ;
25
+ use iter:: { Iterator , FromIterator , Extendable , range} ;
27
26
use iter:: { Filter , AdditiveIterator , Map } ;
28
27
use iter:: { Invert , DoubleEndedIterator , ExactSize } ;
29
28
use libc;
@@ -33,7 +32,6 @@ use ptr;
33
32
use ptr:: RawPtr ;
34
33
use to_str:: ToStr ;
35
34
use uint;
36
- use unstable:: raw:: { Repr , Slice } ;
37
35
use vec;
38
36
use vec:: { OwnedVector , OwnedCopyableVector , ImmutableVector , MutableVector } ;
39
37
use default:: Default ;
@@ -182,23 +180,15 @@ impl<'self, S: Str> StrVector for &'self [S] {
182
180
fn concat ( & self ) -> ~str {
183
181
if self . is_empty ( ) { return ~""; }
184
182
183
+ // `len` calculation may overflow but push_str but will check boundaries
185
184
let len = self . iter ( ) . map ( |s| s. as_slice ( ) . len ( ) ) . sum ( ) ;
186
185
187
- let mut s = with_capacity ( len) ;
186
+ let mut result = with_capacity ( len) ;
188
187
189
- unsafe {
190
- do s. as_mut_buf |buf, _| {
191
- let mut buf = buf;
192
- for ss in self . iter ( ) {
193
- do ss. as_slice ( ) . as_imm_buf |ssbuf, sslen| {
194
- ptr:: copy_memory ( buf, ssbuf, sslen) ;
195
- buf = buf. offset ( sslen as int ) ;
196
- }
197
- }
198
- }
199
- raw:: set_len ( & mut s, len) ;
188
+ for s in self . iter ( ) {
189
+ result. push_str ( s. as_slice ( ) )
200
190
}
201
- s
191
+ result
202
192
}
203
193
204
194
/// Concatenate a vector of strings, placing a given separator between each.
@@ -209,34 +199,21 @@ impl<'self, S: Str> StrVector for &'self [S] {
209
199
if sep. is_empty ( ) { return self . concat ( ) ; }
210
200
211
201
// this is wrong without the guarantee that `self` is non-empty
202
+ // `len` calculation may overflow but push_str but will check boundaries
212
203
let len = sep. len ( ) * ( self . len ( ) - 1 )
213
204
+ self . iter ( ) . map ( |s| s. as_slice ( ) . len ( ) ) . sum ( ) ;
214
- let mut s = ~"" ;
205
+ let mut result = with_capacity ( len ) ;
215
206
let mut first = true ;
216
207
217
- s. reserve ( len) ;
218
-
219
- unsafe {
220
- do s. as_mut_buf |buf, _| {
221
- do sep. as_imm_buf |sepbuf, seplen| {
222
- let mut buf = buf;
223
- for ss in self . iter ( ) {
224
- do ss. as_slice ( ) . as_imm_buf |ssbuf, sslen| {
225
- if first {
226
- first = false ;
227
- } else {
228
- ptr:: copy_memory ( buf, sepbuf, seplen) ;
229
- buf = buf. offset ( seplen as int ) ;
230
- }
231
- ptr:: copy_memory ( buf, ssbuf, sslen) ;
232
- buf = buf. offset ( sslen as int ) ;
233
- }
234
- }
235
- }
208
+ for s in self . iter ( ) {
209
+ if first {
210
+ first = false ;
211
+ } else {
212
+ result. push_str ( sep) ;
236
213
}
237
- raw :: set_len ( & mut s , len ) ;
214
+ result . push_str ( s . as_slice ( ) ) ;
238
215
}
239
- s
216
+ result
240
217
}
241
218
}
242
219
@@ -959,7 +936,6 @@ static TAG_CONT_U8: u8 = 128u8;
959
936
960
937
/// Unsafe operations
961
938
pub mod raw {
962
- use option:: Some ;
963
939
use cast;
964
940
use libc;
965
941
use ptr;
@@ -1062,21 +1038,22 @@ pub mod raw {
1062
1038
}
1063
1039
}
1064
1040
1065
- /// Appends a byte to a string. (Not UTF-8 safe).
1041
+ /// Appends a byte to a string.
1042
+ /// The caller must preserve the valid UTF-8 property.
1066
1043
#[ inline]
1067
1044
pub unsafe fn push_byte ( s : & mut ~str , b : u8 ) {
1068
- let v: & mut ~[ u8 ] = cast:: transmute ( s) ;
1069
- v. push ( b) ;
1045
+ as_owned_vec ( s) . push ( b)
1070
1046
}
1071
1047
1072
- /// Appends a vector of bytes to a string. (Not UTF-8 safe).
1073
- unsafe fn push_bytes ( s : & mut ~ str , bytes : & [ u8 ] ) {
1074
- let new_len = s . len ( ) + bytes . len ( ) ;
1075
- s . reserve_at_least ( new_len ) ;
1076
- for byte in bytes. iter ( ) { push_byte ( & mut * s , * byte ) ; }
1048
+ /// Appends a vector of bytes to a string.
1049
+ /// The caller must preserve the valid UTF-8 property.
1050
+ # [ inline ]
1051
+ pub unsafe fn push_bytes ( s : & mut ~ str , bytes : & [ u8 ] ) {
1052
+ vec :: bytes:: push_bytes ( as_owned_vec ( s ) , bytes ) ;
1077
1053
}
1078
1054
1079
- /// Removes the last byte from a string and returns it. (Not UTF-8 safe).
1055
+ /// Removes the last byte from a string and returns it.
1056
+ /// The caller must preserve the valid UTF-8 property.
1080
1057
pub unsafe fn pop_byte ( s : & mut ~str ) -> u8 {
1081
1058
let len = s. len ( ) ;
1082
1059
assert ! ( ( len > 0 u) ) ;
@@ -1085,7 +1062,8 @@ pub mod raw {
1085
1062
return b;
1086
1063
}
1087
1064
1088
- /// Removes the first byte from a string and returns it. (Not UTF-8 safe).
1065
+ /// Removes the first byte from a string and returns it.
1066
+ /// The caller must preserve the valid UTF-8 property.
1089
1067
pub unsafe fn shift_byte ( s : & mut ~str ) -> u8 {
1090
1068
let len = s. len ( ) ;
1091
1069
assert ! ( ( len > 0 u) ) ;
@@ -1094,15 +1072,21 @@ pub mod raw {
1094
1072
return b;
1095
1073
}
1096
1074
1075
+ /// Access the str in its vector representation.
1076
+ /// The caller must preserve the valid UTF-8 property when modifying.
1077
+ #[ inline]
1078
+ pub unsafe fn as_owned_vec < ' a > ( s : & ' a mut ~str ) -> & ' a mut ~[ u8 ] {
1079
+ cast:: transmute ( s)
1080
+ }
1081
+
1097
1082
/// Sets the length of a string
1098
1083
///
1099
1084
/// This will explicitly set the size of the string, without actually
1100
1085
/// modifying its buffers, so it is up to the caller to ensure that
1101
1086
/// the string is actually the specified size.
1102
1087
#[ inline]
1103
1088
pub unsafe fn set_len ( s : & mut ~str , new_len : uint ) {
1104
- let v: & mut ~[ u8 ] = cast:: transmute ( s) ;
1105
- vec:: raw:: set_len ( v, new_len)
1089
+ vec:: raw:: set_len ( as_owned_vec ( s) , new_len)
1106
1090
}
1107
1091
1108
1092
/// Sets the length of a string
@@ -2053,22 +2037,11 @@ impl<'self> StrSlice<'self> for &'self str {
2053
2037
2054
2038
/// Given a string, make a new string with repeated copies of it.
2055
2039
fn repeat(&self, nn: uint) -> ~str {
2056
- do self.as_imm_buf |buf, len| {
2057
- let mut ret = with_capacity(nn * len);
2058
-
2059
- unsafe {
2060
- do ret.as_mut_buf |rbuf, _len| {
2061
- let mut rbuf = rbuf;
2062
-
2063
- do nn.times {
2064
- ptr::copy_memory(rbuf, buf, len);
2065
- rbuf = rbuf.offset(len as int);
2066
- }
2067
- }
2068
- raw::set_len(&mut ret, nn * len);
2069
- }
2070
- ret
2040
+ let mut ret = with_capacity(nn * self.len());
2041
+ for _ in range(0, nn) {
2042
+ ret.push_str(*self);
2071
2043
}
2044
+ ret
2072
2045
}
2073
2046
2074
2047
/// Retrieves the first character from a string slice and returns
@@ -2191,54 +2164,35 @@ impl OwnedStr for ~str {
2191
2164
/// Appends a string slice to the back of a string, without overallocating
2192
2165
#[inline]
2193
2166
fn push_str_no_overallocate(&mut self, rhs: &str) {
2194
- unsafe {
2195
- let llen = self.len();
2196
- let rlen = rhs.len();
2197
- self.reserve(llen + rlen);
2198
- do self.as_imm_buf |lbuf, _llen| {
2199
- do rhs.as_imm_buf |rbuf, _rlen| {
2200
- let dst = ptr::offset(lbuf, llen as int);
2201
- let dst = cast::transmute_mut_unsafe(dst);
2202
- ptr::copy_memory(dst, rbuf, rlen);
2203
- }
2204
- }
2205
- raw::set_len(self, llen + rlen);
2206
- }
2167
+ let new_cap = self.len() + rhs.len();
2168
+ self.reserve(new_cap);
2169
+ self.push_str(rhs);
2207
2170
}
2208
2171
2209
2172
/// Appends a string slice to the back of a string
2210
2173
#[inline]
2211
2174
fn push_str(&mut self, rhs: &str) {
2212
2175
unsafe {
2213
- let llen = self.len();
2214
- let rlen = rhs.len();
2215
- self.reserve_at_least(llen + rlen);
2216
- do self.as_imm_buf |lbuf, _llen| {
2217
- do rhs.as_imm_buf |rbuf, _rlen| {
2218
- let dst = ptr::offset(lbuf, llen as int);
2219
- let dst = cast::transmute_mut_unsafe(dst);
2220
- ptr::copy_memory(dst, rbuf, rlen);
2221
- }
2222
- }
2223
- raw::set_len(self, llen + rlen);
2176
+ raw::push_bytes(self, rhs.as_bytes());
2224
2177
}
2225
2178
}
2226
2179
2227
2180
/// Appends a character to the back of a string
2228
2181
#[inline]
2229
2182
fn push_char(&mut self, c: char) {
2230
2183
let cur_len = self.len();
2231
- self.reserve_at_least(cur_len + 4); // may use up to 4 bytes
2232
-
2233
- // Attempt to not use an intermediate buffer by just pushing bytes
2234
- // directly onto this string.
2184
+ // may use up to 4 bytes.
2235
2185
unsafe {
2236
- let v = self.repr();
2237
- let len = c.encode_utf8(cast::transmute(Slice {
2238
- data: ((&(*v).data) as *u8).offset(cur_len as int),
2239
- len: 4,
2240
- }));
2241
- raw::set_len(self, cur_len + len);
2186
+ raw::as_owned_vec(self).reserve_additional(4);
2187
+
2188
+ // Attempt to not use an intermediate buffer by just pushing bytes
2189
+ // directly onto this string.
2190
+ let used = do self.as_mut_buf |buf, _| {
2191
+ do vec::raw::mut_buf_as_slice(buf.offset(cur_len as int), 4) |slc| {
2192
+ c.encode_utf8(slc)
2193
+ }
2194
+ };
2195
+ raw::set_len(self, cur_len + used);
2242
2196
}
2243
2197
}
2244
2198
@@ -2298,8 +2252,7 @@ impl OwnedStr for ~str {
2298
2252
#[inline]
2299
2253
fn reserve(&mut self, n: uint) {
2300
2254
unsafe {
2301
- let v: &mut ~[u8] = cast::transmute(self);
2302
- (*v).reserve(n);
2255
+ raw::as_owned_vec(self).reserve(n)
2303
2256
}
2304
2257
}
2305
2258
@@ -2321,7 +2274,7 @@ impl OwnedStr for ~str {
2321
2274
/// * n - The number of bytes to reserve space for
2322
2275
#[inline]
2323
2276
fn reserve_at_least(&mut self, n: uint) {
2324
- self.reserve(uint::next_power_of_two (n))
2277
+ self.reserve(uint::next_power_of_two_opt(n).unwrap_or (n))
2325
2278
}
2326
2279
2327
2280
/// Returns the number of single-byte characters the string can hold without
@@ -2351,8 +2304,9 @@ impl OwnedStr for ~str {
2351
2304
2352
2305
#[inline]
2353
2306
fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T {
2354
- let v: &mut ~[u8] = unsafe { cast::transmute(self) };
2355
- v.as_mut_buf(f)
2307
+ unsafe {
2308
+ raw::as_owned_vec(self).as_mut_buf(f)
2309
+ }
2356
2310
}
2357
2311
}
2358
2312
0 commit comments