use crate::{Flat, buf::Buf};
#[doc(hidden)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Pos(pub(crate) u32);
impl Pos {
#[doc(hidden)]
pub const ZERO: Self = Self(0);
#[doc(hidden)]
#[must_use]
pub const fn offset(self, bytes: usize) -> Self {
Self(self.0 + bytes as u32)
}
}
#[cfg(feature = "alloc")]
pub struct Emitter<T: Flat, B: Buf = crate::buf::AlignedBuf<T>> {
buf: B,
_type: core::marker::PhantomData<T>,
}
#[cfg(not(feature = "alloc"))]
pub struct Emitter<T: Flat, B: Buf> {
buf: B,
_type: core::marker::PhantomData<T>,
}
impl<T: Flat, B: Buf> Emitter<T, B> {
#[doc(hidden)]
#[must_use]
pub fn new() -> Self {
Self { buf: B::empty(), _type: core::marker::PhantomData }
}
#[doc(hidden)]
#[must_use]
pub fn with_capacity(capacity: u32) -> Self {
let mut em = Self::new();
if capacity > 0 {
em.buf.reserve(capacity);
}
em
}
#[doc(hidden)]
#[must_use]
pub fn pos(&self) -> Pos {
Pos(self.buf.len())
}
#[doc(hidden)]
pub fn reserve<U: Flat>(&mut self) -> Pos {
self.buf.alloc::<U>()
}
pub(crate) unsafe fn write<U: Flat>(&mut self, pos: Pos, val: U) {
unsafe { crate::buf::write_flat(&mut self.buf, pos, val) };
}
pub(crate) unsafe fn patch_near(&mut self, at: Pos, target: Pos) {
unsafe { crate::buf::patch_near(&mut self.buf, at, target) };
}
pub(crate) unsafe fn write_bytes_internal(&mut self, at: Pos, src: *const u8, len: usize) {
unsafe { crate::buf::write_bytes(&mut self.buf, at, src, len) };
}
pub(crate) unsafe fn patch_list_header(&mut self, at: Pos, target: Pos, len: u32) {
unsafe { crate::buf::patch_list_header(&mut self.buf, at, target, len) };
}
#[doc(hidden)]
pub fn finish(self) -> crate::Region<T, B> {
unsafe { crate::Region::from_buf(self.buf) }
}
pub(crate) fn buf_ptr(&self) -> *const u8 {
self.buf.as_ptr()
}
pub(crate) fn reserve_bytes(&mut self, additional: u32) {
self.buf.reserve(additional);
}
pub(crate) fn alloc_segment_internal<U: Flat>(&mut self, count: u32) -> Pos {
crate::buf::alloc_segment::<U>(&mut self.buf, count)
}
pub(crate) unsafe fn patch_segment_next(&mut self, seg_pos: Pos, next_seg_pos: Pos) {
unsafe { crate::buf::patch_segment_next(&mut self.buf, seg_pos, next_seg_pos) };
}
pub(crate) fn into_buf(self) -> B {
self.buf
}
}
impl<T: Flat, B: Buf> Default for Emitter<T, B> {
fn default() -> Self {
Self::new()
}
}