10
10
11
11
//! Readers and Writers for in-memory buffers
12
12
13
- use cmp:: max;
14
13
use cmp:: min;
15
14
use container:: Container ;
16
15
use option:: None ;
@@ -20,6 +19,25 @@ use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
20
19
use vec;
21
20
use vec:: { Vector , ImmutableVector , MutableVector , OwnedCloneableVector } ;
22
21
22
+ fn combine ( seek : SeekStyle , cur : uint , end : uint , offset : i64 ) -> IoResult < u64 > {
23
+ // compute offset as signed and clamp to prevent overflow
24
+ let pos = match seek {
25
+ SeekSet => 0 ,
26
+ SeekEnd => end,
27
+ SeekCur => cur,
28
+ } as i64 ;
29
+
30
+ if offset + pos < 0 {
31
+ Err ( IoError {
32
+ kind : io:: InvalidInput ,
33
+ desc : "invalid seek to a negative offset" ,
34
+ detail : None
35
+ } )
36
+ } else {
37
+ Ok ( ( offset + pos) as u64 )
38
+ }
39
+ }
40
+
23
41
/// Writes to an owned, growable byte vector
24
42
///
25
43
/// # Example
@@ -92,19 +110,11 @@ impl Writer for MemWriter {
92
110
}
93
111
}
94
112
95
- // FIXME(#10432)
96
113
impl Seek for MemWriter {
97
114
fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
98
-
99
115
fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
100
- // compute offset as signed and clamp to prevent overflow
101
- let offset = match style {
102
- SeekSet => { 0 }
103
- SeekEnd => { self . buf . len ( ) }
104
- SeekCur => { self . pos }
105
- } as i64 ;
106
-
107
- self . pos = max ( 0 , offset+pos) as uint ;
116
+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
117
+ self . pos = new as uint ;
108
118
Ok ( ( ) )
109
119
}
110
120
}
@@ -139,7 +149,7 @@ impl MemReader {
139
149
/// Tests whether this reader has read all bytes in its buffer.
140
150
///
141
151
/// If `true`, then this will no longer return bytes from `read`.
142
- pub fn eof ( & self ) -> bool { self . pos = = self . buf . len ( ) }
152
+ pub fn eof ( & self ) -> bool { self . pos > = self . buf . len ( ) }
143
153
144
154
/// Acquires an immutable reference to the underlying buffer of this
145
155
/// `MemReader`.
@@ -172,7 +182,11 @@ impl Reader for MemReader {
172
182
173
183
impl Seek for MemReader {
174
184
fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
175
- fn seek ( & mut self , _pos : i64 , _style : SeekStyle ) -> IoResult < ( ) > { fail ! ( ) }
185
+ fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
186
+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
187
+ self . pos = new as uint ;
188
+ Ok ( ( ) )
189
+ }
176
190
}
177
191
178
192
impl Buffer for MemReader {
@@ -236,24 +250,15 @@ impl<'a> Writer for BufWriter<'a> {
236
250
}
237
251
}
238
252
239
- // FIXME(#10432)
240
253
impl < ' a > Seek for BufWriter < ' a > {
241
254
fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
242
-
243
255
fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
244
- // compute offset as signed and clamp to prevent overflow
245
- let offset = match style {
246
- SeekSet => { 0 }
247
- SeekEnd => { self . buf . len ( ) }
248
- SeekCur => { self . pos }
249
- } as i64 ;
250
-
251
- self . pos = max ( 0 , offset+pos) as uint ;
256
+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
257
+ self . pos = new as uint ;
252
258
Ok ( ( ) )
253
259
}
254
260
}
255
261
256
-
257
262
/// Reads from a fixed-size byte slice
258
263
///
259
264
/// # Example
@@ -284,7 +289,7 @@ impl<'a> BufReader<'a> {
284
289
/// Tests whether this reader has read all bytes in its buffer.
285
290
///
286
291
/// If `true`, then this will no longer return bytes from `read`.
287
- pub fn eof ( & self ) -> bool { self . pos = = self . buf . len ( ) }
292
+ pub fn eof ( & self ) -> bool { self . pos > = self . buf . len ( ) }
288
293
}
289
294
290
295
impl < ' a > Reader for BufReader < ' a > {
@@ -307,7 +312,11 @@ impl<'a> Reader for BufReader<'a> {
307
312
308
313
impl < ' a > Seek for BufReader < ' a > {
309
314
fn tell ( & self ) -> IoResult < u64 > { Ok ( self . pos as u64 ) }
310
- fn seek ( & mut self , _pos : i64 , _style : SeekStyle ) -> IoResult < ( ) > { fail ! ( ) }
315
+ fn seek ( & mut self , pos : i64 , style : SeekStyle ) -> IoResult < ( ) > {
316
+ let new = if_ok ! ( combine( style, self . pos, self . buf. len( ) , pos) ) ;
317
+ self . pos = new as uint ;
318
+ Ok ( ( ) )
319
+ }
311
320
}
312
321
313
322
impl < ' a > Buffer for BufReader < ' a > {
@@ -506,4 +515,42 @@ mod test {
506
515
Err ( ..) => { }
507
516
}
508
517
}
518
+
519
+ #[ test]
520
+ fn seek_past_end ( ) {
521
+ let buf = [ 0xff ] ;
522
+ let mut r = BufReader :: new ( buf) ;
523
+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
524
+ assert ! ( r. read( & mut [ ] ) . is_err( ) ) ;
525
+
526
+ let mut r = MemReader :: new ( ~[ 10 ] ) ;
527
+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
528
+ assert ! ( r. read( & mut [ ] ) . is_err( ) ) ;
529
+
530
+ let mut r = MemWriter :: new ( ) ;
531
+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
532
+ assert ! ( r. write( [ 3 ] ) . is_ok( ) ) ;
533
+
534
+ let mut buf = [ 0 ] ;
535
+ let mut r = BufWriter :: new ( buf) ;
536
+ r. seek ( 10 , SeekSet ) . unwrap ( ) ;
537
+ assert ! ( r. write( [ 3 ] ) . is_err( ) ) ;
538
+ }
539
+
540
+ #[ test]
541
+ fn seek_before_0 ( ) {
542
+ let buf = [ 0xff ] ;
543
+ let mut r = BufReader :: new ( buf) ;
544
+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
545
+
546
+ let mut r = MemReader :: new ( ~[ 10 ] ) ;
547
+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
548
+
549
+ let mut r = MemWriter :: new ( ) ;
550
+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
551
+
552
+ let mut buf = [ 0 ] ;
553
+ let mut r = BufWriter :: new ( buf) ;
554
+ assert ! ( r. seek( -1 , SeekSet ) . is_err( ) ) ;
555
+ }
509
556
}
0 commit comments