use crate::{
Flat, Region,
buf::Buf,
emitter::{Emitter, Pos},
};
#[doc(hidden)]
pub trait Patch {
fn alloc<T: Flat>(&mut self) -> Pos;
unsafe fn write_flat<T: Flat>(&mut self, at: Pos, val: T);
unsafe fn patch_near<T: Flat>(&mut self, at: Pos, target: Pos);
unsafe fn patch_list_header<T: Flat>(&mut self, at: Pos, target: Pos, len: u32);
unsafe fn write_bytes(&mut self, at: Pos, src: *const u8, len: usize);
fn alloc_segment<T: Flat>(&mut self, count: u32) -> Pos;
unsafe fn patch_segment_next<T: Flat>(&mut self, seg_pos: Pos, next_seg_pos: Pos);
fn byte_len(&self) -> usize;
fn raw_ptr(&self) -> *const u8;
fn reserve(&mut self, additional: u32);
}
impl<R: Flat, B: Buf> Patch for Emitter<R, B> {
fn alloc<T: Flat>(&mut self) -> Pos {
self.reserve::<T>()
}
unsafe fn write_flat<T: Flat>(&mut self, at: Pos, val: T) {
unsafe { self.write(at, val) };
}
unsafe fn patch_near<T: Flat>(&mut self, at: Pos, target: Pos) {
unsafe { self.patch_near(at, target) };
}
unsafe fn patch_list_header<T: Flat>(&mut self, at: Pos, target: Pos, len: u32) {
unsafe { self.patch_list_header(at, target, len) };
}
unsafe fn write_bytes(&mut self, at: Pos, src: *const u8, len: usize) {
unsafe { self.write_bytes_internal(at, src, len) };
}
fn alloc_segment<T: Flat>(&mut self, count: u32) -> Pos {
self.alloc_segment_internal::<T>(count)
}
unsafe fn patch_segment_next<T: Flat>(&mut self, seg_pos: Pos, next_seg_pos: Pos) {
unsafe { self.patch_segment_next(seg_pos, next_seg_pos) };
}
fn byte_len(&self) -> usize {
self.pos().0 as usize
}
fn raw_ptr(&self) -> *const u8 {
self.buf_ptr()
}
fn reserve(&mut self, additional: u32) {
self.reserve_bytes(additional);
}
}
impl<R: Flat, B: Buf> Patch for Region<R, B> {
fn alloc<T: Flat>(&mut self) -> Pos {
self.alloc_internal::<T>()
}
unsafe fn write_flat<T: Flat>(&mut self, at: Pos, val: T) {
unsafe { self.write_flat_internal(at, val) };
}
unsafe fn patch_near<T: Flat>(&mut self, at: Pos, target: Pos) {
unsafe { self.patch_near_internal(at, target) };
}
unsafe fn patch_list_header<T: Flat>(&mut self, at: Pos, target: Pos, len: u32) {
unsafe { self.patch_list_header_internal(at, target, len) };
}
unsafe fn write_bytes(&mut self, at: Pos, src: *const u8, len: usize) {
unsafe { self.write_bytes_internal(at, src, len) };
}
fn alloc_segment<T: Flat>(&mut self, count: u32) -> Pos {
self.alloc_segment_internal::<T>(count)
}
unsafe fn patch_segment_next<T: Flat>(&mut self, seg_pos: Pos, next_seg_pos: Pos) {
unsafe { self.patch_segment_next_internal(seg_pos, next_seg_pos) };
}
fn byte_len(&self) -> usize {
Self::byte_len(self)
}
fn raw_ptr(&self) -> *const u8 {
self.deref_raw()
}
fn reserve(&mut self, additional: u32) {
self.reserve_internal(additional);
}
}