#![doc(hidden)] //! `CodedInputStream` and `CodedOutputStream` implementations use std::io; use std::io::BufRead; use std::io::Read; use std::mem; use std::slice; #[cfg(feature = "bytes")] use crate::chars::Chars; #[cfg(feature = "bytes")] use bytes::Bytes; use crate::buf_read_iter::BufReadIter; use crate::enums::ProtobufEnum; use crate::error::ProtobufError; use crate::error::ProtobufResult; use crate::error::WireError; use crate::message::Message; use crate::unknown::UnknownValue; use crate::wire_format; use crate::zigzag::decode_zig_zag_32; use crate::zigzag::decode_zig_zag_64; /// Default recursion level limit. 100 is the default value of C++'s implementation. const DEFAULT_RECURSION_LIMIT: u32 = 100; /// Max allocated vec when reading length-delimited from unknown input stream pub(crate) const READ_RAW_BYTES_MAX_ALLOC: usize = 10_000_000; /// Buffered read with handy utilities. pub struct CodedInputStream<'a> { source: BufReadIter<'a>, recursion_level: u32, recursion_limit: u32, } impl<'a> CodedInputStream<'a> { /// Wrap a `Read`. /// /// Note resulting `CodedInputStream` is buffered even if `Read` is not. pub fn new(read: &'a mut dyn Read) -> CodedInputStream<'a> { CodedInputStream::from_buf_read_iter(BufReadIter::from_read(read)) } /// Create from `BufRead`. /// /// `CodedInputStream` will utilize `BufRead` buffer. pub fn from_buffered_reader(buf_read: &'a mut dyn BufRead) -> CodedInputStream<'a> { CodedInputStream::from_buf_read_iter(BufReadIter::from_buf_read(buf_read)) } /// Read from byte slice pub fn from_bytes(bytes: &'a [u8]) -> CodedInputStream<'a> { CodedInputStream::from_buf_read_iter(BufReadIter::from_byte_slice(bytes)) } /// Read from `Bytes`. /// /// `CodedInputStream` operations like /// [`read_carllerche_bytes`](crate::CodedInputStream::read_carllerche_bytes) /// will return a shared copy of this bytes object. #[cfg(feature = "bytes")] pub fn from_carllerche_bytes(bytes: &'a Bytes) -> CodedInputStream<'a> { CodedInputStream::from_buf_read_iter(BufReadIter::from_bytes(bytes)) } fn from_buf_read_iter(source: BufReadIter<'a>) -> CodedInputStream<'a> { CodedInputStream { source: source, recursion_level: 0, recursion_limit: DEFAULT_RECURSION_LIMIT, } } /// Set the recursion limit. pub fn set_recursion_limit(&mut self, limit: u32) { self.recursion_limit = limit; } #[inline] pub(crate) fn incr_recursion(&mut self) -> ProtobufResult<()> { if self.recursion_level >= self.recursion_limit { return Err(ProtobufError::WireError(WireError::OverRecursionLimit)); } self.recursion_level += 1; Ok(()) } #[inline] pub(crate) fn decr_recursion(&mut self) { self.recursion_level -= 1; } /// How many bytes processed pub fn pos(&self) -> u64 { self.source.pos() } /// How many bytes until current limit pub fn bytes_until_limit(&self) -> u64 { self.source.bytes_until_limit() } /// Read bytes into given `buf`. /// /// Return `0` on EOF. // TODO: overload with `Read::read` pub fn read(&mut self, buf: &mut [u8]) -> ProtobufResult<()> { self.source.read_exact(buf)?; Ok(()) } /// Read exact number of bytes as `Bytes` object. /// /// This operation returns a shared view if `CodedInputStream` is /// constructed with `Bytes` parameter. #[cfg(feature = "bytes")] fn read_raw_callerche_bytes(&mut self, count: usize) -> ProtobufResult { self.source.read_exact_bytes(count) } /// Read one byte #[inline(always)] pub fn read_raw_byte(&mut self) -> ProtobufResult { self.source.read_byte() } /// Push new limit, return previous limit. pub fn push_limit(&mut self, limit: u64) -> ProtobufResult { self.source.push_limit(limit) } /// Restore previous limit. pub fn pop_limit(&mut self, old_limit: u64) { self.source.pop_limit(old_limit); } /// Are we at EOF? #[inline(always)] pub fn eof(&mut self) -> ProtobufResult { self.source.eof() } /// Check we are at EOF. /// /// Return error if we are not at EOF. pub fn check_eof(&mut self) -> ProtobufResult<()> { let eof = self.eof()?; if !eof { return Err(ProtobufError::WireError(WireError::UnexpectedEof)); } Ok(()) } fn read_raw_varint64_slow(&mut self) -> ProtobufResult { let mut r: u64 = 0; let mut i = 0; loop { if i == 10 { return Err(ProtobufError::WireError(WireError::IncorrectVarint)); } let b = self.read_raw_byte()?; // TODO: may overflow if i == 9 r = r | (((b & 0x7f) as u64) << (i * 7)); i += 1; if b < 0x80 { return Ok(r); } } } /// Read varint #[inline(always)] pub fn read_raw_varint64(&mut self) -> ProtobufResult { 'slow: loop { let ret; let consume; loop { let rem = self.source.remaining_in_buf(); if rem.len() >= 1 { // most varints are in practice fit in 1 byte if rem[0] < 0x80 { ret = rem[0] as u64; consume = 1; } else { // handle case of two bytes too if rem.len() >= 2 && rem[1] < 0x80 { ret = (rem[0] & 0x7f) as u64 | (rem[1] as u64) << 7; consume = 2; } else if rem.len() >= 10 { // Read from array when buf at at least 10 bytes, // max len for varint. let mut r: u64 = 0; let mut i: usize = 0; { let rem = rem; loop { if i == 10 { return Err(ProtobufError::WireError( WireError::IncorrectVarint, )); } let b = if true { // skip range check unsafe { *rem.get_unchecked(i) } } else { rem[i] }; // TODO: may overflow if i == 9 r = r | (((b & 0x7f) as u64) << (i * 7)); i += 1; if b < 0x80 { break; } } } consume = i; ret = r; } else { break 'slow; } } } else { break 'slow; } break; } self.source.consume(consume); return Ok(ret); } self.read_raw_varint64_slow() } /// Read varint #[inline(always)] pub fn read_raw_varint32(&mut self) -> ProtobufResult { self.read_raw_varint64().map(|v| v as u32) } /// Read little-endian 32-bit integer pub fn read_raw_little_endian32(&mut self) -> ProtobufResult { let mut r = 0u32; let bytes: &mut [u8] = unsafe { let p: *mut u8 = mem::transmute(&mut r); slice::from_raw_parts_mut(p, mem::size_of::()) }; self.read(bytes)?; Ok(r.to_le()) } /// Read little-endian 64-bit integer pub fn read_raw_little_endian64(&mut self) -> ProtobufResult { let mut r = 0u64; let bytes: &mut [u8] = unsafe { let p: *mut u8 = mem::transmute(&mut r); slice::from_raw_parts_mut(p, mem::size_of::()) }; self.read(bytes)?; Ok(r.to_le()) } /// Read tag #[inline] pub fn read_tag(&mut self) -> ProtobufResult { let v = self.read_raw_varint32()?; match wire_format::Tag::new(v) { Some(tag) => Ok(tag), None => Err(ProtobufError::WireError(WireError::IncorrectTag(v))), } } /// Read tag, return it is pair (field number, wire type) #[inline] pub fn read_tag_unpack(&mut self) -> ProtobufResult<(u32, wire_format::WireType)> { self.read_tag().map(|t| t.unpack()) } /// Read `double` pub fn read_double(&mut self) -> ProtobufResult { let bits = self.read_raw_little_endian64()?; unsafe { Ok(mem::transmute::(bits)) } } /// Read `float` pub fn read_float(&mut self) -> ProtobufResult { let bits = self.read_raw_little_endian32()?; unsafe { Ok(mem::transmute::(bits)) } } /// Read `int64` pub fn read_int64(&mut self) -> ProtobufResult { self.read_raw_varint64().map(|v| v as i64) } /// Read `int32` pub fn read_int32(&mut self) -> ProtobufResult { self.read_raw_varint32().map(|v| v as i32) } /// Read `uint64` pub fn read_uint64(&mut self) -> ProtobufResult { self.read_raw_varint64() } /// Read `uint32` pub fn read_uint32(&mut self) -> ProtobufResult { self.read_raw_varint32() } /// Read `sint64` pub fn read_sint64(&mut self) -> ProtobufResult { self.read_uint64().map(decode_zig_zag_64) } /// Read `sint32` pub fn read_sint32(&mut self) -> ProtobufResult { self.read_uint32().map(decode_zig_zag_32) } /// Read `fixed64` pub fn read_fixed64(&mut self) -> ProtobufResult { self.read_raw_little_endian64() } /// Read `fixed32` pub fn read_fixed32(&mut self) -> ProtobufResult { self.read_raw_little_endian32() } /// Read `sfixed64` pub fn read_sfixed64(&mut self) -> ProtobufResult { self.read_raw_little_endian64().map(|v| v as i64) } /// Read `sfixed32` pub fn read_sfixed32(&mut self) -> ProtobufResult { self.read_raw_little_endian32().map(|v| v as i32) } /// Read `bool` pub fn read_bool(&mut self) -> ProtobufResult { self.read_raw_varint32().map(|v| v != 0) } /// Read `enum` as `ProtobufEnum` pub fn read_enum(&mut self) -> ProtobufResult { let i = self.read_int32()?; match ProtobufEnum::from_i32(i) { Some(e) => Ok(e), None => Err(ProtobufError::WireError(WireError::InvalidEnumValue(i))), } } /// Read `repeated` packed `double` pub fn read_repeated_packed_double_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; target.reserve((len / 4) as usize); let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_double()?); } self.pop_limit(old_limit); Ok(()) } /// Read `repeated` packed `float` pub fn read_repeated_packed_float_into(&mut self, target: &mut Vec) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; target.reserve((len / 4) as usize); let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_float()?); } self.pop_limit(old_limit); Ok(()) } /// Read `repeated` packed `int64` pub fn read_repeated_packed_int64_into(&mut self, target: &mut Vec) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len as u64)?; while !self.eof()? { target.push(self.read_int64()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `int32` pub fn read_repeated_packed_int32_into(&mut self, target: &mut Vec) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_int32()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `uint64` pub fn read_repeated_packed_uint64_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_uint64()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `uint32` pub fn read_repeated_packed_uint32_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_uint32()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `sint64` pub fn read_repeated_packed_sint64_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_sint64()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `sint32` pub fn read_repeated_packed_sint32_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_sint32()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `fixed64` pub fn read_repeated_packed_fixed64_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; target.reserve((len / 8) as usize); let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_fixed64()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `fixed32` pub fn read_repeated_packed_fixed32_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; target.reserve((len / 4) as usize); let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_fixed32()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `sfixed64` pub fn read_repeated_packed_sfixed64_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; target.reserve((len / 8) as usize); let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_sfixed64()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `sfixed32` pub fn read_repeated_packed_sfixed32_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; target.reserve((len / 4) as usize); let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_sfixed32()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `bool` pub fn read_repeated_packed_bool_into(&mut self, target: &mut Vec) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; // regular bool value is 1-byte size target.reserve(len as usize); let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_bool()?); } self.pop_limit(old_limit); Ok(()) } /// Read repeated packed `enum` into `ProtobufEnum` pub fn read_repeated_packed_enum_into( &mut self, target: &mut Vec, ) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len)?; while !self.eof()? { target.push(self.read_enum()?); } self.pop_limit(old_limit); Ok(()) } /// Read `UnknownValue` pub fn read_unknown( &mut self, wire_type: wire_format::WireType, ) -> ProtobufResult { match wire_type { wire_format::WireTypeVarint => { self.read_raw_varint64().map(|v| UnknownValue::Varint(v)) } wire_format::WireTypeFixed64 => self.read_fixed64().map(|v| UnknownValue::Fixed64(v)), wire_format::WireTypeFixed32 => self.read_fixed32().map(|v| UnknownValue::Fixed32(v)), wire_format::WireTypeLengthDelimited => { let len = self.read_raw_varint32()?; self.read_raw_bytes(len) .map(|v| UnknownValue::LengthDelimited(v)) } _ => Err(ProtobufError::WireError(WireError::UnexpectedWireType( wire_type, ))), } } /// Skip field pub fn skip_field(&mut self, wire_type: wire_format::WireType) -> ProtobufResult<()> { self.read_unknown(wire_type).map(|_| ()) } /// Read raw bytes into the supplied vector. The vector will be resized as needed and /// overwritten. pub fn read_raw_bytes_into(&mut self, count: u32, target: &mut Vec) -> ProtobufResult<()> { if false { // Master uses this version, but keep existing version for a while // to avoid possible breakages. return self.source.read_exact_to_vec(count as usize, target); } let count = count as usize; // TODO: also do some limits when reading from unlimited source if count as u64 > self.source.bytes_until_limit() { return Err(ProtobufError::WireError(WireError::TruncatedMessage)); } unsafe { target.set_len(0); } if count >= READ_RAW_BYTES_MAX_ALLOC { // avoid calling `reserve` on buf with very large buffer: could be a malformed message let mut take = self.by_ref().take(count as u64); take.read_to_end(target)?; if target.len() != count { return Err(ProtobufError::WireError(WireError::TruncatedMessage)); } } else { target.reserve(count); unsafe { target.set_len(count); } self.source.read_exact(target)?; } Ok(()) } /// Read exact number of bytes pub fn read_raw_bytes(&mut self, count: u32) -> ProtobufResult> { let mut r = Vec::new(); self.read_raw_bytes_into(count, &mut r)?; Ok(r) } /// Skip exact number of bytes pub fn skip_raw_bytes(&mut self, count: u32) -> ProtobufResult<()> { // TODO: make it more efficient self.read_raw_bytes(count).map(|_| ()) } /// Read `bytes` field, length delimited pub fn read_bytes(&mut self) -> ProtobufResult> { let mut r = Vec::new(); self.read_bytes_into(&mut r)?; Ok(r) } /// Read `bytes` field, length delimited #[cfg(feature = "bytes")] pub fn read_carllerche_bytes(&mut self) -> ProtobufResult { let len = self.read_raw_varint32()?; self.read_raw_callerche_bytes(len as usize) } /// Read `string` field, length delimited #[cfg(feature = "bytes")] pub fn read_carllerche_chars(&mut self) -> ProtobufResult { let bytes = self.read_carllerche_bytes()?; Ok(Chars::from_bytes(bytes)?) } /// Read `bytes` field, length delimited pub fn read_bytes_into(&mut self, target: &mut Vec) -> ProtobufResult<()> { let len = self.read_raw_varint32()?; self.read_raw_bytes_into(len, target)?; Ok(()) } /// Read `string` field, length delimited pub fn read_string(&mut self) -> ProtobufResult { let mut r = String::new(); self.read_string_into(&mut r)?; Ok(r) } /// Read `string` field, length delimited pub fn read_string_into(&mut self, target: &mut String) -> ProtobufResult<()> { target.clear(); // take target's buffer let mut vec = mem::replace(target, String::new()).into_bytes(); self.read_bytes_into(&mut vec)?; let s = match String::from_utf8(vec) { Ok(t) => t, Err(_) => return Err(ProtobufError::WireError(WireError::Utf8Error)), }; *target = s; Ok(()) } /// Read message, do not check if message is initialized pub fn merge_message(&mut self, message: &mut M) -> ProtobufResult<()> { let len = self.read_raw_varint64()?; let old_limit = self.push_limit(len)?; message.merge_from(self)?; self.pop_limit(old_limit); Ok(()) } /// Read message pub fn read_message(&mut self) -> ProtobufResult { let mut r: M = Message::new(); self.merge_message(&mut r)?; r.check_initialized()?; Ok(r) } } impl<'a> Read for CodedInputStream<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.source.read(buf).map_err(Into::into) } } impl<'a> BufRead for CodedInputStream<'a> { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.source.fill_buf().map_err(Into::into) } fn consume(&mut self, amt: usize) { self.source.consume(amt) } } /// Helper internal utility, should not be used directly #[doc(hidden)] pub trait WithCodedInputStream { fn with_coded_input_stream(self, cb: F) -> ProtobufResult where F: FnOnce(&mut CodedInputStream) -> ProtobufResult; } impl<'a> WithCodedInputStream for &'a mut (dyn Read + 'a) { fn with_coded_input_stream(self, cb: F) -> ProtobufResult where F: FnOnce(&mut CodedInputStream) -> ProtobufResult, { let mut is = CodedInputStream::new(self); let r = cb(&mut is)?; is.check_eof()?; Ok(r) } } impl<'a> WithCodedInputStream for &'a mut (dyn BufRead + 'a) { fn with_coded_input_stream(self, cb: F) -> ProtobufResult where F: FnOnce(&mut CodedInputStream) -> ProtobufResult, { let mut is = CodedInputStream::from_buffered_reader(self); let r = cb(&mut is)?; is.check_eof()?; Ok(r) } } impl<'a> WithCodedInputStream for &'a [u8] { fn with_coded_input_stream(self, cb: F) -> ProtobufResult where F: FnOnce(&mut CodedInputStream) -> ProtobufResult, { let mut is = CodedInputStream::from_bytes(self); let r = cb(&mut is)?; is.check_eof()?; Ok(r) } } #[cfg(feature = "bytes")] impl<'a> WithCodedInputStream for &'a Bytes { fn with_coded_input_stream(self, cb: F) -> ProtobufResult where F: FnOnce(&mut CodedInputStream) -> ProtobufResult, { let mut is = CodedInputStream::from_carllerche_bytes(self); let r = cb(&mut is)?; is.check_eof()?; Ok(r) } } #[cfg(test)] mod test { use std::fmt::Debug; use std::io; use std::io::BufRead; use std::io::Read; use crate::error::ProtobufError; use crate::error::ProtobufResult; use crate::hex::decode_hex; use super::CodedInputStream; use super::READ_RAW_BYTES_MAX_ALLOC; fn test_read_partial(hex: &str, mut callback: F) where F: FnMut(&mut CodedInputStream), { let d = decode_hex(hex); let mut reader = io::Cursor::new(d); let mut is = CodedInputStream::from_buffered_reader(&mut reader as &mut dyn BufRead); assert_eq!(0, is.pos()); callback(&mut is); } fn test_read(hex: &str, mut callback: F) where F: FnMut(&mut CodedInputStream), { let len = decode_hex(hex).len(); test_read_partial(hex, |reader| { callback(reader); assert!(reader.eof().expect("eof")); assert_eq!(len as u64, reader.pos()); }); } fn test_read_v(hex: &str, v: V, mut callback: F) where F: FnMut(&mut CodedInputStream) -> ProtobufResult, V: PartialEq + Debug, { test_read(hex, |reader| { assert_eq!(v, callback(reader).unwrap()); }); } #[test] fn test_input_stream_read_raw_byte() { test_read("17", |is| { assert_eq!(23, is.read_raw_byte().unwrap()); }); } #[test] fn test_input_stream_read_raw_varint() { test_read_v("07", 7, |reader| reader.read_raw_varint32()); test_read_v("07", 7, |reader| reader.read_raw_varint64()); test_read_v("96 01", 150, |reader| reader.read_raw_varint32()); test_read_v("96 01", 150, |reader| reader.read_raw_varint64()); test_read_v( "ff ff ff ff ff ff ff ff ff 01", 0xffffffffffffffff, |reader| reader.read_raw_varint64(), ); test_read_v("ff ff ff ff 0f", 0xffffffff, |reader| { reader.read_raw_varint32() }); test_read_v("ff ff ff ff 0f", 0xffffffff, |reader| { reader.read_raw_varint64() }); } #[test] fn test_input_stream_read_raw_vaint_malformed() { // varint cannot have length > 10 test_read_partial("ff ff ff ff ff ff ff ff ff ff 01", |reader| { let result = reader.read_raw_varint64(); match result { // TODO: make an enum variant Err(ProtobufError::WireError(..)) => (), _ => panic!(), } }); test_read_partial("ff ff ff ff ff ff ff ff ff ff 01", |reader| { let result = reader.read_raw_varint32(); match result { // TODO: make an enum variant Err(ProtobufError::WireError(..)) => (), _ => panic!(), } }); } #[test] fn test_input_stream_read_raw_varint_unexpected_eof() { test_read_partial("96 97", |reader| { let result = reader.read_raw_varint32(); match result { Err(ProtobufError::WireError(..)) => (), _ => panic!(), } }); } #[test] fn test_input_stream_read_raw_varint_pos() { test_read_partial("95 01 98", |reader| { assert_eq!(149, reader.read_raw_varint32().unwrap()); assert_eq!(2, reader.pos()); }); } #[test] fn test_input_stream_read_int32() { test_read_v("02", 2, |reader| reader.read_int32()); } #[test] fn test_input_stream_read_float() { test_read_v("95 73 13 61", 17e19, |is| is.read_float()); } #[test] fn test_input_stream_read_double() { test_read_v("40 d5 ab 68 b3 07 3d 46", 23e29, |is| is.read_double()); } #[test] fn test_input_stream_skip_raw_bytes() { test_read("", |reader| { reader.skip_raw_bytes(0).unwrap(); }); test_read("aa bb", |reader| { reader.skip_raw_bytes(2).unwrap(); }); test_read("aa bb cc dd ee ff", |reader| { reader.skip_raw_bytes(6).unwrap(); }); } #[test] fn test_input_stream_read_raw_bytes() { test_read("", |reader| { assert_eq!( Vec::from(&b""[..]), reader.read_raw_bytes(0).expect("read_raw_bytes") ); }) } #[test] fn test_input_stream_limits() { test_read("aa bb cc", |is| { let old_limit = is.push_limit(1).unwrap(); assert_eq!(1, is.bytes_until_limit()); let r1 = is.read_raw_bytes(1).unwrap(); assert_eq!(&[0xaa as u8], &r1[..]); is.pop_limit(old_limit); let r2 = is.read_raw_bytes(2).unwrap(); assert_eq!(&[0xbb as u8, 0xcc], &r2[..]); }); } #[test] fn test_input_stream_io_read() { test_read("aa bb cc", |is| { let mut buf = [0; 3]; assert_eq!(Read::read(is, &mut buf).expect("io::Read"), 3); assert_eq!(buf, [0xaa, 0xbb, 0xcc]); }); } #[test] fn test_input_stream_io_bufread() { test_read("aa bb cc", |is| { assert_eq!( BufRead::fill_buf(is).expect("io::BufRead::fill_buf"), &[0xaa, 0xbb, 0xcc] ); BufRead::consume(is, 3); }); } #[test] fn test_input_stream_read_raw_bytes_into_huge() { let mut v = Vec::new(); for i in 0..READ_RAW_BYTES_MAX_ALLOC + 1000 { v.push((i % 10) as u8); } let mut slice: &[u8] = v.as_slice(); let mut is = CodedInputStream::new(&mut slice); let mut buf = Vec::new(); is.read_raw_bytes_into(READ_RAW_BYTES_MAX_ALLOC as u32 + 10, &mut buf) .expect("read"); assert_eq!(READ_RAW_BYTES_MAX_ALLOC + 10, buf.len()); buf.clear(); is.read_raw_bytes_into(1000 - 10, &mut buf).expect("read"); assert_eq!(1000 - 10, buf.len()); assert!(is.eof().expect("eof")); } }