use core::num::NonZeroUsize;
use super::super::transcode_progress::TranscodeProgress;
pub(in crate::transcode) struct TranscodeState<'a, Input, Output> {
input: &'a [Input],
output: &'a mut [Output],
input_start: usize,
output_start: usize,
input_cursor: usize,
output_cursor: usize,
}
impl<'a, Input, Output> TranscodeState<'a, Input, Output> {
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn new(
input: &'a [Input],
input_index: usize,
output: &'a mut [Output],
output_index: usize,
) -> Self {
debug_assert!(
input_index <= input.len(),
"input index must be within the input slice",
);
Self {
input,
output,
input_start: input_index,
output_start: output_index,
input_cursor: input_index,
output_cursor: output_index,
}
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn input(&self) -> &[Input] {
self.input
}
#[inline(always)]
pub(in crate::transcode) fn output_mut(&mut self) -> &mut [Output] {
self.output
}
#[inline(always)]
pub(in crate::transcode) fn input_output_mut(
&mut self,
) -> (&[Input], &mut [Output]) {
(self.input, self.output)
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) const fn input_start(&self) -> usize {
self.input_start
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) const fn output_start(&self) -> usize {
self.output_start
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) const fn input_cursor(&self) -> usize {
self.input_cursor
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) const fn output_cursor(&self) -> usize {
self.output_cursor
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn has_input(&self) -> bool {
self.input_cursor < self.input.len()
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn needs_output(&self) -> bool {
self.output_cursor == self.output.len()
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn available_input(&self) -> usize {
self.input.len() - self.input_cursor
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn available_output(&self) -> usize {
self.output.len().saturating_sub(self.output_cursor)
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) const fn read(&self) -> usize {
self.input_cursor - self.input_start
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) const fn written(&self) -> usize {
self.output_cursor - self.output_start
}
#[inline(always)]
pub(in crate::transcode) fn advance_input(&mut self, read: usize) {
self.input_cursor += read;
}
#[inline(always)]
pub(in crate::transcode) fn advance_output(&mut self, written: usize) {
self.output_cursor += written;
}
#[inline(always)]
pub(in crate::transcode) fn advance(
&mut self,
read: usize,
written: usize,
) {
self.advance_input(read);
self.advance_output(written);
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn complete_progress(&self) -> TranscodeProgress {
TranscodeProgress::complete(self.read(), self.written())
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn need_input_progress(
&self,
required: NonZeroUsize,
available: usize,
) -> TranscodeProgress {
TranscodeProgress::need_input(
self.input_cursor,
required,
available,
self.read(),
self.written(),
)
}
#[inline(always)]
#[must_use]
pub(in crate::transcode) fn need_output_progress(
&self,
required: NonZeroUsize,
available: usize,
) -> TranscodeProgress {
TranscodeProgress::need_output(
self.output_cursor,
required,
available,
self.read(),
self.written(),
)
}
}