Skip to content

Commit 4c3faa7

Browse files
committed
Vendor std::io::Cursor as buf::Cursor (closes tokio-rs#75)
Extracts the minimal parts of std::io::Cursor needed to support bytes use cases. This is needed to support no_std as std::io is unavailable in these contexts. It also (arguably) improves the API ergonomics by simplifying imports. Per notes on tokio-rs#75, changes the u64 position to a u32 to save space.
1 parent 6750a26 commit 4c3faa7

14 files changed

+133
-97
lines changed

src/buf/buf.rs

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain};
1+
use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain, Cursor};
22
use byteorder::ByteOrder;
33
use iovec::IoVec;
44

5-
use std::{cmp, io, ptr};
5+
use std::{cmp, ptr};
66

77
/// Read bytes from a buffer.
88
///
@@ -15,8 +15,7 @@ use std::{cmp, io, ptr};
1515
/// The simplest `Buf` is a `Cursor` wrapping a `[u8]`.
1616
///
1717
/// ```
18-
/// use bytes::Buf;
19-
/// use std::io::Cursor;
18+
/// use bytes::{Buf, Cursor};
2019
///
2120
/// let mut buf = Cursor::new(b"hello world");
2221
///
@@ -39,8 +38,7 @@ pub trait Buf {
3938
/// # Examples
4039
///
4140
/// ```
42-
/// use bytes::Buf;
43-
/// use std::io::Cursor;
41+
/// use bytes::{Buf, Cursor};
4442
///
4543
/// let mut buf = Cursor::new(b"hello world");
4644
///
@@ -67,8 +65,7 @@ pub trait Buf {
6765
/// # Examples
6866
///
6967
/// ```
70-
/// use bytes::Buf;
71-
/// use std::io::Cursor;
68+
/// use bytes::{Buf, Cursor};
7269
///
7370
/// let mut buf = Cursor::new(b"hello world");
7471
///
@@ -134,8 +131,7 @@ pub trait Buf {
134131
/// # Examples
135132
///
136133
/// ```
137-
/// use bytes::Buf;
138-
/// use std::io::Cursor;
134+
/// use bytes::{Buf, Cursor};
139135
///
140136
/// let mut buf = Cursor::new(b"hello world");
141137
///
@@ -166,8 +162,7 @@ pub trait Buf {
166162
/// # Examples
167163
///
168164
/// ```
169-
/// use bytes::Buf;
170-
/// use std::io::Cursor;
165+
/// use bytes::{Buf, Cursor};
171166
///
172167
/// let mut buf = Cursor::new(b"a");
173168
///
@@ -189,8 +184,7 @@ pub trait Buf {
189184
/// # Examples
190185
///
191186
/// ```
192-
/// use bytes::Buf;
193-
/// use std::io::Cursor;
187+
/// use bytes::{Buf, Cursor};
194188
///
195189
/// let mut buf = Cursor::new(b"hello world");
196190
/// let mut dst = [0; 5];
@@ -232,8 +226,7 @@ pub trait Buf {
232226
/// # Examples
233227
///
234228
/// ```
235-
/// use bytes::Buf;
236-
/// use std::io::Cursor;
229+
/// use bytes::{Buf, Cursor};
237230
///
238231
/// let mut buf = Cursor::new(b"\x08 hello");
239232
/// assert_eq!(8, buf.get_u8());
@@ -255,8 +248,7 @@ pub trait Buf {
255248
/// # Examples
256249
///
257250
/// ```
258-
/// use bytes::Buf;
259-
/// use std::io::Cursor;
251+
/// use bytes::{Buf, Cursor};
260252
///
261253
/// let mut buf = Cursor::new(b"\x08 hello");
262254
/// assert_eq!(8, buf.get_i8());
@@ -278,8 +270,7 @@ pub trait Buf {
278270
/// # Examples
279271
///
280272
/// ```
281-
/// use bytes::{Buf, BigEndian};
282-
/// use std::io::Cursor;
273+
/// use bytes::{Buf, BigEndian, Cursor};
283274
///
284275
/// let mut buf = Cursor::new(b"\x08\x09 hello");
285276
/// assert_eq!(0x0809, buf.get_u16::<BigEndian>());
@@ -301,8 +292,7 @@ pub trait Buf {
301292
/// # Examples
302293
///
303294
/// ```
304-
/// use bytes::{Buf, BigEndian};
305-
/// use std::io::Cursor;
295+
/// use bytes::{Buf, BigEndian, Cursor};
306296
///
307297
/// let mut buf = Cursor::new(b"\x08\x09 hello");
308298
/// assert_eq!(0x0809, buf.get_i16::<BigEndian>());
@@ -324,8 +314,7 @@ pub trait Buf {
324314
/// # Examples
325315
///
326316
/// ```
327-
/// use bytes::{Buf, BigEndian};
328-
/// use std::io::Cursor;
317+
/// use bytes::{Buf, BigEndian, Cursor};
329318
///
330319
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
331320
/// assert_eq!(0x0809A0A1, buf.get_u32::<BigEndian>());
@@ -347,8 +336,7 @@ pub trait Buf {
347336
/// # Examples
348337
///
349338
/// ```
350-
/// use bytes::{Buf, BigEndian};
351-
/// use std::io::Cursor;
339+
/// use bytes::{Buf, BigEndian, Cursor};
352340
///
353341
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
354342
/// assert_eq!(0x0809A0A1, buf.get_i32::<BigEndian>());
@@ -370,8 +358,7 @@ pub trait Buf {
370358
/// # Examples
371359
///
372360
/// ```
373-
/// use bytes::{Buf, BigEndian};
374-
/// use std::io::Cursor;
361+
/// use bytes::{Buf, BigEndian, Cursor};
375362
///
376363
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
377364
/// assert_eq!(0x0102030405060708, buf.get_u64::<BigEndian>());
@@ -393,8 +380,7 @@ pub trait Buf {
393380
/// # Examples
394381
///
395382
/// ```
396-
/// use bytes::{Buf, BigEndian};
397-
/// use std::io::Cursor;
383+
/// use bytes::{Buf, BigEndian, Cursor};
398384
///
399385
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
400386
/// assert_eq!(0x0102030405060708, buf.get_i64::<BigEndian>());
@@ -416,8 +402,7 @@ pub trait Buf {
416402
/// # Examples
417403
///
418404
/// ```
419-
/// use bytes::{Buf, BigEndian};
420-
/// use std::io::Cursor;
405+
/// use bytes::{Buf, BigEndian, Cursor};
421406
///
422407
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
423408
/// assert_eq!(0x010203, buf.get_uint::<BigEndian>(3));
@@ -439,8 +424,7 @@ pub trait Buf {
439424
/// # Examples
440425
///
441426
/// ```
442-
/// use bytes::{Buf, BigEndian};
443-
/// use std::io::Cursor;
427+
/// use bytes::{Buf, BigEndian, Cursor};
444428
///
445429
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
446430
/// assert_eq!(0x010203, buf.get_int::<BigEndian>(3));
@@ -463,8 +447,7 @@ pub trait Buf {
463447
/// # Examples
464448
///
465449
/// ```
466-
/// use bytes::{Buf, BigEndian};
467-
/// use std::io::Cursor;
450+
/// use bytes::{Buf, BigEndian, Cursor};
468451
///
469452
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello");
470453
/// assert_eq!(1.2f32, buf.get_f32::<BigEndian>());
@@ -487,8 +470,7 @@ pub trait Buf {
487470
/// # Examples
488471
///
489472
/// ```
490-
/// use bytes::{Buf, BigEndian};
491-
/// use std::io::Cursor;
473+
/// use bytes::{Buf, BigEndian, Cursor};
492474
///
493475
/// let mut buf = Cursor::new(b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello");
494476
/// assert_eq!(1.2f64, buf.get_f64::<BigEndian>());
@@ -535,8 +517,7 @@ pub trait Buf {
535517
/// # Examples
536518
///
537519
/// ```
538-
/// use bytes::{Buf, BufMut};
539-
/// use std::io::Cursor;
520+
/// use bytes::{Buf, BufMut, Cursor};
540521
///
541522
/// let mut buf = Cursor::new("hello world").take(5);
542523
/// let mut dst = vec![];
@@ -586,8 +567,7 @@ pub trait Buf {
586567
/// # Examples
587568
///
588569
/// ```
589-
/// use bytes::{Buf, BufMut};
590-
/// use std::io::Cursor;
570+
/// use bytes::{Buf, BufMut, Cursor};
591571
///
592572
/// let mut buf = Cursor::new("hello world");
593573
/// let mut dst = vec![];
@@ -689,12 +669,12 @@ impl<T: Buf + ?Sized> Buf for Box<T> {
689669
}
690670
}
691671

692-
impl<T: AsRef<[u8]>> Buf for io::Cursor<T> {
672+
impl<T: AsRef<[u8]>> Buf for Cursor<T> {
693673
fn remaining(&self) -> usize {
694674
let len = self.get_ref().as_ref().len();
695675
let pos = self.position();
696676

697-
if pos >= len as u64 {
677+
if pos >= len as u32 {
698678
return 0;
699679
}
700680

@@ -718,7 +698,7 @@ impl<T: AsRef<[u8]>> Buf for io::Cursor<T> {
718698

719699
assert!(pos <= self.get_ref().as_ref().len());
720700

721-
self.set_position(pos as u64);
701+
self.set_position(pos as u32);
722702
}
723703
}
724704

src/buf/buf_mut.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::{IntoBuf, Writer};
1+
use super::{Cursor, IntoBuf, Writer};
22
use byteorder::ByteOrder;
33
use iovec::IoVec;
44

5-
use std::{cmp, io, ptr, usize};
5+
use std::{cmp, ptr, usize};
66

77
/// A trait for values that provide sequential write access to bytes.
88
///
@@ -34,8 +34,7 @@ pub trait BufMut {
3434
/// # Examples
3535
///
3636
/// ```
37-
/// use bytes::BufMut;
38-
/// use std::io::Cursor;
37+
/// use bytes::{BufMut, Cursor};
3938
///
4039
/// let mut dst = [0; 10];
4140
/// let mut buf = Cursor::new(&mut dst[..]);
@@ -104,8 +103,7 @@ pub trait BufMut {
104103
/// # Examples
105104
///
106105
/// ```
107-
/// use bytes::BufMut;
108-
/// use std::io::Cursor;
106+
/// use bytes::{BufMut, Cursor};
109107
///
110108
/// let mut dst = [0; 5];
111109
/// let mut buf = Cursor::new(&mut dst);
@@ -253,8 +251,7 @@ pub trait BufMut {
253251
/// `self` must have enough remaining capacity to contain all of `src`.
254252
///
255253
/// ```
256-
/// use bytes::BufMut;
257-
/// use std::io::Cursor;
254+
/// use bytes::{BufMut, Cursor};
258255
///
259256
/// let mut dst = [0; 6];
260257
///
@@ -672,7 +669,7 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
672669
}
673670
}
674671

675-
impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
672+
impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for Cursor<T> {
676673
fn remaining_mut(&self) -> usize {
677674
use Buf;
678675
self.remaining()

src/buf/cursor.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// at http://rust-lang.org/COPYRIGHT.
3+
//
4+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7+
// option. This file may not be copied, modified, or distributed
8+
// except according to those terms.
9+
10+
use std::cmp;
11+
use std::io::{self, BufRead, Read};
12+
13+
/// A `Cursor` wraps another type and provides it with a
14+
/// [`Seek`] implementation.
15+
///
16+
/// `Cursor`s are typically used with in-memory buffers to allow them to
17+
/// implement [`Read`] and/or [`Write`], allowing these buffers to be used
18+
/// anywhere you might use a reader or writer that does actual I/O.
19+
///
20+
/// The standard library implements some I/O traits on various types which
21+
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
22+
/// `Cursor<`[`&[u8]`][bytes]`>`.
23+
#[derive(Clone, Debug)]
24+
pub struct Cursor<T> {
25+
inner: T,
26+
pos: u32,
27+
}
28+
29+
impl<T> Cursor<T> {
30+
/// Creates a new cursor wrapping the provided underlying I/O object.
31+
///
32+
/// Cursor initial position is `0` even if underlying object (e.
33+
/// g. `Vec`) is not empty. So writing to cursor starts with
34+
/// overwriting `Vec` content, not with appending to it.
35+
pub fn new(inner: T) -> Cursor<T> {
36+
Cursor { pos: 0, inner: inner }
37+
}
38+
39+
/// Gets a reference to the underlying value in this cursor.
40+
pub fn get_ref(&self) -> &T { &self.inner }
41+
42+
/// Gets a mutable reference to the underlying value in this cursor.
43+
///
44+
/// Care should be taken to avoid modifying the internal I/O state of the
45+
/// underlying value as it may corrupt this cursor's position.
46+
pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
47+
48+
/// Returns the current position of this cursor.
49+
pub fn position(&self) -> u32 { self.pos }
50+
51+
/// Sets the position of this cursor.
52+
pub fn set_position(&mut self, pos: u32) { self.pos = pos; }
53+
}
54+
55+
impl<T> Read for Cursor<T> where T: AsRef<[u8]> {
56+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
57+
let n = Read::read(&mut self.fill_buf()?, buf)?;
58+
self.pos += n as u32;
59+
Ok(n)
60+
}
61+
}
62+
63+
impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> {
64+
fn fill_buf(&mut self) -> io::Result<&[u8]> {
65+
let amt = cmp::min(self.pos, self.inner.as_ref().len() as u32);
66+
Ok(&self.inner.as_ref()[(amt as usize)..])
67+
}
68+
fn consume(&mut self, amt: usize) { self.pos += amt as u32; }
69+
}

0 commit comments

Comments
 (0)