Skip to content

Commit

Permalink
Update WriteBuf
Browse files Browse the repository at this point in the history
  • Loading branch information
osa1 committed Aug 26, 2020
1 parent 344cc3f commit a84f426
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions rts/motoko-rts/src/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ macro_rules! format {
})
}

/// A stack-allocated buffer that implements `core::fmt::Write`. `Write` methods will write to the
/// buffer until it's filled and then ignore the rest, without failing.
pub(crate) struct WriteBuf<'a> {
buf: &'a mut [u8],
offset: usize,
Expand All @@ -76,23 +78,18 @@ impl<'a> WriteBuf<'a> {
}
}

// https://stackoverflow.com/questions/39488327/how-to-format-output-to-a-byte-array-with-no-std-and-no-allocator
impl<'a> fmt::Write for WriteBuf<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
// Amount of space left in the write buffer
let buf_space_left = self.buf.len() - self.offset;
let buf = &mut self.buf[self.offset..];
// Copy the bytes to the buffer. Note that the buffer and the copied slice have to have the
// same length otherwise `copy_from_slice` panics.
let bytes = s.as_bytes();
// Skip over already-copied data
let remainder = &mut self.buf[self.offset..];
// Check if there is space remaining (return error instead of panicking)
if remainder.len() < bytes.len() {
return Err(core::fmt::Error);
}
// Make the two slices the same length
let remainder = &mut remainder[..bytes.len()];
// Copy
remainder.copy_from_slice(bytes);
// Update offset to avoid overwriting
self.offset += bytes.len();

let copy_len = core::cmp::min(buf_space_left, bytes.len());
(&mut buf[..copy_len]).copy_from_slice(&bytes[..copy_len]);
// Update offset
self.offset += copy_len;
Ok(())
}
}
Expand Down

0 comments on commit a84f426

Please sign in to comment.