Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions protobuf/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
/// Results in error if message is not fully initialized.
fn write_to(&self, os: &mut CodedOutputStream) -> ProtobufResult<()> {
self.check_initialized()?;

// cache sizes
self.compute_size();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is necessary?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indeed. the cached internal size is not used later.

// TODO: reserve additional
self.write_to_with_cached_sizes(os)?;

Ok(())
}

Expand All @@ -71,9 +66,6 @@ pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
let size = self.compute_size();
os.write_raw_varint32(size)?;
self.write_to_with_cached_sizes(os)?;

// TODO: assert we've written same number of bytes as computed

Ok(())
}

Expand Down Expand Up @@ -103,13 +95,26 @@ pub trait Message: fmt::Debug + Clear + Any + Send + Sync {
}
}

/// Write the message to the writer.
/// Write the message to the writer; an internal buffer is used.
fn write_to_writer(&self, w: &mut Write) -> ProtobufResult<()> {
w.with_coded_output_stream(|os| self.write_to(os))
}

/// Write the message to the writer.
fn write_to_writer_without_buffer(&self, w: &mut Write) -> ProtobufResult<()> {
// TODO: add a unbuffer version.
w.with_coded_output_stream(|os| {
os.use_internal_buffer = false;
self.write_to(os)
})
}

/// Write the message to bytes vec.
fn write_to_vec(&self, v: &mut Vec<u8>) -> ProtobufResult<()> {
let size = self.compute_size() as usize;
if v.capacity() - v.len() < size {
v.reserve(size - v.len());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think something is off here. Does this function end up writing to the start of v or to v.len() - 1? It seems that line 115 assumes the latter and line 116 assumes the former.

}
v.with_coded_output_stream(|os| self.write_to(os))
}

Expand Down
26 changes: 24 additions & 2 deletions protobuf/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,9 @@ pub struct CodedOutputStream<'a> {
buffer: &'a mut [u8],
// within buffer
position: usize,

// It's only works for `Write` trait.
pub use_internal_buffer: bool,
}

impl<'a> CodedOutputStream<'a> {
Expand All @@ -979,6 +982,7 @@ impl<'a> CodedOutputStream<'a> {
target: OutputTarget::Write(writer, buffer_storage),
buffer: buffer,
position: 0,
use_internal_buffer: true,
}
}

Expand All @@ -990,6 +994,7 @@ impl<'a> CodedOutputStream<'a> {
target: OutputTarget::Bytes,
buffer: bytes,
position: 0,
use_internal_buffer: true,
}
}

Expand All @@ -1002,6 +1007,7 @@ impl<'a> CodedOutputStream<'a> {
target: OutputTarget::Vec(vec),
buffer: &mut [],
position: 0,
use_internal_buffer: true,
}
}

Expand Down Expand Up @@ -1055,6 +1061,14 @@ impl<'a> CodedOutputStream<'a> {

/// Write a byte
pub fn write_raw_byte(&mut self, byte: u8) -> ProtobufResult<()> {
if !self.use_internal_buffer {
match self.target {
OutputTarget::Write(ref mut w, _) => w.write_all(&[byte])?,
_ => unreachable!(),
}
return Ok(());
}

if self.position as usize == self.buffer.len() {
self.refresh_buffer()?;
}
Expand All @@ -1065,6 +1079,14 @@ impl<'a> CodedOutputStream<'a> {

/// Write bytes
pub fn write_raw_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
if !self.use_internal_buffer {
match self.target {
OutputTarget::Write(ref mut w, _) => w.write_all(bytes)?,
_ => unreachable!(),
}
return Ok(());
}

if bytes.len() <= self.buffer.len() - self.position {
let bottom = self.position as usize;
let top = bottom + (bytes.len() as usize);
Expand Down Expand Up @@ -1111,7 +1133,7 @@ impl<'a> CodedOutputStream<'a> {

/// Write varint
pub fn write_raw_varint32(&mut self, value: u32) -> ProtobufResult<()> {
if self.buffer.len() - self.position >= 5 {
if self.use_internal_buffer && self.buffer.len() - self.position >= 5 {
// fast path
let len = varint::encode_varint32(value, &mut self.buffer[self.position..]);
self.position += len;
Expand All @@ -1126,7 +1148,7 @@ impl<'a> CodedOutputStream<'a> {

/// Write varint
pub fn write_raw_varint64(&mut self, value: u64) -> ProtobufResult<()> {
if self.buffer.len() - self.position >= 10 {
if self.use_internal_buffer && self.buffer.len() - self.position >= 10 {
// fast path
let len = varint::encode_varint64(value, &mut self.buffer[self.position..]);
self.position += len;
Expand Down