@@ -30,7 +30,9 @@ enum seek_style { seek_set, seek_end, seek_cur, }
30
30
// The raw underlying reader iface. All readers must implement this.
31
31
iface reader {
32
32
// FIXME (#2004): Seekable really should be orthogonal.
33
- fn read_bytes( uint) -> ~[ u8] ;
33
+
34
+ // FIXME (#2982): This should probably return an error.
35
+ fn read( buf: & [ mut u8] , len: uint) -> uint;
34
36
fn read_byte ( ) -> int ;
35
37
fn unread_byte ( int ) ;
36
38
fn eof ( ) -> bool ;
@@ -41,6 +43,16 @@ iface reader {
41
43
// Generic utility functions defined on readers
42
44
43
45
impl reader_util for reader {
46
+ fn read_bytes ( len : uint ) -> ~[ u8 ] {
47
+ let mut buf = ~[ mut] ;
48
+ vec:: reserve ( buf, len) ;
49
+ unsafe { vec:: unsafe:: set_len ( buf, len) ; }
50
+
51
+ let count = self . read ( buf, len) ;
52
+
53
+ unsafe { vec:: unsafe:: set_len ( buf, count) ; }
54
+ vec:: from_mut ( buf)
55
+ }
44
56
fn read_chars ( n : uint ) -> ~[ char ] {
45
57
// returns the (consumed offset, n_req), appends characters to &chars
46
58
fn chars_from_buf ( buf : ~[ u8 ] , & chars: ~[ char ] ) -> ( uint , uint ) {
@@ -192,15 +204,15 @@ fn convert_whence(whence: seek_style) -> i32 {
192
204
}
193
205
194
206
impl of reader for * libc:: FILE {
195
- fn read_bytes ( len : uint ) -> ~[ u8 ] {
196
- let mut buf : ~[ mut u8] = ~[ mut] ;
197
- vec:: reserve ( buf, len) ;
198
- do vec:: as_mut_buf ( buf) |b| {
199
- let read = libc:: fread ( b as * mut c_void , 1 u as size_t ,
200
- len as size_t , self ) ;
201
- unsafe { vec:: unsafe:: set_len ( buf, read as uint ) } ;
207
+ fn read ( buf : & [ mut u8] , len : uint ) -> uint {
208
+ do vec:: unpack_slice ( buf) |buf_p, buf_len| {
209
+ assert buf_len <= len;
210
+
211
+ let count = libc:: fread ( buf_p as * mut c_void , 1 u as size_t ,
212
+ len as size_t , self ) ;
213
+
214
+ count as uint
202
215
}
203
- ret vec:: from_mut ( buf) ;
204
216
}
205
217
fn read_byte ( ) -> int { ret libc:: fgetc ( self ) as int ; }
206
218
fn unread_byte ( byte : int ) { libc:: ungetc ( byte as c_int , self ) ; }
@@ -216,7 +228,7 @@ impl of reader for *libc::FILE {
216
228
// duration of its lifetime.
217
229
// FIXME there really should be a better way to do this // #2004
218
230
impl < T : reader , C > of reader for { base : T , cleanup : C } {
219
- fn read_bytes ( len : uint ) -> ~ [ u8 ] { self . base . read_bytes ( len) }
231
+ fn read ( buf : & [ mut u8 ] , len : uint ) -> uint { self . base . read ( buf , len) }
220
232
fn read_byte ( ) -> int { self . base . read_byte ( ) }
221
233
fn unread_byte ( byte : int ) { self . base . unread_byte ( byte) ; }
222
234
fn eof ( ) -> bool { self . base . eof ( ) }
@@ -262,13 +274,15 @@ fn file_reader(path: ~str) -> result<reader, ~str> {
262
274
type byte_buf = {buf: ~[const u8], mut pos: uint, len: uint};
263
275
264
276
impl of reader for byte_buf {
265
- fn read_bytes(len: uint) -> ~[u8] {
266
- let rest = self.len - self.pos;
267
- let mut to_read = len;
268
- if rest < to_read { to_read = rest; }
269
- let range = vec::slice(self.buf, self.pos, self.pos + to_read);
270
- self.pos += to_read;
271
- ret range;
277
+ fn read(buf: &[mut u8], len: uint) -> uint {
278
+ let count = uint::min(len, self.len - self.pos);
279
+
280
+ vec::u8::memcpy(buf, vec::const_view(self.buf, self.pos, self.len),
281
+ count);
282
+
283
+ self.pos += count;
284
+
285
+ count
272
286
}
273
287
fn read_byte() -> int {
274
288
if self.pos == self.len { ret -1; }
0 commit comments