@@ -19,8 +19,9 @@ use iter::{Extendable, FromIterator, Iterator, range};
19
19
use mem;
20
20
use option:: { None , Option , Some } ;
21
21
use ptr:: RawPtr ;
22
+ use ptr;
22
23
use slice:: { OwnedVector , Vector , CloneableVector } ;
23
- use str:: { OwnedStr , Str , StrSlice , StrAllocating } ;
24
+ use str:: { CharRange , OwnedStr , Str , StrSlice , StrAllocating } ;
24
25
use str;
25
26
use vec:: Vec ;
26
27
@@ -215,19 +216,49 @@ impl StrBuf {
215
216
Some ( byte)
216
217
}
217
218
219
+ /// Removes the last character from the string buffer and returns it. Returns `None` if this
220
+ /// string buffer is empty.
221
+ #[ inline]
222
+ pub fn pop_char ( & mut self ) -> Option < char > {
223
+ let len = self . len ( ) ;
224
+ if len == 0 {
225
+ return None
226
+ }
227
+
228
+ let CharRange { ch, next} = self . as_slice ( ) . char_range_at_reverse ( len) ;
229
+ unsafe {
230
+ self . vec . set_len ( next) ;
231
+ }
232
+ Some ( ch)
233
+ }
234
+
218
235
/// Removes the first byte from the string buffer and returns it. Returns `None` if this string
219
236
/// buffer is empty.
220
237
///
221
238
/// The caller must preserve the valid UTF-8 property.
222
239
pub unsafe fn shift_byte ( & mut self ) -> Option < u8 > {
240
+ self . vec . shift ( )
241
+ }
242
+
243
+ /// Removes the first character from the string buffer and returns it. Returns `None` if this
244
+ /// string buffer is empty.
245
+ ///
246
+ /// # Warning
247
+ ///
248
+ /// This is a O(n) operation as it requires copying every element in the buffer.
249
+ pub fn shift_char ( & mut self ) -> Option < char > {
223
250
let len = self . len ( ) ;
224
251
if len == 0 {
225
252
return None
226
253
}
227
254
228
- let byte = self . as_slice ( ) [ 0 ] ;
229
- * self = self . as_slice ( ) . slice ( 1 , len) . into_strbuf ( ) ;
230
- Some ( byte)
255
+ let CharRange { ch, next} = self . as_slice ( ) . char_range_at ( 0 ) ;
256
+ let new_len = len - next;
257
+ unsafe {
258
+ ptr:: copy_memory ( self . vec . as_mut_ptr ( ) , self . vec . as_ptr ( ) . offset ( next as int ) , new_len) ;
259
+ self . vec . set_len ( new_len) ;
260
+ }
261
+ Some ( ch)
231
262
}
232
263
233
264
/// Views the string buffer as a mutable sequence of bytes.
@@ -357,6 +388,28 @@ mod tests {
357
388
assert_eq ! ( data. as_slice( ) , "ประเทศไทย中华b¢€𤭢" ) ;
358
389
}
359
390
391
+ #[ test]
392
+ fn test_pop_char ( ) {
393
+ let mut data = StrBuf :: from_str ( "ประเทศไทย中华b¢€𤭢" ) ;
394
+ assert_eq ! ( data. pop_char( ) . unwrap( ) , '𤭢' ) ; // 4 bytes
395
+ assert_eq ! ( data. pop_char( ) . unwrap( ) , '€' ) ; // 3 bytes
396
+ assert_eq ! ( data. pop_char( ) . unwrap( ) , '¢' ) ; // 2 bytes
397
+ assert_eq ! ( data. pop_char( ) . unwrap( ) , 'b' ) ; // 1 bytes
398
+ assert_eq ! ( data. pop_char( ) . unwrap( ) , '华' ) ;
399
+ assert_eq ! ( data. as_slice( ) , "ประเทศไทย中" ) ;
400
+ }
401
+
402
+ #[ test]
403
+ fn test_shift_char ( ) {
404
+ let mut data = StrBuf :: from_str ( "𤭢€¢b华ประเทศไทย中" ) ;
405
+ assert_eq ! ( data. shift_char( ) . unwrap( ) , '𤭢' ) ; // 4 bytes
406
+ assert_eq ! ( data. shift_char( ) . unwrap( ) , '€' ) ; // 3 bytes
407
+ assert_eq ! ( data. shift_char( ) . unwrap( ) , '¢' ) ; // 2 bytes
408
+ assert_eq ! ( data. shift_char( ) . unwrap( ) , 'b' ) ; // 1 bytes
409
+ assert_eq ! ( data. shift_char( ) . unwrap( ) , '华' ) ;
410
+ assert_eq ! ( data. as_slice( ) , "ประเทศไทย中" ) ;
411
+ }
412
+
360
413
#[ test]
361
414
fn test_str_truncate ( ) {
362
415
let mut s = StrBuf :: from_str ( "12345" ) ;
0 commit comments