protobuf/coded_output_stream/
buffer.rsuse std::fmt;
use std::fmt::Formatter;
use std::mem::MaybeUninit;
use std::slice;
use crate::misc::maybe_uninit_write_slice;
pub(crate) struct OutputBuffer {
buffer: *mut [MaybeUninit<u8>],
pos_within_buf: usize,
}
impl fmt::Debug for OutputBuffer {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("OutputBuffer")
.field("buffer.len", &self.buffer().len())
.field("pos_within_buf", &self.pos_within_buf)
.finish()
}
}
impl OutputBuffer {
#[inline]
pub(crate) fn new(buffer: *mut [MaybeUninit<u8>]) -> OutputBuffer {
Self {
buffer,
pos_within_buf: 0,
}
}
#[inline]
pub(crate) fn buffer(&self) -> &[MaybeUninit<u8>] {
unsafe { &*self.buffer }
}
#[inline]
fn buffer_mut(&mut self) -> &mut [MaybeUninit<u8>] {
unsafe { &mut *self.buffer }
}
#[inline]
pub(crate) fn pos_within_buf(&self) -> usize {
self.pos_within_buf
}
#[inline]
pub(crate) fn filled(&self) -> &[u8] {
unsafe { slice::from_raw_parts_mut(self.buffer as *mut u8, self.pos_within_buf) }
}
#[inline]
pub(crate) fn unfilled(&mut self) -> &mut [MaybeUninit<u8>] {
let pos_within_buf = self.pos_within_buf;
unsafe { self.buffer_mut().get_unchecked_mut(pos_within_buf..) }
}
#[inline]
pub(crate) fn unfilled_len(&self) -> usize {
self.buffer().len() - self.pos_within_buf
}
#[inline]
pub(crate) unsafe fn advance(&mut self, n: usize) {
debug_assert!(n <= self.unfilled_len());
self.pos_within_buf += n;
}
#[inline]
pub(crate) fn rewind(&mut self) {
self.pos_within_buf = 0;
}
#[inline]
pub(crate) fn replace_buffer_keep_pos(&mut self, buffer: *mut [MaybeUninit<u8>]) {
unsafe {
assert!(self.pos_within_buf <= (&*buffer).len());
}
self.buffer = buffer;
}
#[inline]
pub(crate) unsafe fn write_byte(&mut self, b: u8) {
debug_assert!(self.unfilled_len() >= 1);
let pos_within_buf = self.pos_within_buf;
self.buffer_mut().get_unchecked_mut(pos_within_buf).write(b);
self.pos_within_buf += 1;
}
#[inline]
pub(crate) unsafe fn write_bytes(&mut self, bytes: &[u8]) {
debug_assert!(self.unfilled_len() >= bytes.len());
let bottom = self.pos_within_buf as usize;
let top = bottom + (bytes.len() as usize);
let buffer = self.buffer_mut().get_unchecked_mut(bottom..top);
maybe_uninit_write_slice(buffer, bytes);
self.pos_within_buf += bytes.len();
}
}