mod buffer;
mod output_target;
pub(crate) mod with;
use std::io;
use std::io::Write;
use std::mem::MaybeUninit;
use std::ptr;
use std::slice;
use crate::byteorder::LITTLE_ENDIAN;
use crate::coded_output_stream::buffer::OutputBuffer;
use crate::coded_output_stream::output_target::OutputTarget;
use crate::error::ProtobufError;
use crate::rt::packed::vec_packed_enum_or_unknown_data_size;
use crate::rt::packed::vec_packed_fixed_data_size;
use crate::rt::packed::vec_packed_varint_data_size;
use crate::rt::packed::vec_packed_varint_zigzag_data_size;
use crate::varint::encode::encode_varint32;
use crate::varint::encode::encode_varint64;
use crate::varint::encode::encoded_varint64_len;
use crate::varint::MAX_VARINT_ENCODED_LEN;
use crate::wire_format;
use crate::wire_format::check_message_size;
use crate::wire_format::WireType;
use crate::wire_format::MAX_MESSAGE_SIZE;
use crate::zigzag::encode_zig_zag_32;
use crate::zigzag::encode_zig_zag_64;
use crate::Enum;
use crate::EnumOrUnknown;
use crate::Message;
use crate::MessageDyn;
use crate::MessageFull;
use crate::UnknownFields;
use crate::UnknownValueRef;
const OUTPUT_STREAM_BUFFER_SIZE: usize = 8 * 1024;
#[derive(Debug)]
pub struct CodedOutputStream<'a> {
target: OutputTarget<'a>,
buffer: OutputBuffer,
pos_of_buffer_start: u64,
}
impl<'a> CodedOutputStream<'a> {
pub fn new(writer: &'a mut dyn Write) -> CodedOutputStream<'a> {
let buffer_len = OUTPUT_STREAM_BUFFER_SIZE;
let mut buffer_storage = Vec::with_capacity(buffer_len);
let buffer = OutputBuffer::new(buffer_storage.spare_capacity_mut());
CodedOutputStream {
target: OutputTarget::Write(writer, buffer_storage),
buffer,
pos_of_buffer_start: 0,
}
}
pub fn bytes(bytes: &'a mut [u8]) -> CodedOutputStream<'a> {
let buffer =
ptr::slice_from_raw_parts_mut(bytes.as_mut_ptr() as *mut MaybeUninit<u8>, bytes.len());
let buffer = OutputBuffer::new(buffer);
CodedOutputStream {
target: OutputTarget::Bytes,
buffer,
pos_of_buffer_start: 0,
}
}
pub fn vec(vec: &'a mut Vec<u8>) -> CodedOutputStream<'a> {
let buffer = OutputBuffer::new(vec.spare_capacity_mut());
CodedOutputStream {
target: OutputTarget::Vec(vec),
buffer,
pos_of_buffer_start: 0,
}
}
pub(crate) fn reserve_additional(
&mut self,
additional: u32,
message: &str,
) -> crate::Result<()> {
if additional as usize <= self.buffer.unfilled_len() {
return Ok(());
}
match &mut self.target {
OutputTarget::Write(..) => Ok(()),
OutputTarget::Vec(v) => {
let reserve = (additional as usize)
.checked_add(self.buffer.pos_within_buf())
.unwrap();
v.reserve(reserve);
self.buffer.replace_buffer_keep_pos(v.spare_capacity_mut());
Ok(())
}
OutputTarget::Bytes => {
Err(ProtobufError::BufferHasNotEnoughCapacity(message.to_owned()).into())
}
}
}
pub(crate) fn reserve_additional_for_length_delimited(
&mut self,
size: u32,
message: &str,
) -> crate::Result<()> {
debug_assert!(
size <= MAX_MESSAGE_SIZE as u32,
"Caller of this function is responsible to guarantee \
that message size does not exceed; size: {}, MAX_MESSAGE_SIZE: {}",
size,
MAX_MESSAGE_SIZE,
);
let reserve = size + encoded_varint64_len(size as u64) as u32;
self.reserve_additional(reserve, message)
}
pub fn total_bytes_written(&self) -> u64 {
self.pos_of_buffer_start + self.buffer.pos_within_buf() as u64
}
pub fn check_eof(&self) {
match self.target {
OutputTarget::Bytes => {
assert_eq!(
self.buffer.buffer().len() as u64,
self.buffer.pos_within_buf() as u64
);
}
OutputTarget::Write(..) | OutputTarget::Vec(..) => {
panic!("must not be called with Writer or Vec");
}
}
}
fn refresh_buffer(&mut self) -> crate::Result<()> {
match self.target {
OutputTarget::Write(ref mut write, _) => {
write.write_all(self.buffer.filled())?;
self.pos_of_buffer_start += self.buffer.pos_within_buf() as u64;
self.buffer.rewind();
}
OutputTarget::Vec(ref mut vec) => unsafe {
let vec_len = vec.len();
assert!(vec_len + self.buffer.pos_within_buf() <= vec.capacity());
vec.set_len(vec_len + self.buffer.pos_within_buf());
vec.reserve(1);
self.pos_of_buffer_start += self.buffer.pos_within_buf() as u64;
self.buffer = OutputBuffer::new(vec.spare_capacity_mut());
},
OutputTarget::Bytes => {
return Err(ProtobufError::IoError(io::Error::new(
io::ErrorKind::Other,
"given slice is too small to serialize the message",
))
.into());
}
}
Ok(())
}
pub fn flush(&mut self) -> crate::Result<()> {
match &mut self.target {
OutputTarget::Bytes => Ok(()),
OutputTarget::Vec(vec) => {
let vec_len = vec.len();
assert!(vec_len + self.buffer.pos_within_buf() <= vec.capacity());
unsafe {
vec.set_len(vec_len + self.buffer.pos_within_buf());
}
self.pos_of_buffer_start += self.buffer.pos_within_buf() as u64;
self.buffer = OutputBuffer::new(vec.spare_capacity_mut());
Ok(())
}
OutputTarget::Write(..) => self.refresh_buffer(),
}
}
pub fn write_raw_byte(&mut self, byte: u8) -> crate::Result<()> {
if self.buffer.unfilled_len() == 0 {
self.refresh_buffer()?;
}
unsafe { self.buffer.write_byte(byte) };
Ok(())
}
pub fn write_raw_bytes(&mut self, bytes: &[u8]) -> crate::Result<()> {
if bytes.len() <= self.buffer.unfilled_len() {
unsafe { self.buffer.write_bytes(bytes) };
return Ok(());
}
self.refresh_buffer()?;
assert!(self.buffer.pos_within_buf() == 0);
if bytes.len() <= self.buffer.unfilled_len() {
unsafe { self.buffer.write_bytes(bytes) };
return Ok(());
}
match self.target {
OutputTarget::Bytes => {
unreachable!();
}
OutputTarget::Write(ref mut write, _) => {
write.write_all(bytes)?;
}
OutputTarget::Vec(ref mut vec) => {
assert!(self.buffer.pos_within_buf() == 0);
vec.extend(bytes);
self.buffer = OutputBuffer::new(vec.spare_capacity_mut());
self.pos_of_buffer_start += bytes.len() as u64;
}
}
Ok(())
}
pub fn write_tag(&mut self, field_number: u32, wire_type: WireType) -> crate::Result<()> {
self.write_raw_varint32(wire_format::Tag::make(field_number, wire_type).value())
}
pub fn write_raw_varint32(&mut self, value: u32) -> crate::Result<()> {
if self.buffer.unfilled_len() >= 5 {
unsafe {
let len = encode_varint32(value, self.buffer.unfilled());
self.buffer.advance(len);
};
Ok(())
} else {
let buf = &mut [0u8; 5];
let len = encode_varint32(value, unsafe {
slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut MaybeUninit<u8>, buf.len())
});
self.write_raw_bytes(&buf[..len])
}
}
pub fn write_raw_varint64(&mut self, value: u64) -> crate::Result<()> {
if self.buffer.unfilled_len() >= MAX_VARINT_ENCODED_LEN {
unsafe {
let len = encode_varint64(value, self.buffer.unfilled());
self.buffer.advance(len);
};
Ok(())
} else {
let buf = &mut [0u8; MAX_VARINT_ENCODED_LEN];
let len = encode_varint64(value, unsafe {
slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut MaybeUninit<u8>, buf.len())
});
self.write_raw_bytes(&buf[..len])
}
}
pub fn write_raw_little_endian32(&mut self, value: u32) -> crate::Result<()> {
self.write_raw_bytes(&value.to_le_bytes())
}
pub fn write_raw_little_endian64(&mut self, value: u64) -> crate::Result<()> {
self.write_raw_bytes(&value.to_le_bytes())
}
pub fn write_float_no_tag(&mut self, value: f32) -> crate::Result<()> {
self.write_raw_little_endian32(value.to_bits())
}
pub fn write_double_no_tag(&mut self, value: f64) -> crate::Result<()> {
self.write_raw_little_endian64(value.to_bits())
}
pub fn write_float(&mut self, field_number: u32, value: f32) -> crate::Result<()> {
self.write_tag(field_number, WireType::Fixed32)?;
self.write_float_no_tag(value)?;
Ok(())
}
pub fn write_double(&mut self, field_number: u32, value: f64) -> crate::Result<()> {
self.write_tag(field_number, WireType::Fixed64)?;
self.write_double_no_tag(value)?;
Ok(())
}
pub fn write_uint64_no_tag(&mut self, value: u64) -> crate::Result<()> {
self.write_raw_varint64(value)
}
pub fn write_uint32_no_tag(&mut self, value: u32) -> crate::Result<()> {
self.write_raw_varint32(value)
}
pub fn write_int64_no_tag(&mut self, value: i64) -> crate::Result<()> {
self.write_raw_varint64(value as u64)
}
pub fn write_int32_no_tag(&mut self, value: i32) -> crate::Result<()> {
self.write_raw_varint64(value as u64)
}
pub fn write_sint64_no_tag(&mut self, value: i64) -> crate::Result<()> {
self.write_uint64_no_tag(encode_zig_zag_64(value))
}
pub fn write_sint32_no_tag(&mut self, value: i32) -> crate::Result<()> {
self.write_uint32_no_tag(encode_zig_zag_32(value))
}
pub fn write_fixed64_no_tag(&mut self, value: u64) -> crate::Result<()> {
self.write_raw_little_endian64(value)
}
pub fn write_fixed32_no_tag(&mut self, value: u32) -> crate::Result<()> {
self.write_raw_little_endian32(value)
}
pub fn write_sfixed64_no_tag(&mut self, value: i64) -> crate::Result<()> {
self.write_raw_little_endian64(value as u64)
}
pub fn write_sfixed32_no_tag(&mut self, value: i32) -> crate::Result<()> {
self.write_raw_little_endian32(value as u32)
}
pub fn write_bool_no_tag(&mut self, value: bool) -> crate::Result<()> {
self.write_raw_varint32(if value { 1 } else { 0 })
}
pub fn write_enum_no_tag(&mut self, value: i32) -> crate::Result<()> {
self.write_int32_no_tag(value)
}
pub fn write_enum_obj_no_tag<E>(&mut self, value: E) -> crate::Result<()>
where
E: Enum,
{
self.write_enum_no_tag(value.value())
}
pub fn write_enum_or_unknown_no_tag<E>(&mut self, value: EnumOrUnknown<E>) -> crate::Result<()>
where
E: Enum,
{
self.write_enum_no_tag(value.value())
}
pub fn write_unknown_no_tag(&mut self, unknown: UnknownValueRef) -> crate::Result<()> {
match unknown {
UnknownValueRef::Fixed64(fixed64) => self.write_raw_little_endian64(fixed64),
UnknownValueRef::Fixed32(fixed32) => self.write_raw_little_endian32(fixed32),
UnknownValueRef::Varint(varint) => self.write_raw_varint64(varint),
UnknownValueRef::LengthDelimited(bytes) => self.write_bytes_no_tag(bytes),
}
}
pub fn write_uint64(&mut self, field_number: u32, value: u64) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_uint64_no_tag(value)?;
Ok(())
}
pub fn write_uint32(&mut self, field_number: u32, value: u32) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_uint32_no_tag(value)?;
Ok(())
}
pub fn write_int64(&mut self, field_number: u32, value: i64) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_int64_no_tag(value)?;
Ok(())
}
pub fn write_int32(&mut self, field_number: u32, value: i32) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_int32_no_tag(value)?;
Ok(())
}
pub fn write_sint64(&mut self, field_number: u32, value: i64) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_sint64_no_tag(value)?;
Ok(())
}
pub fn write_sint32(&mut self, field_number: u32, value: i32) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_sint32_no_tag(value)?;
Ok(())
}
pub fn write_fixed64(&mut self, field_number: u32, value: u64) -> crate::Result<()> {
self.write_tag(field_number, WireType::Fixed64)?;
self.write_fixed64_no_tag(value)?;
Ok(())
}
pub fn write_fixed32(&mut self, field_number: u32, value: u32) -> crate::Result<()> {
self.write_tag(field_number, WireType::Fixed32)?;
self.write_fixed32_no_tag(value)?;
Ok(())
}
pub fn write_sfixed64(&mut self, field_number: u32, value: i64) -> crate::Result<()> {
self.write_tag(field_number, WireType::Fixed64)?;
self.write_sfixed64_no_tag(value)?;
Ok(())
}
pub fn write_sfixed32(&mut self, field_number: u32, value: i32) -> crate::Result<()> {
self.write_tag(field_number, WireType::Fixed32)?;
self.write_sfixed32_no_tag(value)?;
Ok(())
}
pub fn write_bool(&mut self, field_number: u32, value: bool) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_bool_no_tag(value)?;
Ok(())
}
pub fn write_enum(&mut self, field_number: u32, value: i32) -> crate::Result<()> {
self.write_tag(field_number, WireType::Varint)?;
self.write_enum_no_tag(value)?;
Ok(())
}
pub fn write_enum_obj<E>(&mut self, field_number: u32, value: E) -> crate::Result<()>
where
E: Enum,
{
self.write_enum(field_number, value.value())
}
pub fn write_enum_or_unknown<E>(
&mut self,
field_number: u32,
value: EnumOrUnknown<E>,
) -> crate::Result<()>
where
E: Enum,
{
self.write_enum(field_number, value.value())
}
pub fn write_unknown(
&mut self,
field_number: u32,
value: UnknownValueRef,
) -> crate::Result<()> {
self.write_tag(field_number, value.wire_type())?;
self.write_unknown_no_tag(value)?;
Ok(())
}
pub fn write_unknown_fields(&mut self, fields: &UnknownFields) -> crate::Result<()> {
for (number, value) in fields {
self.write_unknown(number, value)?;
}
Ok(())
}
pub(crate) fn write_unknown_fields_sorted(
&mut self,
fields: &UnknownFields,
) -> crate::Result<()> {
let mut fields: Vec<_> = fields.iter().collect();
fields.sort_by_key(|(n, _)| *n);
for (number, value) in fields {
self.write_unknown(number, value)?;
}
Ok(())
}
pub fn write_bytes_no_tag(&mut self, bytes: &[u8]) -> crate::Result<()> {
self.write_raw_varint32(bytes.len() as u32)?;
self.write_raw_bytes(bytes)?;
Ok(())
}
pub fn write_string_no_tag(&mut self, s: &str) -> crate::Result<()> {
self.write_bytes_no_tag(s.as_bytes())
}
pub fn write_message_no_tag<M: Message>(&mut self, msg: &M) -> crate::Result<()> {
msg.write_length_delimited_to(self)
}
pub fn write_message_no_tag_dyn(&mut self, msg: &dyn MessageDyn) -> crate::Result<()> {
let size = msg.compute_size_dyn();
let size = check_message_size(size)?;
self.write_raw_varint32(size)?;
msg.write_to_dyn(self)?;
Ok(())
}
pub fn write_bytes(&mut self, field_number: u32, bytes: &[u8]) -> crate::Result<()> {
self.write_tag(field_number, WireType::LengthDelimited)?;
self.write_bytes_no_tag(bytes)?;
Ok(())
}
pub fn write_string(&mut self, field_number: u32, s: &str) -> crate::Result<()> {
self.write_tag(field_number, WireType::LengthDelimited)?;
self.write_string_no_tag(s)?;
Ok(())
}
pub fn write_repeated_packed_float_no_tag(&mut self, values: &[f32]) -> crate::Result<()> {
if LITTLE_ENDIAN {
let bytes =
unsafe { slice::from_raw_parts(values.as_ptr() as *const u8, values.len() * 4) };
self.write_raw_bytes(bytes)
} else {
for v in values {
self.write_float_no_tag(*v)?;
}
Ok(())
}
}
pub fn write_repeated_packed_float(
&mut self,
field_number: u32,
values: &[f32],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_fixed_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_float_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_double_no_tag(&mut self, values: &[f64]) -> crate::Result<()> {
if LITTLE_ENDIAN {
let bytes =
unsafe { slice::from_raw_parts(values.as_ptr() as *const u8, values.len() * 8) };
self.write_raw_bytes(bytes)
} else {
for v in values {
self.write_double_no_tag(*v)?;
}
Ok(())
}
}
pub fn write_repeated_packed_double(
&mut self,
field_number: u32,
values: &[f64],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_fixed_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_double_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_fixed32_no_tag(&mut self, values: &[u32]) -> crate::Result<()> {
if LITTLE_ENDIAN {
let bytes =
unsafe { slice::from_raw_parts(values.as_ptr() as *const u8, values.len() * 4) };
self.write_raw_bytes(bytes)?;
} else {
for v in values {
self.write_fixed32_no_tag(*v)?;
}
}
Ok(())
}
pub fn write_repeated_packed_fixed32(
&mut self,
field_number: u32,
values: &[u32],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_fixed_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_fixed32_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_fixed64_no_tag(&mut self, values: &[u64]) -> crate::Result<()> {
if LITTLE_ENDIAN {
let bytes =
unsafe { slice::from_raw_parts(values.as_ptr() as *const u8, values.len() * 8) };
self.write_raw_bytes(bytes)?;
} else {
for v in values {
self.write_fixed64_no_tag(*v)?;
}
}
Ok(())
}
pub fn write_repeated_packed_fixed64(
&mut self,
field_number: u32,
values: &[u64],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_fixed_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_fixed64_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_sfixed32_no_tag(&mut self, values: &[i32]) -> crate::Result<()> {
if LITTLE_ENDIAN {
let bytes =
unsafe { slice::from_raw_parts(values.as_ptr() as *const u8, values.len() * 4) };
self.write_raw_bytes(bytes)?;
} else {
for v in values {
self.write_sfixed32_no_tag(*v)?;
}
}
Ok(())
}
pub fn write_repeated_packed_sfixed32(
&mut self,
field_number: u32,
values: &[i32],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_fixed_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_sfixed32_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_sfixed64_no_tag(&mut self, values: &[i64]) -> crate::Result<()> {
if LITTLE_ENDIAN {
let bytes =
unsafe { slice::from_raw_parts(values.as_ptr() as *const u8, values.len() * 8) };
self.write_raw_bytes(bytes)?;
} else {
for v in values {
self.write_sfixed64_no_tag(*v)?;
}
}
Ok(())
}
pub fn write_repeated_packed_sfixed64(
&mut self,
field_number: u32,
values: &[i64],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_fixed_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_sfixed64_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_int32_no_tag(&mut self, values: &[i32]) -> crate::Result<()> {
for v in values {
self.write_int32_no_tag(*v)?;
}
Ok(())
}
pub fn write_repeated_packed_int32(
&mut self,
field_number: u32,
values: &[i32],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_varint_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_int32_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_int64_no_tag(&mut self, values: &[i64]) -> crate::Result<()> {
for v in values {
self.write_int64_no_tag(*v)?;
}
Ok(())
}
pub fn write_repeated_packed_int64(
&mut self,
field_number: u32,
values: &[i64],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_varint_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_int64_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_uint32_no_tag(&mut self, values: &[u32]) -> crate::Result<()> {
for v in values {
self.write_uint32_no_tag(*v)?;
}
Ok(())
}
pub fn write_repeated_packed_uint32(
&mut self,
field_number: u32,
values: &[u32],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_varint_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_uint32_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_uint64_no_tag(&mut self, values: &[u64]) -> crate::Result<()> {
for v in values {
self.write_uint64_no_tag(*v)?;
}
Ok(())
}
pub fn write_repeated_packed_uint64(
&mut self,
field_number: u32,
values: &[u64],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_varint_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_uint64_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_sint32_no_tag(&mut self, values: &[i32]) -> crate::Result<()> {
for v in values {
self.write_sint32_no_tag(*v)?;
}
Ok(())
}
pub fn write_repeated_packed_sint32(
&mut self,
field_number: u32,
values: &[i32],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_varint_zigzag_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_sint32_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_sint64_no_tag(&mut self, values: &[i64]) -> crate::Result<()> {
for v in values {
self.write_sint64_no_tag(*v)?;
}
Ok(())
}
pub fn write_repeated_packed_sint64(
&mut self,
field_number: u32,
values: &[i64],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_varint_zigzag_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_sint64_no_tag(values)?;
Ok(())
}
pub fn write_repeated_packed_bool_no_tag(&mut self, values: &[bool]) -> crate::Result<()> {
for v in values {
self.write_bool_no_tag(*v)?;
}
Ok(())
}
pub fn write_repeated_packed_bool(
&mut self,
field_number: u32,
values: &[bool],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_fixed_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_bool_no_tag(values)?;
Ok(())
}
#[inline]
pub fn write_repeated_packed_enum_or_unknown_no_tag<E: Enum>(
&mut self,
values: &[EnumOrUnknown<E>],
) -> crate::Result<()> {
self.write_repeated_packed_int32_no_tag(EnumOrUnknown::cast_to_values(values))
}
pub fn write_repeated_packed_enum_or_unknown<E: Enum>(
&mut self,
field_number: u32,
values: &[EnumOrUnknown<E>],
) -> crate::Result<()> {
if values.is_empty() {
return Ok(());
}
self.write_tag(field_number, WireType::LengthDelimited)?;
let data_size = vec_packed_enum_or_unknown_data_size(values);
self.write_raw_varint32(data_size as u32)?;
self.write_repeated_packed_enum_or_unknown_no_tag(values)?;
Ok(())
}
pub fn write_message<M: MessageFull>(
&mut self,
field_number: u32,
msg: &M,
) -> crate::Result<()> {
self.write_tag(field_number, WireType::LengthDelimited)?;
self.write_message_no_tag(msg)?;
Ok(())
}
pub fn write_message_dyn(
&mut self,
field_number: u32,
msg: &dyn MessageDyn,
) -> crate::Result<()> {
self.write_tag(field_number, WireType::LengthDelimited)?;
self.write_message_no_tag_dyn(msg)?;
Ok(())
}
}
impl<'a> Write for CodedOutputStream<'a> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.write_raw_bytes(buf)?;
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
CodedOutputStream::flush(self).map_err(Into::into)
}
}
impl<'a> Drop for CodedOutputStream<'a> {
fn drop(&mut self) {
CodedOutputStream::flush(self).expect("failed to flush");
}
}
#[cfg(test)]
mod test {
use std::iter;
use super::*;
use crate::hex::decode_hex;
use crate::hex::encode_hex;
fn test_write<F>(expected: &str, mut gen: F)
where
F: FnMut(&mut CodedOutputStream) -> crate::Result<()>,
{
let expected_bytes = decode_hex(expected);
{
let mut v = Vec::new();
{
let mut os = CodedOutputStream::new(&mut v as &mut dyn Write);
gen(&mut os).unwrap();
os.flush().unwrap();
}
assert_eq!(encode_hex(&expected_bytes), encode_hex(&v));
}
{
let mut r = Vec::with_capacity(expected_bytes.len());
r.resize(expected_bytes.len(), 0);
{
let mut os = CodedOutputStream::bytes(&mut r);
gen(&mut os).unwrap();
os.check_eof();
}
assert_eq!(encode_hex(&expected_bytes), encode_hex(&r));
}
{
let mut r = Vec::new();
r.extend(&[11, 22, 33, 44, 55, 66, 77]);
{
let mut os = CodedOutputStream::vec(&mut r);
gen(&mut os).unwrap();
os.flush().unwrap();
}
r.drain(..7);
assert_eq!(encode_hex(&expected_bytes), encode_hex(&r));
}
}
#[test]
fn test_output_stream_write_raw_byte() {
test_write("a1", |os| os.write_raw_byte(0xa1));
}
#[test]
fn test_output_stream_write_tag() {
test_write("08", |os| os.write_tag(1, WireType::Varint));
}
#[test]
#[cfg_attr(miri, ignore)] fn test_output_stream_write_raw_bytes() {
test_write("00 ab", |os| os.write_raw_bytes(&[0x00, 0xab]));
let expected = iter::repeat("01 02 03 04")
.take(2048)
.collect::<Vec<_>>()
.join(" ");
test_write(&expected, |os| {
for _ in 0..2048 {
os.write_raw_bytes(&[0x01, 0x02, 0x03, 0x04])?;
}
Ok(())
});
}
#[test]
fn test_output_stream_write_raw_varint32() {
test_write("96 01", |os| os.write_raw_varint32(150));
test_write("ff ff ff ff 0f", |os| os.write_raw_varint32(0xffffffff));
}
#[test]
fn test_output_stream_write_raw_varint64() {
test_write("96 01", |os| os.write_raw_varint64(150));
test_write("ff ff ff ff ff ff ff ff ff 01", |os| {
os.write_raw_varint64(0xffffffffffffffff)
});
}
#[test]
fn test_output_stream_write_int32_no_tag() {
test_write("ff ff ff ff ff ff ff ff ff 01", |os| {
os.write_int32_no_tag(-1)
});
}
#[test]
fn test_output_stream_write_int64_no_tag() {
test_write("ff ff ff ff ff ff ff ff ff 01", |os| {
os.write_int64_no_tag(-1)
});
}
#[test]
fn test_output_stream_write_raw_little_endian32() {
test_write("f1 e2 d3 c4", |os| os.write_raw_little_endian32(0xc4d3e2f1));
}
#[test]
fn test_output_stream_write_float_no_tag() {
test_write("95 73 13 61", |os| os.write_float_no_tag(17e19));
}
#[test]
fn test_output_stream_write_double_no_tag() {
test_write("40 d5 ab 68 b3 07 3d 46", |os| {
os.write_double_no_tag(23e29)
});
}
#[test]
fn test_output_stream_write_raw_little_endian64() {
test_write("f1 e2 d3 c4 b5 a6 07 f8", |os| {
os.write_raw_little_endian64(0xf807a6b5c4d3e2f1)
});
}
#[test]
fn test_output_stream_io_write() {
let expected = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77];
{
let mut v = Vec::new();
{
let mut os = CodedOutputStream::new(&mut v as &mut dyn Write);
Write::write(&mut os, &expected).expect("io::Write::write");
Write::flush(&mut os).expect("io::Write::flush");
}
assert_eq!(expected, *v);
}
{
let mut v = Vec::with_capacity(expected.len());
v.resize(expected.len(), 0);
{
let mut os = CodedOutputStream::bytes(&mut v);
Write::write(&mut os, &expected).expect("io::Write::write");
Write::flush(&mut os).expect("io::Write::flush");
os.check_eof();
}
assert_eq!(expected, *v);
}
{
let mut v = Vec::new();
{
let mut os = CodedOutputStream::vec(&mut v);
Write::write(&mut os, &expected).expect("io::Write::write");
Write::flush(&mut os).expect("io::Write::flush");
}
assert_eq!(expected, *v);
}
}
#[test]
fn flush_for_vec_does_not_allocate_more() {
let mut v = Vec::with_capacity(10);
{
let mut os = CodedOutputStream::vec(&mut v);
for i in 0..10 {
os.write_raw_byte(i as u8).unwrap();
}
os.flush().unwrap();
}
assert_eq!(10, v.len());
assert_eq!(10, v.capacity());
}
#[test]
fn total_bytes_written_to_bytes() {
let mut buf = vec![0; 10];
let mut stream = CodedOutputStream::bytes(&mut buf);
assert_eq!(0, stream.total_bytes_written());
stream.write_raw_bytes(&[11, 22]).unwrap();
assert_eq!(2, stream.total_bytes_written());
stream.write_raw_bytes(&[33, 44, 55]).unwrap();
assert_eq!(5, stream.total_bytes_written());
}
#[test]
fn total_bytes_written_to_vec() {
let mut buf = Vec::new();
let mut stream = CodedOutputStream::vec(&mut buf);
for i in 0..100 {
stream.write_raw_bytes(&[0, 1, 2]).unwrap();
assert_eq!((i + 1) * 3, stream.total_bytes_written());
}
}
}